From fc10e46a0b100877a6a8da76514cc4eedde65754 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Mon, 6 Jan 2025 15:51:33 +0530 Subject: [PATCH] [mob] Allow joining public links --- mobile/lib/services/collections_service.dart | 53 +++++++++---------- mobile/lib/services/remote_sync_service.dart | 7 +++ .../shared_public_collection_page.dart | 52 +++++++++++++++++- 3 files changed, 82 insertions(+), 30 deletions(-) diff --git a/mobile/lib/services/collections_service.dart b/mobile/lib/services/collections_service.dart index 0bc60dda15..9c3961f139 100644 --- a/mobile/lib/services/collections_service.dart +++ b/mobile/lib/services/collections_service.dart @@ -1143,36 +1143,31 @@ class CollectionsService { BuildContext context, int collectionID, ) async { - try { - final authToken = await getSharedPublicAlbumToken(collectionID); - final jwtToken = await getSharedPublicAlbumTokenJWT(collectionID); - final key = await getSharedPublicAlbumKey(collectionID); - if (key.isEmpty) { - throw Exception("Collection key not found"); - } - final encryptedKey = CryptoUtil.sealSync( - getCollectionKey(collectionID), - CryptoUtil.base642bin( - Configuration.instance.getKeyAttributes()!.publicKey, - ), - ); - await _enteDio.post( - "/collections/join-link", - data: { - "collectionID": collectionID, - "encryptedKey": CryptoUtil.bin2base64(encryptedKey), - }, - options: Options( - headers: { - "X-Auth-Access-Token": authToken, - "X-Auth-JWT-Token": jwtToken, - }, - ), - ); - } catch (e) { - _logger.warning("Failed to join public collection $e"); - await showGenericErrorDialog(context: context, error: e); + final authToken = await getSharedPublicAlbumToken(collectionID); + final jwtToken = await getSharedPublicAlbumTokenJWT(collectionID); + final key = await getSharedPublicAlbumKey(collectionID); + if (key.isEmpty) { + throw Exception("Collection key not found"); } + final encryptedKey = CryptoUtil.sealSync( + getCollectionKey(collectionID), + CryptoUtil.base642bin( + Configuration.instance.getKeyAttributes()!.publicKey, + ), + ); + await _enteDio.post( + "/collections/join-link", + data: { + "collectionID": collectionID, + "encryptedKey": CryptoUtil.bin2base64(encryptedKey), + }, + options: Options( + headers: { + "X-Auth-Access-Token": authToken, + "X-Auth-JWT-Token": jwtToken, + }, + ), + ); } Future getSharedPublicAlbumKey(int collectionID) async { diff --git a/mobile/lib/services/remote_sync_service.dart b/mobile/lib/services/remote_sync_service.dart index 1134955e05..f6b2a7897d 100644 --- a/mobile/lib/services/remote_sync_service.dart +++ b/mobile/lib/services/remote_sync_service.dart @@ -306,6 +306,13 @@ class RemoteSyncService { _logger.info("[Collection-$collectionID] synced"); } + Future joinAndSyncCollection( + BuildContext context, int collectionID) async { + await _collectionsService.joinPublicCollection(context, collectionID); + await _collectionsService.sync(); + await _syncCollectionDiff(collectionID, 0); + } + Future _syncCollectionDiffDelete(Diff diff, int collectionID) async { final fileIDs = diff.deletedFiles.map((f) => f.uploadedFileID!).toList(); final localDeleteCount = diff --git a/mobile/lib/ui/viewer/gallery/shared_public_collection_page.dart b/mobile/lib/ui/viewer/gallery/shared_public_collection_page.dart index 9cb3cf66cd..60a25a8492 100644 --- a/mobile/lib/ui/viewer/gallery/shared_public_collection_page.dart +++ b/mobile/lib/ui/viewer/gallery/shared_public_collection_page.dart @@ -4,16 +4,24 @@ import "package:photos/core/event_bus.dart"; import "package:photos/events/collection_meta_event.dart"; import "package:photos/events/collection_updated_event.dart"; import "package:photos/events/files_updated_event.dart"; +import "package:photos/generated/l10n.dart"; import "package:photos/models/collection/collection_items.dart"; import "package:photos/models/file/file.dart"; import "package:photos/models/file_load_result.dart"; import "package:photos/models/gallery_type.dart"; import "package:photos/models/selected_files.dart"; +import "package:photos/services/collections_service.dart"; +import "package:photos/services/remote_sync_service.dart"; +import "package:photos/ui/components/notification_widget.dart"; +import "package:photos/ui/sharing/share_collection_page.dart"; import "package:photos/ui/viewer/actions/file_selection_overlay_bar.dart"; +import "package:photos/ui/viewer/gallery/collection_page.dart"; import "package:photos/ui/viewer/gallery/gallery.dart"; import "package:photos/ui/viewer/gallery/gallery_app_bar_widget.dart"; import "package:photos/ui/viewer/gallery/state/gallery_files_inherited_widget.dart"; import "package:photos/ui/viewer/gallery/state/selection_state.dart"; +import "package:photos/utils/dialog_util.dart"; +import "package:photos/utils/navigation_util.dart"; class SharedPublicCollectionPage extends StatefulWidget { final CollectionWithThumbnail c; @@ -39,6 +47,12 @@ class _SharedPublicCollectionPageState extends State { final _selectedFiles = SelectedFiles(); final galleryType = GalleryType.sharedPublicCollection; + final logger = Logger("SharedPublicCollectionPage"); + @override + void initState() { + super.initState(); + logger.info("Init SharedPublicCollectionPage"); + } @override void dispose() { @@ -48,7 +62,6 @@ class _SharedPublicCollectionPageState @override Widget build(BuildContext context) { - final logger = Logger("SharedPublicCollectionPage"); logger.info("Building SharedPublicCollectionPage"); final List? initialFiles = widget.c.thumbnail != null ? [widget.c.thumbnail!] : null; @@ -79,6 +92,43 @@ class _SharedPublicCollectionPageState selectedFiles: _selectedFiles, initialFiles: initialFiles, albumName: widget.c.collection.displayName, + header: Padding( + padding: const EdgeInsets.all(8.0), + child: NotificationWidget( + actionIcon: Icons.join_right, + startIcon: Icons.people_alt_outlined, + text: 'Join album', + subText: widget.c.collection.isCollectEnabledForPublicLink() + ? "to view and add your photos" + : 'to add this to shared albums', + type: NotificationType.notice, + onTap: () async { + final dialog = + createProgressDialog(context, S.of(context).pleaseWait); + await dialog.show(); + try { + logger.info("Joining collection ${widget.c.collection.id}"); + await RemoteSyncService.instance + .joinAndSyncCollection(context, widget.c.collection.id); + logger.info("Syncing collections"); + + // route to the collection + final c = CollectionsService.instance + .getCollectionByID(widget.c.collection.id); + logger.info("Joining collection ${widget.c.collection.id}"); + await dialog.hide(); + Navigator.of(context).pop(); + await routeToPage( + context, CollectionPage(CollectionWithThumbnail(c!, null))); + } catch (e, s) { + logger.severe("Failed to join collection", e, s); + showGenericErrorDialog(context: context, error: e).ignore(); + } finally { + await dialog.hide(); + } + }, + ), + ), sortAsyncFn: () => widget.c.collection.pubMagicMetadata.asc ?? false, );