diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index b1ba3666..4cb8a1ad 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -654,6 +654,10 @@ "configButtonLabel": "CONFIG", "useAsAlbumCoverTooltip": "Use as album cover", "helpTooltip": "Help", + "removeFromAlbumTooltip": "Remove from album", + "@removeFromAlbumTooltip": { + "description": "Remove the opened photo from an album" + }, "changelogTitle": "Changelog", "@changelogTitle": { diff --git a/lib/l10n/untranslated-messages.txt b/lib/l10n/untranslated-messages.txt index 041a55e7..ff574e01 100644 --- a/lib/l10n/untranslated-messages.txt +++ b/lib/l10n/untranslated-messages.txt @@ -20,18 +20,22 @@ "metadataTaskPauseNoWiFiNotification", "configButtonLabel", "useAsAlbumCoverTooltip", - "helpTooltip" + "helpTooltip", + "removeFromAlbumTooltip" ], "es": [ - "helpTooltip" + "helpTooltip", + "removeFromAlbumTooltip" ], "fr": [ - "helpTooltip" + "helpTooltip", + "removeFromAlbumTooltip" ], "ru": [ - "helpTooltip" + "helpTooltip", + "removeFromAlbumTooltip" ] } diff --git a/lib/widget/album_browser.dart b/lib/widget/album_browser.dart index e00e93c5..8f9b2483 100644 --- a/lib/widget/album_browser.dart +++ b/lib/widget/album_browser.dart @@ -285,7 +285,7 @@ class _AlbumBrowserState extends State } Navigator.pushNamed(context, Viewer.routeName, arguments: ViewerArguments(widget.account, _backingFiles, fileIndex, - album: widget.album)); + album: _album)); } void _onSelectionAppBarSharePressed(BuildContext context) { @@ -508,6 +508,7 @@ class _AlbumBrowserState extends State if (ev.album.albumFile!.path == _album?.albumFile?.path) { setState(() { _album = ev.album; + _transformItems(); initCover(widget.account, ev.album); }); } diff --git a/lib/widget/viewer_detail_pane.dart b/lib/widget/viewer_detail_pane.dart index fc5d5714..8a596196 100644 --- a/lib/widget/viewer_detail_pane.dart +++ b/lib/widget/viewer_detail_pane.dart @@ -115,6 +115,15 @@ class _ViewerDetailPaneState extends State { children: [ Row( children: [ + if (widget.album != null && + widget.album!.albumFile?.isOwned(widget.account.username) == + true && + widget.album!.provider is AlbumStaticProvider) + _DetailPaneButton( + icon: Icons.remove_outlined, + label: L10n.of(context).removeFromAlbumTooltip, + onPressed: () => _onRemoveFromAlbumPressed(context), + ), if (widget.album != null && widget.album!.albumFile?.isOwned(widget.account.username) == true) @@ -245,6 +254,43 @@ class _ViewerDetailPaneState extends State { } } + Future _onRemoveFromAlbumPressed(BuildContext context) async { + assert(widget.album!.provider is AlbumStaticProvider); + await _onAction( + context, + null, + L10n.of(context).removeSelectedFromAlbumSuccessNotification(1), + () async { + final albumRepo = AlbumRepo(AlbumCachedDataSource()); + try { + final newItems = + AlbumStaticProvider.of(widget.album!).items.where((element) { + if (element is AlbumFileItem) { + return element.file.path != widget.file.path; + } else { + return true; + } + }).toList(); + await UpdateAlbum(albumRepo)( + widget.account, + widget.album!.copyWith( + provider: AlbumStaticProvider( + items: newItems, + ), + )); + if (mounted) { + Navigator.of(context).pop(); + } + } catch (e, stackTrace) { + _log.shout("[_onRemoveFromAlbumPressed] Failed while updating album", + e, stackTrace); + rethrow; + } + }, + failureText: L10n.of(context).removeSelectedFromAlbumFailureNotification, + ); + } + Future _onSetAlbumCoverPressed(BuildContext context) async { assert(widget.album != null); _log.info( @@ -401,15 +447,18 @@ class _ViewerDetailPaneState extends State { Future _onAction( BuildContext context, - String processingText, + String? processingText, String successText, FutureOr Function() action, { String? failureText, }) async { - var controller = SnackBarManager().showSnackBar(SnackBar( - content: Text(processingText), - duration: k.snackBarDurationShort, - )); + ScaffoldFeatureController? controller; + if (processingText != null) { + controller = SnackBarManager().showSnackBar(SnackBar( + content: Text(processingText), + duration: k.snackBarDurationShort, + )); + } controller?.closed.whenComplete(() { controller = null; });