From 07c640cf90dbff36f2dda02780ef1ab00d9ce2e9 Mon Sep 17 00:00:00 2001 From: Aman Raj Singh Mourya Date: Thu, 15 May 2025 16:33:16 +0530 Subject: [PATCH] refractor: extract string + code refractor and improvements --- mobile/lib/l10n/intl_en.arb | 6 +- .../collection_sharing_actions.dart | 3 +- .../lib/ui/collections/album/list_item.dart | 209 ++++++++---------- .../ui/collections/album/new_row_item.dart | 3 +- .../ui/collections/collection_list_page.dart | 2 +- mobile/lib/ui/collections/flex_grid_view.dart | 6 +- .../album_action_bar_widget.dart | 4 +- .../album_bottom_action_bar_widget.dart | 2 +- .../lib/ui/sharing/add_participant_page.dart | 2 +- mobile/lib/ui/tabs/user_collections_tab.dart | 3 +- .../album_selection_action_widget.dart | 16 +- .../actions/album_selection_overlay_bar.dart | 19 +- 12 files changed, 134 insertions(+), 141 deletions(-) diff --git a/mobile/lib/l10n/intl_en.arb b/mobile/lib/l10n/intl_en.arb index d5207f0d10..b6e929bfae 100644 --- a/mobile/lib/l10n/intl_en.arb +++ b/mobile/lib/l10n/intl_en.arb @@ -1737,5 +1737,9 @@ "cLFamilyPlanDesc": "You can now set limits on how much storage your family members can use.", "cLBulkEdit": "Bulk Edit dates", "cLBulkEditDesc": "You can now select multiple photos, and edit date/time for all of them with one quick action. Shifting dates is also supported.", - "curatedMemories": "Curated memories" + "curatedMemories": "Curated memories", + "deleteMultipleAlbumDialog": "Also delete the photos (and videos) present in these {count} albums from all other albums they are part of?", + "addParticipants": "Add participants", + "selectedAlbums": "{count} selected", + "actionNotSupportedOnFavouritesAlbum": "Action not supported on Favourites album" } \ No newline at end of file diff --git a/mobile/lib/ui/actions/collection/collection_sharing_actions.dart b/mobile/lib/ui/actions/collection/collection_sharing_actions.dart index 82b3ba1fbe..0583798dcf 100644 --- a/mobile/lib/ui/actions/collection/collection_sharing_actions.dart +++ b/mobile/lib/ui/actions/collection/collection_sharing_actions.dart @@ -391,8 +391,7 @@ class CollectionActions { ), ], bodyWidget: StyledText( - text: - "Also delete the photos (and videos) present in these ${collections.length} albums from all other albums they are part of?", + text: S.of(bContext).deleteMultipleAlbumDialog(collections.length), style: textTheme.body.copyWith(color: textMutedDark), tags: { 'bold': StyledTextTag( diff --git a/mobile/lib/ui/collections/album/list_item.dart b/mobile/lib/ui/collections/album/list_item.dart index ff3837a4b1..255d6de147 100644 --- a/mobile/lib/ui/collections/album/list_item.dart +++ b/mobile/lib/ui/collections/album/list_item.dart @@ -31,23 +31,89 @@ class AlbumListItemWidget extends StatelessWidget { final colorScheme = getEnteColorScheme(context); const sideOfThumbnail = 60.0; + final albumWidget = Flexible( + flex: 6, + child: Row( + children: [ + ClipRRect( + borderRadius: const BorderRadius.horizontal( + left: Radius.circular(4), + ), + child: SizedBox( + height: sideOfThumbnail, + width: sideOfThumbnail, + child: FutureBuilder( + future: CollectionsService.instance.getCover(collection), + builder: (context, snapshot) { + if (snapshot.hasData) { + final thumbnail = snapshot.data!; + return ThumbnailWidget( + thumbnail, + showFavForAlbumOnly: true, + shouldShowOwnerAvatar: false, + ); + } else { + return const NoThumbnailWidget(addBorder: false); + } + }, + ), + ), + ), + const SizedBox(width: 12), + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + collection.displayName, + overflow: TextOverflow.ellipsis, + ), + FutureBuilder( + future: CollectionsService.instance.getFileCount(collection), + builder: (context, snapshot) { + if (snapshot.hasData) { + return Text( + S.of(context).memoryCount( + snapshot.data!, + NumberFormat().format(snapshot.data!), + ), + style: textTheme.small.copyWith( + color: colorScheme.textMuted, + ), + ); + } else { + if (snapshot.hasError) { + Logger("AlbumListItemWidget").severe( + "Failed to fetch file count of collection", + snapshot.error, + ); + } + return Text( + "", + style: textTheme.small.copyWith( + color: colorScheme.textMuted, + ), + ); + } + }, + ), + ], + ), + ), + ], + ), + ); + return GestureDetector( - onTap: () { - if (onTapCallback != null) { - onTapCallback!(collection); - } - }, - onLongPress: () { - if (onLongPressCallback != null) { - onLongPressCallback!(collection); - } - }, + onTap: () => onTapCallback?.call(collection), + onLongPress: () => onLongPressCallback?.call(collection), behavior: HitTestBehavior.opaque, child: ListenableBuilder( listenable: selectedAlbums!, builder: (context, _) { final isSelected = selectedAlbums?.isAlbumSelected(collection) ?? false; + return AnimatedContainer( curve: Curves.easeOut, duration: const Duration(milliseconds: 200), @@ -57,116 +123,31 @@ class AlbumListItemWidget extends StatelessWidget { ? colorScheme.strokeMuted : colorScheme.strokeFainter, ), - borderRadius: const BorderRadius.all( - Radius.circular(4), - ), + borderRadius: const BorderRadius.all(Radius.circular(4)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Flexible( - flex: 6, - child: Row( - children: [ - ClipRRect( - borderRadius: const BorderRadius.horizontal( - left: Radius.circular(4), - ), - child: SizedBox( - height: sideOfThumbnail, - width: sideOfThumbnail, - child: FutureBuilder( - future: CollectionsService.instance - .getCover(collection), - builder: (context, snapshot) { - if (snapshot.hasData) { - final thumbnail = snapshot.data!; - return ThumbnailWidget( - thumbnail, - showFavForAlbumOnly: true, - shouldShowOwnerAvatar: false, - ); - } else { - return const NoThumbnailWidget( - addBorder: false, - ); - } - }, - ), - ), - ), - const SizedBox(width: 12), - Flexible( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - collection.displayName, - overflow: TextOverflow.ellipsis, - ), - FutureBuilder( - future: CollectionsService.instance - .getFileCount(collection), - builder: (context, snapshot) { - if (snapshot.hasData) { - return Text( - S.of(context).memoryCount( - snapshot.data!, - NumberFormat().format(snapshot.data!), - ), - style: textTheme.small.copyWith( - color: colorScheme.textMuted, - ), - ); - } else { - if (snapshot.hasError) { - Logger("AlbumListItemWidget").severe( - "Failed to fetch file count of collection", - snapshot.error, - ); - } - return Text( - "", - style: textTheme.small.copyWith( - color: colorScheme.textMuted, - ), - ); - } - }, - ), - ], - ), - ), - ], - ), - ), + albumWidget, Flexible( flex: 1, - child: ListenableBuilder( - listenable: selectedAlbums!, - builder: (context, _) { - final isSelected = - selectedAlbums?.isAlbumSelected(collection) ?? false; - - return AnimatedSwitcher( - duration: const Duration(milliseconds: 200), - switchInCurve: Curves.easeOut, - switchOutCurve: Curves.easeIn, - child: isSelected - ? IconButtonWidget( - key: const ValueKey("selected"), - icon: Icons.check_circle_rounded, - iconButtonType: IconButtonType.secondary, - iconColor: colorScheme.blurStrokeBase, - ) - : IconButtonWidget( - key: const ValueKey("unselected"), - icon: Icons.chevron_right_outlined, - iconButtonType: IconButtonType.secondary, - iconColor: colorScheme.blurStrokePressed, - ), - ); - }, + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 200), + switchInCurve: Curves.easeOut, + switchOutCurve: Curves.easeIn, + child: isSelected + ? IconButtonWidget( + key: const ValueKey("selected"), + icon: Icons.check_circle_rounded, + iconButtonType: IconButtonType.secondary, + iconColor: colorScheme.blurStrokeBase, + ) + : IconButtonWidget( + key: const ValueKey("unselected"), + icon: Icons.chevron_right_outlined, + iconButtonType: IconButtonType.secondary, + iconColor: colorScheme.blurStrokePressed, + ), ), ), ], diff --git a/mobile/lib/ui/collections/album/new_row_item.dart b/mobile/lib/ui/collections/album/new_row_item.dart index 6212d17657..66d2e517e3 100644 --- a/mobile/lib/ui/collections/album/new_row_item.dart +++ b/mobile/lib/ui/collections/album/new_row_item.dart @@ -36,7 +36,7 @@ class NewAlbumRowItemWidget extends StatelessWidget { alwaysShowSuccessState: false, initialValue: "", textCapitalization: TextCapitalization.words, - popnavAfterSubmission: false, + popnavAfterSubmission: true, onSubmit: (String text) async { if (text.trim() == "") { return; @@ -50,7 +50,6 @@ class NewAlbumRowItemWidget extends StatelessWidget { context, CollectionPage(CollectionWithThumbnail(c, null)), ); - Navigator.of(context).pop(); } catch (e, s) { Logger("CreateNewAlbumRowItemWidget") .severe("Failed to rename album", e, s); diff --git a/mobile/lib/ui/collections/collection_list_page.dart b/mobile/lib/ui/collections/collection_list_page.dart index 10f5014be7..914b67b439 100644 --- a/mobile/lib/ui/collections/collection_list_page.dart +++ b/mobile/lib/ui/collections/collection_list_page.dart @@ -125,6 +125,7 @@ class _CollectionListPageState extends State { _selectedAlbum, widget.sectionType, collections!, + showSelectAllButton: true, ), ], ), @@ -217,7 +218,6 @@ class _CollectionListPageState extends State { : AlbumSortDirection.ascending; await localSettings.setAlbumSortDirection(albumSortDirection!); await refreshCollections(); - setState(() {}); Bus.instance.fire(AlbumSortOrderChangeEvent()); } }, diff --git a/mobile/lib/ui/collections/flex_grid_view.dart b/mobile/lib/ui/collections/flex_grid_view.dart index d1166628cf..ef7803808a 100644 --- a/mobile/lib/ui/collections/flex_grid_view.dart +++ b/mobile/lib/ui/collections/flex_grid_view.dart @@ -26,8 +26,8 @@ class CollectionsFlexiGridViewWidget extends StatefulWidget { Width changes dynamically with screen width such that we can fit 2 in one row. Keep the width integral (center the albums to distribute excess pixels) */ - static const maxThumbnailWidth = 170.0; - static const fixedGapBetweenAlbum = 2.0; + static const maxThumbnailWidth = 224.0; + static const fixedGapBetweenAlbum = 4.0; static const minGapForHorizontalPadding = 8.0; static const collectionItemsToPreload = 20; @@ -115,7 +115,7 @@ class _CollectionsFlexiGridViewWidgetState } Widget _buildGridView(BuildContext context, Key key) { - final double screenWidth = MediaQuery.of(context).size.width; + final double screenWidth = MediaQuery.sizeOf(context).width; final int albumsCountInOneRow = max(screenWidth ~/ CollectionsFlexiGridViewWidget.maxThumbnailWidth, 3); final double gapBetweenAlbums = (albumsCountInOneRow - 1) * diff --git a/mobile/lib/ui/components/bottom_action_bar/album_action_bar_widget.dart b/mobile/lib/ui/components/bottom_action_bar/album_action_bar_widget.dart index a7c8a1a31d..db4dee8d9a 100644 --- a/mobile/lib/ui/components/bottom_action_bar/album_action_bar_widget.dart +++ b/mobile/lib/ui/components/bottom_action_bar/album_action_bar_widget.dart @@ -47,7 +47,9 @@ class _AlbumActionBarWidgetState extends State { valueListenable: _selectedAlbumNotifier, builder: (context, value, child) { return Text( - "${widget.selectedAlbums?.albums.length ?? 0} selected", + S.of(context).selectedAlbums( + widget.selectedAlbums?.albums.length ?? 0, + ), style: textTheme.miniMuted, ); }, diff --git a/mobile/lib/ui/components/bottom_action_bar/album_bottom_action_bar_widget.dart b/mobile/lib/ui/components/bottom_action_bar/album_bottom_action_bar_widget.dart index bcb568b405..3312584085 100644 --- a/mobile/lib/ui/components/bottom_action_bar/album_bottom_action_bar_widget.dart +++ b/mobile/lib/ui/components/bottom_action_bar/album_bottom_action_bar_widget.dart @@ -24,7 +24,7 @@ class AlbumBottomActionBarWidget extends StatelessWidget { @override Widget build(BuildContext context) { final bottomPadding = MediaQuery.paddingOf(context).bottom; - final widthOfScreen = MediaQuery.of(context).size.width; + final widthOfScreen = MediaQuery.sizeOf(context).width; final colorScheme = getEnteColorScheme(context); final double leftRightPadding = widthOfScreen > restrictedMaxWidth ? (widthOfScreen - restrictedMaxWidth) / 2 diff --git a/mobile/lib/ui/sharing/add_participant_page.dart b/mobile/lib/ui/sharing/add_participant_page.dart index 3fa1dffd0b..e5f23daa43 100644 --- a/mobile/lib/ui/sharing/add_participant_page.dart +++ b/mobile/lib/ui/sharing/add_participant_page.dart @@ -85,7 +85,7 @@ class _AddParticipantPage extends State { appBar: AppBar( title: Text( widget.isMultipleCollections - ? "Add participants" + ? S.of(context).addParticipants : widget.isAddingViewer ? S.of(context).addViewer : S.of(context).addCollaborator, diff --git a/mobile/lib/ui/tabs/user_collections_tab.dart b/mobile/lib/ui/tabs/user_collections_tab.dart index 16acbc1640..00b973a395 100644 --- a/mobile/lib/ui/tabs/user_collections_tab.dart +++ b/mobile/lib/ui/tabs/user_collections_tab.dart @@ -221,7 +221,7 @@ class _UserCollectionsTabState extends State ), SliverToBoxAdapter( child: - SizedBox(height: 64 + MediaQuery.of(context).padding.bottom), + SizedBox(height: 64 + MediaQuery.paddingOf(context).bottom), ), ], ), @@ -229,6 +229,7 @@ class _UserCollectionsTabState extends State widget.selectedAlbums!, UISectionType.homeCollections, collections, + showSelectAllButton: false, ), ], ); diff --git a/mobile/lib/ui/viewer/actions/album_selection_action_widget.dart b/mobile/lib/ui/viewer/actions/album_selection_action_widget.dart index e625c31da2..93b16c67a1 100644 --- a/mobile/lib/ui/viewer/actions/album_selection_action_widget.dart +++ b/mobile/lib/ui/viewer/actions/album_selection_action_widget.dart @@ -56,7 +56,7 @@ class _AlbumSelectionActionWidgetState @override Widget build(BuildContext context) { if (widget.selectedAlbums.albums.isEmpty) { - return const SizedBox(); + return const SizedBox.shrink(); } final List items = []; final hasPinnedAlbum = @@ -166,9 +166,6 @@ class _AlbumSelectionActionWidgetState collections: widget.selectedAlbums.albums.toList(), ), ); - if (hasFavorites) { - _showFavToast(); - } widget.selectedAlbums.clearAll(); } @@ -176,6 +173,7 @@ class _AlbumSelectionActionWidgetState int count = 0; final List nonEmptyCollection = []; + final List errors = []; for (final collection in widget.selectedAlbums.albums) { count = await FilesDB.instance.collectionFileCount(collection.id); final bool isEmptyCollection = count == 0; @@ -184,7 +182,7 @@ class _AlbumSelectionActionWidgetState await CollectionsService.instance.trashEmptyCollection(collection); } catch (e, s) { _logger.warning("failed to trash collection", e, s); - await showGenericErrorDialog(context: context, error: e); + errors.add(e); } } else if (collection.type == CollectionType.favorites) { continue; @@ -192,6 +190,12 @@ class _AlbumSelectionActionWidgetState nonEmptyCollection.add(collection); } } + if (errors.isNotEmpty) { + await showGenericErrorDialog( + context: context, + error: errors.first, + ); + } if (nonEmptyCollection.isNotEmpty) { final bool result = await collectionActions.deleteMultipleCollectionSheet( @@ -366,7 +370,7 @@ class _AlbumSelectionActionWidgetState void _showFavToast() { showShortToast( context, - "The Favorites album cannot be modified", + S.of(context).actionNotSupportedOnFavouritesAlbum, ); } } diff --git a/mobile/lib/ui/viewer/actions/album_selection_overlay_bar.dart b/mobile/lib/ui/viewer/actions/album_selection_overlay_bar.dart index 08bd4969e2..1e0393bb03 100644 --- a/mobile/lib/ui/viewer/actions/album_selection_overlay_bar.dart +++ b/mobile/lib/ui/viewer/actions/album_selection_overlay_bar.dart @@ -13,6 +13,7 @@ class AlbumSelectionOverlayBar extends StatefulWidget { final List collections; final Color? backgroundColor; final UISectionType sectionType; + final bool showSelectAllButton; const AlbumSelectionOverlayBar( this.selectedAlbums, @@ -21,6 +22,7 @@ class AlbumSelectionOverlayBar extends StatefulWidget { super.key, this.onClose, this.backgroundColor, + this.showSelectAllButton = false, }); @override @@ -60,14 +62,15 @@ class _AlbumSelectionOverlayBarState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, children: [ - Padding( - padding: const EdgeInsets.only(right: 4), - child: SelectAllAlbumsButton( - widget.selectedAlbums, - widget.collections, - backgroundColor: widget.backgroundColor, + if (widget.showSelectAllButton) + Padding( + padding: const EdgeInsets.only(right: 4), + child: SelectAllAlbumsButton( + widget.selectedAlbums, + widget.collections, + backgroundColor: widget.backgroundColor, + ), ), - ), const SizedBox(height: 8), Container( decoration: BoxDecoration(boxShadow: shadowFloatFaintLight), @@ -123,7 +126,7 @@ class _SelectAllAlbumsButtonState extends State { if (_allSelected) { widget.selectedAlbums.clearAll(); } else { - widget.selectedAlbums.selectAll( + widget.selectedAlbums.select( widget.collections.toSet(), ); }