Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face

This commit is contained in:
Neeraj Gupta 2024-04-11 13:17:15 +05:30
commit f459b1c2dd
40 changed files with 671 additions and 2031 deletions

View file

@ -46,7 +46,7 @@ You can alternatively install the build from PlayStore or F-Droid.
## 🧑‍💻 Building from source
1. [Install Flutter v3.13.4](https://flutter.dev/docs/get-started/install).
1. [Install Flutter v3.16.9](https://flutter.dev/docs/get-started/install).
2. Pull in all submodules with `git submodule update --init --recursive`

View file

@ -1,91 +0,0 @@
unknown
person
bicycle
car
motorcycle
airplane
bus
train
truck
boat
traffic light
fire hydrant
unknown
stop sign
parking meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
unknown
backpack
umbrella
unknown
unknown
handbag
tie
suitcase
frisbee
skis
snowboard
sports ball
kite
baseball bat
baseball glove
skateboard
surfboard
tennis racket
bottle
unknown
wine glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot dog
pizza
donut
cake
chair
couch
potted plant
bed
unknown
dining table
unknown
unknown
toilet
unknown
tv
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
unknown
book
clock
vase
scissors
teddy bear
hair drier
toothbrush

View file

@ -1,30 +0,0 @@
waterfall
snow
landscape
underwater
architecture
sunset / sunrise
blue sky
cloudy sky
greenery
autumn leaves
portrait
flower
night shot
stage concert
fireworks
candle light
neon lights
indoor
backlight
text documents
qr images
group portrait
computer screens
kids
dog
cat
macro
food
beach
mountain

View file

@ -1,8 +1,11 @@
PODS:
- background_fetch (1.2.1):
- background_fetch (1.3.2):
- Flutter
- battery_info (0.0.1):
- Flutter
- bonsoir_darwin (3.0.0):
- Flutter
- FlutterMacOS
- connectivity_plus (0.0.1):
- Flutter
- ReachabilitySwift
@ -10,38 +13,38 @@ PODS:
- Flutter
- file_saver (0.0.1):
- Flutter
- Firebase/CoreOnly (10.18.0):
- FirebaseCore (= 10.18.0)
- Firebase/Messaging (10.18.0):
- Firebase/CoreOnly (10.22.0):
- FirebaseCore (= 10.22.0)
- Firebase/Messaging (10.22.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 10.18.0)
- firebase_core (2.24.2):
- Firebase/CoreOnly (= 10.18.0)
- FirebaseMessaging (~> 10.22.0)
- firebase_core (2.27.0):
- Firebase/CoreOnly (= 10.22.0)
- Flutter
- firebase_messaging (14.7.10):
- Firebase/Messaging (= 10.18.0)
- firebase_messaging (14.7.19):
- Firebase/Messaging (= 10.22.0)
- firebase_core
- Flutter
- FirebaseCore (10.18.0):
- FirebaseCore (10.22.0):
- FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.12)
- GoogleUtilities/Logger (~> 7.12)
- FirebaseCoreInternal (10.21.0):
- FirebaseCoreInternal (10.24.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)"
- FirebaseInstallations (10.21.0):
- FirebaseInstallations (10.24.0):
- FirebaseCore (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/UserDefaults (~> 7.8)
- PromisesObjC (~> 2.1)
- FirebaseMessaging (10.18.0):
- FirebaseMessaging (10.22.0):
- FirebaseCore (~> 10.0)
- FirebaseInstallations (~> 10.0)
- GoogleDataTransport (~> 9.2)
- GoogleDataTransport (~> 9.3)
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Reachability (~> 7.8)
- GoogleUtilities/UserDefaults (~> 7.8)
- nanopb (< 2.30910.0, >= 2.30908.0)
- nanopb (< 2.30911.0, >= 2.30908.0)
- fk_user_agent (2.0.0):
- Flutter
- Flutter (1.0.0)
@ -72,27 +75,35 @@ PODS:
- fluttertoast (0.0.2):
- Flutter
- Toast
- GoogleDataTransport (9.3.0):
- GoogleDataTransport (9.4.1):
- GoogleUtilities/Environment (~> 7.7)
- nanopb (< 2.30910.0, >= 2.30908.0)
- nanopb (< 2.30911.0, >= 2.30908.0)
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/AppDelegateSwizzler (7.12.0):
- GoogleUtilities/AppDelegateSwizzler (7.13.0):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (7.12.0):
- GoogleUtilities/Privacy
- GoogleUtilities/Environment (7.13.0):
- GoogleUtilities/Privacy
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/Logger (7.12.0):
- GoogleUtilities/Logger (7.13.0):
- GoogleUtilities/Environment
- GoogleUtilities/Network (7.12.0):
- GoogleUtilities/Privacy
- GoogleUtilities/Network (7.13.0):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Privacy
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (7.12.0)"
- GoogleUtilities/Reachability (7.12.0):
- "GoogleUtilities/NSData+zlib (7.13.0)":
- GoogleUtilities/Privacy
- GoogleUtilities/Privacy (7.13.0)
- GoogleUtilities/Reachability (7.13.0):
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (7.12.0):
- GoogleUtilities/Privacy
- GoogleUtilities/UserDefaults (7.13.0):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- home_widget (0.0.1):
- Flutter
- image_editor_common (1.0.0):
@ -116,6 +127,8 @@ PODS:
- libwebp/sharpyuv (1.3.2)
- libwebp/webp (1.3.2):
- libwebp/sharpyuv
- local_auth_darwin (0.0.1):
- Flutter
- local_auth_ios (0.0.1):
- Flutter
- Mantle (2.2.0):
@ -133,11 +146,11 @@ PODS:
- Flutter
- move_to_background (0.0.1):
- Flutter
- nanopb (2.30909.1):
- nanopb/decode (= 2.30909.1)
- nanopb/encode (= 2.30909.1)
- nanopb/decode (2.30909.1)
- nanopb/encode (2.30909.1)
- nanopb (2.30910.0):
- nanopb/decode (= 2.30910.0)
- nanopb/encode (= 2.30910.0)
- nanopb/decode (2.30910.0)
- nanopb/encode (2.30910.0)
- onnxruntime (0.0.1):
- Flutter
- onnxruntime-objc (= 1.15.1)
@ -154,30 +167,30 @@ PODS:
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- permission_handler_apple (9.1.1):
- permission_handler_apple (9.3.0):
- Flutter
- photo_manager (2.0.0):
- Flutter
- FlutterMacOS
- PromisesObjC (2.3.1)
- ReachabilitySwift (5.0.0)
- receive_sharing_intent (1.6.7):
- PromisesObjC (2.4.0)
- ReachabilitySwift (5.2.1)
- receive_sharing_intent (1.6.8):
- Flutter
- screen_brightness_ios (0.1.0):
- Flutter
- SDWebImage (5.18.11):
- SDWebImage/Core (= 5.18.11)
- SDWebImage/Core (5.18.11)
- SDWebImage (5.19.1):
- SDWebImage/Core (= 5.19.1)
- SDWebImage/Core (5.19.1)
- SDWebImageWebPCoder (0.14.5):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.17)
- Sentry/HybridSDK (8.18.0):
- SentryPrivate (= 8.18.0)
- sentry_flutter (0.0.1):
- Sentry/HybridSDK (8.21.0):
- SentryPrivate (= 8.21.0)
- sentry_flutter (7.19.0):
- Flutter
- FlutterMacOS
- Sentry/HybridSDK (= 8.18.0)
- SentryPrivate (8.18.0)
- Sentry/HybridSDK (= 8.21.0)
- SentryPrivate (8.21.0)
- share_plus (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
@ -201,29 +214,7 @@ PODS:
- sqlite3/fts5
- sqlite3/perf-threadsafe
- sqlite3/rtree
- TensorFlowLiteC (2.12.0):
- TensorFlowLiteC/Core (= 2.12.0)
- TensorFlowLiteC/Core (2.12.0)
- TensorFlowLiteC/CoreML (2.12.0):
- TensorFlowLiteC/Core
- TensorFlowLiteC/Metal (2.12.0):
- TensorFlowLiteC/Core
- TensorFlowLiteSwift (2.12.0):
- TensorFlowLiteSwift/Core (= 2.12.0)
- TensorFlowLiteSwift/Core (2.12.0):
- TensorFlowLiteC (= 2.12.0)
- TensorFlowLiteSwift/CoreML (2.12.0):
- TensorFlowLiteC/CoreML (= 2.12.0)
- TensorFlowLiteSwift/Core (= 2.12.0)
- TensorFlowLiteSwift/Metal (2.12.0):
- TensorFlowLiteC/Metal (= 2.12.0)
- TensorFlowLiteSwift/Core (= 2.12.0)
- tflite_flutter (0.0.1):
- Flutter
- TensorFlowLiteSwift (= 2.12.0)
- TensorFlowLiteSwift/CoreML (= 2.12.0)
- TensorFlowLiteSwift/Metal (= 2.12.0)
- Toast (4.1.0)
- Toast (4.1.1)
- uni_links (0.0.1):
- Flutter
- url_launcher_ios (0.0.1):
@ -242,6 +233,7 @@ PODS:
DEPENDENCIES:
- background_fetch (from `.symlinks/plugins/background_fetch/ios`)
- battery_info (from `.symlinks/plugins/battery_info/ios`)
- bonsoir_darwin (from `.symlinks/plugins/bonsoir_darwin/darwin`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_saver (from `.symlinks/plugins/file_saver/ios`)
@ -263,6 +255,7 @@ DEPENDENCIES:
- in_app_purchase_storekit (from `.symlinks/plugins/in_app_purchase_storekit/darwin`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`)
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
- local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`)
- media_extension (from `.symlinks/plugins/media_extension/ios`)
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
@ -322,6 +315,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/background_fetch/ios"
battery_info:
:path: ".symlinks/plugins/battery_info/ios"
bonsoir_darwin:
:path: ".symlinks/plugins/bonsoir_darwin/darwin"
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/ios"
device_info_plus:
@ -364,6 +359,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/integration_test/ios"
isar_flutter_libs:
:path: ".symlinks/plugins/isar_flutter_libs/ios"
local_auth_darwin:
:path: ".symlinks/plugins/local_auth_darwin/darwin"
local_auth_ios:
:path: ".symlinks/plugins/local_auth_ios/ios"
media_extension:
@ -420,20 +417,21 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/wakelock_plus/ios"
SPEC CHECKSUMS:
background_fetch: 896944864b038d2837fc750d470e9841e1e6a363
background_fetch: 2319bf7e18237b4b269430b7f14d177c0df09c5a
battery_info: 09f5c9ee65394f2291c8c6227bedff345b8a730c
connectivity_plus: 53efb943fc2882c8512d84c45707bcabc4c36076
bonsoir_darwin: 127bdc632fdc154ae2f277a4d5c86a6212bc75be
connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
Firebase: 414ad272f8d02dfbf12662a9d43f4bba9bec2a06
firebase_core: 0af4a2b24f62071f9bf283691c0ee41556dcb3f5
firebase_messaging: 90e8a6db84b6e1e876cebce4f30f01dc495e7014
FirebaseCore: 2322423314d92f946219c8791674d2f3345b598f
FirebaseCoreInternal: 43c1788eaeee9d1b97caaa751af567ce11010d00
FirebaseInstallations: 390ea1d10a4d02b20c965cbfd527ee9b3b412acb
FirebaseMessaging: 9bc34a98d2e0237e1b121915120d4d48ddcf301e
Firebase: 797fd7297b7e1be954432743a0b3f90038e45a71
firebase_core: 100945864b4aedce3cfef0c62ab864858bf013cf
firebase_messaging: e65050bf9b187511d80ea3a4de7cf5573d2c7543
FirebaseCore: 0326ec9b05fbed8f8716cddbf0e36894a13837f7
FirebaseCoreInternal: bcb5acffd4ea05e12a783ecf835f2210ce3dc6af
FirebaseInstallations: 8f581fca6478a50705d2bd2abd66d306e0f5736e
FirebaseMessaging: 9f71037fd9db3376a4caa54e5a3949d1027b4b6e
fk_user_agent: 1f47ec39291e8372b1d692b50084b0d54103c545
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_email_sender: 02d7443217d8c41483223627972bfdc09f74276b
flutter_image_compress: 5a5e9aee05b6553048b8df1c3bc456d0afaac433
flutter_inappwebview: 3d32228f1304635e7c028b0d4252937730bbc6cf
@ -443,15 +441,16 @@ SPEC CHECKSUMS:
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
flutter_sodium: c84426b4de738514b5b66cfdeb8a06634e72fe0b
fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265
GoogleDataTransport: 57c22343ab29bc686febbf7cbb13bad167c2d8fe
GoogleUtilities: 0759d1a57ebb953965c2dfe0ba4c82e95ccc2e34
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
GoogleUtilities: d053d902a8edaa9904e1bd00c37535385b8ed152
home_widget: 0434835a4c9a75704264feff6be17ea40e0f0d57
image_editor_common: d6f6644ae4a6de80481e89fe6d0a8c49e30b4b43
in_app_purchase_storekit: 9e9931234f0adcf71ae323f8c83785b96030edf1
in_app_purchase_storekit: 0e4b3c2e43ba1e1281f4f46dd71b0593ce529892
integration_test: 13825b8a9334a850581300559b8839134b124670
isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
local_auth_ios: 1ba1475238daa33a6ffa2a29242558437be435ac
local_auth_darwin: c7e464000a6a89e952235699e32b329457608d98
local_auth_ios: 5046a18c018dd973247a0564496c8898dbb5adf9
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
media_extension: 6d30dc1431ebaa63f43c397c37917b1a0a597a4c
media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1
@ -459,7 +458,7 @@ SPEC CHECKSUMS:
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e
motionphoto: d4a432b8c8f22fb3ad966258597c0103c9c5ff16
move_to_background: 39a5b79b26d577b0372cbe8a8c55e7aa9fcd3a2d
nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5
nanopb: 438bc412db1928dac798aa6fd75726007be04262
onnxruntime: e9346181d75b8dea8733bdae512a22c298962e00
onnxruntime-c: ebdcfd8650bcbd10121c125262f99dea681b92a3
onnxruntime-objc: ae7acec7a3d03eaf072d340afed7a35635c1c2a6
@ -467,33 +466,30 @@ SPEC CHECKSUMS:
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
photo_manager: 4f6810b7dfc4feb03b461ac1a70dacf91fba7604
PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
receive_sharing_intent: 9ca20ae908f83c36ddaaaa8c9bd30ce4700495e8
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
ReachabilitySwift: 5ae15e16814b5f9ef568963fb2c87aeb49158c66
receive_sharing_intent: 6837b01768e567fe8562182397bf43d63d8c6437
screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625
SDWebImage: a3ba0b8faac7228c3c8eadd1a55c9c9fe5e16457
SDWebImage: 40b0b4053e36c660a764958bff99eed16610acbb
SDWebImageWebPCoder: c94f09adbca681822edad9e532ac752db713eabf
Sentry: 8984a4ffb2b9bd2894d74fb36e6f5833865bc18e
sentry_flutter: c87a0556eeb6cbf7f9f924d30e878bdedf22d364
SentryPrivate: 2f0c9ba4c3fc993f70eab6ca95673509561e0085
Sentry: ebc12276bd17613a114ab359074096b6b3725203
sentry_flutter: 88ebea3f595b0bc16acc5bedacafe6d60c12dcd5
SentryPrivate: d651efb234cf385ec9a1cdd3eff94b5e78a0e0fe
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
sqlite3: 73b7fc691fdc43277614250e04d183740cb15078
sqlite3_flutter_libs: af0e8fe9bce48abddd1ffdbbf839db0302d72d80
TensorFlowLiteC: 20785a69299185a379ba9852b6625f00afd7984a
TensorFlowLiteSwift: 3a4928286e9e35bdd3e17970f48e53c80d25e793
tflite_flutter: 9433d086a3060431bbc9f3c7c20d017db0e72d08
Toast: ec33c32b8688982cecc6348adeae667c1b9938da
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
video_player_avfoundation: e9e6f9cae7d7a6d9b43519b0aab382bca60fcfd1
url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586
video_player_avfoundation: 02011213dab73ae3687df27ce441fbbcc82b5579
video_thumbnail: c4e2a3c539e247d4de13cd545344fd2d26ffafd1
volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9
wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47
PODFILE CHECKSUM: c1a8f198a245ed1f10e40b617efdb129b021b225
COCOAPODS: 1.14.3
COCOAPODS: 1.15.2

View file

@ -174,6 +174,7 @@
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
ABF2FD2FD606DC6DD54BD9AB /* [CP] Embed Pods Frameworks */,
F5BF2E85B889CF8483C26F35 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@ -292,6 +293,7 @@
"${BUILT_PRODUCTS_DIR}/Toast/Toast.framework",
"${BUILT_PRODUCTS_DIR}/background_fetch/background_fetch.framework",
"${BUILT_PRODUCTS_DIR}/battery_info/battery_info.framework",
"${BUILT_PRODUCTS_DIR}/bonsoir_darwin/bonsoir_darwin.framework",
"${BUILT_PRODUCTS_DIR}/connectivity_plus/connectivity_plus.framework",
"${BUILT_PRODUCTS_DIR}/device_info_plus/device_info_plus.framework",
"${BUILT_PRODUCTS_DIR}/file_saver/file_saver.framework",
@ -311,6 +313,7 @@
"${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework",
"${BUILT_PRODUCTS_DIR}/isar_flutter_libs/isar_flutter_libs.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}/media_extension/media_extension.framework",
"${BUILT_PRODUCTS_DIR}/media_kit_libs_ios_video/media_kit_libs_ios_video.framework",
@ -375,6 +378,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Toast.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/background_fetch.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/battery_info.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/bonsoir_darwin.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity_plus.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info_plus.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_saver.framework",
@ -394,6 +398,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/isar_flutter_libs.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}/media_extension.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/media_kit_libs_ios_video.framework",
@ -466,6 +471,24 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
F5BF2E85B889CF8483C26F35 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/permission_handler_apple/permission_handler_apple_privacy.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/permission_handler_apple_privacy.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */

View file

@ -181,6 +181,7 @@ extension DeviceFiles on FilesDB {
final Set<String> existingPathIds = await getDevicePathIDs();
for (Tuple2<AssetPathEntity, String> tup in devicePathInfo) {
final AssetPathEntity pathEntity = tup.item1;
final assetCount = await pathEntity.assetCountAsync;
final String localID = tup.item2;
final bool shouldUpdate = existingPathIds.contains(pathEntity.id);
if (shouldUpdate) {
@ -190,11 +191,11 @@ extension DeviceFiles on FilesDB {
[
pathEntity.name,
localID,
pathEntity.assetCount,
assetCount,
pathEntity.id,
pathEntity.name,
localID,
pathEntity.assetCount,
assetCount,
],
);
if (rowUpdated > 0) {
@ -208,7 +209,7 @@ extension DeviceFiles on FilesDB {
{
"id": pathEntity.id,
"name": pathEntity.name,
"count": pathEntity.assetCount,
"count": assetCount,
"cover_id": localID,
"should_backup": shouldBackup ? _sqlBoolTrue : _sqlBoolFalse,
},

View file

@ -0,0 +1,3 @@
class YOLOFaceInterpreterInitializationException implements Exception {}
class YOLOFaceInterpreterRunException implements Exception {}

View file

@ -11,9 +11,9 @@ import 'package:logging/logging.dart';
import 'package:onnxruntime/onnxruntime.dart';
import "package:photos/face/model/dimension.dart";
import 'package:photos/services/machine_learning/face_ml/face_detection/detection.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/face_detection_exceptions.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/naive_non_max_suppression.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/yolov5face/yolo_face_detection_exceptions.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/yolov5face/yolo_filter_extract_detections.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/yolo_filter_extract_detections.dart';
import "package:photos/services/remote_assets_service.dart";
import "package:photos/utils/image_ml_isolate.dart";
import "package:photos/utils/image_ml_util.dart";
@ -21,22 +21,26 @@ import "package:synchronized/synchronized.dart";
enum FaceDetectionOperation { yoloInferenceAndPostProcessing }
class YoloOnnxFaceDetection {
/// This class is responsible for running the face detection model (YOLOv5Face) on ONNX runtime, and can be accessed through the singleton instance [FaceDetectionService.instance].
class FaceDetectionService {
static final _logger = Logger('YOLOFaceDetectionService');
final _computer = Computer.shared();
int sessionAddress = 0;
static const kModelBucketEndpoint = "https://models.ente.io/";
static const kRemoteBucketModelPath = "yolov5s_face_640_640_dynamic.onnx";
static const String kModelBucketEndpoint = "https://models.ente.io/";
static const String kRemoteBucketModelPath =
"yolov5s_face_640_640_dynamic.onnx";
// static const kRemoteBucketModelPath = "yolov5n_face_640_640.onnx";
static const modelRemotePath = kModelBucketEndpoint + kRemoteBucketModelPath;
static const String modelRemotePath =
kModelBucketEndpoint + kRemoteBucketModelPath;
static const kInputWidth = 640;
static const kInputHeight = 640;
static const kIouThreshold = 0.4;
static const kMinScoreSigmoidThreshold = 0.7;
static const int kInputWidth = 640;
static const int kInputHeight = 640;
static const double kIouThreshold = 0.4;
static const double kMinScoreSigmoidThreshold = 0.7;
static const int kNumKeypoints = 5;
bool isInitialized = false;
@ -55,7 +59,7 @@ class YoloOnnxFaceDetection {
bool isRunning = false;
// singleton pattern
YoloOnnxFaceDetection._privateConstructor();
FaceDetectionService._privateConstructor();
/// Use this instance to access the FaceDetection service. Make sure to call `init()` before using it.
/// e.g. `await FaceDetection.instance.init();`
@ -63,9 +67,9 @@ class YoloOnnxFaceDetection {
/// Then you can use `predict()` to get the bounding boxes of the faces, so `FaceDetection.instance.predict(imageData)`
///
/// config options: yoloV5FaceN //
static final instance = YoloOnnxFaceDetection._privateConstructor();
static final instance = FaceDetectionService._privateConstructor();
factory YoloOnnxFaceDetection() => instance;
factory FaceDetectionService() => instance;
/// Check if the interpreter is initialized, if not initialize it with `loadModel()`
Future<void> init() async {
@ -178,7 +182,7 @@ class YoloOnnxFaceDetection {
dev.log(
'[YOLOFaceDetectionService] Error while running inference: $e \n $s',
);
throw YOLOInterpreterRunException();
throw YOLOFaceInterpreterRunException();
}
stopwatchInterpreter.stop();
dev.log(
@ -297,7 +301,7 @@ class YoloOnnxFaceDetection {
// runOptions.release();
} catch (e, s) {
_logger.severe('Error while running inference: $e \n $s');
throw YOLOInterpreterRunException();
throw YOLOFaceInterpreterRunException();
}
stopwatchInterpreter.stop();
_logger.info(
@ -367,7 +371,7 @@ class YoloOnnxFaceDetection {
// runOptions.release();
} catch (e, s) {
_logger.severe('Error while running inference: $e \n $s');
throw YOLOInterpreterRunException();
throw YOLOFaceInterpreterRunException();
}
stopwatchInterpreter.stop();
_logger.info(
@ -585,7 +589,7 @@ class YoloOnnxFaceDetection {
runOptions.release();
} catch (e, s) {
_logger.severe('Error while running inference: $e \n $s');
throw YOLOInterpreterRunException();
throw YOLOFaceInterpreterRunException();
}
stopwatchInterpreter.stop();
_logger.info(
@ -770,7 +774,7 @@ class YoloOnnxFaceDetection {
dev.log(
'[YOLOFaceDetectionService] Error while running inference: $e \n $s',
);
throw YOLOInterpreterRunException();
throw YOLOFaceInterpreterRunException();
}
stopwatchInterpreter.stop();
dev.log(

View file

@ -1,3 +0,0 @@
class YOLOInterpreterInitializationException implements Exception {}
class YOLOInterpreterRunException implements Exception {}

View file

@ -1,31 +0,0 @@
import 'dart:math' as math show log;
class FaceDetectionOptionsYOLO {
final double minScoreSigmoidThreshold;
final double iouThreshold;
final int inputWidth;
final int inputHeight;
final int numCoords;
final int numKeypoints;
final int numValuesPerKeypoint;
final int maxNumFaces;
final double scoreClippingThresh;
final double inverseSigmoidMinScoreThreshold;
final bool useSigmoidScore;
final bool flipVertically;
FaceDetectionOptionsYOLO({
required this.minScoreSigmoidThreshold,
required this.iouThreshold,
required this.inputWidth,
required this.inputHeight,
this.numCoords = 14,
this.numKeypoints = 5,
this.numValuesPerKeypoint = 2,
this.maxNumFaces = 100,
this.scoreClippingThresh = 100.0,
this.useSigmoidScore = true,
this.flipVertically = false,
}) : inverseSigmoidMinScoreThreshold =
math.log(minScoreSigmoidThreshold / (1 - minScoreSigmoidThreshold));
}

View file

@ -1,22 +0,0 @@
import 'package:photos/services/machine_learning/face_ml/face_detection/yolov5face/yolo_face_detection_options.dart';
import 'package:photos/services/machine_learning/face_ml/model_file.dart';
class YOLOModelConfig {
final String modelPath;
final FaceDetectionOptionsYOLO faceOptions;
YOLOModelConfig({
required this.modelPath,
required this.faceOptions,
});
}
final YOLOModelConfig yoloV5FaceS640x640DynamicBatchonnx = YOLOModelConfig(
modelPath: ModelFile.yoloV5FaceS640x640DynamicBatchonnx,
faceOptions: FaceDetectionOptionsYOLO(
minScoreSigmoidThreshold: 0.8,
iouThreshold: 0.4,
inputWidth: 640,
inputHeight: 640,
),
);

View file

@ -1,15 +0,0 @@
class FaceEmbeddingOptions {
final int inputWidth;
final int inputHeight;
final int embeddingLength;
final int numChannels;
final bool preWhiten;
FaceEmbeddingOptions({
required this.inputWidth,
required this.inputHeight,
this.embeddingLength = 192,
this.numChannels = 3,
this.preWhiten = false,
});
}

View file

@ -1,35 +1,37 @@
import 'dart:io';
import "dart:math" show min, max, sqrt;
// import 'dart:math' as math show min, max;
import 'dart:typed_data' show Uint8List;
import "dart:io" show File;
import 'dart:math' as math show max, min, sqrt;
import 'dart:typed_data' show Float32List;
import "package:flutter/foundation.dart";
import "package:logging/logging.dart";
import 'package:photos/models/ml/ml_typedefs.dart';
import 'package:computer/computer.dart';
import 'package:logging/logging.dart';
import 'package:onnxruntime/onnxruntime.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/detection.dart';
import 'package:photos/services/machine_learning/face_ml/face_embedding/face_embedding_exceptions.dart';
import 'package:photos/services/machine_learning/face_ml/face_embedding/face_embedding_options.dart';
import 'package:photos/services/machine_learning/face_ml/face_embedding/mobilefacenet_model_config.dart';
import 'package:photos/utils/image_ml_isolate.dart';
import 'package:photos/utils/image_ml_util.dart';
import 'package:tflite_flutter/tflite_flutter.dart';
import "package:photos/services/remote_assets_service.dart";
import "package:photos/utils/image_ml_isolate.dart";
import "package:synchronized/synchronized.dart";
/// This class is responsible for running the MobileFaceNet model, and can be accessed through the singleton `FaceEmbedding.instance`.
class FaceEmbedding {
Interpreter? _interpreter;
IsolateInterpreter? _isolateInterpreter;
int get getAddress => _interpreter!.address;
/// This class is responsible for running the face embedding model (MobileFaceNet) on ONNX runtime, and can be accessed through the singleton instance [FaceEmbeddingService.instance].
class FaceEmbeddingService {
static const kModelBucketEndpoint = "https://models.ente.io/";
static const kRemoteBucketModelPath = "mobilefacenet_opset15.onnx";
static const modelRemotePath = kModelBucketEndpoint + kRemoteBucketModelPath;
final outputShapes = <List<int>>[];
final outputTypes = <TensorType>[];
static const int kInputSize = 112;
static const int kEmbeddingSize = 192;
static const int kNumChannels = 3;
static const bool kPreWhiten = false;
final _logger = Logger("FaceEmbeddingService");
static final _logger = Logger('FaceEmbeddingOnnx');
bool isInitialized = false;
int sessionAddress = 0;
final _computer = Computer.shared();
final _computerLock = Lock();
final MobileFaceNetModelConfig config;
final FaceEmbeddingOptions embeddingOptions;
// singleton pattern
FaceEmbedding._privateConstructor({required this.config})
: embeddingOptions = config.faceEmbeddingOptions;
FaceEmbeddingService._privateConstructor();
/// Use this instance to access the FaceEmbedding service. Make sure to call `init()` before using it.
/// e.g. `await FaceEmbedding.instance.init();`
@ -37,243 +39,211 @@ class FaceEmbedding {
/// Then you can use `predict()` to get the embedding of a face, so `FaceEmbedding.instance.predict(imageData)`
///
/// config options: faceEmbeddingEnte
static final instance =
FaceEmbedding._privateConstructor(config: faceEmbeddingEnte);
factory FaceEmbedding() => instance;
static final instance = FaceEmbeddingService._privateConstructor();
factory FaceEmbeddingService() => instance;
/// Check if the interpreter is initialized, if not initialize it with `loadModel()`
Future<void> init() async {
if (_interpreter == null || _isolateInterpreter == null) {
await _loadModel();
if (!isInitialized) {
_logger.info('init is called');
final model =
await RemoteAssetsService.instance.getAsset(modelRemotePath);
final startTime = DateTime.now();
// Doing this from main isolate since `rootBundle` cannot be accessed outside it
sessionAddress = await _computer.compute(
_loadModel,
param: {
"modelPath": model.path,
},
);
final endTime = DateTime.now();
_logger.info(
"Face embedding model loaded, took: ${(endTime.millisecondsSinceEpoch - startTime.millisecondsSinceEpoch).toString()}ms",
);
if (sessionAddress != -1) {
isInitialized = true;
}
}
}
Future<void> dispose() async {
_logger.info('dispose() is called');
Future<void> release() async {
if (isInitialized) {
await _computer
.compute(_releaseModel, param: {'address': sessionAddress});
isInitialized = false;
sessionAddress = 0;
}
}
static Future<int> _loadModel(Map args) async {
final sessionOptions = OrtSessionOptions()
..setInterOpNumThreads(1)
..setIntraOpNumThreads(1)
..setSessionGraphOptimizationLevel(GraphOptimizationLevel.ortEnableAll);
try {
// _logger.info('Loading face embedding model');
final session =
OrtSession.fromFile(File(args["modelPath"]), sessionOptions);
// _logger.info('Face embedding model loaded');
return session.address;
} catch (e, _) {
// _logger.severe('Face embedding model not loaded', e, s);
}
return -1;
}
static Future<void> _releaseModel(Map args) async {
final address = args['address'] as int;
if (address == 0) {
return;
}
final session = OrtSession.fromAddress(address);
session.release();
return;
}
Future<(List<double>, bool, double)> predictFromImageDataInComputer(
String imagePath,
FaceDetectionRelative face,
) async {
assert(sessionAddress != 0 && sessionAddress != -1 && isInitialized);
try {
_interpreter?.close();
_interpreter = null;
await _isolateInterpreter?.close();
_isolateInterpreter = null;
final stopwatchDecoding = Stopwatch()..start();
final (inputImageList, _, isBlur, blurValue, _) =
await ImageMlIsolate.instance.preprocessMobileFaceNetOnnx(
imagePath,
[face],
);
stopwatchDecoding.stop();
_logger.info(
'MobileFaceNet image decoding and preprocessing is finished, in ${stopwatchDecoding.elapsedMilliseconds}ms',
);
final stopwatch = Stopwatch()..start();
_logger.info('MobileFaceNet interpreter.run is called');
final embedding = await _computer.compute(
inferFromMap,
param: {
'input': inputImageList,
'address': sessionAddress,
'inputSize': kInputSize,
},
taskName: 'createFaceEmbedding',
) as List<double>;
stopwatch.stop();
_logger.info(
'MobileFaceNet interpreter.run is finished, in ${stopwatch.elapsedMilliseconds}ms',
);
_logger.info(
'MobileFaceNet results (only first few numbers): embedding ${embedding.sublist(0, 5)}',
);
_logger.info(
'Mean of embedding: ${embedding.reduce((a, b) => a + b) / embedding.length}',
);
_logger.info(
'Max of embedding: ${embedding.reduce(math.max)}',
);
_logger.info(
'Min of embedding: ${embedding.reduce(math.min)}',
);
return (embedding, isBlur[0], blurValue[0]);
} catch (e) {
_logger.severe('Error while closing interpreter: $e');
_logger.info('MobileFaceNet Error while running inference: $e');
rethrow;
}
}
/// WARNING: This function only works for one face at a time. it's better to use [predict], which can handle both single and multiple faces.
Future<List<double>> predictSingle(
Uint8List imageData,
FaceDetectionRelative face,
) async {
assert(_interpreter != null && _isolateInterpreter != null);
Future<List<List<double>>> predictInComputer(Float32List input) async {
assert(sessionAddress != 0 && sessionAddress != -1 && isInitialized);
return await _computerLock.synchronized(() async {
try {
final stopwatch = Stopwatch()..start();
_logger.info('MobileFaceNet interpreter.run is called');
final embeddings = await _computer.compute(
inferFromMap,
param: {
'input': input,
'address': sessionAddress,
'inputSize': kInputSize,
},
taskName: 'createFaceEmbedding',
) as List<List<double>>;
stopwatch.stop();
_logger.info(
'MobileFaceNet interpreter.run is finished, in ${stopwatch.elapsedMilliseconds}ms',
);
final stopwatch = Stopwatch()..start();
// Image decoding and preprocessing
List<List<List<List<num>>>> input;
List output;
try {
final stopwatchDecoding = Stopwatch()..start();
final (inputImageMatrix, _, _, _, _) =
await ImageMlIsolate.instance.preprocessMobileFaceNet(
imageData,
[face],
);
input = inputImageMatrix;
stopwatchDecoding.stop();
_logger.info(
'Image decoding and preprocessing is finished, in ${stopwatchDecoding.elapsedMilliseconds}ms',
);
output = createEmptyOutputMatrix(outputShapes[0]);
} catch (e) {
_logger.severe('Error while decoding and preprocessing image: $e');
throw MobileFaceNetImagePreprocessingException();
}
_logger.info('interpreter.run is called');
// Run inference
try {
await _isolateInterpreter!.run(input, output);
// _interpreter!.run(input, output);
// ignore: avoid_catches_without_on_clauses
} catch (e) {
_logger.severe('Error while running inference: $e');
throw MobileFaceNetInterpreterRunException();
}
_logger.info('interpreter.run is finished');
// Get output tensors
final embedding = output[0] as List<double>;
// Normalize the embedding
final norm = sqrt(embedding.map((e) => e * e).reduce((a, b) => a + b));
for (int i = 0; i < embedding.length; i++) {
embedding[i] /= norm;
}
stopwatch.stop();
_logger.info(
'predict() executed in ${stopwatch.elapsedMilliseconds}ms',
);
// _logger.info(
// 'results (only first few numbers): embedding ${embedding.sublist(0, 5)}',
// );
// _logger.info(
// 'Mean of embedding: ${embedding.reduce((a, b) => a + b) / embedding.length}',
// );
// _logger.info(
// 'Max of embedding: ${embedding.reduce(math.max)}',
// );
// _logger.info(
// 'Min of embedding: ${embedding.reduce(math.min)}',
// );
return embedding;
return embeddings;
} catch (e) {
_logger.info('MobileFaceNet Error while running inference: $e');
rethrow;
}
});
}
Future<List<List<double>>> predict(
List<Num3DInputMatrix> inputImageMatrix,
static Future<List<List<double>>> predictSync(
Float32List input,
int sessionAddress,
) async {
assert(_interpreter != null && _isolateInterpreter != null);
final stopwatch = Stopwatch()..start();
_checkPreprocessedInput(inputImageMatrix); // [inputHeight, inputWidth, 3]
final input = [inputImageMatrix];
// await encodeAndSaveData(inputImageMatrix, 'input_mobilefacenet');
final output = <int, Object>{};
final outputShape = outputShapes[0];
outputShape[0] = inputImageMatrix.length;
output[0] = createEmptyOutputMatrix(outputShape);
// for (int i = 0; i < faces.length; i++) {
// output[i] = createEmptyOutputMatrix(outputShapes[0]);
// }
_logger.info('interpreter.run is called');
// Run inference
final stopwatchInterpreter = Stopwatch()..start();
assert(sessionAddress != 0 && sessionAddress != -1);
try {
await _isolateInterpreter!.runForMultipleInputs(input, output);
// _interpreter!.runForMultipleInputs(input, output);
// ignore: avoid_catches_without_on_clauses
final stopwatch = Stopwatch()..start();
_logger.info('MobileFaceNet interpreter.run is called');
final embeddings = await infer(
input,
sessionAddress,
kInputSize,
);
stopwatch.stop();
_logger.info(
'MobileFaceNet interpreter.run is finished, in ${stopwatch.elapsedMilliseconds}ms',
);
return embeddings;
} catch (e) {
_logger.severe('Error while running inference: $e');
throw MobileFaceNetInterpreterRunException();
_logger.info('MobileFaceNet Error while running inference: $e');
rethrow;
}
stopwatchInterpreter.stop();
_logger.info(
'interpreter.run is finished, in ${stopwatchInterpreter.elapsedMilliseconds}ms',
}
static Future<List<List<double>>> inferFromMap(Map args) async {
final inputImageList = args['input'] as Float32List;
final address = args['address'] as int;
final inputSize = args['inputSize'] as int;
return await infer(inputImageList, address, inputSize);
}
static Future<List<List<double>>> infer(
Float32List inputImageList,
int address,
int inputSize,
) async {
final runOptions = OrtRunOptions();
final int numberOfFaces =
inputImageList.length ~/ (inputSize * inputSize * 3);
final inputOrt = OrtValueTensor.createTensorWithDataList(
inputImageList,
[numberOfFaces, inputSize, inputSize, 3],
);
// _logger.info('output: $output');
final inputs = {'img_inputs': inputOrt};
final session = OrtSession.fromAddress(address);
final List<OrtValue?> outputs = session.run(runOptions, inputs);
final embeddings = outputs[0]?.value as List<List<double>>;
// Get output tensors
final embeddings = <List<double>>[];
final outerEmbedding = output[0]! as Iterable<dynamic>;
for (int i = 0; i < inputImageMatrix.length; i++) {
final embedding = List<double>.from(outerEmbedding.toList()[i]);
// _logger.info("The $i-th embedding: $embedding");
embeddings.add(embedding);
}
// await encodeAndSaveData(embeddings, 'output_mobilefacenet');
// Normalize the embedding
for (int i = 0; i < embeddings.length; i++) {
final embedding = embeddings[i];
final norm = sqrt(embedding.map((e) => e * e).reduce((a, b) => a + b));
for (int j = 0; j < embedding.length; j++) {
embedding[j] /= norm;
for (final embedding in embeddings) {
double normalization = 0;
for (int i = 0; i < kEmbeddingSize; i++) {
normalization += embedding[i] * embedding[i];
}
final double sqrtNormalization = math.sqrt(normalization);
for (int i = 0; i < kEmbeddingSize; i++) {
embedding[i] = embedding[i] / sqrtNormalization;
}
}
stopwatch.stop();
_logger.info(
'predictBatch() executed in ${stopwatch.elapsedMilliseconds}ms',
);
return embeddings;
}
Future<void> _loadModel() async {
_logger.info('loadModel is called');
try {
final interpreterOptions = InterpreterOptions();
// Android Delegates
// TODO: Make sure this works on both platforms: Android and iOS
if (Platform.isAndroid) {
// Use GPU Delegate (GPU). WARNING: It doesn't work on emulator
// if (!kDebugMode) {
// interpreterOptions.addDelegate(GpuDelegateV2());
// }
// Use XNNPACK Delegate (CPU)
interpreterOptions.addDelegate(XNNPackDelegate());
}
// iOS Delegates
if (Platform.isIOS) {
// Use Metal Delegate (GPU)
interpreterOptions.addDelegate(GpuDelegate());
}
// Load model from assets
_interpreter ??= await Interpreter.fromAsset(
config.modelPath,
options: interpreterOptions,
);
_isolateInterpreter ??=
await IsolateInterpreter.create(address: _interpreter!.address);
_logger.info('Interpreter created from asset: ${config.modelPath}');
// Get tensor input shape [1, 112, 112, 3]
final inputTensors = _interpreter!.getInputTensors().first;
_logger.info('Input Tensors: $inputTensors');
// Get tensour output shape [1, 192]
final outputTensors = _interpreter!.getOutputTensors();
final outputTensor = outputTensors.first;
_logger.info('Output Tensors: $outputTensor');
for (var tensor in outputTensors) {
outputShapes.add(tensor.shape);
outputTypes.add(tensor.type);
}
_logger.info('outputShapes: $outputShapes');
_logger.info('loadModel is finished');
// ignore: avoid_catches_without_on_clauses
} catch (e) {
_logger.severe('Error while creating interpreter: $e');
throw MobileFaceNetInterpreterInitializationException();
}
}
void _checkPreprocessedInput(
List<Num3DInputMatrix> inputMatrix,
) {
final embeddingOptions = config.faceEmbeddingOptions;
if (inputMatrix.isEmpty) {
// Check if the input is empty
throw MobileFaceNetEmptyInput();
}
// Check if the input is the correct size
if (inputMatrix[0].length != embeddingOptions.inputHeight ||
inputMatrix[0][0].length != embeddingOptions.inputWidth) {
throw MobileFaceNetWrongInputSize();
}
final flattened = inputMatrix[0].expand((i) => i).expand((i) => i);
final minValue = flattened.reduce(min);
final maxValue = flattened.reduce(max);
if (minValue < -1 || maxValue > 1) {
throw MobileFaceNetWrongInputRange();
}
}
}

View file

@ -1,20 +0,0 @@
import 'package:photos/services/machine_learning/face_ml/face_embedding/face_embedding_options.dart';
import 'package:photos/services/machine_learning/face_ml/model_file.dart';
class MobileFaceNetModelConfig {
final String modelPath;
final FaceEmbeddingOptions faceEmbeddingOptions;
MobileFaceNetModelConfig({
required this.modelPath,
required this.faceEmbeddingOptions,
});
}
final MobileFaceNetModelConfig faceEmbeddingEnte = MobileFaceNetModelConfig(
modelPath: ModelFile.faceEmbeddingEnte,
faceEmbeddingOptions: FaceEmbeddingOptions(
inputWidth: 112,
inputHeight: 112,
),
);

View file

@ -1,246 +0,0 @@
import "dart:io" show File;
import 'dart:math' as math show max, min, sqrt;
import 'dart:typed_data' show Float32List;
import 'package:computer/computer.dart';
import 'package:logging/logging.dart';
import 'package:onnxruntime/onnxruntime.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/detection.dart';
import "package:photos/services/remote_assets_service.dart";
import "package:photos/utils/image_ml_isolate.dart";
import "package:synchronized/synchronized.dart";
class FaceEmbeddingOnnx {
static const kModelBucketEndpoint = "https://models.ente.io/";
static const kRemoteBucketModelPath = "mobilefacenet_opset15.onnx";
static const modelRemotePath = kModelBucketEndpoint + kRemoteBucketModelPath;
static const int kInputSize = 112;
static const int kEmbeddingSize = 192;
static final _logger = Logger('FaceEmbeddingOnnx');
bool isInitialized = false;
int sessionAddress = 0;
final _computer = Computer.shared();
final _computerLock = Lock();
// singleton pattern
FaceEmbeddingOnnx._privateConstructor();
/// Use this instance to access the FaceEmbedding service. Make sure to call `init()` before using it.
/// e.g. `await FaceEmbedding.instance.init();`
///
/// Then you can use `predict()` to get the embedding of a face, so `FaceEmbedding.instance.predict(imageData)`
///
/// config options: faceEmbeddingEnte
static final instance = FaceEmbeddingOnnx._privateConstructor();
factory FaceEmbeddingOnnx() => instance;
/// Check if the interpreter is initialized, if not initialize it with `loadModel()`
Future<void> init() async {
if (!isInitialized) {
_logger.info('init is called');
final model =
await RemoteAssetsService.instance.getAsset(modelRemotePath);
final startTime = DateTime.now();
// Doing this from main isolate since `rootBundle` cannot be accessed outside it
sessionAddress = await _computer.compute(
_loadModel,
param: {
"modelPath": model.path,
},
);
final endTime = DateTime.now();
_logger.info(
"Face embedding model loaded, took: ${(endTime.millisecondsSinceEpoch - startTime.millisecondsSinceEpoch).toString()}ms",
);
if (sessionAddress != -1) {
isInitialized = true;
}
}
}
Future<void> release() async {
if (isInitialized) {
await _computer
.compute(_releaseModel, param: {'address': sessionAddress});
isInitialized = false;
sessionAddress = 0;
}
}
static Future<int> _loadModel(Map args) async {
final sessionOptions = OrtSessionOptions()
..setInterOpNumThreads(1)
..setIntraOpNumThreads(1)
..setSessionGraphOptimizationLevel(GraphOptimizationLevel.ortEnableAll);
try {
// _logger.info('Loading face embedding model');
final session =
OrtSession.fromFile(File(args["modelPath"]), sessionOptions);
// _logger.info('Face embedding model loaded');
return session.address;
} catch (e, _) {
// _logger.severe('Face embedding model not loaded', e, s);
}
return -1;
}
static Future<void> _releaseModel(Map args) async {
final address = args['address'] as int;
if (address == 0) {
return;
}
final session = OrtSession.fromAddress(address);
session.release();
return;
}
Future<(List<double>, bool, double)> predictFromImageDataInComputer(
String imagePath,
FaceDetectionRelative face,
) async {
assert(sessionAddress != 0 && sessionAddress != -1 && isInitialized);
try {
final stopwatchDecoding = Stopwatch()..start();
final (inputImageList, _, isBlur, blurValue, _) =
await ImageMlIsolate.instance.preprocessMobileFaceNetOnnx(
imagePath,
[face],
);
stopwatchDecoding.stop();
_logger.info(
'MobileFaceNet image decoding and preprocessing is finished, in ${stopwatchDecoding.elapsedMilliseconds}ms',
);
final stopwatch = Stopwatch()..start();
_logger.info('MobileFaceNet interpreter.run is called');
final embedding = await _computer.compute(
inferFromMap,
param: {
'input': inputImageList,
'address': sessionAddress,
'inputSize': kInputSize,
},
taskName: 'createFaceEmbedding',
) as List<double>;
stopwatch.stop();
_logger.info(
'MobileFaceNet interpreter.run is finished, in ${stopwatch.elapsedMilliseconds}ms',
);
_logger.info(
'MobileFaceNet results (only first few numbers): embedding ${embedding.sublist(0, 5)}',
);
_logger.info(
'Mean of embedding: ${embedding.reduce((a, b) => a + b) / embedding.length}',
);
_logger.info(
'Max of embedding: ${embedding.reduce(math.max)}',
);
_logger.info(
'Min of embedding: ${embedding.reduce(math.min)}',
);
return (embedding, isBlur[0], blurValue[0]);
} catch (e) {
_logger.info('MobileFaceNet Error while running inference: $e');
rethrow;
}
}
Future<List<List<double>>> predictInComputer(Float32List input) async {
assert(sessionAddress != 0 && sessionAddress != -1 && isInitialized);
return await _computerLock.synchronized(() async {
try {
final stopwatch = Stopwatch()..start();
_logger.info('MobileFaceNet interpreter.run is called');
final embeddings = await _computer.compute(
inferFromMap,
param: {
'input': input,
'address': sessionAddress,
'inputSize': kInputSize,
},
taskName: 'createFaceEmbedding',
) as List<List<double>>;
stopwatch.stop();
_logger.info(
'MobileFaceNet interpreter.run is finished, in ${stopwatch.elapsedMilliseconds}ms',
);
return embeddings;
} catch (e) {
_logger.info('MobileFaceNet Error while running inference: $e');
rethrow;
}
});
}
static Future<List<List<double>>> predictSync(
Float32List input,
int sessionAddress,
) async {
assert(sessionAddress != 0 && sessionAddress != -1);
try {
final stopwatch = Stopwatch()..start();
_logger.info('MobileFaceNet interpreter.run is called');
final embeddings = await infer(
input,
sessionAddress,
kInputSize,
);
stopwatch.stop();
_logger.info(
'MobileFaceNet interpreter.run is finished, in ${stopwatch.elapsedMilliseconds}ms',
);
return embeddings;
} catch (e) {
_logger.info('MobileFaceNet Error while running inference: $e');
rethrow;
}
}
static Future<List<List<double>>> inferFromMap(Map args) async {
final inputImageList = args['input'] as Float32List;
final address = args['address'] as int;
final inputSize = args['inputSize'] as int;
return await infer(inputImageList, address, inputSize);
}
static Future<List<List<double>>> infer(
Float32List inputImageList,
int address,
int inputSize,
) async {
final runOptions = OrtRunOptions();
final int numberOfFaces =
inputImageList.length ~/ (inputSize * inputSize * 3);
final inputOrt = OrtValueTensor.createTensorWithDataList(
inputImageList,
[numberOfFaces, inputSize, inputSize, 3],
);
final inputs = {'img_inputs': inputOrt};
final session = OrtSession.fromAddress(address);
final List<OrtValue?> outputs = session.run(runOptions, inputs);
final embeddings = outputs[0]?.value as List<List<double>>;
for (final embedding in embeddings) {
double normalization = 0;
for (int i = 0; i < kEmbeddingSize; i++) {
normalization += embedding[i] * embedding[i];
}
final double sqrtNormalization = math.sqrt(normalization);
for (int i = 0; i < kEmbeddingSize; i++) {
embedding[i] = embedding[i] / sqrtNormalization;
}
}
return embeddings;
}
}

View file

@ -1,4 +1,4 @@
import 'package:photos/services/machine_learning/face_ml/face_detection/yolov5face/onnx_face_detection.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/face_detection_service.dart';
/// Blur detection threshold
const kLaplacianThreshold = 15;
@ -10,4 +10,4 @@ const kLapacianDefault = 10000.0;
const kMinHighQualityFaceScore = 0.80;
/// The minimum score for a face to be detected, regardless of quality. Use [kMinHighQualityFaceScore] for high quality faces.
const kMinFaceDetectionScore = YoloOnnxFaceDetection.kMinScoreSigmoidThreshold;
const kMinFaceDetectionScore = FaceDetectionService.kMinScoreSigmoidThreshold;

View file

@ -28,10 +28,10 @@ import "package:photos/models/file/file_type.dart";
import "package:photos/models/ml/ml_versions.dart";
import 'package:photos/services/machine_learning/face_ml/face_clustering/linear_clustering_service.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/detection.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/yolov5face/onnx_face_detection.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/yolov5face/yolo_face_detection_exceptions.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/face_detection_exceptions.dart';
import 'package:photos/services/machine_learning/face_ml/face_detection/face_detection_service.dart';
import 'package:photos/services/machine_learning/face_ml/face_embedding/face_embedding_exceptions.dart';
import 'package:photos/services/machine_learning/face_ml/face_embedding/onnx_face_embedding.dart';
import 'package:photos/services/machine_learning/face_ml/face_embedding/face_embedding_service.dart';
import 'package:photos/services/machine_learning/face_ml/face_filtering/face_filtering_constants.dart';
import 'package:photos/services/machine_learning/face_ml/face_ml_exceptions.dart';
import 'package:photos/services/machine_learning/face_ml/face_ml_result.dart';
@ -90,7 +90,7 @@ class FaceMlService {
_logger.info("init called");
await _computer.compute(initOrtEnv);
try {
await YoloOnnxFaceDetection.instance.init();
await FaceDetectionService.instance.init();
} catch (e, s) {
_logger.severe("Could not initialize yolo onnx", e, s);
}
@ -102,7 +102,7 @@ class FaceMlService {
}
}
try {
await FaceEmbeddingOnnx.instance.init();
await FaceEmbeddingService.instance.init();
} catch (e, s) {
_logger.severe("Could not initialize mobilefacenet", e, s);
}
@ -142,7 +142,7 @@ class FaceMlService {
return;
}
try {
await YoloOnnxFaceDetection.instance.release();
await FaceDetectionService.instance.release();
} catch (e, s) {
_logger.severe("Could not dispose yolo onnx", e, s);
}
@ -152,7 +152,7 @@ class FaceMlService {
_logger.severe("Could not dispose image ml isolate", e, s);
}
try {
await FaceEmbeddingOnnx.instance.release();
await FaceEmbeddingService.instance.release();
} catch (e, s) {
_logger.severe("Could not dispose mobilefacenet", e, s);
}
@ -894,8 +894,9 @@ class FaceMlService {
"enteFileID": enteFile.uploadedFileID ?? -1,
"filePath": filePath,
"faceDetectionAddress":
YoloOnnxFaceDetection.instance.sessionAddress,
"faceEmbeddingAddress": FaceEmbeddingOnnx.instance.sessionAddress,
FaceDetectionService.instance.sessionAddress,
"faceEmbeddingAddress":
FaceEmbeddingService.instance.sessionAddress,
}
),
) as String?;
@ -1042,7 +1043,7 @@ class FaceMlService {
try {
// Get the bounding boxes of the faces
final (List<FaceDetectionRelative> faces, dataSize) =
await YoloOnnxFaceDetection.instance.predictInComputer(imagePath);
await FaceDetectionService.instance.predictInComputer(imagePath);
// Add detected faces to the resultBuilder
if (resultBuilder != null) {
@ -1050,9 +1051,9 @@ class FaceMlService {
}
return faces;
} on YOLOInterpreterInitializationException {
} on YOLOFaceInterpreterInitializationException {
throw CouldNotInitializeFaceDetector();
} on YOLOInterpreterRunException {
} on YOLOFaceInterpreterRunException {
throw CouldNotRunFaceDetector();
} catch (e) {
_logger.severe('Face detection failed: $e');
@ -1076,7 +1077,7 @@ class FaceMlService {
try {
// Get the bounding boxes of the faces
final (List<FaceDetectionRelative> faces, dataSize) =
await YoloOnnxFaceDetection.predictSync(
await FaceDetectionService.predictSync(
image,
imageByteData,
interpreterAddress,
@ -1088,9 +1089,9 @@ class FaceMlService {
}
return faces;
} on YOLOInterpreterInitializationException {
} on YOLOFaceInterpreterInitializationException {
throw CouldNotInitializeFaceDetector();
} on YOLOInterpreterRunException {
} on YOLOFaceInterpreterRunException {
throw CouldNotRunFaceDetector();
} catch (e) {
dev.log('[SEVERE] Face detection failed: $e');
@ -1185,7 +1186,7 @@ class FaceMlService {
try {
// Get the embedding of the faces
final List<List<double>> embeddings =
await FaceEmbeddingOnnx.instance.predictInComputer(facesList);
await FaceEmbeddingService.instance.predictInComputer(facesList);
// Add the embeddings to the resultBuilder
if (resultBuilder != null) {
@ -1218,7 +1219,7 @@ class FaceMlService {
try {
// Get the embedding of the faces
final List<List<double>> embeddings =
await FaceEmbeddingOnnx.predictSync(facesList, interpreterAddress);
await FaceEmbeddingService.predictSync(facesList, interpreterAddress);
// Add the embeddings to the resultBuilder
if (resultBuilder != null) {

View file

@ -375,7 +375,10 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
textInputAction: TextInputAction.next,
),
),
const Divider(thickness: 1),
Divider(
thickness: 1,
color: getEnteColorScheme(context).strokeFaint,
),
const SizedBox(height: 12),
_getAgreement(),
const SizedBox(height: 40),

View file

@ -8,6 +8,7 @@ import "package:photos/generated/l10n.dart";
import "package:photos/l10n/l10n.dart";
import "package:photos/models/api/user/srp.dart";
import 'package:photos/services/user_service.dart';
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/account/login_pwd_verification_page.dart";
import 'package:photos/ui/common/dynamic_fab.dart';
import 'package:photos/ui/common/web_page.dart';
@ -159,10 +160,11 @@ class _LoginPageState extends State<LoginPage> {
autofocus: true,
),
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 18),
Padding(
padding: const EdgeInsets.symmetric(vertical: 18),
child: Divider(
thickness: 1,
color: getEnteColorScheme(context).strokeFaint,
),
),
Padding(

View file

@ -282,10 +282,11 @@ class _LoginPasswordVerificationPageState
},
),
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 18),
Padding(
padding: const EdgeInsets.symmetric(vertical: 18),
child: Divider(
thickness: 1,
color: getEnteColorScheme(context).strokeFaint,
),
),
Padding(

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:photos/ente_theme_data.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/user_service.dart';
import "package:photos/theme/ente_theme.dart";
import 'package:photos/ui/common/dynamic_fab.dart';
import 'package:step_progress_indicator/step_progress_indicator.dart';
import "package:styled_text/styled_text.dart";
@ -16,7 +17,7 @@ class OTTVerificationPage extends StatefulWidget {
this.email, {
this.isChangeEmail = false,
this.isCreateAccountScreen = false,
this.isResetPasswordScreen = false,
this.isResetPasswordScreen = false,
Key? key,
}) : super(key: key);
@ -78,9 +79,11 @@ class _OTTVerificationPageState extends State<OTTVerificationPage> {
_verificationCodeController.text,
);
} else {
UserService.instance
.verifyEmail(context, _verificationCodeController.text,
isResettingPasswordScreen: widget.isResetPasswordScreen,);
UserService.instance.verifyEmail(
context,
_verificationCodeController.text,
isResettingPasswordScreen: widget.isResetPasswordScreen,
);
}
FocusScope.of(context).unfocus();
},
@ -130,21 +133,21 @@ class _OTTVerificationPageState extends State<OTTVerificationPage> {
},
),
),
widget.isResetPasswordScreen ?
Text(
S.of(context).toResetVerifyEmail,
style: Theme.of(context)
.textTheme
.titleMedium!
.copyWith(fontSize: 14),
):
Text(
S.of(context).checkInboxAndSpamFolder,
style: Theme.of(context)
.textTheme
.titleMedium!
.copyWith(fontSize: 14),
),
widget.isResetPasswordScreen
? Text(
S.of(context).toResetVerifyEmail,
style: Theme.of(context)
.textTheme
.titleMedium!
.copyWith(fontSize: 14),
)
: Text(
S.of(context).checkInboxAndSpamFolder,
style: Theme.of(context)
.textTheme
.titleMedium!
.copyWith(fontSize: 14),
),
],
),
),
@ -178,8 +181,9 @@ class _OTTVerificationPageState extends State<OTTVerificationPage> {
},
),
),
const Divider(
Divider(
thickness: 1,
color: getEnteColorScheme(context).strokeFaint,
),
Padding(
padding: const EdgeInsets.all(20),

View file

@ -9,6 +9,7 @@ import 'package:photos/core/event_bus.dart';
import 'package:photos/events/subscription_purchased_event.dart';
import "package:photos/generated/l10n.dart";
import "package:photos/services/user_service.dart";
import "package:photos/theme/ente_theme.dart";
import 'package:photos/ui/account/recovery_page.dart';
import 'package:photos/ui/common/dynamic_fab.dart';
import 'package:photos/ui/components/buttons/button_widget.dart';
@ -257,10 +258,11 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
},
),
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 18),
Padding(
padding: const EdgeInsets.symmetric(vertical: 18),
child: Divider(
thickness: 1,
color: getEnteColorScheme(context).strokeFaint,
),
),
Padding(

View file

@ -3,6 +3,7 @@ import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:photos/core/configuration.dart';
import "package:photos/generated/l10n.dart";
import "package:photos/theme/ente_theme.dart";
import 'package:photos/ui/account/password_entry_page.dart';
import 'package:photos/ui/common/dynamic_fab.dart';
import 'package:photos/utils/dialog_util.dart';
@ -123,10 +124,11 @@ class _RecoveryPageState extends State<RecoveryPage> {
},
),
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 18),
Padding(
padding: const EdgeInsets.symmetric(vertical: 18),
child: Divider(
thickness: 1,
color: getEnteColorScheme(context).strokeFaint,
),
),
Row(

View file

@ -210,10 +210,11 @@ class _RequestPasswordVerificationPageState
},
),
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 18),
Padding(
padding: const EdgeInsets.symmetric(vertical: 18),
child: Divider(
thickness: 1,
color: getEnteColorScheme(context).strokeFaint,
),
),
],

View file

@ -5,6 +5,7 @@ import 'package:photos/ente_theme_data.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/sessions.dart';
import 'package:photos/services/user_service.dart';
import "package:photos/theme/ente_theme.dart";
import 'package:photos/ui/common/loading_widget.dart';
import "package:photos/utils/date_time_util.dart";
import 'package:photos/utils/dialog_util.dart';
@ -106,7 +107,9 @@ class _SessionsPageState extends State<SessionsPage> {
),
),
),
const Divider(),
Divider(
color: getEnteColorScheme(context).strokeFaint,
),
],
);
}

View file

@ -25,8 +25,8 @@ class _ToggleSwitchWidgetState extends State<ToggleSwitchWidget> {
@override
void initState() {
toggleValue = widget.value.call();
super.initState();
toggleValue = widget.value.call();
}
@override
@ -50,8 +50,13 @@ class _ToggleSwitchWidgetState extends State<ToggleSwitchWidget> {
child: FittedBox(
fit: BoxFit.contain,
child: Switch.adaptive(
activeColor: enteColorScheme.primary400,
inactiveTrackColor: enteColorScheme.fillMuted,
inactiveTrackColor: Colors.transparent,
activeTrackColor: enteColorScheme.primary500,
activeColor: Colors.white,
inactiveThumbColor: enteColorScheme.primary500,
trackOutlineColor: MaterialStateColor.resolveWith(
(states) => enteColorScheme.primary500,
),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
value: toggleValue ?? false,
onChanged: (negationOfToggleValue) async {

View file

@ -10,6 +10,7 @@ import 'package:photos/events/sync_status_update_event.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/sync_service.dart';
import 'package:photos/services/user_remote_flag_service.dart';
import "package:photos/theme/ente_theme.dart";
import 'package:photos/theme/text_style.dart';
import 'package:photos/ui/account/verify_recovery_page.dart';
import 'package:photos/ui/components/home_header_widget.dart';
@ -93,8 +94,9 @@ class _StatusBarWidgetState extends State<StatusBarWidget> {
: const Text("ente", style: brandStyleMedium),
),
_showErrorBanner
? const Divider(
? Divider(
height: 8,
color: getEnteColorScheme(context).strokeFaint,
)
: const SizedBox.shrink(),
_showErrorBanner

View file

@ -284,7 +284,7 @@ class _HomeWidgetState extends State<HomeWidget> {
void _initMediaShareSubscription() {
// For sharing images coming from outside the app while the app is in the memory
_intentDataStreamSubscription =
ReceiveSharingIntent.getMediaStream().listen(
ReceiveSharingIntent.instance.getMediaStream().listen(
(List<SharedMediaFile> value) {
setState(() {
_shouldRenderCreateCollectionSheet = true;
@ -296,7 +296,9 @@ class _HomeWidgetState extends State<HomeWidget> {
},
);
// For sharing images coming from outside the app while the app is closed
ReceiveSharingIntent.getInitialMedia().then((List<SharedMediaFile> value) {
ReceiveSharingIntent.instance
.getInitialMedia()
.then((List<SharedMediaFile> value) {
if (mounted) {
setState(() {
_sharedFiles = value;
@ -380,7 +382,7 @@ class _HomeWidgetState extends State<HomeWidget> {
//So to stop showing multiple CreateCollectionSheets, this flag
//needs to be set to false the first time it is rendered.
_shouldRenderCreateCollectionSheet = false;
ReceiveSharingIntent.reset();
ReceiveSharingIntent.instance.reset();
Future.delayed(const Duration(milliseconds: 10), () {
showCollectionActionSheet(
context,

View file

@ -10,6 +10,7 @@ import 'package:photos/events/user_logged_out_event.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/collection/collection.dart';
import 'package:photos/services/collections_service.dart';
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/collections/button/archived_button.dart";
import "package:photos/ui/collections/button/hidden_button.dart";
import "package:photos/ui/collections/button/trash_button.dart";
@ -184,7 +185,11 @@ class _UserCollectionsTabState extends State<UserCollectionsTab>
),
)
: const SliverToBoxAdapter(child: SizedBox.shrink()),
const SliverToBoxAdapter(child: Divider()),
SliverToBoxAdapter(
child: Divider(
color: getEnteColorScheme(context).strokeFaint,
),
),
const SliverToBoxAdapter(child: SizedBox(height: 12)),
SliverToBoxAdapter(
child: Padding(

View file

@ -13,18 +13,18 @@ packages:
dependency: transitive
description:
name: _flutterfire_internals
sha256: f5628cd9c92ed11083f425fd1f8f1bc60ecdda458c81d73b143aeda036c35fe7
sha256: "4eec93681221723a686ad580c2e7d960e1017cf1a4e0a263c2573c2c6b0bf5cd"
url: "https://pub.dev"
source: hosted
version: "1.3.16"
version: "1.3.25"
adaptive_theme:
dependency: "direct main"
description:
name: adaptive_theme
sha256: b0c4c35b22ef8226757881fe4dce38c40a06c551bca83236022ec7613e157c83
sha256: f4ee609b464e5efc68131d9d15ba9aa1de4e3b5ede64be17781c6e19a52d637d
url: "https://pub.dev"
source: hosted
version: "3.5.0"
version: "3.6.0"
analyzer:
dependency: transitive
description:
@ -93,10 +93,10 @@ packages:
dependency: "direct main"
description:
name: background_fetch
sha256: f70b28a0f7a3156195e9742229696f004ea3bf10f74039b7bf4c78a74fbda8a4
sha256: dbffec0317ccdef6e2014cb543e147f52441e29c4fcb53dfd23558c4d92ddece
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.3.2"
battery_info:
dependency: "direct main"
description:
@ -113,6 +113,38 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.6"
bonsoir:
dependency: transitive
description:
name: bonsoir
sha256: "800d77c0581fff06cc43ef2b7723dfe5ee9b899ab0fdf80fb1c7b8829a5deb5c"
url: "https://pub.dev"
source: hosted
version: "3.0.0+1"
bonsoir_android:
dependency: transitive
description:
name: bonsoir_android
sha256: "7207c36fd7e0f3c7c2d8cf353f02bd640d96e2387d575837f8ac051c9cbf4aa7"
url: "https://pub.dev"
source: hosted
version: "3.0.0+1"
bonsoir_darwin:
dependency: transitive
description:
name: bonsoir_darwin
sha256: "7211042c85da2d6efa80c0976bbd9568f2b63624097779847548ed4530675ade"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
bonsoir_platform_interface:
dependency: transitive
description:
name: bonsoir_platform_interface
sha256: "64d57cd52bd477b4891e9b9d419e6408da171ed9e0efc8aa716e7e343d5d93ad"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
boolean_selector:
dependency: transitive
description:
@ -157,18 +189,18 @@ packages:
dependency: "direct dev"
description:
name: build_runner
sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21"
sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22"
url: "https://pub.dev"
source: hosted
version: "2.4.8"
version: "2.4.9"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: c9e32d21dd6626b5c163d48b037ce906bbe428bc23ab77bcd77bb21e593b6185
sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799"
url: "https://pub.dev"
source: hosted
version: "7.2.11"
version: "7.3.0"
built_collection:
dependency: transitive
description:
@ -181,10 +213,10 @@ packages:
dependency: transitive
description:
name: built_value
sha256: a3ec2e0f967bc47f69f95009bb93db936288d61d5343b9436e378b28a2f830c6
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
url: "https://pub.dev"
source: hosted
version: "8.9.0"
version: "8.9.2"
cached_network_image:
dependency: "direct main"
description:
@ -209,6 +241,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.1"
cast:
dependency: "direct main"
description:
name: cast
sha256: b70f6be547a53481dffec93ad3cc4974fae5ed707f0b677d4a50c329d7299b98
url: "https://pub.dev"
source: hosted
version: "2.0.0"
characters:
dependency: transitive
description:
@ -269,10 +309,10 @@ packages:
dependency: "direct main"
description:
name: collection
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.17.2"
version: "1.18.0"
computer:
dependency: "direct main"
description:
@ -285,11 +325,10 @@ packages:
connectivity_plus:
dependency: "direct main"
description:
path: "packages/connectivity_plus/connectivity_plus"
ref: check_mobile_first
resolved-ref: "452aa4b6448adbd3a9e592b82da3e9d355af2125"
url: "https://github.com/ente-io/plus_plugins.git"
source: git
name: connectivity_plus
sha256: "77a180d6938f78ca7d2382d2240eb626c0f6a735d0bfdce227d8ffb80f95c48b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
connectivity_plus_platform_interface:
dependency: transitive
@ -311,18 +350,18 @@ packages:
dependency: transitive
description:
name: coverage
sha256: "2fb815080e44a09b85e0f2ca8a820b15053982b2e714b59267719e8a9ff17097"
sha256: "595a29b55ce82d53398e1bcc2cba525d7bd7c59faeb2d2540e9d42c390cfeeeb"
url: "https://pub.dev"
source: hosted
version: "1.6.3"
version: "1.6.4"
cross_file:
dependency: "direct main"
description:
name: cross_file
sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5"
sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e
url: "https://pub.dev"
source: hosted
version: "0.3.3+7"
version: "0.3.3+8"
crypto:
dependency: "direct main"
description:
@ -383,10 +422,10 @@ packages:
dependency: "direct main"
description:
name: device_info_plus
sha256: "0042cb3b2a76413ea5f8a2b40cec2a33e01d0c937e91f0f7c211fde4f7739ba6"
sha256: "77f757b789ff68e4eaf9c56d1752309bd9f7ad557cb105b938a7f8eb89e59110"
url: "https://pub.dev"
source: hosted
version: "9.1.1"
version: "9.1.2"
device_info_plus_platform_interface:
dependency: transitive
description:
@ -479,18 +518,18 @@ packages:
dependency: "direct main"
description:
name: extended_image
sha256: b4d72a27851751cfadaf048936d42939db7cd66c08fdcfe651eeaa1179714ee6
sha256: d7f091d068fcac7246c4b22a84b8dac59a62e04d29a5c172710c696e67a22f94
url: "https://pub.dev"
source: hosted
version: "8.1.1"
version: "8.2.0"
extended_image_library:
dependency: transitive
description:
name: extended_image_library
sha256: "8bf87c0b14dcb59200c923a9a3952304e4732a0901e40811428834ef39018ee1"
sha256: "9b55fc5ebc65fad984de66b8f177a1bef2a84d79203c9c213f75ff83c2c29edd"
url: "https://pub.dev"
source: hosted
version: "3.6.0"
version: "4.0.1"
fade_indexed_stack:
dependency: "direct main"
description:
@ -552,10 +591,10 @@ packages:
dependency: "direct main"
description:
name: firebase_core
sha256: "96607c0e829a581c2a483c658f04e8b159964c3bae2730f73297070bc85d40bb"
sha256: "53316975310c8af75a96e365f9fccb67d1c544ef0acdbf0d88bbe30eedd1c4f9"
url: "https://pub.dev"
source: hosted
version: "2.24.2"
version: "2.27.0"
firebase_core_platform_interface:
dependency: transitive
description:
@ -568,34 +607,34 @@ packages:
dependency: transitive
description:
name: firebase_core_web
sha256: d585bdf3c656c3f7821ba1bd44da5f13365d22fcecaf5eb75c4295246aaa83c0
sha256: c8e1d59385eee98de63c92f961d2a7062c5d9a65e7f45bdc7f1b0b205aab2492
url: "https://pub.dev"
source: hosted
version: "2.10.0"
version: "2.11.5"
firebase_messaging:
dependency: "direct main"
description:
name: firebase_messaging
sha256: "980259425fa5e2afc03e533f33723335731d21a56fd255611083bceebf4373a8"
sha256: e41586e0fd04fe9a40424f8b0053d0832e6d04f49e020cdaf9919209a28497e9
url: "https://pub.dev"
source: hosted
version: "14.7.10"
version: "14.7.19"
firebase_messaging_platform_interface:
dependency: transitive
description:
name: firebase_messaging_platform_interface
sha256: "54e283a0e41d81d854636ad0dad73066adc53407a60a7c3189c9656e2f1b6107"
sha256: f7a9d74ff7fc588a924f6b2eaeaa148b0db521b13a9db55f6ad45864fa98c06e
url: "https://pub.dev"
source: hosted
version: "4.5.18"
version: "4.5.27"
firebase_messaging_web:
dependency: transitive
description:
name: firebase_messaging_web
sha256: "90dc7ed885e90a24bb0e56d661d4d2b5f84429697fd2cbb9e5890a0ca370e6f4"
sha256: fc21e771166860c55b103701c5ac7cdb2eec28897b97c42e6e5703cbedf9e02e
url: "https://pub.dev"
source: hosted
version: "3.5.18"
version: "3.6.8"
fixnum:
dependency: transitive
description:
@ -621,10 +660,10 @@ packages:
dependency: "direct main"
description:
name: flutter_animate
sha256: cabe33af6201144be052352d53572a1b8a4f5782b46080be7520d95abe763715
sha256: "7c8a6594a9252dad30cc2ef16e33270b6248c4dedc3b3d06c86c4f3f4dc05ae5"
url: "https://pub.dev"
source: hosted
version: "4.4.1"
version: "4.5.0"
flutter_cache_manager:
dependency: "direct main"
description:
@ -767,10 +806,10 @@ packages:
dependency: "direct main"
description:
name: flutter_native_splash
sha256: "17d9671396fb8ec45ad10f4a975eb8a0f70bedf0fdaf0720b31ea9de6da8c4da"
sha256: "558f10070f03ee71f850a78f7136ab239a67636a294a44a06b6b7345178edb1e"
url: "https://pub.dev"
source: hosted
version: "2.3.7"
version: "2.3.10"
flutter_password_strength:
dependency: "direct main"
description:
@ -783,10 +822,10 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
sha256: "592dc01a18961a51c24ae5d963b724b2b7fa4a95c100fe8eb6ca8a5a4732cadf"
url: "https://pub.dev"
source: hosted
version: "2.0.17"
version: "2.0.18"
flutter_secure_storage:
dependency: "direct main"
description:
@ -835,6 +874,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.1"
flutter_shaders:
dependency: transitive
description:
name: flutter_shaders
sha256: "02750b545c01ff4d8e9bbe8f27a7731aa3778402506c67daa1de7f5fc3f4befe"
url: "https://pub.dev"
source: hosted
version: "0.1.2"
flutter_sodium:
dependency: "direct main"
description:
@ -847,10 +894,10 @@ packages:
dependency: transitive
description:
name: flutter_spinkit
sha256: b39c753e909d4796906c5696a14daf33639a76e017136c8d82bf3e620ce5bb8e
sha256: d2696eed13732831414595b98863260e33e8882fc069ee80ec35d4ac9ddb0472
url: "https://pub.dev"
source: hosted
version: "5.2.0"
version: "5.2.1"
flutter_staggered_grid_view:
dependency: "direct main"
description:
@ -881,10 +928,10 @@ packages:
dependency: "direct dev"
description:
name: freezed
sha256: "6c5031daae12c7072b3a87eff98983076434b4889ef2a44384d0cae3f82372ba"
sha256: "91bce569d4805ea5bad6619a3e8690df8ad062a235165af4c0c5d928dda15eaf"
url: "https://pub.dev"
source: hosted
version: "2.4.6"
version: "2.5.1"
freezed_annotation:
dependency: "direct main"
description:
@ -966,10 +1013,10 @@ packages:
dependency: "direct main"
description:
name: http
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.2.0"
http_client_helper:
dependency: transitive
description:
@ -998,18 +1045,18 @@ packages:
dependency: "direct main"
description:
name: image
sha256: "004a2e90ce080f8627b5a04aecb4cdfac87d2c3f3b520aa291260be5a32c033d"
sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e"
url: "https://pub.dev"
source: hosted
version: "4.1.4"
version: "4.1.7"
image_editor:
dependency: "direct main"
description:
name: image_editor
sha256: "9877a057b0cd2fafcd9a3dce5279948bd850d53ce76231a83c9678a2c9f186e9"
sha256: "6401a431ef1e988e35a8b19ff02cb7d31bd881fd7db0d39261ac8236683ef1c1"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "1.4.0"
image_editor_common:
dependency: transitive
description:
@ -1018,6 +1065,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.1"
image_editor_ohos:
dependency: transitive
description:
name: image_editor_ohos
sha256: "55c08871814efdd19b3927327b5913649dd1ea36e0a83aa77ab668dad3160dcc"
url: "https://pub.dev"
source: hosted
version: "0.0.6"
image_editor_platform_interface:
dependency: transitive
description:
@ -1038,10 +1093,10 @@ packages:
dependency: transitive
description:
name: in_app_purchase_android
sha256: "28164faac635a6cc357c96f47813e675eec7622a8f41e829b501573dbbce2cce"
sha256: "6863bf74335ccbd80829e8c3d16176f90794f0f8593a4505a7ab79d17334a0bf"
url: "https://pub.dev"
source: hosted
version: "0.3.0+17"
version: "0.3.3"
in_app_purchase_platform_interface:
dependency: transitive
description:
@ -1054,10 +1109,10 @@ packages:
dependency: transitive
description:
name: in_app_purchase_storekit
sha256: c4b17a7f2ca8ddc7fd7996a8c32a3af6beddf91d651997c8675a5f23c103c9bc
sha256: e0f860e760488dbd666e0f27e239d128cba744607fc62434dc76c19d1c292439
url: "https://pub.dev"
source: hosted
version: "0.3.8+1"
version: "0.3.13+1"
integration_test:
dependency: "direct dev"
description: flutter
@ -1131,10 +1186,10 @@ packages:
dependency: "direct main"
description:
name: latlong2
sha256: "18712164760cee655bc790122b0fd8f3d5b3c36da2cb7bf94b68a197fbb0811b"
sha256: "98227922caf49e6056f91b6c56945ea1c7b166f28ffcd5fb8e72fc0b453cc8fe"
url: "https://pub.dev"
source: hosted
version: "0.9.0"
version: "0.9.1"
like_button:
dependency: "direct main"
description:
@ -1171,26 +1226,34 @@ packages:
dependency: "direct main"
description:
name: local_auth
sha256: "27679ed8e0d7daab2357db6bb7076359e083a56b295c0c59723845301da6aed9"
sha256: "280421b416b32de31405b0a25c3bd42dfcef2538dfbb20c03019e02a5ed55ed0"
url: "https://pub.dev"
source: hosted
version: "2.1.8"
version: "2.2.0"
local_auth_android:
dependency: "direct main"
description:
name: local_auth_android
sha256: "54e9c35ce52c06333355ab0d0f41e4c06dbca354b23426765ba41dfb1de27598"
sha256: "3bcd732dda7c75fcb7ddaef12e131230f53dcc8c00790d0d6efb3aa0fbbeda57"
url: "https://pub.dev"
source: hosted
version: "1.0.36"
version: "1.0.37"
local_auth_darwin:
dependency: transitive
description:
name: local_auth_darwin
sha256: "33381a15b0de2279523eca694089393bb146baebdce72a404555d03174ebc1e9"
url: "https://pub.dev"
source: hosted
version: "1.2.2"
local_auth_ios:
dependency: "direct main"
description:
name: local_auth_ios
sha256: eb283b530029b334698918f1e282d4483737cbca972ff21b9193be3d6de8e2b8
sha256: "6dde47dc852bc0c8343cb58e66a46efb16b62eddf389ce103d4dacb0c6c40c71"
url: "https://pub.dev"
source: hosted
version: "1.1.6"
version: "1.1.7"
local_auth_platform_interface:
dependency: transitive
description:
@ -1323,10 +1386,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
mgrs_dart:
dependency: transitive
description:
@ -1339,10 +1402,10 @@ packages:
dependency: transitive
description:
name: mime
sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2"
url: "https://pub.dev"
source: hosted
version: "1.0.4"
version: "1.0.5"
ml_linalg:
dependency: "direct main"
description:
@ -1351,6 +1414,7 @@ packages:
url: "https://pub.dev"
source: hosted
version: "13.11.31"
version: "1.0.5"
modal_bottom_sheet:
dependency: "direct main"
description:
@ -1510,10 +1574,10 @@ packages:
dependency: transitive
description:
name: path_provider_android
sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
sha256: "51f0d2c554cfbc9d6a312ab35152fc77e2f0b758ce9f1a444a3a1e5b8f3c6b7f"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
version: "2.2.3"
path_provider_foundation:
dependency: transitive
description:
@ -1558,58 +1622,74 @@ packages:
dependency: "direct main"
description:
name: permission_handler
sha256: "284a66179cabdf942f838543e10413246f06424d960c92ba95c84439154fcac8"
sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb"
url: "https://pub.dev"
source: hosted
version: "11.0.1"
version: "11.3.1"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: f9fddd3b46109bd69ff3f9efa5006d2d309b7aec0f3c1c5637a60a2d5659e76e
sha256: "1acac6bae58144b442f11e66621c062aead9c99841093c38f5bcdcc24c1c3474"
url: "https://pub.dev"
source: hosted
version: "11.1.0"
version: "12.0.5"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
sha256: e9ad66020b89ff1b63908f247c2c6f931c6e62699b756ef8b3c4569350cd8662
url: "https://pub.dev"
source: hosted
version: "9.1.4"
version: "9.4.4"
permission_handler_html:
dependency: transitive
description:
name: permission_handler_html
sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d"
url: "https://pub.dev"
source: hosted
version: "0.1.1"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4"
sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20"
url: "https://pub.dev"
source: hosted
version: "3.12.0"
version: "4.2.1"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
url: "https://pub.dev"
source: hosted
version: "0.1.3"
version: "0.2.1"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "5.4.0"
version: "6.0.2"
photo_manager:
dependency: "direct main"
description:
name: photo_manager
sha256: "2d698826421ebd045ecc0df60422e9dd24bd22b178310b68444385f783735b55"
sha256: df594f989f0c31cdb3ed48f3d49cb9ffadf11cc3700d2c3460b1912c93432621
url: "https://pub.dev"
source: hosted
version: "2.8.1"
version: "3.0.0"
photo_manager_image_provider:
dependency: transitive
description:
name: photo_manager_image_provider
sha256: "38ef1023dc11de3a8669f16e7c981673b3c5cfee715d17120f4b87daa2cdd0af"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
photo_view:
dependency: "direct main"
description:
@ -1630,10 +1710,10 @@ packages:
dependency: transitive
description:
name: platform
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "3.1.2"
plugin_platform_interface:
dependency: transitive
description:
@ -1646,10 +1726,10 @@ packages:
dependency: "direct main"
description:
name: pointycastle
sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
sha256: "70fe966348fe08c34bf929582f1d8247d9d9408130723206472b4687227e4333"
url: "https://pub.dev"
source: hosted
version: "3.7.4"
version: "3.8.0"
polylabel:
dependency: transitive
description:
@ -1694,10 +1774,10 @@ packages:
dependency: "direct main"
description:
name: provider
sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096"
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
url: "https://pub.dev"
source: hosted
version: "6.1.1"
version: "6.1.2"
pub_semver:
dependency: transitive
description:
@ -1726,10 +1806,10 @@ packages:
dependency: "direct main"
description:
name: receive_sharing_intent
sha256: "8fdf5927934041264becf65199ef8057b8b176e879d95ffa0420cd2a6219c0fd"
sha256: fe02f858ac9f8d44d62e1964dadded000bb48dea424085ed280d542a61c4e8ba
url: "https://pub.dev"
source: hosted
version: "1.6.7"
version: "1.7.0"
rxdart:
dependency: transitive
description:
@ -1806,18 +1886,18 @@ packages:
dependency: "direct main"
description:
name: sentry
sha256: "5686ed515bb620dc52b4ae99a6586fe720d443591183cf1f620ec5d1f0eec100"
sha256: fe99a06970b909a491b7f89d54c9b5119772e3a48a400308a6e129625b333f5b
url: "https://pub.dev"
source: hosted
version: "7.15.0"
version: "7.19.0"
sentry_flutter:
dependency: "direct main"
description:
name: sentry_flutter
sha256: "505dec3b6810562785d2c34ae871c73ff2cba6cf436c32c188f0464df226ba8f"
sha256: fc013d4a753447320f62989b1871fdc1f20c77befcc8be3e38774dd7402e7a62
url: "https://pub.dev"
source: hosted
version: "7.15.0"
version: "7.19.0"
share_plus:
dependency: "direct main"
description:
@ -1846,10 +1926,10 @@ packages:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: df08bc3a07d01f5ea47b45d03ffcba1fa9cd5370fb44b3f38c70e42cced0f956
sha256: "251eb156a8b5fa9ce033747d73535bf53911071f8d3b6f4f0b578505ce0d4496"
url: "https://pub.dev"
source: hosted
version: "3.3.1"
version: "3.4.0"
share_plus_web:
dependency: transitive
description:
@ -1910,10 +1990,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_web
sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
version: "2.2.2"
shared_preferences_windows:
dependency: transitive
description:
@ -2043,10 +2123,10 @@ packages:
dependency: "direct main"
description:
name: sqlite3
sha256: db65233e6b99e99b2548932f55a987961bc06d82a31a0665451fa0b4fff4c3fb
sha256: "072128763f1547e3e9b4735ce846bfd226d68019ccda54db4cd427b12dfdedc9"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.4.0"
sqlite3_flutter_libs:
dependency: "direct main"
description:
@ -2067,10 +2147,10 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.11.1"
step_progress_indicator:
dependency: "direct main"
description:
@ -2083,10 +2163,10 @@ packages:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
stream_transform:
dependency: transitive
description:
@ -2155,34 +2235,26 @@ packages:
dependency: "direct dev"
description:
name: test
sha256: "13b41f318e2a5751c3169137103b60c584297353d4b1761b66029bae6411fe46"
sha256: a1f7595805820fcc05e5c52e3a231aedd0b72972cb333e8c738a8b1239448b6f
url: "https://pub.dev"
source: hosted
version: "1.24.3"
version: "1.24.9"
test_api:
dependency: transitive
description:
name: test_api
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.6.0"
version: "0.6.1"
test_core:
dependency: transitive
description:
name: test_core
sha256: "99806e9e6d95c7b059b7a0fc08f07fc53fabe54a829497f0d9676299f1e8637e"
sha256: a757b14fc47507060a162cc2530d9a4a2f92f5100a952c7443b5cad5ef5b106a
url: "https://pub.dev"
source: hosted
version: "0.5.3"
tflite_flutter:
dependency: "direct main"
description:
name: tflite_flutter
sha256: ffb8651fdb116ab0131d6dc47ff73883e0f634ad1ab12bb2852eef1bbeab4a6a
url: "https://pub.dev"
source: hosted
version: "0.10.4"
version: "0.5.9"
time:
dependency: transitive
description:
@ -2283,26 +2355,26 @@ packages:
dependency: "direct main"
description:
name: url_launcher
sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c
sha256: "0ecc004c62fd3ed36a2ffcbe0dd9700aee63bd7532d0b642a488b1ec310f492e"
url: "https://pub.dev"
source: hosted
version: "6.2.4"
version: "6.2.5"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f"
sha256: d4ed0711849dd8e33eb2dd69c25db0d0d3fdc37e0a62e629fe32f57a22db2745
url: "https://pub.dev"
source: hosted
version: "6.2.2"
version: "6.3.0"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03"
sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5"
url: "https://pub.dev"
source: hosted
version: "6.2.4"
version: "6.2.5"
url_launcher_linux:
dependency: transitive
description:
@ -2323,18 +2395,18 @@ packages:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.3.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "7fd2f55fe86cea2897b963e864dc01a7eb0719ecc65fcef4c1cc3d686d718bb2"
sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.2.3"
url_launcher_windows:
dependency: transitive
description:
@ -2372,18 +2444,18 @@ packages:
dependency: transitive
description:
name: video_player_android
sha256: "7f8f25d7ad56819a82b2948357f3c3af071f6a678db33833b26ec36bbc221316"
sha256: "4dd9b8b86d70d65eecf3dcabfcdfbb9c9115d244d022654aba49a00336d540c2"
url: "https://pub.dev"
source: hosted
version: "2.4.11"
version: "2.4.12"
video_player_avfoundation:
dependency: transitive
description:
name: video_player_avfoundation
sha256: bc923884640d6dc403050586eb40713cdb8d1d84e6886d8aca50ab04c59124c2
sha256: "309e3962795e761be010869bae65c0b0e45b5230c5cee1bec72197ca7db040ed"
url: "https://pub.dev"
source: hosted
version: "2.5.2"
version: "2.5.6"
video_player_platform_interface:
dependency: transitive
description:
@ -2420,10 +2492,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: c620a6f783fa22436da68e42db7ebbf18b8c44b9a46ab911f666ff09ffd9153f
sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583
url: "https://pub.dev"
source: hosted
version: "11.7.1"
version: "11.10.0"
volume_controller:
dependency: transitive
description:
@ -2468,10 +2540,10 @@ packages:
dependency: transitive
description:
name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
version: "0.3.0"
web_socket_channel:
dependency: transitive
description:
@ -2500,10 +2572,10 @@ packages:
dependency: "direct main"
description:
name: wechat_assets_picker
sha256: f78c7797dc88e3c9170d318acc9f535ca104ab648cc69ab3b7745f1ceac29910
sha256: "9934724a45fdb2b12e332d8190c58713e6675c37c630d53608e0f50167215c9f"
url: "https://pub.dev"
source: hosted
version: "8.8.1+1"
version: "8.9.0-dev.1"
widgets_to_image:
dependency: "direct main"
description:
@ -2516,10 +2588,10 @@ packages:
dependency: transitive
description:
name: win32
sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574
sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
url: "https://pub.dev"
source: hosted
version: "5.1.1"
version: "5.2.0"
win32_registry:
dependency: transitive
description:
@ -2548,10 +2620,10 @@ packages:
dependency: transitive
description:
name: xml
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.3.0"
version: "6.5.0"
xmlstream:
dependency: transitive
description:
@ -2577,5 +2649,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.1.0 <4.0.0"
flutter: ">=3.13.0"
dart: ">=3.2.3 <4.0.0"
flutter: ">=3.16.6"

View file

@ -27,6 +27,7 @@ dependencies:
battery_info: ^1.1.1
bip39: ^1.0.6
cached_network_image: ^3.0.0
cast: ^2.0.0
chewie:
git:
url: https://github.com/ente-io/chewie.git
@ -59,7 +60,6 @@ dependencies:
extended_image: ^8.1.1
fade_indexed_stack: ^0.2.2
fast_base58: ^0.2.1
figma_squircle: ^0.5.3
file_saver:
# Use forked version till this PR is merged: https://github.com/incrediblezayed/file_saver/pull/87
@ -133,7 +133,7 @@ dependencies:
path_provider: ^2.1.1
pedantic: ^1.9.2
permission_handler: ^11.0.1
photo_manager: ^2.8.1
photo_manager: ^3.0.0
photo_view: ^0.14.0
pinput: ^1.2.2
pointycastle: ^3.7.3
@ -141,7 +141,7 @@ dependencies:
protobuf: ^3.1.0
provider: ^6.0.0
quiver: ^3.0.1
receive_sharing_intent: ^1.6.7
receive_sharing_intent: ^1.7.0
scrollable_positioned_list: ^0.3.5
sentry: ^7.9.0
sentry_flutter: ^7.9.0
@ -158,10 +158,6 @@ dependencies:
syncfusion_flutter_core: ^19.2.49
syncfusion_flutter_sliders: ^19.2.49
synchronized: ^3.1.0
tflite_flutter: ^0.10.1
# tflite_flutter_helper:
# git:
# url: https://github.com/pnyompen/tflite_flutter_helper.git # Fixes https://github.com/am15h/tflite_flutter_helper/issues/57
tuple: ^2.0.0
uni_links: ^0.5.1
url_launcher: ^6.0.3
@ -179,10 +175,11 @@ dependencies:
widgets_to_image: ^0.0.2
dependency_overrides:
# current fork of tfite_flutter_helper depends on ffi: ^1.x.x
# but we need ffi: ^2.0.1 for newer packages. The original tfite_flutter_helper
#
ffi: ^2.1.0
connectivity_plus: ^4.0.0
#Remove this after upgrading to flutter v3.19x
#Build fails when resolving to latest version of ffi on flutter v3.16.x
ffi: 2.1.0
video_player:
git:
url: https://github.com/ente-io/packages.git