diff --git a/lib/ui/viewer/search_tab/albums_section.dart b/lib/ui/viewer/search_tab/albums_section.dart new file mode 100644 index 000000000..ef7fe8a36 --- /dev/null +++ b/lib/ui/viewer/search_tab/albums_section.dart @@ -0,0 +1,92 @@ +import "package:figma_squircle/figma_squircle.dart"; +import "package:flutter/material.dart"; +import "package:photos/models/search/album_search_result.dart"; +import "package:photos/models/search/search_types.dart"; +import "package:photos/services/collections_service.dart"; +import "package:photos/theme/ente_theme.dart"; +import "package:photos/ui/viewer/file/no_thumbnail_widget.dart"; +import "package:photos/ui/viewer/file/thumbnail_widget.dart"; +import "package:photos/ui/viewer/search_tab/search_tab.dart"; +import "package:photos/ui/viewer/search_tab/section_header.dart"; + +class AlbumsSection extends StatelessWidget { + final List albumSearchResults; + const AlbumsSection(this.albumSearchResults, {super.key}); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SectionHeader( + SectionType.album, + hasMore: (albumSearchResults.length > SearchTab.hasMoreThreshold), + ), + const SizedBox(height: 2), + SizedBox( + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 4.5), + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.horizontal, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: albumSearchResults + .map( + (albumSearchResult) => + AlbumRecommendation(albumSearchResult), + ) + .toList(), + ), + ), + ), + ], + ); + } +} + +class AlbumRecommendation extends StatelessWidget { + final AlbumSearchResult albumSearchResult; + const AlbumRecommendation(this.albumSearchResult, {super.key}); + + @override + Widget build(BuildContext context) { + final enteTextTheme = getEnteTextTheme(context); + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 2.5), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ClipSmoothRect( + radius: SmoothBorderRadius(cornerRadius: 2.35, cornerSmoothing: 1), + child: SizedBox( + width: 100, + height: 100, + child: albumSearchResult.previewThumbnail() != null + ? ThumbnailWidget( + albumSearchResult.previewThumbnail()!, + shouldShowArchiveStatus: false, + ) + : const NoThumbnailWidget(), + ), + ), + const SizedBox(height: 2), + Text( + albumSearchResult.name(), + style: enteTextTheme.small, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + const SizedBox(height: 3), + Text( + CollectionsService.instance + .getCachedFileCount( + albumSearchResult.collectionWithThumbnail.collection, + ) + .toString(), + style: enteTextTheme.smallMuted, + ), + ], + ), + ); + } +} diff --git a/lib/ui/viewer/search_tab/search_tab.dart b/lib/ui/viewer/search_tab/search_tab.dart index 6bdb6ad7e..075c62e0d 100644 --- a/lib/ui/viewer/search_tab/search_tab.dart +++ b/lib/ui/viewer/search_tab/search_tab.dart @@ -2,6 +2,7 @@ import "package:fade_indexed_stack/fade_indexed_stack.dart"; import "package:flutter/material.dart"; import "package:flutter_animate/flutter_animate.dart"; import "package:photos/core/constants.dart"; +import "package:photos/models/search/album_search_result.dart"; import "package:photos/models/search/index_of_indexed_stack.dart"; import "package:photos/models/search/search_types.dart"; import "package:photos/states/all_sections_examples_state.dart"; @@ -10,8 +11,10 @@ import "package:photos/ui/viewer/search/result/no_result_widget.dart"; import "package:photos/ui/viewer/search/search_section.dart"; import "package:photos/ui/viewer/search/search_suggestions.dart"; import "package:photos/ui/viewer/search/tab_empty_state.dart"; +import 'package:photos/ui/viewer/search_tab/albums_section.dart'; class SearchTab extends StatefulWidget { + static const hasMoreThreshold = 6; const SearchTab({Key? key}) : super(key: key); @override @@ -93,11 +96,19 @@ class _AllSearchSectionsState extends State { physics: const BouncingScrollPhysics(), itemCount: searchTypes.length, itemBuilder: (context, index) { - return SearchSection( - sectionType: searchTypes[index], - examples: snapshot.data!.elementAt(index), - limit: searchSectionLimit, - ); + switch (searchTypes[index]) { + case SectionType.album: + return AlbumsSection( + snapshot.data!.elementAt(index) + as List, + ); + default: + return SearchSection( + sectionType: searchTypes[index], + examples: snapshot.data!.elementAt(index), + limit: searchSectionLimit, + ); + } }, ) .animate( diff --git a/lib/ui/viewer/search_tab/section_header.dart b/lib/ui/viewer/search_tab/section_header.dart new file mode 100644 index 000000000..f6466f092 --- /dev/null +++ b/lib/ui/viewer/search_tab/section_header.dart @@ -0,0 +1,34 @@ +import "package:flutter/material.dart"; +import "package:photos/models/search/search_types.dart"; +import "package:photos/theme/ente_theme.dart"; + +class SectionHeader extends StatelessWidget { + final SectionType sectionType; + final bool hasMore; + const SectionHeader(this.sectionType, {required this.hasMore, super.key}); + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.all(12), + child: Text( + sectionType.sectionTitle(context), + style: getEnteTextTheme(context).largeBold, + ), + ), + hasMore + ? Padding( + padding: const EdgeInsets.all(12), + child: Icon( + Icons.chevron_right_outlined, + color: getEnteColorScheme(context).strokeMuted, + ), + ) + : const SizedBox.shrink(), + ], + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index b71d5908f..63d08a2b2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -507,6 +507,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + figma_squircle: + dependency: "direct main" + description: + name: figma_squircle + sha256: "790b91a9505e90d246f6efe2fa065ff7fffe658c7b44fe9b5b20c7b0ad3818c0" + url: "https://pub.dev" + source: hosted + version: "0.5.3" file: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index f2d90ab65..09d332559 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -58,6 +58,7 @@ dependencies: fade_indexed_stack: ^0.2.2 fast_base58: ^0.2.1 + figma_squircle: ^0.5.3 file_saver: # Use forked version till this PR is merged: https://github.com/incrediblezayed/file_saver/pull/87 git: https://github.com/jesims/file_saver.git