2023-08-27 07:07:35 +02:00
|
|
|
import 'package:flutter/material.dart';
|
2024-06-17 17:47:04 +02:00
|
|
|
import 'package:immich_mobile/models/search/search_curated_content.model.dart';
|
|
|
|
import 'package:immich_mobile/widgets/search/search_map_thumbnail.dart';
|
2024-05-07 06:04:21 +02:00
|
|
|
import 'package:immich_mobile/widgets/search/thumbnail_with_info.dart';
|
2024-05-01 04:36:40 +02:00
|
|
|
import 'package:immich_mobile/entities/store.entity.dart';
|
2023-09-28 05:26:48 +02:00
|
|
|
|
2024-06-17 17:47:04 +02:00
|
|
|
class CuratedPlacesRow extends StatelessWidget {
|
2023-08-27 07:07:35 +02:00
|
|
|
const CuratedPlacesRow({
|
|
|
|
super.key,
|
2024-06-17 17:47:04 +02:00
|
|
|
required this.content,
|
|
|
|
required this.imageSize,
|
2023-09-28 05:26:48 +02:00
|
|
|
this.isMapEnabled = true,
|
2024-06-17 17:47:04 +02:00
|
|
|
this.onTap,
|
2023-08-27 07:07:35 +02:00
|
|
|
});
|
|
|
|
|
2024-06-17 17:47:04 +02:00
|
|
|
final bool isMapEnabled;
|
|
|
|
final List<SearchCuratedContent> content;
|
|
|
|
final double imageSize;
|
|
|
|
|
|
|
|
/// Callback with the content and the index when tapped
|
|
|
|
final Function(SearchCuratedContent, int)? onTap;
|
|
|
|
|
2023-08-27 07:07:35 +02:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2023-09-28 05:26:48 +02:00
|
|
|
// Calculating the actual index of the content based on the whether map is enabled or not.
|
|
|
|
// If enabled, inject map as the first item in the list (index 0) and so the actual content will start from index 1
|
|
|
|
final int actualContentIndex = isMapEnabled ? 1 : 0;
|
2023-08-27 07:07:35 +02:00
|
|
|
|
2024-06-17 17:47:04 +02:00
|
|
|
return SizedBox(
|
|
|
|
height: imageSize,
|
2024-06-24 16:24:57 +02:00
|
|
|
child: ListView.separated(
|
2024-06-17 17:47:04 +02:00
|
|
|
scrollDirection: Axis.horizontal,
|
|
|
|
padding: const EdgeInsets.symmetric(
|
|
|
|
horizontal: 16,
|
|
|
|
),
|
2024-06-24 16:24:57 +02:00
|
|
|
separatorBuilder: (context, index) => const SizedBox(width: 10),
|
2024-06-17 17:47:04 +02:00
|
|
|
itemBuilder: (context, index) {
|
|
|
|
// Injecting Map thumbnail as the first element
|
|
|
|
if (isMapEnabled && index == 0) {
|
2024-06-24 16:24:57 +02:00
|
|
|
return SizedBox.square(
|
|
|
|
dimension: imageSize,
|
|
|
|
child: SearchMapThumbnail(size: imageSize),
|
2024-06-17 17:47:04 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
final actualIndex = index - actualContentIndex;
|
|
|
|
final object = content[actualIndex];
|
|
|
|
final thumbnailRequestUrl =
|
|
|
|
'${Store.get(StoreKey.serverEndpoint)}/assets/${object.id}/thumbnail';
|
2024-06-24 16:24:57 +02:00
|
|
|
return SizedBox.square(
|
|
|
|
dimension: imageSize,
|
|
|
|
child: ThumbnailWithInfo(
|
|
|
|
imageUrl: thumbnailRequestUrl,
|
|
|
|
textInfo: object.label,
|
|
|
|
onTap: () => onTap?.call(object, actualIndex),
|
2023-09-28 05:26:48 +02:00
|
|
|
),
|
2024-06-17 17:47:04 +02:00
|
|
|
);
|
|
|
|
},
|
|
|
|
itemCount: content.length + actualContentIndex,
|
2023-08-27 07:07:35 +02:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|