diff --git a/i18n/en.json b/i18n/en.json index b142dc7fca..869a230e27 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1034,6 +1034,7 @@ }, "exif": "Exif", "exif_bottom_sheet_description": "Add Description...", + "exif_bottom_sheet_no_description": "No description", "exif_bottom_sheet_description_error": "Error updating description", "exif_bottom_sheet_details": "DETAILS", "exif_bottom_sheet_location": "LOCATION", diff --git a/mobile/lib/presentation/pages/drift_remote_album.page.dart b/mobile/lib/presentation/pages/drift_remote_album.page.dart index a69736a474..edf80d07b4 100644 --- a/mobile/lib/presentation/pages/drift_remote_album.page.dart +++ b/mobile/lib/presentation/pages/drift_remote_album.page.dart @@ -173,7 +173,7 @@ class _RemoteAlbumPageState extends ConsumerState { final user = ref.watch(currentUserProvider); final isOwner = user != null ? user.id == _album.ownerId : false; final canAddPhotos = - await ref.read(remoteAlbumUserRoleProvider((_album.id, user!.id)).future) == AlbumUserRole.editor; + await ref.read(remoteAlbumServiceProvider).getUserRole(_album.id, user?.id ?? '') == AlbumUserRole.editor; showModalBottomSheet( context: context, diff --git a/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet.widget.dart index 3dd8f994bd..c2ab8d6ed6 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet.widget.dart @@ -151,7 +151,7 @@ class _AssetDetailBottomSheet extends ConsumerWidget { trailing: asset.hasRemote && isOwner ? const Icon(Icons.edit, size: 18) : null, onTap: asset.hasRemote && isOwner ? () async => await _editDateTime(context, ref) : null, ), - if (exifInfo != null && isOwner) _SheetAssetDescription(exif: exifInfo), + if (exifInfo != null) _SheetAssetDescription(exif: exifInfo, isEditable: isOwner), const SheetPeopleDetails(), const SheetLocationDetails(), // Details header @@ -265,8 +265,9 @@ class _SheetTile extends ConsumerWidget { class _SheetAssetDescription extends ConsumerStatefulWidget { final ExifInfo exif; + final bool isEditable; - const _SheetAssetDescription({required this.exif}); + const _SheetAssetDescription({required this.exif, this.isEditable = true, super.key}); @override ConsumerState<_SheetAssetDescription> createState() => _SheetAssetDescriptionState(); @@ -312,27 +313,33 @@ class _SheetAssetDescriptionState extends ConsumerState<_SheetAssetDescription> // Update controller text when EXIF data changes final currentDescription = currentExifInfo?.description ?? ''; + final hintText = (widget.isEditable ? 'exif_bottom_sheet_description' : 'exif_bottom_sheet_no_description').t( + context: context, + ); if (_controller.text != currentDescription && !_descriptionFocus.hasFocus) { _controller.text = currentDescription; } return Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8), - child: TextField( - controller: _controller, - keyboardType: TextInputType.multiline, - focusNode: _descriptionFocus, - maxLines: null, // makes it grow as text is added - decoration: InputDecoration( - hintText: 'exif_bottom_sheet_description'.t(context: context), - border: InputBorder.none, - enabledBorder: InputBorder.none, - focusedBorder: InputBorder.none, - disabledBorder: InputBorder.none, - errorBorder: InputBorder.none, - focusedErrorBorder: InputBorder.none, + child: IgnorePointer( + ignoring: !widget.isEditable, + child: TextField( + controller: _controller, + keyboardType: TextInputType.multiline, + focusNode: _descriptionFocus, + maxLines: null, // makes it grow as text is added + decoration: InputDecoration( + hintText: hintText, + border: InputBorder.none, + enabledBorder: InputBorder.none, + focusedBorder: InputBorder.none, + disabledBorder: InputBorder.none, + errorBorder: InputBorder.none, + focusedErrorBorder: InputBorder.none, + ), + onTapOutside: (_) => saveDescription(currentExifInfo?.description), ), - onTapOutside: (_) => saveDescription(currentExifInfo?.description), ), ); } diff --git a/mobile/lib/presentation/widgets/bottom_sheet/remote_album_bottom_sheet.widget.dart b/mobile/lib/presentation/widgets/bottom_sheet/remote_album_bottom_sheet.widget.dart index 638f860fde..7db8a80af2 100644 --- a/mobile/lib/presentation/widgets/bottom_sheet/remote_album_bottom_sheet.widget.dart +++ b/mobile/lib/presentation/widgets/bottom_sheet/remote_album_bottom_sheet.widget.dart @@ -95,19 +95,22 @@ class _RemoteAlbumBottomSheetState extends ConsumerState const ShareActionButton(source: ActionSource.timeline), if (multiselect.hasRemote) ...[ const ShareLinkActionButton(source: ActionSource.timeline), - if (ownsAlbum) const ArchiveActionButton(source: ActionSource.timeline), - if (ownsAlbum) const FavoriteActionButton(source: ActionSource.timeline), + + if (ownsAlbum) ...[ + const ArchiveActionButton(source: ActionSource.timeline), + const FavoriteActionButton(source: ActionSource.timeline), + ], const DownloadActionButton(source: ActionSource.timeline), - if (ownsAlbum) + if (ownsAlbum) ...[ isTrashEnable ? const TrashActionButton(source: ActionSource.timeline) : const DeletePermanentActionButton(source: ActionSource.timeline), - if (ownsAlbum) const EditDateTimeActionButton(source: ActionSource.timeline), - if (ownsAlbum) const EditLocationActionButton(source: ActionSource.timeline), - if (ownsAlbum) const MoveToLockFolderActionButton(source: ActionSource.timeline), - if (multiselect.selectedAssets.length > 1 && ownsAlbum) - const StackActionButton(source: ActionSource.timeline), - if (multiselect.hasStacked) const UnStackActionButton(source: ActionSource.timeline), + const EditDateTimeActionButton(source: ActionSource.timeline), + const EditLocationActionButton(source: ActionSource.timeline), + const MoveToLockFolderActionButton(source: ActionSource.timeline), + if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline), + if (multiselect.hasStacked) const UnStackActionButton(source: ActionSource.timeline), + ], ], if (multiselect.hasLocal) ...[ const DeleteLocalActionButton(source: ActionSource.timeline), diff --git a/mobile/lib/providers/infrastructure/remote_album.provider.dart b/mobile/lib/providers/infrastructure/remote_album.provider.dart index ffdbe8aa36..38ba52dc56 100644 --- a/mobile/lib/providers/infrastructure/remote_album.provider.dart +++ b/mobile/lib/providers/infrastructure/remote_album.provider.dart @@ -178,13 +178,3 @@ final remoteAlbumSharedUsersProvider = FutureProvider.autoDispose.family(( - ref, - data, -) async { - final link = ref.keepAlive(); - ref.onDispose(() => link.close()); - final service = ref.watch(remoteAlbumServiceProvider); - return service.getUserRole(data.$1, data.$2); -});