diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 7efa06b0c..f59ed7e0d 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -8,6 +8,38 @@ PODS: - ReachabilitySwift - device_info (0.0.1): - Flutter + - Firebase/CoreOnly (10.9.0): + - FirebaseCore (= 10.9.0) + - Firebase/Messaging (10.9.0): + - Firebase/CoreOnly + - FirebaseMessaging (~> 10.9.0) + - firebase_core (2.13.1): + - Firebase/CoreOnly (= 10.9.0) + - Flutter + - firebase_messaging (14.6.2): + - Firebase/Messaging (= 10.9.0) + - firebase_core + - Flutter + - FirebaseCore (10.9.0): + - FirebaseCoreInternal (~> 10.0) + - GoogleUtilities/Environment (~> 7.8) + - GoogleUtilities/Logger (~> 7.8) + - FirebaseCoreInternal (10.13.0): + - "GoogleUtilities/NSData+zlib (~> 7.8)" + - FirebaseInstallations (10.13.0): + - FirebaseCore (~> 10.0) + - GoogleUtilities/Environment (~> 7.8) + - GoogleUtilities/UserDefaults (~> 7.8) + - PromisesObjC (~> 2.1) + - FirebaseMessaging (10.9.0): + - FirebaseCore (~> 10.0) + - FirebaseInstallations (~> 10.0) + - GoogleDataTransport (~> 9.2) + - GoogleUtilities/AppDelegateSwizzler (~> 7.8) + - GoogleUtilities/Environment (~> 7.8) + - GoogleUtilities/Reachability (~> 7.8) + - GoogleUtilities/UserDefaults (~> 7.8) + - nanopb (< 2.30910.0, >= 2.30908.0) - fk_user_agent (2.0.0): - Flutter - Flutter (1.0.0) @@ -39,8 +71,32 @@ PODS: - FMDB (2.7.5): - FMDB/standard (= 2.7.5) - FMDB/standard (2.7.5) + - GoogleDataTransport (9.2.5): + - GoogleUtilities/Environment (~> 7.7) + - nanopb (< 2.30910.0, >= 2.30908.0) + - PromisesObjC (< 3.0, >= 1.2) + - GoogleUtilities/AppDelegateSwizzler (7.11.5): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Environment (7.11.5): + - PromisesObjC (< 3.0, >= 1.2) + - GoogleUtilities/Logger (7.11.5): + - GoogleUtilities/Environment + - GoogleUtilities/Network (7.11.5): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (7.11.5)" + - GoogleUtilities/Reachability (7.11.5): + - GoogleUtilities/Logger + - GoogleUtilities/UserDefaults (7.11.5): + - GoogleUtilities/Logger - image_editor_common (1.0.0): - Flutter + - in_app_purchase_storekit (0.0.1): + - Flutter + - FlutterMacOS - integration_test (0.0.1): - Flutter - libwebp (1.3.1): @@ -66,6 +122,11 @@ PODS: - Flutter - move_to_background (0.0.1): - Flutter + - nanopb (2.30909.0): + - nanopb/decode (= 2.30909.0) + - nanopb/encode (= 2.30909.0) + - nanopb/decode (2.30909.0) + - nanopb/encode (2.30909.0) - open_mail_app (0.0.1): - Flutter - OrderedSet (5.0.0) @@ -77,6 +138,7 @@ PODS: - photo_manager (2.0.0): - Flutter - FlutterMacOS + - PromisesObjC (2.3.1) - ReachabilitySwift (5.0.0) - receive_sharing_intent (0.0.1): - Flutter @@ -123,6 +185,8 @@ DEPENDENCIES: - camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`) - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - device_info (from `.symlinks/plugins/device_info/ios`) + - firebase_core (from `.symlinks/plugins/firebase_core/ios`) + - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - fk_user_agent (from `.symlinks/plugins/fk_user_agent/ios`) - Flutter (from `Flutter`) - flutter_email_sender (from `.symlinks/plugins/flutter_email_sender/ios`) @@ -134,6 +198,7 @@ DEPENDENCIES: - flutter_sodium (from `.symlinks/plugins/flutter_sodium/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - image_editor_common (from `.symlinks/plugins/image_editor_common/ios`) + - in_app_purchase_storekit (from `.symlinks/plugins/in_app_purchase_storekit/darwin`) - integration_test (from `.symlinks/plugins/integration_test/ios`) - local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`) - media_extension (from `.symlinks/plugins/media_extension/ios`) @@ -158,10 +223,19 @@ DEPENDENCIES: SPEC REPOS: trunk: + - Firebase + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - FirebaseMessaging - FMDB + - GoogleDataTransport + - GoogleUtilities - libwebp - Mantle + - nanopb - OrderedSet + - PromisesObjC - ReachabilitySwift - SDWebImage - SDWebImageWebPCoder @@ -178,6 +252,10 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/connectivity_plus/ios" device_info: :path: ".symlinks/plugins/device_info/ios" + firebase_core: + :path: ".symlinks/plugins/firebase_core/ios" + firebase_messaging: + :path: ".symlinks/plugins/firebase_messaging/ios" fk_user_agent: :path: ".symlinks/plugins/fk_user_agent/ios" Flutter: @@ -200,6 +278,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/fluttertoast/ios" image_editor_common: :path: ".symlinks/plugins/image_editor_common/ios" + in_app_purchase_storekit: + :path: ".symlinks/plugins/in_app_purchase_storekit/darwin" integration_test: :path: ".symlinks/plugins/integration_test/ios" local_auth_ios: @@ -248,6 +328,13 @@ SPEC CHECKSUMS: camera_avfoundation: 3125e8cd1a4387f6f31c6c63abb8a55892a9eeeb connectivity_plus: 53efb943fc2882c8512d84c45707bcabc4c36076 device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 + Firebase: bd152f0f3d278c4060c5c71359db08ebcfd5a3e2 + firebase_core: ce64b0941c6d87c6ef5022ae9116a158236c8c94 + firebase_messaging: 42912365e62efc1ea3e00724e5eecba6068ddb88 + FirebaseCore: b68d3616526ec02e4d155166bbafb8eca64af557 + FirebaseCoreInternal: b342e37cd4f5b4454ec34308f073420e7920858e + FirebaseInstallations: b28af1b9f997f1a799efe818c94695a3728c352f + FirebaseMessaging: 6b7052cc3da7bc8e5f72bef871243e8f04a14eed fk_user_agent: 1f47ec39291e8372b1d692b50084b0d54103c545 Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 flutter_email_sender: 02d7443217d8c41483223627972bfdc09f74276b @@ -259,7 +346,10 @@ SPEC CHECKSUMS: flutter_sodium: c84426b4de738514b5b66cfdeb8a06634e72fe0b fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + GoogleDataTransport: 54dee9d48d14580407f8f5fbf2f496e92437a2f2 + GoogleUtilities: 13e2c67ede716b8741c7989e26893d151b2b2084 image_editor_common: d6f6644ae4a6de80481e89fe6d0a8c49e30b4b43 + in_app_purchase_storekit: 4fb7ee9e824b1f09107fbfbbce8c4b276366dc43 integration_test: 13825b8a9334a850581300559b8839134b124670 libwebp: 33dc822fbbf4503668d09f7885bbfedc76c45e96 local_auth_ios: c6cf091ded637a88f24f86a8875d8b0f526e2605 @@ -267,11 +357,13 @@ SPEC CHECKSUMS: media_extension: 6d30dc1431ebaa63f43c397c37917b1a0a597a4c motionphoto: d4a432b8c8f22fb3ad966258597c0103c9c5ff16 move_to_background: 39a5b79b26d577b0372cbe8a8c55e7aa9fcd3a2d + nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 open_mail_app: 794172f6a22cd16319d3ddaf45e945b2f74952b0 OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c package_info_plus: fd030dabf36271f146f1f3beacd48f564b0f17f7 path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 photo_manager: 4f6810b7dfc4feb03b461ac1a70dacf91fba7604 + PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 receive_sharing_intent: c0d87310754e74c0f9542947e7cbdf3a0335a3b1 SDWebImage: 750adf017a315a280c60fde706ab1e552a3ae4e9 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 60f0a1ccc..967a41dba 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -260,8 +260,15 @@ inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseMessaging/FirebaseMessaging.framework", + "${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework", + "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", "${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework", "${BUILT_PRODUCTS_DIR}/OrderedSet/OrderedSet.framework", + "${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework", "${BUILT_PRODUCTS_DIR}/ReachabilitySwift/Reachability.framework", "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework", @@ -282,12 +289,14 @@ "${BUILT_PRODUCTS_DIR}/flutter_sodium/flutter_sodium.framework", "${BUILT_PRODUCTS_DIR}/fluttertoast/fluttertoast.framework", "${BUILT_PRODUCTS_DIR}/image_editor_common/image_editor_common.framework", + "${BUILT_PRODUCTS_DIR}/in_app_purchase_storekit/in_app_purchase_storekit.framework", "${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework", "${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework", "${BUILT_PRODUCTS_DIR}/local_auth_ios/local_auth_ios.framework", "${BUILT_PRODUCTS_DIR}/media_extension/media_extension.framework", "${BUILT_PRODUCTS_DIR}/motionphoto/motionphoto.framework", "${BUILT_PRODUCTS_DIR}/move_to_background/move_to_background.framework", + "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework", "${BUILT_PRODUCTS_DIR}/open_mail_app/open_mail_app.framework", "${BUILT_PRODUCTS_DIR}/package_info_plus/package_info_plus.framework", "${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework", @@ -308,8 +317,15 @@ name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreInternal.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseMessaging.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleDataTransport.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OrderedSet.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework", @@ -330,12 +346,14 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_sodium.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fluttertoast.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/image_editor_common.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/in_app_purchase_storekit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/local_auth_ios.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/media_extension.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/motionphoto.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/move_to_background.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/open_mail_app.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework", diff --git a/lib/ui/viewer/file/detail_page.dart b/lib/ui/viewer/file/detail_page.dart index 10f8d88d1..c665f8b91 100644 --- a/lib/ui/viewer/file/detail_page.dart +++ b/lib/ui/viewer/file/detail_page.dart @@ -1,3 +1,5 @@ +import "dart:math"; + import 'package:extended_image/extended_image.dart'; import "package:flutter/foundation.dart"; import 'package:flutter/material.dart'; @@ -161,7 +163,6 @@ class _DetailPageState extends State { Widget _buildPageView(BuildContext context) { final bottomPadding = MediaQuery.of(context).padding.bottom; - _logger.info("Building with " + _selectedIndexNotifier.value.toString()); return PageView.builder( itemBuilder: (context, index) { final file = _files![index]; @@ -173,6 +174,7 @@ class _DetailPageState extends State { shouldDisableScroll: (value) { if (_shouldDisableScroll != value) { setState(() { + _logger.fine('setState $_shouldDisableScroll to $value'); _shouldDisableScroll = value; }); } @@ -209,7 +211,16 @@ class _DetailPageState extends State { ); }, onPageChanged: (index) { - _selectedIndexNotifier.value = index; + if(_selectedIndexNotifier.value == index) { + if(kDebugMode) { + debugPrint("onPageChanged called with same index $index"); + } + // always notify listeners when the index is the same because + // the total number of files might have changed + _selectedIndexNotifier.notifyListeners(); + } else { + _selectedIndexNotifier.value = index; + } _preloadEntries(); }, physics: _shouldDisableScroll @@ -270,6 +281,7 @@ class _DetailPageState extends State { ); setState(() { + _logger.fine('setState loadStartEntries'); // Returned result could be a subtype of File // ignore: unnecessary_cast final files = result.files.reversed.map((e) => e as EnteFile).toList(); @@ -302,6 +314,7 @@ class _DetailPageState extends State { if (!result.hasMore) { _hasLoadedTillEnd = true; } + _logger.fine('setState loadEndEntries hasMore ${result.hasMore}'); _files!.addAll(result.files); }); } @@ -322,24 +335,21 @@ class _DetailPageState extends State { Navigator.of(context).pop(); // Close pageview return; } - if (_selectedIndexNotifier.value == totalFiles - 1) { - // Deleted the last file - await _pageController.previousPage( + setState(() { + _files!.remove(file); + _selectedIndexNotifier.value = min(_selectedIndexNotifier.value, + totalFiles - 2,); + }); + final currentPageIndex = _pageController.page!.round(); + final int targetPageIndex = _files!.length > currentPageIndex + ? currentPageIndex + : currentPageIndex - 1; + if (_files!.isNotEmpty) { + _pageController.animateToPage( + targetPageIndex, duration: const Duration(milliseconds: 200), curve: Curves.easeInOut, ); - setState(() { - _files!.remove(file); - }); - } else { - await _pageController.nextPage( - duration: const Duration(milliseconds: 200), - curve: Curves.easeInOut, - ); - setState(() { - _selectedIndexNotifier.value--; - _files!.remove(file); - }); } } diff --git a/lib/ui/viewer/file/file_app_bar.dart b/lib/ui/viewer/file/file_app_bar.dart index 8ebe63bee..ed8bd5dd2 100644 --- a/lib/ui/viewer/file/file_app_bar.dart +++ b/lib/ui/viewer/file/file_app_bar.dart @@ -89,7 +89,7 @@ class FileAppBarState extends State { } AppBar _buildAppBar() { - debugPrint("building app bar"); + _logger.fine("building app bar ${widget.file.generatedID?.toString()}"); final List actions = []; final isTrashedFile = widget.file is TrashFile; diff --git a/lib/ui/viewer/file/file_bottom_bar.dart b/lib/ui/viewer/file/file_bottom_bar.dart index 572d2bee3..e57ef5eb2 100644 --- a/lib/ui/viewer/file/file_bottom_bar.dart +++ b/lib/ui/viewer/file/file_bottom_bar.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:flutter/cupertino.dart'; import "package:flutter/foundation.dart"; import 'package:flutter/material.dart'; +import "package:logging/logging.dart"; import "package:photos/generated/l10n.dart"; import 'package:photos/models/file/file.dart'; import 'package:photos/models/file/file_type.dart'; @@ -52,6 +53,8 @@ class FileBottomBarState extends State { } Widget _getBottomBar() { + Logger("FileBottomBar").fine("building bottom bar ${widget.file + .generatedID}"); final List children = []; final bool isOwnedByUser = widget.file.ownerID == null || widget.file.ownerID == widget.userID; @@ -59,7 +62,7 @@ class FileBottomBarState extends State { children.add( Text( widget.file.generatedID?.toString() ?? 'null', - style: TextStyle(color: Colors.white), + style: const TextStyle(color: Colors.white), ), ); } diff --git a/lib/ui/viewer/file/file_widget.dart b/lib/ui/viewer/file/file_widget.dart index 85cac0d7e..8bfaa2f72 100644 --- a/lib/ui/viewer/file/file_widget.dart +++ b/lib/ui/viewer/file/file_widget.dart @@ -25,6 +25,9 @@ class FileWidget extends StatelessWidget { @override Widget build(BuildContext context) { + // Specify key to ensure that the widget is rebuilt when the file changes + // Before changing this, ensure that file deletes are handled properly + final String fileKey = "file_${file.generatedID}"; if (file.fileType == FileType.livePhoto || file.fileType == FileType.image) { return ZoomableLiveImage( @@ -32,6 +35,7 @@ class FileWidget extends StatelessWidget { shouldDisableScroll: shouldDisableScroll, tagPrefix: tagPrefix, backgroundDecoration: backgroundDecoration, + key: key ?? ValueKey(fileKey), ); } else if (file.fileType == FileType.video) { return VideoWidget( @@ -39,6 +43,7 @@ class FileWidget extends StatelessWidget { autoPlay: autoPlay ?? false, // Autoplay if it was opened directly tagPrefix: tagPrefix, playbackCallback: playbackCallback, + key: key ?? ValueKey(fileKey), ); } else { Logger('FileWidget').severe('unsupported file type ${file.fileType}'); diff --git a/lib/ui/viewer/file/zoomable_image.dart b/lib/ui/viewer/file/zoomable_image.dart index a17e54b4b..4a57bf86d 100644 --- a/lib/ui/viewer/file/zoomable_image.dart +++ b/lib/ui/viewer/file/zoomable_image.dart @@ -59,8 +59,8 @@ class _ZoomableImageState extends State @override void initState() { _photo = widget.photo; - _logger = Logger("ZoomableImage_" + _photo.tag); - debugPrint('initState for ${_photo.toString()}'); + _logger = Logger("ZoomableImage"); + _logger.info('initState for ${_photo.generatedID} with tag ${_photo.tag}'); _scaleStateChangedCallback = (value) { if (widget.shouldDisableScroll != null) { widget.shouldDisableScroll!(value != PhotoViewScaleState.initial); diff --git a/lib/ui/viewer/file/zoomable_live_image.dart b/lib/ui/viewer/file/zoomable_live_image.dart index c82da609c..f7e2aa55a 100644 --- a/lib/ui/viewer/file/zoomable_live_image.dart +++ b/lib/ui/viewer/file/zoomable_live_image.dart @@ -45,6 +45,8 @@ class _ZoomableLiveImageState extends State @override void initState() { _enteFile = widget.enteFile; + _logger.info('initState for ${_enteFile.generatedID} with tag ${_enteFile + .tag} and name ${_enteFile.displayName}'); super.initState(); }