diff --git a/mobile/apps/photos/ios/Podfile.lock b/mobile/apps/photos/ios/Podfile.lock index 55224eaaf9..627d2debd6 100644 --- a/mobile/apps/photos/ios/Podfile.lock +++ b/mobile/apps/photos/ios/Podfile.lock @@ -12,6 +12,8 @@ PODS: - Flutter - device_info_plus (0.0.1): - Flutter + - emoji_picker_flutter (0.0.1): + - Flutter - ffmpeg_kit_custom (6.0.3) - ffmpeg_kit_flutter (6.0.3): - ffmpeg_kit_custom @@ -127,9 +129,6 @@ PODS: - libwebp/sharpyuv (1.5.0) - libwebp/webp (1.5.0): - libwebp/sharpyuv - - local_auth_darwin (0.0.1): - - Flutter - - FlutterMacOS - local_auth_ios (0.0.1): - Flutter - Mantle (2.2.0): @@ -230,6 +229,8 @@ PODS: - Flutter - url_launcher_ios (0.0.1): - Flutter + - vibration (1.7.5): + - Flutter - video_player_avfoundation (0.0.1): - Flutter - FlutterMacOS @@ -250,6 +251,7 @@ DEPENDENCIES: - cupertino_http (from `.symlinks/plugins/cupertino_http/darwin`) - dart_ui_isolate (from `.symlinks/plugins/dart_ui_isolate/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) + - emoji_picker_flutter (from `.symlinks/plugins/emoji_picker_flutter/ios`) - ffmpeg_kit_flutter (from `.symlinks/plugins/ffmpeg_kit_flutter/ios`) - file_saver (from `.symlinks/plugins/file_saver/ios`) - firebase_core (from `.symlinks/plugins/firebase_core/ios`) @@ -269,7 +271,6 @@ DEPENDENCIES: - in_app_purchase_storekit (from `.symlinks/plugins/in_app_purchase_storekit/darwin`) - integration_test (from `.symlinks/plugins/integration_test/ios`) - launcher_icon_switcher (from `.symlinks/plugins/launcher_icon_switcher/ios`) - - local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`) - local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`) - maps_launcher (from `.symlinks/plugins/maps_launcher/ios`) - media_extension (from `.symlinks/plugins/media_extension/ios`) @@ -297,6 +298,7 @@ DEPENDENCIES: - thermal (from `.symlinks/plugins/thermal/ios`) - ua_client_hints (from `.symlinks/plugins/ua_client_hints/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + - vibration (from `.symlinks/plugins/vibration/ios`) - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`) - video_thumbnail (from `.symlinks/plugins/video_thumbnail/ios`) - volume_controller (from `.symlinks/plugins/volume_controller/ios`) @@ -304,7 +306,7 @@ DEPENDENCIES: - workmanager (from `.symlinks/plugins/workmanager/ios`) SPEC REPOS: - https://github.com/ente-io/ffmpeg-kit-custom-repo-ios: + https://github.com/ente-io/ffmpeg-kit-custom-repo-ios.git: - ffmpeg_kit_custom trunk: - Firebase @@ -339,6 +341,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/dart_ui_isolate/ios" device_info_plus: :path: ".symlinks/plugins/device_info_plus/ios" + emoji_picker_flutter: + :path: ".symlinks/plugins/emoji_picker_flutter/ios" ffmpeg_kit_flutter: :path: ".symlinks/plugins/ffmpeg_kit_flutter/ios" file_saver: @@ -377,8 +381,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/integration_test/ios" launcher_icon_switcher: :path: ".symlinks/plugins/launcher_icon_switcher/ios" - local_auth_darwin: - :path: ".symlinks/plugins/local_auth_darwin/darwin" local_auth_ios: :path: ".symlinks/plugins/local_auth_ios/ios" maps_launcher: @@ -433,6 +435,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/ua_client_hints/ios" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" + vibration: + :path: ".symlinks/plugins/vibration/ios" video_player_avfoundation: :path: ".symlinks/plugins/video_player_avfoundation/darwin" video_thumbnail: @@ -445,83 +449,84 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/workmanager/ios" SPEC CHECKSUMS: - app_links: 76b66b60cc809390ca1ad69bfd66b998d2387ac7 - battery_info: 83f3aae7be2fccefab1d2bf06b8aa96f11c8bcdd - connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd - cupertino_http: 94ac07f5ff090b8effa6c5e2c47871d48ab7c86c - dart_ui_isolate: 46f6714abe6891313267153ef6f9748d8ecfcab1 - device_info_plus: 335f3ce08d2e174b9fdc3db3db0f4e3b1f66bd89 + app_links: f3e17e4ee5e357b39d8b95290a9b2c299fca71c6 + battery_info: b6c551049266af31556b93c9d9b9452cfec0219f + connectivity_plus: 2a701ffec2c0ae28a48cf7540e279787e77c447d + cupertino_http: 947a233f40cfea55167a49f2facc18434ea117ba + dart_ui_isolate: d5bcda83ca4b04f129d70eb90110b7a567aece14 + device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 + emoji_picker_flutter: fe2e6151c5b548e975d546e6eeb567daf0962a58 ffmpeg_kit_custom: 682b4f2f1ff1f8abae5a92f6c3540f2441d5be99 - ffmpeg_kit_flutter: 915b345acc97d4142e8a9a8549d177ff10f043f5 - file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6 + ffmpeg_kit_flutter: 9dce4803991478c78c6fb9f972703301101095fe + file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808 Firebase: d80354ed7f6df5f9aca55e9eb47cc4b634735eaf - firebase_core: 6cbed78b4f298ed103a9fd034e6dbc846320480f - firebase_messaging: 5e0adf2eb18b0ee59aa0c109314c091a0497ecac + firebase_core: 6e223dfa350b2edceb729cea505eaaef59330682 + firebase_messaging: 07fde77ae28c08616a1d4d870450efc2b38cf40d FirebaseCore: 99fe0c4b44a39f37d99e6404e02009d2db5d718d FirebaseCoreInternal: df24ce5af28864660ecbd13596fc8dd3a8c34629 FirebaseInstallations: 6c963bd2a86aca0481eef4f48f5a4df783ae5917 FirebaseMessaging: 487b634ccdf6f7b7ff180fdcb2a9935490f764e8 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - flutter_email_sender: aa1e9772696691d02cd91fea829856c11efb8e58 - flutter_image_compress_common: 1697a328fd72bfb335507c6bca1a65fa5ad87df1 - flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99 - flutter_local_notifications: a5a732f069baa862e728d839dd2ebb904737effb - flutter_native_splash: 6cad9122ea0fad137d23137dd14b937f3e90b145 - flutter_secure_storage: 2c2ff13db9e0a5647389bff88b0ecac56e3f3418 - flutter_sodium: 7e4621538491834eba53bd524547854bcbbd6987 - flutter_timezone: 7c838e17ffd4645d261e87037e5bebf6d38fe544 - fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1 + flutter_email_sender: e03bdda7637bcd3539bfe718fddd980e9508efaa + flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e + flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4 + flutter_local_notifications: ff50f8405aaa0ccdc7dcfb9022ca192e8ad9688f + flutter_native_splash: f71420956eb811e6d310720fee915f1d42852e7a + flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be + flutter_sodium: a00383520fc689c688b66fd3092984174712493e + flutter_timezone: ac3da59ac941ff1c98a2e1f0293420e020120282 + fluttertoast: 21eecd6935e7064cc1fcb733a4c5a428f3f24f0f GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 - home_widget: f169fc41fd807b4d46ab6615dc44d62adbf9f64f - image_editor_common: 3de87e7c4804f4ae24c8f8a998362b98c105cac1 - in_app_purchase_storekit: d1a48cb0f8b29dbf5f85f782f5dd79b21b90a5e6 - integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e - launcher_icon_switcher: 84c218d233505aa7d8655d8fa61a3ba802c022da + home_widget: 0434835a4c9a75704264feff6be17ea40e0f0d57 + image_editor_common: d6f6644ae4a6de80481e89fe6d0a8c49e30b4b43 + in_app_purchase_storekit: a1ce04056e23eecc666b086040239da7619cd783 + integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 + launcher_icon_switcher: 8e0ad2131a20c51c1dd939896ee32e70cd845b37 libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8 - local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391 - local_auth_ios: f7a1841beef3151d140a967c2e46f30637cdf451 + local_auth_ios: 5046a18c018dd973247a0564496c8898dbb5adf9 Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d - maps_launcher: edf829809ba9e894d70e569bab11c16352dedb45 - media_extension: 671e2567880d96c95c65c9a82ccceed8f2e309fd - media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854 - media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474 - motion_sensors: 741e702c17467b9569a92165dda8d4d88c6167f1 - motionphoto: 23e2aeb5c6380112f69468d71f970fa7438e5ed1 - move_to_background: 7e3467dd2a1d1013e98c9c1cb93fd53cd7ef9d84 + maps_launcher: 2e5b6a2d664ec6c27f82ffa81b74228d770ab203 + media_extension: 6618f07abd762cdbfaadf1b0c56a287e820f0c84 + media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1 + media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e + motion_sensors: 03f55b7c637a7e365a0b5f9697a449f9059d5d91 + motionphoto: 8b65ce50c7d7ff3c767534fc3768b2eed9ac24e4 + move_to_background: cd3091014529ec7829e342ad2d75c0a11f4378a5 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 - native_video_player: 6809dec117e8997161dbfb42a6f90d6df71a504d - objective_c: 89e720c30d716b036faf9c9684022048eee1eee2 - onnxruntime: f9b296392c96c42882be020a59dbeac6310d81b2 + native_video_player: 29ab24a926804ac8c4a57eb6d744c7d927c2bc3e + objective_c: 77e887b5ba1827970907e10e832eec1683f3431d + onnxruntime: e7c2ae44385191eaad5ae64c935a72debaddc997 onnxruntime-c: a909204639a1f035f575127ac406f781ac797c9c onnxruntime-objc: b6fab0f1787aa6f7190c2013f03037df4718bd8b - open_mail_app: 7314a609e88eed22d53671279e189af7a0ab0f11 + open_mail_app: 70273c53f768beefdafbe310c3d9086e4da3cb02 OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 - package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 - path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 - permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d - photo_manager: d2fbcc0f2d82458700ee6256a15018210a81d413 - privacy_screen: 3159a541f5d3a31bea916cfd4e58f9dc722b3fd4 + package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4 + path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 + permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 + photo_manager: ff695c7a1dd5bc379974953a2b5c0a293f7c4c8a + privacy_screen: 1a131c052ceb3c3659934b003b0d397c2381a24e PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 - receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00 + receive_sharing_intent: 79c848f5b045674ad60b9fea3bafea59962ad2c1 SDWebImage: f29024626962457f3470184232766516dee8dfea SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380 Sentry: da60d980b197a46db0b35ea12cb8f39af48d8854 - sentry_flutter: 27892878729f42701297c628eb90e7c6529f3684 - share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a - shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 - sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 + sentry_flutter: 2df8b0aab7e4aba81261c230cbea31c82a62dd1b + share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f + shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 + sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d sqlite3: 3c950dc86011117c307eb0b28c4a7bb449dce9f1 - sqlite3_flutter_libs: 3c323550ef3b928bc0aa9513c841e45a7d242832 - system_info_plus: 555ce7047fbbf29154726db942ae785c29211740 - thermal: d4c48be750d1ddbab36b0e2dcb2471531bc8df41 - ua_client_hints: 92fe0d139619b73ec9fcb46cc7e079a26178f586 - url_launcher_ios: 694010445543906933d732453a59da0a173ae33d - video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b - video_thumbnail: 584ccfa55d8fd2f3d5507218b0a18d84c839c620 - volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12 - wakelock_plus: 04623e3f525556020ebd4034310f20fe7fda8b49 - workmanager: 01be2de7f184bd15de93a1812936a2b7f42ef07e + sqlite3_flutter_libs: 069c435986dd4b63461aecd68f4b30be4a9e9daa + system_info_plus: 5393c8da281d899950d751713575fbf91c7709aa + thermal: a9261044101ae8f532fa29cab4e8270b51b3f55c + ua_client_hints: aeabd123262c087f0ce151ef96fa3ab77bfc8b38 + url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe + vibration: 7d883d141656a1c1a6d8d238616b2042a51a1241 + video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3 + video_thumbnail: 94ba6705afbaa120b77287080424930f23ea0c40 + volume_controller: 2e3de73d6e7e81a0067310d17fb70f2f86d71ac7 + wakelock_plus: 373cfe59b235a6dd5837d0fb88791d2f13a90d56 + workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6 PODFILE CHECKSUM: a8ef88ad74ba499756207e7592c6071a96756d18 diff --git a/mobile/apps/photos/ios/Runner.xcodeproj/project.pbxproj b/mobile/apps/photos/ios/Runner.xcodeproj/project.pbxproj index d1c1bff9f4..db6d40da7d 100644 --- a/mobile/apps/photos/ios/Runner.xcodeproj/project.pbxproj +++ b/mobile/apps/photos/ios/Runner.xcodeproj/project.pbxproj @@ -532,6 +532,7 @@ "${BUILT_PRODUCTS_DIR}/cupertino_http/cupertino_http.framework", "${BUILT_PRODUCTS_DIR}/dart_ui_isolate/dart_ui_isolate.framework", "${BUILT_PRODUCTS_DIR}/device_info_plus/device_info_plus.framework", + "${BUILT_PRODUCTS_DIR}/emoji_picker_flutter/emoji_picker_flutter.framework", "${BUILT_PRODUCTS_DIR}/file_saver/file_saver.framework", "${BUILT_PRODUCTS_DIR}/flutter_email_sender/flutter_email_sender.framework", "${BUILT_PRODUCTS_DIR}/flutter_image_compress_common/flutter_image_compress_common.framework", @@ -548,7 +549,6 @@ "${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework", "${BUILT_PRODUCTS_DIR}/launcher_icon_switcher/launcher_icon_switcher.framework", "${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework", - "${BUILT_PRODUCTS_DIR}/local_auth_darwin/local_auth_darwin.framework", "${BUILT_PRODUCTS_DIR}/local_auth_ios/local_auth_ios.framework", "${BUILT_PRODUCTS_DIR}/maps_launcher/maps_launcher.framework", "${BUILT_PRODUCTS_DIR}/media_extension/media_extension.framework", @@ -576,6 +576,7 @@ "${BUILT_PRODUCTS_DIR}/thermal/thermal.framework", "${BUILT_PRODUCTS_DIR}/ua_client_hints/ua_client_hints.framework", "${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework", + "${BUILT_PRODUCTS_DIR}/vibration/vibration.framework", "${BUILT_PRODUCTS_DIR}/video_player_avfoundation/video_player_avfoundation.framework", "${BUILT_PRODUCTS_DIR}/video_thumbnail/video_thumbnail.framework", "${BUILT_PRODUCTS_DIR}/volume_controller/volume_controller.framework", @@ -628,6 +629,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/cupertino_http.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/dart_ui_isolate.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info_plus.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/emoji_picker_flutter.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_saver.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_email_sender.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_image_compress_common.framework", @@ -644,7 +646,6 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/launcher_icon_switcher.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/local_auth_darwin.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/local_auth_ios.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/maps_launcher.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/media_extension.framework", @@ -672,6 +673,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/thermal.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ua_client_hints.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/vibration.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_player_avfoundation.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_thumbnail.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/volume_controller.framework", diff --git a/mobile/apps/photos/lib/generated/l10n.dart b/mobile/apps/photos/lib/generated/l10n.dart index 84cef71699..14b4c3aeea 100644 --- a/mobile/apps/photos/lib/generated/l10n.dart +++ b/mobile/apps/photos/lib/generated/l10n.dart @@ -12495,6 +12495,118 @@ class S { args: [], ); } + + /// `Undo` + String get undo { + return Intl.message( + 'Undo', + name: 'undo', + desc: '', + args: [], + ); + } + + /// `Redo` + String get redo { + return Intl.message( + 'Redo', + name: 'redo', + desc: '', + args: [], + ); + } + + /// `Filter` + String get filter { + return Intl.message( + 'Filter', + name: 'filter', + desc: '', + args: [], + ); + } + + /// `Adjust` + String get adjust { + return Intl.message( + 'Adjust', + name: 'adjust', + desc: '', + args: [], + ); + } + + /// `Draw` + String get draw { + return Intl.message( + 'Draw', + name: 'draw', + desc: '', + args: [], + ); + } + + /// `Sticker` + String get sticker { + return Intl.message( + 'Sticker', + name: 'sticker', + desc: '', + args: [], + ); + } + + /// `Brush Color` + String get brushColor { + return Intl.message( + 'Brush Color', + name: 'brushColor', + desc: '', + args: [], + ); + } + + /// `Font` + String get font { + return Intl.message( + 'Font', + name: 'font', + desc: '', + args: [], + ); + } + + /// `Background` + String get background { + return Intl.message( + 'Background', + name: 'background', + desc: '', + args: [], + ); + } + + /// `Align` + String get align { + return Intl.message( + 'Align', + name: 'align', + desc: '', + args: [], + ); + } + + /// `{count, plural, =1{Added successfully to 1 album} other{Added successfully to {count} albums}}` + String addedToAlbums(int count) { + return Intl.plural( + count, + one: 'Added successfully to 1 album', + other: 'Added successfully to $count albums', + name: 'addedToAlbums', + desc: 'Message shown when items are added to albums', + args: [count], + ); + } } class AppLocalizationDelegate extends LocalizationsDelegate { diff --git a/mobile/apps/photos/lib/l10n/intl_en.arb b/mobile/apps/photos/lib/l10n/intl_en.arb index 21998814da..017637a8b8 100644 --- a/mobile/apps/photos/lib/l10n/intl_en.arb +++ b/mobile/apps/photos/lib/l10n/intl_en.arb @@ -1808,5 +1808,24 @@ "automaticallyAnalyzeAndSplitGrouping": "We will automatically analyze the grouping to determine if there are multiple people present, and separate them out again. This may take a few seconds.", "layout": "Layout", "day": "Day", - "peopleAutoAddDesc": "Select the people you want to automatically add to the album" + "peopleAutoAddDesc": "Select the people you want to automatically add to the album", + "undo": "Undo", + "redo": "Redo", + "filter": "Filter", + "adjust": "Adjust", + "draw": "Draw", + "sticker": "Sticker", + "brushColor": "Brush Color", + "font": "Font", + "background": "Background", + "align": "Align", + "addedToAlbums": "{count, plural, =1{Added successfully to 1 album} other{Added successfully to {count} albums}}", + "@addedToAlbums": { + "description": "Message shown when items are added to albums", + "placeholders": { + "count": { + "type": "int" + } + } + } } \ No newline at end of file diff --git a/mobile/apps/photos/lib/models/collection/collection.dart b/mobile/apps/photos/lib/models/collection/collection.dart index 35d4a5167a..ffb60673c5 100644 --- a/mobile/apps/photos/lib/models/collection/collection.dart +++ b/mobile/apps/photos/lib/models/collection/collection.dart @@ -142,7 +142,9 @@ class Collection { bool canAutoAdd(int userID) { final canEditCollection = isOwner(userID) || getRole(userID) == CollectionParticipantRole.collaborator; - return canEditCollection && !isDeleted; + final isFavoritesOrUncategorized = type == CollectionType.favorites || + type == CollectionType.uncategorized; + return canEditCollection && !isDeleted && !isFavoritesOrUncategorized; } bool isDownloadEnabledForPublicLink() { diff --git a/mobile/apps/photos/lib/models/search/search_types.dart b/mobile/apps/photos/lib/models/search/search_types.dart index eb0cd0ea85..d5e27e671c 100644 --- a/mobile/apps/photos/lib/models/search/search_types.dart +++ b/mobile/apps/photos/lib/models/search/search_types.dart @@ -187,11 +187,14 @@ extension SectionTypeExtensions on SectionType { try { final Collection c = await CollectionsService.instance.createAlbum(text); - unawaited( - routeToPage( - context, - CollectionPage(CollectionWithThumbnail(c, null)), - ), + + // Close the dialog now so that it does not flash when leaving the album again. + Navigator.of(context).pop(); + + // ignore: unawaited_futures + await routeToPage( + context, + CollectionPage(CollectionWithThumbnail(c, null)), ); } catch (e, s) { Logger("CreateNewAlbumIcon") diff --git a/mobile/apps/photos/lib/services/smart_albums_service.dart b/mobile/apps/photos/lib/services/smart_albums_service.dart index 1aa8148f46..1be07b7519 100644 --- a/mobile/apps/photos/lib/services/smart_albums_service.dart +++ b/mobile/apps/photos/lib/services/smart_albums_service.dart @@ -86,23 +86,35 @@ class SmartAlbumsService { return; } + _logger.info("Syncing Smart Albums"); final cachedConfigs = await getSmartConfigs(); final userId = Configuration.instance.getUserID()!; for (final entry in cachedConfigs.entries) { final collectionId = entry.key; final config = entry.value; + + if (config.personIDs.isEmpty) { + _logger.warning( + "Skipping sync for collection ($collectionId) as it has no person IDs", + ); + continue; + } + final collection = CollectionsService.instance.getCollectionByID(collectionId); - if (!(collection?.canAutoAdd(userId) ?? false)) { + if (collection == null || !collection.canAutoAdd(userId)) { _logger.warning( - "Deleting collection config ($collectionId) as user does not have permission", - ); - await _deleteEntry( - userId: userId, - collectionId: collectionId, + "For config ($collectionId) user does not have permission", ); + if (collection?.isDeleted ?? false) { + await _deleteEntry( + userId: userId, + collectionId: collectionId, + ); + } + continue; } @@ -166,11 +178,14 @@ class SmartAlbumsService { newConfig = newConfig.addFiles(updatedAtMap, pendingSyncFiles); await saveConfig(newConfig); - } catch (_) {} + } catch (e, sT) { + _logger.warning(e, sT); + } } } syncingCollection = null; Bus.instance.fire(SmartAlbumSyncingEvent()); + _logger.fine("Smart Albums sync completed"); } Future addPeopleToSmartAlbum( @@ -214,11 +229,6 @@ class SmartAlbumsService { addWithCustomID: config.id == null, userId: userId, ); - } else if (config.id != null) { - await _deleteEntry( - userId: userId, - collectionId: config.collectionId, - ); } } @@ -238,6 +248,7 @@ class SmartAlbumsService { bool addWithCustomID = false, required int userId, }) async { + _logger.fine("Adding or updating entity for collection ($collectionId)"); final id = getId(collectionId: collectionId, userId: userId); final result = await entityService.addOrUpdate( type, @@ -254,6 +265,7 @@ class SmartAlbumsService { required int userId, required int collectionId, }) async { + _logger.fine("Deleting entry for collection ($collectionId)"); final id = getId(collectionId: collectionId, userId: userId); await entityService.deleteEntry(id); _lastCacheRefreshTime = 0; // Invalidate cache diff --git a/mobile/apps/photos/lib/ui/collections/album/smart_album_people.dart b/mobile/apps/photos/lib/ui/collections/album/smart_album_people.dart index 17e6f58218..7ee8c8c594 100644 --- a/mobile/apps/photos/lib/ui/collections/album/smart_album_people.dart +++ b/mobile/apps/photos/lib/ui/collections/album/smart_album_people.dart @@ -2,6 +2,7 @@ import "dart:async"; import "package:flutter/foundation.dart"; import 'package:flutter/material.dart'; +import "package:logging/logging.dart"; import "package:photos/core/event_bus.dart"; import "package:photos/db/files_db.dart"; import "package:photos/events/collection_updated_event.dart"; @@ -36,6 +37,8 @@ class _SmartAlbumPeopleState extends State { final _selectedPeople = SelectedPeople(); SmartAlbumConfig? currentConfig; + final _logger = Logger("SmartAlbumPeople"); + @override void initState() { super.initState(); @@ -168,11 +171,16 @@ class _SmartAlbumPeopleState extends State { await dialog.hide(); Navigator.pop(context); - } catch (e) { + } catch (error, stackTrace) { + _logger.severe( + "Error saving smart album config", + error, + stackTrace, + ); await dialog.hide(); await showGenericErrorDialog( context: context, - error: e, + error: error, ); } } diff --git a/mobile/apps/photos/lib/ui/collections/album/vertical_list.dart b/mobile/apps/photos/lib/ui/collections/album/vertical_list.dart index d65ae4049f..9b10cd49a2 100644 --- a/mobile/apps/photos/lib/ui/collections/album/vertical_list.dart +++ b/mobile/apps/photos/lib/ui/collections/album/vertical_list.dart @@ -146,7 +146,7 @@ class _AlbumVerticalListWidgetState extends State { }, showOnlyLoadingState: true, textCapitalization: TextCapitalization.words, - popnavAfterSubmission: false, + popnavAfterSubmission: true, ); if (result is Exception) { await showGenericErrorDialog( diff --git a/mobile/apps/photos/lib/ui/collections/collection_action_sheet.dart b/mobile/apps/photos/lib/ui/collections/collection_action_sheet.dart index d049be0102..64fe799e46 100644 --- a/mobile/apps/photos/lib/ui/collections/collection_action_sheet.dart +++ b/mobile/apps/photos/lib/ui/collections/collection_action_sheet.dart @@ -310,9 +310,7 @@ class _CollectionActionSheetState extends State { if (result) { showShortToast( context, - "Added successfully to " + - _selectedCollections.length.toString() + - " albums", + S.of(context).addedToAlbums(_selectedCollections.length), ); widget.selectedFiles?.clearAll(); } diff --git a/mobile/apps/photos/lib/ui/tools/editor/filtered_image.dart b/mobile/apps/photos/lib/ui/tools/editor/filtered_image.dart deleted file mode 100644 index 31c74590ac..0000000000 --- a/mobile/apps/photos/lib/ui/tools/editor/filtered_image.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/widgets.dart'; -import 'package:image_editor/image_editor.dart'; - -class FilteredImage extends StatelessWidget { - const FilteredImage({ - required this.child, - this.brightness, - this.saturation, - this.hue, - super.key, - }); - - final double? brightness, saturation, hue; - final Widget child; - - @override - Widget build(BuildContext context) { - return ColorFiltered( - colorFilter: ColorFilter.matrix( - ColorFilterGenerator.brightnessAdjustMatrix( - value: brightness ?? 1, - ), - ), - child: ColorFiltered( - colorFilter: ColorFilter.matrix( - ColorFilterGenerator.saturationAdjustMatrix( - value: saturation ?? 1, - ), - ), - child: ColorFiltered( - colorFilter: ColorFilter.matrix( - ColorFilterGenerator.hueAdjustMatrix( - value: hue ?? 0, - ), - ), - child: child, - ), - ), - ); - } -} - -class ColorFilterGenerator { - static List hueAdjustMatrix({double value = 1}) { - value = value * pi; - - if (value == 0) { - return [ - 1, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - ]; - } - final double cosVal = cos(value); - final double sinVal = sin(value); - const double lumR = 0.213; - const double lumG = 0.715; - const double lumB = 0.072; - - return List.from([ - (lumR + (cosVal * (1 - lumR))) + (sinVal * (-lumR)), - (lumG + (cosVal * (-lumG))) + (sinVal * (-lumG)), - (lumB + (cosVal * (-lumB))) + (sinVal * (1 - lumB)), - 0, - 0, - (lumR + (cosVal * (-lumR))) + (sinVal * 0.143), - (lumG + (cosVal * (1 - lumG))) + (sinVal * 0.14), - (lumB + (cosVal * (-lumB))) + (sinVal * (-0.283)), - 0, - 0, - (lumR + (cosVal * (-lumR))) + (sinVal * (-(1 - lumR))), - (lumG + (cosVal * (-lumG))) + (sinVal * lumG), - (lumB + (cosVal * (1 - lumB))) + (sinVal * lumB), - 0, - 0, - 0, - 0, - 0, - 1, - 0, - ]).map((i) => i.toDouble()).toList(); - } - - static List brightnessAdjustMatrix({double value = 1}) { - return ColorOption.brightness(value).matrix; - } - - static List saturationAdjustMatrix({double value = 1}) { - return ColorOption.saturation(value).matrix; - } -} diff --git a/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_app_bar.dart b/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_app_bar.dart index 03e84cf75d..730feb5d3a 100644 --- a/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_app_bar.dart +++ b/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_app_bar.dart @@ -1,7 +1,8 @@ import 'package:flutter/material.dart'; import "package:flutter_svg/svg.dart"; import "package:photos/ente_theme_data.dart"; -import "package:photos/theme/ente_theme.dart"; +import "package:photos/generated/l10n.dart"; + import "package:photos/theme/ente_theme.dart"; import "package:pro_image_editor/models/editor_configs/pro_image_editor_configs.dart"; class ImageEditorAppBar extends StatelessWidget implements PreferredSizeWidget { @@ -43,7 +44,7 @@ class ImageEditorAppBar extends StatelessWidget implements PreferredSizeWidget { enableUndo ? close() : Navigator.of(context).pop(); }, child: Text( - 'Cancel', + S.of(context).cancel, style: getEnteTextTheme(context).body, ), ), @@ -52,7 +53,7 @@ class ImageEditorAppBar extends StatelessWidget implements PreferredSizeWidget { mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ IconButton( - tooltip: 'Undo', + tooltip: S.of(context).undo, onPressed: () { undo != null ? undo!() : null; }, @@ -66,7 +67,7 @@ class ImageEditorAppBar extends StatelessWidget implements PreferredSizeWidget { ), const SizedBox(width: 12), IconButton( - tooltip: 'Redo', + tooltip: S.of(context).redo, onPressed: () { redo != null ? redo!() : null; }, @@ -88,7 +89,7 @@ class ImageEditorAppBar extends StatelessWidget implements PreferredSizeWidget { key: ValueKey(isMainEditor ? 'save_copy' : 'done'), onPressed: done, child: Text( - isMainEditor ? 'Save Copy' : 'Done', + isMainEditor ? S.of(context).saveCopy : S.of(context).done, style: getEnteTextTheme(context).body.copyWith( color: isMainEditor ? (enableUndo diff --git a/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_crop_rotate.dart b/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_crop_rotate.dart index a222ed92e4..10333cd3ce 100644 --- a/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_crop_rotate.dart +++ b/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_crop_rotate.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import "package:flutter_svg/svg.dart"; +import "package:photos/generated/l10n.dart"; import "package:photos/theme/ente_theme.dart"; import "package:photos/ui/tools/editor/image_editor/circular_icon_button.dart"; import "package:photos/ui/tools/editor/image_editor/image_editor_configs_mixin.dart"; @@ -113,7 +114,7 @@ class _ImageEditorCropRotateBarState extends State children: [ CircularIconButton( svgPath: "assets/image-editor/image-editor-crop-rotate.svg", - label: "Rotate", + label: S.of(context).rotate, onTap: () { widget.editor.rotate(); }, @@ -121,7 +122,7 @@ class _ImageEditorCropRotateBarState extends State const SizedBox(width: 6), CircularIconButton( svgPath: "assets/image-editor/image-editor-flip.svg", - label: "Flip", + label: S.of(context).flip, onTap: () { widget.editor.flip(); }, diff --git a/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_main_bottom_bar.dart b/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_main_bottom_bar.dart index 3321e645c1..32dc0a5ed8 100644 --- a/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_main_bottom_bar.dart +++ b/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_main_bottom_bar.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; +import "package:photos/generated/l10n.dart"; import "package:photos/ui/tools/editor/image_editor/circular_icon_button.dart"; import "package:photos/ui/tools/editor/image_editor/image_editor_configs_mixin.dart"; import "package:photos/ui/tools/editor/image_editor/image_editor_constants.dart"; @@ -90,7 +91,7 @@ class ImageEditorMainBottomBarState extends State children: [ CircularIconButton( svgPath: "assets/image-editor/image-editor-crop.svg", - label: "Crop", + label: S.of(context).crop, onTap: () { widget.editor.openCropRotateEditor(); }, @@ -98,21 +99,21 @@ class ImageEditorMainBottomBarState extends State CircularIconButton( svgPath: "assets/image-editor/image-editor-filter.svg", - label: "Filter", + label: S.of(context).filter, onTap: () { widget.editor.openFilterEditor(); }, ), CircularIconButton( svgPath: "assets/image-editor/image-editor-tune.svg", - label: "Adjust", + label: S.of(context).adjust, onTap: () { widget.editor.openTuneEditor(); }, ), CircularIconButton( svgPath: "assets/image-editor/image-editor-paint.svg", - label: "Draw", + label: S.of(context).draw, onTap: () { widget.editor.openPaintingEditor(); }, @@ -120,7 +121,7 @@ class ImageEditorMainBottomBarState extends State CircularIconButton( svgPath: "assets/image-editor/image-editor-sticker.svg", - label: "Sticker", + label: S.of(context).sticker, onTap: () { widget.editor.openEmojiEditor(); }, diff --git a/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_page_new.dart b/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_page.dart similarity index 99% rename from mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_page_new.dart rename to mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_page.dart index f99799378e..e6bc90dbab 100644 --- a/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_page_new.dart +++ b/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_page.dart @@ -37,12 +37,12 @@ import "package:photos/utils/navigation_util.dart"; import "package:pro_image_editor/models/editor_configs/main_editor_configs.dart"; import 'package:pro_image_editor/pro_image_editor.dart'; -class NewImageEditor extends StatefulWidget { +class ImageEditorPage extends StatefulWidget { final ente.EnteFile originalFile; final File file; final DetailPageConfiguration detailPageConfig; - const NewImageEditor({ + const ImageEditorPage({ super.key, required this.file, required this.originalFile, @@ -50,10 +50,10 @@ class NewImageEditor extends StatefulWidget { }); @override - State createState() => _NewImageEditorState(); + State createState() => _ImageEditorPageState(); } -class _NewImageEditorState extends State { +class _ImageEditorPageState extends State { final _mainEditorBarKey = GlobalKey(); final editorKey = GlobalKey(); final _logger = Logger("ImageEditor"); diff --git a/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_paint_bar.dart b/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_paint_bar.dart index 0e4d1dd44f..5c7fe2c97d 100644 --- a/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_paint_bar.dart +++ b/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_paint_bar.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import "package:photos/generated/l10n.dart"; import "package:photos/theme/ente_theme.dart"; import "package:photos/ui/tools/editor/image_editor/image_editor_color_picker.dart"; import "package:photos/ui/tools/editor/image_editor/image_editor_configs_mixin.dart"; @@ -63,7 +64,7 @@ class _ImageEditorPaintBarState extends State Padding( padding: const EdgeInsets.only(left: 20.0), child: Text( - "Brush Color", + S.of(context).brushColor, style: getEnteTextTheme(context).body, ), ), diff --git a/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_text_bar.dart b/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_text_bar.dart index 3115aa3933..d4327fb136 100644 --- a/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_text_bar.dart +++ b/mobile/apps/photos/lib/ui/tools/editor/image_editor/image_editor_text_bar.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import "package:flutter_svg/svg.dart"; +import "package:photos/generated/l10n.dart"; import "package:photos/theme/ente_theme.dart"; import "package:photos/ui/tools/editor/image_editor/circular_icon_button.dart"; import "package:photos/ui/tools/editor/image_editor/image_editor_color_picker.dart"; @@ -75,7 +76,7 @@ class _ImageEditorTextBarState extends State children: [ CircularIconButton( svgPath: "assets/image-editor/image-editor-text-color.svg", - label: "Color", + label: S.of(context).color, isSelected: selectedActionIndex == 0, onTap: () { _selectAction(0); @@ -83,7 +84,7 @@ class _ImageEditorTextBarState extends State ), CircularIconButton( svgPath: "assets/image-editor/image-editor-text-font.svg", - label: "Font", + label: S.of(context).font, isSelected: selectedActionIndex == 1, onTap: () { _selectAction(1); @@ -91,7 +92,7 @@ class _ImageEditorTextBarState extends State ), CircularIconButton( svgPath: "assets/image-editor/image-editor-text-background.svg", - label: "Background", + label: S.of(context).background, isSelected: selectedActionIndex == 2, onTap: () { setState(() { @@ -101,7 +102,7 @@ class _ImageEditorTextBarState extends State ), CircularIconButton( svgPath: "assets/image-editor/image-editor-text-align-left.svg", - label: "Align", + label: S.of(context).align, isSelected: selectedActionIndex == 3, onTap: () { setState(() { diff --git a/mobile/apps/photos/lib/ui/tools/editor/image_editor_page.dart b/mobile/apps/photos/lib/ui/tools/editor/image_editor_page.dart deleted file mode 100644 index 99874d7c3a..0000000000 --- a/mobile/apps/photos/lib/ui/tools/editor/image_editor_page.dart +++ /dev/null @@ -1,553 +0,0 @@ -import "dart:async"; -import 'dart:io'; -import 'dart:math'; -import 'dart:typed_data'; -import 'dart:ui' as ui show Image; - -import 'package:extended_image/extended_image.dart'; -import 'package:flutter/material.dart'; -import "package:flutter_image_compress/flutter_image_compress.dart"; -import 'package:image_editor/image_editor.dart'; -import 'package:logging/logging.dart'; -import 'package:path/path.dart' as path; -import 'package:photo_manager/photo_manager.dart'; -import 'package:photos/core/event_bus.dart'; -import 'package:photos/db/files_db.dart'; -import 'package:photos/events/local_photos_updated_event.dart'; -import "package:photos/generated/l10n.dart"; -import 'package:photos/models/file/file.dart' as ente; -import 'package:photos/models/location/location.dart'; -import 'package:photos/services/sync/sync_service.dart'; -import 'package:photos/ui/common/loading_widget.dart'; -import 'package:photos/ui/components/action_sheet_widget.dart'; -import 'package:photos/ui/components/buttons/button_widget.dart'; -import 'package:photos/ui/components/models/button_type.dart'; -import 'package:photos/ui/notification/toast.dart'; -import 'package:photos/ui/tools/editor/filtered_image.dart'; -import 'package:photos/ui/viewer/file/detail_page.dart'; -import 'package:photos/utils/dialog_util.dart'; -import 'package:photos/utils/navigation_util.dart'; -import 'package:syncfusion_flutter_core/theme.dart'; -import 'package:syncfusion_flutter_sliders/sliders.dart'; - -class ImageEditorPage extends StatefulWidget { - final ImageProvider imageProvider; - final DetailPageConfiguration detailPageConfig; - final ente.EnteFile originalFile; - - const ImageEditorPage( - this.imageProvider, - this.originalFile, - this.detailPageConfig, { - super.key, - }); - - @override - State createState() => _ImageEditorPageState(); -} - -class _ImageEditorPageState extends State { - static const double kBrightnessDefault = 1; - static const double kBrightnessMin = 0; - static const double kBrightnessMax = 2; - static const double kSaturationDefault = 1; - static const double kSaturationMin = 0; - static const double kSaturationMax = 2; - - final _logger = Logger("ImageEditor"); - final GlobalKey editorKey = - GlobalKey(); - - double? _brightness = kBrightnessDefault; - double? _saturation = kSaturationDefault; - bool _hasEdited = false; - - @override - Widget build(BuildContext context) { - return PopScope( - canPop: false, - onPopInvokedWithResult: (didPop, _) async { - if (_hasBeenEdited()) { - await _showExitConfirmationDialog(context); - } else { - replacePage(context, DetailPage(widget.detailPageConfig)); - } - }, - child: Scaffold( - appBar: AppBar( - backgroundColor: const Color(0x00000000), - elevation: 0, - actions: _hasBeenEdited() - ? [ - IconButton( - padding: const EdgeInsets.only(right: 16, left: 16), - onPressed: () { - editorKey.currentState!.reset(); - setState(() { - _brightness = kBrightnessDefault; - _saturation = kSaturationDefault; - }); - }, - icon: const Icon(Icons.history), - ), - ] - : [], - ), - body: Column( - children: [ - Expanded(child: _buildImage()), - const Padding(padding: EdgeInsets.all(4)), - Column( - children: [ - _buildBrightness(), - _buildSat(), - ], - ), - const Padding(padding: EdgeInsets.all(8)), - SafeArea(child: _buildBottomBar()), - Padding(padding: EdgeInsets.all(Platform.isIOS ? 16 : 6)), - ], - ), - ), - ); - } - - bool _hasBeenEdited() { - return _hasEdited || - _saturation != kSaturationDefault || - _brightness != kBrightnessDefault; - } - - Widget _buildImage() { - return Hero( - tag: widget.detailPageConfig.tagPrefix + widget.originalFile.tag, - child: ExtendedImage( - image: widget.imageProvider, - extendedImageEditorKey: editorKey, - mode: ExtendedImageMode.editor, - fit: BoxFit.contain, - initEditorConfigHandler: (_) => EditorConfig( - maxScale: 8.0, - cropRectPadding: const EdgeInsets.all(20.0), - hitTestSize: 20.0, - cornerColor: const Color.fromRGBO(45, 150, 98, 1), - editActionDetailsIsChanged: (_) { - setState(() { - _hasEdited = true; - }); - }, - ), - loadStateChanged: (state) { - if (state.extendedImageLoadState == LoadState.completed) { - return FilteredImage( - brightness: _brightness, - saturation: _saturation, - child: state.completedWidget, - ); - } - return const EnteLoadingWidget(); - }, - ), - ); - } - - Widget _buildBottomBar() { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - _buildFlipButton(), - _buildRotateLeftButton(), - _buildRotateRightButton(), - _buildSaveButton(), - ], - ); - } - - Widget _buildFlipButton() { - final TextStyle subtitle2 = Theme.of(context).textTheme.titleSmall!; - - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () { - flip(); - }, - child: SizedBox( - width: 80, - child: Column( - children: [ - Padding( - padding: const EdgeInsets.only(bottom: 2), - child: Icon( - Icons.flip, - color: Theme.of(context).iconTheme.color!.withOpacity(0.8), - size: 20, - ), - ), - const Padding(padding: EdgeInsets.all(2)), - Text( - S.of(context).flip, - style: subtitle2.copyWith( - color: subtitle2.color!.withOpacity(0.8), - ), - textAlign: TextAlign.center, - ), - ], - ), - ), - ); - } - - Widget _buildRotateLeftButton() { - final TextStyle subtitle2 = Theme.of(context).textTheme.titleSmall!; - - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () { - rotate(false); - }, - child: SizedBox( - width: 80, - child: Column( - children: [ - Icon( - Icons.rotate_left, - color: Theme.of(context).iconTheme.color!.withOpacity(0.8), - ), - const Padding(padding: EdgeInsets.all(2)), - Text( - S.of(context).rotateLeft, - style: subtitle2.copyWith( - color: subtitle2.color!.withOpacity(0.8), - ), - textAlign: TextAlign.center, - ), - ], - ), - ), - ); - } - - Widget _buildRotateRightButton() { - final TextStyle subtitle2 = Theme.of(context).textTheme.titleSmall!; - - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () { - rotate(true); - }, - child: SizedBox( - width: 80, - child: Column( - children: [ - Icon( - Icons.rotate_right, - color: Theme.of(context).iconTheme.color!.withOpacity(0.8), - ), - const Padding(padding: EdgeInsets.all(2)), - Text( - S.of(context).rotateRight, - style: subtitle2.copyWith( - color: subtitle2.color!.withOpacity(0.8), - ), - textAlign: TextAlign.center, - ), - ], - ), - ), - ); - } - - Widget _buildSaveButton() { - final TextStyle subtitle2 = Theme.of(context).textTheme.titleSmall!; - - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () { - _saveEdits(); - }, - child: SizedBox( - width: 80, - child: Column( - children: [ - Icon( - Icons.save_alt_outlined, - color: Theme.of(context).iconTheme.color!.withOpacity(0.8), - ), - const Padding(padding: EdgeInsets.all(2)), - Text( - S.of(context).saveCopy, - style: subtitle2.copyWith( - color: subtitle2.color!.withOpacity(0.8), - ), - textAlign: TextAlign.center, - ), - ], - ), - ), - ); - } - - Future _saveEdits() async { - final dialog = createProgressDialog(context, S.of(context).saving); - await dialog.show(); - final ExtendedImageEditorState? state = editorKey.currentState; - if (state == null) { - return; - } - final Rect? rect = state.getCropRect(); - if (rect == null) { - return; - } - final EditActionDetails action = state.editAction!; - final double radian = action.rotateAngle; - - final bool flipHorizontal = action.flipY; - final bool flipVertical = action.flipX; - final Uint8List img = state.rawImageData; - - // ignore: unnecessary_null_comparison - if (img == null) { - _logger.severe("null rawImageData"); - showToast(context, S.of(context).somethingWentWrong); - return; - } - - final ImageEditorOption option = ImageEditorOption(); - - option.addOption(ClipOption.fromRect(rect)); - option.addOption( - FlipOption(horizontal: flipHorizontal, vertical: flipVertical), - ); - if (action.hasRotateAngle) { - option.addOption(RotateOption(radian.toInt())); - } - - option.addOption(ColorOption.saturation(_saturation!)); - option.addOption(ColorOption.brightness(_brightness!)); - - option.outputFormat = const OutputFormat.jpeg(100); - - final DateTime start = DateTime.now(); - Uint8List? result = await ImageEditor.editImage( - image: img, - imageEditorOption: option, - ); - if (result == null) { - _logger.severe("null result"); - showToast(context, S.of(context).somethingWentWrong); - return; - } - _logger.info('Size before compression = ${result.length}'); - - final ui.Image decodedResult = await decodeImageFromList(result); - result = await FlutterImageCompress.compressWithList( - result, - minWidth: decodedResult.width, - minHeight: decodedResult.height, - ); - _logger.info('Size after compression = ${result.length}'); - final Duration diff = DateTime.now().difference(start); - _logger.info('image_editor time : $diff'); - - try { - final fileName = - path.basenameWithoutExtension(widget.originalFile.title!) + - "_edited_" + - DateTime.now().microsecondsSinceEpoch.toString() + - ".JPEG"; - //Disabling notifications for assets changing to insert the file into - //files db before triggering a sync. - await PhotoManager.stopChangeNotify(); - final AssetEntity newAsset = - await (PhotoManager.editor.saveImage(result, filename: fileName)); - final newFile = await ente.EnteFile.fromAsset( - widget.originalFile.deviceFolder ?? '', - newAsset, - ); - - newFile.creationTime = widget.originalFile.creationTime; - newFile.collectionID = widget.originalFile.collectionID; - newFile.location = widget.originalFile.location; - if (!newFile.hasLocation && widget.originalFile.localID != null) { - final assetEntity = await widget.originalFile.getAsset; - if (assetEntity != null) { - final latLong = await assetEntity.latlngAsync(); - newFile.location = Location( - latitude: latLong.latitude, - longitude: latLong.longitude, - ); - } - } - newFile.generatedID = await FilesDB.instance.insertAndGetId(newFile); - Bus.instance.fire(LocalPhotosUpdatedEvent([newFile], source: "editSave")); - unawaited(SyncService.instance.sync()); - showShortToast(context, S.of(context).editsSaved); - _logger.info("Original file " + widget.originalFile.toString()); - _logger.info("Saved edits to file " + newFile.toString()); - final files = widget.detailPageConfig.files; - - // the index could be -1 if the files fetched doesn't contain the newly - // edited files - int selectionIndex = - files.indexWhere((file) => file.generatedID == newFile.generatedID); - if (selectionIndex == -1) { - files.add(newFile); - selectionIndex = files.length - 1; - } - await dialog.hide(); - replacePage( - context, - DetailPage( - widget.detailPageConfig.copyWith( - files: files, - selectedIndex: min(selectionIndex, files.length - 1), - ), - ), - ); - } catch (e, s) { - await dialog.hide(); - showToast(context, S.of(context).oopsCouldNotSaveEdits); - _logger.severe(e, s); - } finally { - await PhotoManager.startChangeNotify(); - } - } - - void flip() { - editorKey.currentState?.flip(); - } - - void rotate(bool right) { - editorKey.currentState?.rotate(right: right); - } - - Widget _buildSat() { - final TextStyle subtitle2 = Theme.of(context).textTheme.titleSmall!; - - return Container( - padding: const EdgeInsets.fromLTRB(20, 0, 20, 0), - child: Row( - children: [ - SizedBox( - width: 42, - child: FittedBox( - fit: BoxFit.scaleDown, - alignment: Alignment.centerLeft, - child: Text( - S.of(context).color, - style: subtitle2.copyWith( - color: subtitle2.color!.withOpacity(0.8), - ), - ), - ), - ), - Expanded( - child: SfSliderTheme( - data: SfSliderThemeData( - activeTrackHeight: 4, - inactiveTrackHeight: 2, - inactiveTrackColor: Colors.grey[900], - activeTrackColor: const Color.fromRGBO(45, 150, 98, 1), - thumbColor: const Color.fromRGBO(45, 150, 98, 1), - thumbRadius: 10, - tooltipBackgroundColor: Colors.grey[900], - ), - child: SfSlider( - onChanged: (value) { - setState(() { - _saturation = value; - }); - }, - value: _saturation, - enableTooltip: true, - stepSize: 0.01, - min: kSaturationMin, - max: kSaturationMax, - ), - ), - ), - ], - ), - ); - } - - Widget _buildBrightness() { - final TextStyle subtitle2 = Theme.of(context).textTheme.titleSmall!; - - return Container( - padding: const EdgeInsets.fromLTRB(20, 0, 20, 0), - child: Row( - children: [ - SizedBox( - width: 42, - child: FittedBox( - fit: BoxFit.scaleDown, - alignment: Alignment.centerLeft, - child: Text( - S.of(context).light, - style: subtitle2.copyWith( - color: subtitle2.color!.withOpacity(0.8), - ), - ), - ), - ), - Expanded( - child: SfSliderTheme( - data: SfSliderThemeData( - activeTrackHeight: 4, - inactiveTrackHeight: 2, - activeTrackColor: const Color.fromRGBO(45, 150, 98, 1), - inactiveTrackColor: Colors.grey[900], - thumbColor: const Color.fromRGBO(45, 150, 98, 1), - thumbRadius: 10, - tooltipBackgroundColor: Colors.grey[900], - ), - child: SfSlider( - onChanged: (value) { - setState(() { - _brightness = value; - }); - }, - value: _brightness, - enableTooltip: true, - stepSize: 0.01, - min: kBrightnessMin, - max: kBrightnessMax, - ), - ), - ), - ], - ), - ); - } - - Future _showExitConfirmationDialog(BuildContext context) async { - final actionResult = await showActionSheet( - context: context, - buttons: [ - ButtonWidget( - labelText: S.of(context).yesDiscardChanges, - buttonType: ButtonType.critical, - buttonSize: ButtonSize.large, - shouldStickToDarkTheme: true, - buttonAction: ButtonAction.first, - isInAlert: true, - ), - ButtonWidget( - labelText: S.of(context).no, - buttonType: ButtonType.secondary, - buttonSize: ButtonSize.large, - buttonAction: ButtonAction.second, - shouldStickToDarkTheme: true, - isInAlert: true, - ), - ], - body: S.of(context).doYouWantToDiscardTheEditsYouHaveMade, - actionSheetType: ActionSheetType.defaultActionSheet, - ); - if (actionResult?.action != null && - actionResult!.action == ButtonAction.first) { - replacePage(context, DetailPage(widget.detailPageConfig)); - } - } -} diff --git a/mobile/apps/photos/lib/ui/viewer/file/detail_page.dart b/mobile/apps/photos/lib/ui/viewer/file/detail_page.dart index 5cb0d8fcbe..18b50f6357 100644 --- a/mobile/apps/photos/lib/ui/viewer/file/detail_page.dart +++ b/mobile/apps/photos/lib/ui/viewer/file/detail_page.dart @@ -19,8 +19,7 @@ import "package:photos/services/local_authentication_service.dart"; import "package:photos/states/detail_page_state.dart"; import "package:photos/ui/common/fast_scroll_physics.dart"; import 'package:photos/ui/notification/toast.dart'; -import "package:photos/ui/tools/editor/image_editor/image_editor_page_new.dart"; -import 'package:photos/ui/tools/editor/image_editor_page.dart'; +import "package:photos/ui/tools/editor/image_editor/image_editor_page.dart"; import "package:photos/ui/tools/editor/video_editor_page.dart"; import "package:photos/ui/viewer/file/file_app_bar.dart"; import "package:photos/ui/viewer/file/file_bottom_bar.dart"; @@ -64,16 +63,30 @@ class DetailPageConfiguration { } } -class DetailPage extends StatefulWidget { +class DetailPage extends StatelessWidget { final DetailPageConfiguration config; const DetailPage(this.config, {super.key}); @override - State createState() => _DetailPageState(); + Widget build(BuildContext context) { + // Separating body to a different widget to avoid + // unnecessary reinitialization of the InheritedDetailPageState + // when the body is rebuilt, which can reset state stored in it. + return InheritedDetailPageState(child: _Body(config)); + } } -class _DetailPageState extends State { +class _Body extends StatefulWidget { + final DetailPageConfiguration config; + + const _Body(this.config); + + @override + State<_Body> createState() => _BodyState(); +} + +class _BodyState extends State<_Body> { final _logger = Logger("DetailPageState"); bool _shouldDisableScroll = false; List? _files; @@ -137,102 +150,100 @@ class _DetailPageState extends State { _files!.length.toString() + " files .", ); - return InheritedDetailPageState( - child: PopScope( - canPop: !isGuestView, - onPopInvokedWithResult: (didPop, _) async { - if (isGuestView) { - final authenticated = await _requestAuthentication(); - if (authenticated) { - Bus.instance.fire(GuestViewEvent(false, false)); - await localSettings.setOnGuestView(false); - } + return PopScope( + canPop: !isGuestView, + onPopInvokedWithResult: (didPop, _) async { + if (isGuestView) { + final authenticated = await _requestAuthentication(); + if (authenticated) { + Bus.instance.fire(GuestViewEvent(false, false)); + await localSettings.setOnGuestView(false); } - }, - child: Scaffold( - appBar: PreferredSize( - preferredSize: const Size.fromHeight(80), - child: ValueListenableBuilder( - builder: (BuildContext context, int selectedIndex, _) { - return FileAppBar( - _files![selectedIndex], - _onFileRemoved, - widget.config.mode == DetailPageMode.full, - enableFullScreenNotifier: InheritedDetailPageState.of(context) - .enableFullScreenNotifier, - ); - }, - valueListenable: _selectedIndexNotifier, - ), + } + }, + child: Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(80), + child: ValueListenableBuilder( + builder: (BuildContext context, int selectedIndex, _) { + return FileAppBar( + _files![selectedIndex], + _onFileRemoved, + widget.config.mode == DetailPageMode.full, + enableFullScreenNotifier: InheritedDetailPageState.of(context) + .enableFullScreenNotifier, + ); + }, + valueListenable: _selectedIndexNotifier, ), - extendBodyBehindAppBar: true, - resizeToAvoidBottomInset: false, - backgroundColor: Colors.black, - body: Center( - child: Stack( - children: [ - _buildPageView(), - ValueListenableBuilder( - builder: (BuildContext context, int selectedIndex, _) { - return FileBottomBar( - _files![selectedIndex], - _onNewImageEditor, - widget.config.mode == DetailPageMode.minimalistic && - !isGuestView, - onFileRemoved: _onFileRemoved, - userID: Configuration.instance.getUserID(), - enableFullScreenNotifier: - InheritedDetailPageState.of(context) - .enableFullScreenNotifier, - ); - }, - valueListenable: _selectedIndexNotifier, - ), - ValueListenableBuilder( - valueListenable: _selectedIndexNotifier, - builder: (BuildContext context, int selectedIndex, _) { - if (_files![selectedIndex].isPanorama() == true) { - return ValueListenableBuilder( - valueListenable: InheritedDetailPageState.of(context) + ), + extendBodyBehindAppBar: true, + resizeToAvoidBottomInset: false, + backgroundColor: Colors.black, + body: Center( + child: Stack( + children: [ + _buildPageView(), + ValueListenableBuilder( + builder: (BuildContext context, int selectedIndex, _) { + return FileBottomBar( + _files![selectedIndex], + _onEditFileRequested, + widget.config.mode == DetailPageMode.minimalistic && + !isGuestView, + onFileRemoved: _onFileRemoved, + userID: Configuration.instance.getUserID(), + enableFullScreenNotifier: + InheritedDetailPageState.of(context) .enableFullScreenNotifier, - builder: (context, value, child) { - return IgnorePointer( - ignoring: value, - child: AnimatedOpacity( - duration: const Duration(milliseconds: 200), - opacity: !value ? 1.0 : 0.0, - child: Align( - alignment: Alignment.center, - child: Tooltip( - message: S.of(context).panorama, - child: IconButton( - style: IconButton.styleFrom( - backgroundColor: const Color(0xAA252525), - fixedSize: const Size(44, 44), - ), - icon: const Icon( - Icons.threesixty, - color: Colors.white, - size: 26, - ), - onPressed: () async { - await openPanoramaViewerPage( - _files![selectedIndex], - ); - }, + ); + }, + valueListenable: _selectedIndexNotifier, + ), + ValueListenableBuilder( + valueListenable: _selectedIndexNotifier, + builder: (BuildContext context, int selectedIndex, _) { + if (_files![selectedIndex].isPanorama() == true) { + return ValueListenableBuilder( + valueListenable: InheritedDetailPageState.of(context) + .enableFullScreenNotifier, + builder: (context, value, child) { + return IgnorePointer( + ignoring: value, + child: AnimatedOpacity( + duration: const Duration(milliseconds: 200), + opacity: !value ? 1.0 : 0.0, + child: Align( + alignment: Alignment.center, + child: Tooltip( + message: S.of(context).panorama, + child: IconButton( + style: IconButton.styleFrom( + backgroundColor: const Color(0xAA252525), + fixedSize: const Size(44, 44), ), + icon: const Icon( + Icons.threesixty, + color: Colors.white, + size: 26, + ), + onPressed: () async { + await openPanoramaViewerPage( + _files![selectedIndex], + ); + }, ), ), ), - ); - }, - ); - } - return const SizedBox(); - }, - ), - ], - ), + ), + ); + }, + ); + } + return const SizedBox(); + }, + ), + ], ), ), ), @@ -358,68 +369,6 @@ class _DetailPageState extends State { } } - Future _onNewImageEditor(EnteFile file) async { - if (file.uploadedFileID != null && - file.ownerID != Configuration.instance.getUserID()) { - _logger.severe( - "Attempt to edit unowned file", - UnauthorizedEditError(), - StackTrace.current, - ); - // ignore: unawaited_futures - showErrorDialog( - context, - S.of(context).sorry, - S.of(context).weDontSupportEditingPhotosAndAlbumsThatYouDont, - ); - return; - } - final dialog = createProgressDialog(context, S.of(context).pleaseWait); - await dialog.show(); - - try { - final ioFile = await getFile(file); - if (ioFile == null) { - showShortToast(context, S.of(context).failedToFetchOriginalForEdit); - await dialog.hide(); - return; - } - if (file.fileType == FileType.video) { - await dialog.hide(); - replacePage( - context, - VideoEditorPage( - file: file, - ioFile: ioFile, - detailPageConfig: widget.config.copyWith( - files: _files, - selectedIndex: _selectedIndexNotifier.value, - ), - ), - ); - return; - } - final imageProvider = - ExtendedFileImageProvider(ioFile, cacheRawData: true); - await precacheImage(imageProvider, context); - await dialog.hide(); - replacePage( - context, - NewImageEditor( - originalFile: file, - file: ioFile, - detailPageConfig: widget.config.copyWith( - files: _files, - selectedIndex: _selectedIndexNotifier.value, - ), - ), - ); - } catch (e) { - await dialog.hide(); - _logger.warning("Failed to initiate edit", e); - } - } - Future _onEditFileRequested(EnteFile file) async { if (file.uploadedFileID != null && file.ownerID != Configuration.instance.getUserID()) { @@ -438,6 +387,7 @@ class _DetailPageState extends State { } final dialog = createProgressDialog(context, S.of(context).pleaseWait); await dialog.show(); + try { final ioFile = await getFile(file); if (ioFile == null) { @@ -467,9 +417,9 @@ class _DetailPageState extends State { replacePage( context, ImageEditorPage( - imageProvider, - file, - widget.config.copyWith( + originalFile: file, + file: ioFile, + detailPageConfig: widget.config.copyWith( files: _files, selectedIndex: _selectedIndexNotifier.value, ), diff --git a/mobile/apps/photos/pubspec.lock b/mobile/apps/photos/pubspec.lock index 13f6212d27..84aef16996 100644 --- a/mobile/apps/photos/pubspec.lock +++ b/mobile/apps/photos/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 + sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" url: "https://pub.dev" source: hosted - version: "72.0.0" + version: "76.0.0" _flutterfire_internals: dependency: transitive description: @@ -21,7 +21,7 @@ packages: dependency: transitive description: dart source: sdk - version: "0.3.2" + version: "0.3.3" adaptive_theme: dependency: "direct main" description: @@ -34,10 +34,10 @@ packages: dependency: transitive description: name: analyzer - sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 + sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" url: "https://pub.dev" source: hosted - version: "6.7.0" + version: "6.11.0" android_intent_plus: dependency: "direct main" description: @@ -317,10 +317,10 @@ packages: dependency: "direct main" description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" computer: dependency: "direct main" description: @@ -1271,38 +1271,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.3.0" - image_editor: - dependency: "direct main" - description: - name: image_editor - sha256: "38070067264fd9fea4328ca630d2ff7bd65ebe6aa4ed375d983b732d2ae7146b" - url: "https://pub.dev" - source: hosted - version: "1.6.0" - image_editor_common: - dependency: transitive - description: - name: image_editor_common - sha256: "93d2f5c8b636f862775dd62a9ec20d09c8272598daa02f935955a4640e1844ee" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - image_editor_ohos: - dependency: transitive - description: - name: image_editor_ohos - sha256: "06756859586d5acefec6e3b4f356f9b1ce05ef09213bcb9a0ce1680ecea2d054" - url: "https://pub.dev" - source: hosted - version: "0.0.9" - image_editor_platform_interface: - dependency: transitive - description: - name: image_editor_platform_interface - sha256: "474517efc770464f7d99942472d8cfb369a3c378e95466ec17f74d2b80bd40de" - url: "https://pub.dev" - source: hosted - version: "1.1.0" in_app_purchase: dependency: "direct main" description: @@ -1424,18 +1392,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -1544,10 +1512,10 @@ packages: dependency: transitive description: name: macros - sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" url: "https://pub.dev" source: hosted - version: "0.1.2-main.4" + version: "0.1.3-main.0" maps_launcher: dependency: "direct main" description: @@ -1586,24 +1554,24 @@ packages: description: path: media_kit ref: HEAD - resolved-ref: "3c4ff28c43d20e68f8d587956b2f525292c25a80" + resolved-ref: c9617f570b8c0ba02857e721997f78c053a856c1 url: "https://github.com/media-kit/media-kit" source: git - version: "1.1.11" + version: "1.2.0" media_kit_libs_android_video: dependency: transitive description: name: media_kit_libs_android_video - sha256: "9dd8012572e4aff47516e55f2597998f0a378e3d588d0fad0ca1f11a53ae090c" + sha256: adff9b571b8ead0867f9f91070f8df39562078c0eb3371d88b9029a2d547d7b7 url: "https://pub.dev" source: hosted - version: "1.3.6" + version: "1.3.7" media_kit_libs_ios_video: dependency: "direct main" description: path: "libs/ios/media_kit_libs_ios_video" ref: HEAD - resolved-ref: "3c4ff28c43d20e68f8d587956b2f525292c25a80" + resolved-ref: c9617f570b8c0ba02857e721997f78c053a856c1 url: "https://github.com/media-kit/media-kit" source: git version: "1.1.4" @@ -1611,10 +1579,10 @@ packages: dependency: transitive description: name: media_kit_libs_linux - sha256: e186891c31daa6bedab4d74dcdb4e8adfccc7d786bfed6ad81fe24a3b3010310 + sha256: "2b473399a49ec94452c4d4ae51cfc0f6585074398d74216092bf3d54aac37ecf" url: "https://pub.dev" source: hosted - version: "1.1.3" + version: "1.2.1" media_kit_libs_macos_video: dependency: transitive description: @@ -1628,27 +1596,27 @@ packages: description: path: "libs/universal/media_kit_libs_video" ref: HEAD - resolved-ref: "3c4ff28c43d20e68f8d587956b2f525292c25a80" + resolved-ref: c9617f570b8c0ba02857e721997f78c053a856c1 url: "https://github.com/media-kit/media-kit" source: git - version: "1.0.5" + version: "1.0.6" media_kit_libs_windows_video: dependency: transitive description: name: media_kit_libs_windows_video - sha256: "32654572167825c42c55466f5d08eee23ea11061c84aa91b09d0e0f69bdd0887" + sha256: dff76da2778729ab650229e6b4ec6ec111eb5151431002cbd7ea304ff1f112ab url: "https://pub.dev" source: hosted - version: "1.0.10" + version: "1.0.11" media_kit_video: dependency: "direct main" description: path: media_kit_video ref: HEAD - resolved-ref: "3c4ff28c43d20e68f8d587956b2f525292c25a80" + resolved-ref: c9617f570b8c0ba02857e721997f78c053a856c1 url: "https://github.com/media-kit/media-kit" source: git - version: "1.2.5" + version: "1.3.0" meta: dependency: transitive description: @@ -1712,7 +1680,7 @@ packages: description: path: "." ref: HEAD - resolved-ref: "7814e2c61ee1fa74cef73b946eb08519c35bdaa5" + resolved-ref: "64e47a446bf3b64f012f2076481cebea51ca27cf" url: "https://github.com/ente-io/motionphoto.git" source: git version: "0.0.1" @@ -2325,7 +2293,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_gen: dependency: transitive description: @@ -2450,10 +2418,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" step_progress_indicator: dependency: "direct main" description: @@ -2482,10 +2450,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" styled_text: dependency: "direct main" description: @@ -2546,26 +2514,26 @@ packages: dependency: "direct dev" description: name: test - sha256: "7ee44229615f8f642b68120165ae4c2a75fe77ae2065b1e55ae4711f6cf0899e" + sha256: "713a8789d62f3233c46b4a90b174737b2c04cb6ae4500f2aa8b1be8f03f5e67f" url: "https://pub.dev" source: hosted - version: "1.25.7" + version: "1.25.8" test_api: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.3" test_core: dependency: transitive description: name: test_core - sha256: "55ea5a652e38a1dfb32943a7973f3681a60f872f8c3a05a14664ad54ef9c6696" + sha256: "12391302411737c176b0b5d6491f466b0dd56d4763e347b6714efbaa74d7953d" url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.5" thermal: dependency: "direct main" description: @@ -2845,10 +2813,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.3.0" volume_controller: dependency: transitive description: @@ -2909,10 +2877,10 @@ packages: dependency: transitive description: name: webdriver - sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" + sha256: "3d773670966f02a646319410766d3b5e1037efb7f07cc68f844d5e06cd4d61c8" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.4" webkit_inspection_protocol: dependency: transitive description: diff --git a/mobile/apps/photos/pubspec.yaml b/mobile/apps/photos/pubspec.yaml index 8d118c27ee..d515a83352 100644 --- a/mobile/apps/photos/pubspec.yaml +++ b/mobile/apps/photos/pubspec.yaml @@ -12,7 +12,7 @@ description: ente photos application # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.2.0+1120 +version: 1.2.0+1200 publish_to: none environment: @@ -114,7 +114,6 @@ dependencies: html_unescape: ^2.0.0 http: ^1.1.0 image: ^4.0.17 - image_editor: ^1.6.0 in_app_purchase: ^3.0.7 intl: ^0.19.0 latlong2: ^0.9.0