Compare commits

..

75 Commits

Author SHA1 Message Date
laurenspriem
a694bf9b6c flutter downgrade dependencies 2025-07-24 09:02:05 +02:00
laurenspriem
bfcfa691a2 upgrade frb and run frb gen command 2025-07-23 17:55:07 +02:00
laurenspriem
2703c6a33a Bump to be up to date with internal branch 2025-07-23 17:39:19 +02:00
laurenspriem
3ad94f362a Resolve merge conflicts 2025-07-23 17:06:54 +02:00
laurenspriem
8508ca74f2 Merge branch 'main' into usearch_again 2025-07-23 15:05:06 +02:00
laurenspriem
eed12c2089 Merge branch 'internal-15_06_2025' into usearch_again 2025-06-09 12:34:55 +05:30
laurenspriem
889aed6024 Bump for internal release 2025-06-09 12:34:29 +05:30
laurenspriem
ac7840cbfd Merge branch 'internal-15_06_2025' into usearch_again 2025-06-09 12:33:03 +05:30
laurenspriem
1f1304ca5b Upgrade usearch to fix Armv8-R issues 2025-06-09 12:31:38 +05:30
Neeraj Gupta
94098d8a07 Bump version 2025-06-06 12:35:30 +05:30
Neeraj Gupta
4b9c5fcb73 Merge branch 'internal-15_06_2025' of https://github.com/ente-io/auth into internal-15_06_2025 2025-06-06 12:33:48 +05:30
Neeraj Gupta
6ed16e5e02 Merge branch 'main' into internal-15_06_2025 2025-06-06 12:33:21 +05:30
laurenspriem
82a8e504af Merge branch 'internal-15_06_2025' into usearch_again 2025-06-04 22:14:26 +05:30
ashilkn
cc1660d9af bump up build number" 2025-06-04 18:24:59 +05:30
ashilkn
52b6fc108b Merge branch 'memory_improvement' into internal-15_06_2025 2025-06-04 18:19:37 +05:30
Neeraj Gupta
8b3b20aa93 Remove unsued type 2025-06-02 18:38:45 +05:30
Neeraj Gupta
408b0bfe2d Merge branch 'internal-15_06_2025' of https://github.com/ente-io/auth into internal-15_06_2025 2025-06-02 17:55:33 +05:30
Neeraj Gupta
655be76428 Bump version 2025-06-02 17:55:06 +05:30
Neeraj Gupta
9fedf8d6b7 Merge branch 'main' into internal-15_06_2025 2025-06-02 17:54:47 +05:30
ashilkn
7c4e775872 Bump build number 2025-06-02 14:56:04 +05:30
Neeraj Gupta
ecfa640c28 Bump version 2025-05-30 15:44:46 +05:30
Neeraj Gupta
1997eb20f3 Merge branch 'main' into internal-15_06_2025 2025-05-30 15:44:30 +05:30
laurenspriem
726425bbb6 Put vector db behind feature flag internal 2025-05-27 14:07:34 +05:30
laurenspriem
c068f26604 Aggressive logging of vectorDB migration 2025-05-22 11:32:36 +05:30
laurenspriem
e60c2b1192 GC hints 2025-05-22 11:19:19 +05:30
laurenspriem
beb049f817 Reduce batch size in migration 2025-05-22 10:38:43 +05:30
laurenspriem
7021c9fe02 Bump for internal release 2025-05-12 17:05:31 +05:30
laurenspriem
c2d5dece9e Merge branch 'main' into usearch_again 2025-05-12 17:04:42 +05:30
laurenspriem
b76d41b84d Specify rust version in readme 2025-05-12 15:48:27 +05:30
laurenspriem
3b9c76649d Update readme to include rust 2025-05-12 15:12:31 +05:30
laurenspriem
62ed8b6975 Log vector db stats when opening connection 2025-05-12 14:46:55 +05:30
laurenspriem
2422dba4d4 vector db more stats logging 2025-05-12 14:23:16 +05:30
laurenspriem
eb1916e3a3 integrate vector db in magic search 2025-05-12 11:39:02 +05:30
laurenspriem
df0d9137a6 Integration clip embeddings in vector db 2025-05-11 13:09:56 +05:30
laurenspriem
fc36b87965 Clip migration method 2025-05-11 13:09:20 +05:30
laurenspriem
63d90ea275 Class for vector db stats 2025-05-09 16:36:39 +05:30
laurenspriem
bb7f8a5eef More testing 2025-05-09 15:59:46 +05:30
laurenspriem
2f5a02ec43 delete table option 2025-05-09 12:57:44 +05:30
laurenspriem
d411d91966 vector db api ensure capacity safety 2025-05-09 12:56:59 +05:30
laurenspriem
54b712953a vector db api let clear include capacity reset 2025-05-09 10:49:03 +05:30
laurenspriem
27ad020adc Testing clip migration to vector DB 2025-05-08 17:40:01 +05:30
laurenspriem
ce112bd4d7 Index stats method 2025-05-08 15:23:23 +05:30
laurenspriem
2ffb73d053 Consistent method parameters 2025-05-08 15:07:50 +05:30
laurenspriem
6478d438b5 vector db api ensure never duplicate keys 2025-05-08 14:30:51 +05:30
laurenspriem
d87069eb4c vectordb api add documentation 2025-05-08 12:31:09 +05:30
laurenspriem
5447350ab1 vector db api add check for key 2025-05-08 12:29:41 +05:30
laurenspriem
ea1a2960bf First implementation of clip vector db 2025-05-08 12:08:55 +05:30
laurenspriem
832f2c451e Add bulk get method to vector db api 2025-05-08 11:47:50 +05:30
laurenspriem
715c7c23a7 Add bulk remove embeddings api 2025-05-08 10:29:25 +05:30
laurenspriem
e9c2e40a43 Update to latest usearch 2025-05-07 13:25:40 +05:30
laurenspriem
603c275c09 Update basic usearch test 2025-05-07 12:01:45 +05:30
laurenspriem
7b9d6df2fd Fix ios build issue 2025-05-07 11:32:53 +05:30
laurenspriem
a4afecef3d Fix ios config 2025-05-07 10:50:39 +05:30
laurenspriem
4d9bfb89ae macos config 2025-05-07 10:36:17 +05:30
laurenspriem
f2a74bd35e Merge branch 'main' into usearch_again 2025-05-06 15:34:59 +05:30
laurenspriem
8c65a21b86 don't generate for web 2025-04-10 13:03:52 +05:30
laurenspriem
a07e8477fb format 2025-04-09 15:34:06 +05:30
laurenspriem
8b489e9ced Give distances in bulk search 2025-04-09 15:31:03 +05:30
laurenspriem
77e2bb1d46 Stop our own vector comparisons in benchmark 2025-04-09 15:21:20 +05:30
laurenspriem
4ce24e080a logging of benchmarking 2025-04-09 14:22:39 +05:30
laurenspriem
4e5ca3dca6 Benchmark face embeddings 2025-04-09 13:43:39 +05:30
laurenspriem
2ed155ab47 ignore trailing commas in generated code 2025-04-09 13:14:26 +05:30
laurenspriem
65e71e3caf Reintroduce reset_index method 2025-04-09 10:49:50 +05:30
laurenspriem
ee5efbcfcc Don't consume index if not needed 2025-04-09 10:43:07 +05:30
laurenspriem
6cf4530f7d Remove reset index 2025-04-09 10:06:46 +05:30
laurenspriem
e6ee09ca30 Back to basic error handling 2025-04-08 17:03:41 +05:30
laurenspriem
6d2f53b86c Update usearch 2025-04-08 14:56:47 +05:30
laurenspriem
6500748c5a Make vector db stateful in rust 2025-04-08 14:48:30 +05:30
laurenspriem
120dbeb4fc Fix null pointer crash 2025-04-05 16:56:14 +05:30
laurenspriem
c42807487b Upgrade Android NDK to r28 latest stable 2025-04-05 16:11:03 +05:30
laurenspriem
e707e24da9 first integration of usearch 2025-04-05 16:10:39 +05:30
laurenspriem
af817ec439 Test rust 2025-04-04 11:49:54 +05:30
laurenspriem
ddb44d8fd7 Integrate flutter_rust_bridge 2025-03-31 15:56:03 +05:30
laurenspriem
778822b12d Upgrade sdk 2025-03-31 15:47:51 +05:30
laurenspriem
9599ec3236 dart format 2025-03-31 15:34:48 +05:30
311 changed files with 10587 additions and 3548 deletions

View File

@@ -4,7 +4,7 @@ on:
workflow_dispatch: # Allow manually running the action
env:
FLUTTER_VERSION: "3.29.3"
FLUTTER_VERSION: "3.24.3"
permissions:
contents: write

View File

@@ -8,7 +8,7 @@ on:
- ".github/workflows/auth-lint.yml"
env:
FLUTTER_VERSION: "3.29.3"
FLUTTER_VERSION: "3.24.3"
permissions:
contents: read

View File

@@ -29,7 +29,7 @@ on:
- "auth-v*"
env:
FLUTTER_VERSION: "3.29.3"
FLUTTER_VERSION: "3.24.3"
permissions:
contents: write
@@ -98,7 +98,7 @@ jobs:
- name: Install appimagetool
run: |
wget -O appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
wget -O appimagetool "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
chmod +x appimagetool
mv appimagetool /usr/local/bin/

View File

@@ -5,7 +5,7 @@ on:
workflow_dispatch: # Allow manually running the action
env:
FLUTTER_VERSION: "3.29.3"
FLUTTER_VERSION: "3.24.3"
permissions:
contents: write

View File

@@ -4,7 +4,7 @@ on:
workflow_dispatch: # Allow manually running the action
env:
FLUTTER_VERSION: "3.29.3"
FLUTTER_VERSION: "3.24.3"
RUST_VERSION: "1.85.1"
permissions:

View File

@@ -4,7 +4,7 @@ on:
workflow_dispatch: # Allow manually running the action
env:
FLUTTER_VERSION: "3.29.3"
FLUTTER_VERSION: "3.24.3"
permissions:
contents: write

View File

@@ -8,7 +8,7 @@ on:
- ".github/workflows/mobile-lint.yml"
env:
FLUTTER_VERSION: "3.29.3"
FLUTTER_VERSION: "3.24.3"
permissions:
contents: read

View File

@@ -9,7 +9,7 @@ on:
- "photos-v*"
env:
FLUTTER_VERSION: "3.29.3"
FLUTTER_VERSION: "3.24.3"
permissions:
contents: write

Submodule auth/assets/simple-icons added at 6dcfdc2f58

1
auth/flutter Submodule

Submodule auth/flutter added at 5874a72aa4

View File

@@ -1,3 +1,3 @@
{
"flutter": "3.29.3"
"flutter": "3.24.3"
}

View File

@@ -44,5 +44,4 @@ android/key.properties
dist/
# FVM Version Cache
.fvm/
lib/l10n/arb/*.dart
.fvm/

View File

@@ -44,7 +44,7 @@ or managing your secrets, please use our mobile or desktop app.
## 🧑‍💻 Build from source
1. [Install Flutter v3.29.3](https://flutter.dev/docs/get-started/install).
1. [Install Flutter](https://flutter.dev/docs/get-started/install)
2. Pull in all submodules with `git submodule update --init --recursive`

View File

@@ -739,10 +739,6 @@
"lu.ma"
]
},
{
"title": "MangaDex",
"slug": "mangadex"
},
{
"title": "Marketplace.tf",
"slug": "marketplacedottf"

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -1,32 +0,0 @@
#
# Generated file, do not edit.
#
import lldb
def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict):
"""Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages."""
base = frame.register["x0"].GetValueAsAddress()
page_len = frame.register["x1"].GetValueAsUnsigned()
# Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the
# first page to see if handled it correctly. This makes diagnosing
# misconfiguration (e.g. missing breakpoint) easier.
data = bytearray(page_len)
data[0:8] = b'IHELPED!'
error = lldb.SBError()
frame.GetThread().GetProcess().WriteMemory(base, data, error)
if not error.Success():
print(f'Failed to write into {base}[+{page_len}]', error)
return
def __lldb_init_module(debugger: lldb.SBDebugger, _):
target = debugger.GetDummyTarget()
# Caveat: must use BreakpointCreateByRegEx here and not
# BreakpointCreateByName. For some reasons callback function does not
# get carried over from dummy target for the later.
bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$")
bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__))
bp.SetAutoContinue(True)
print("-- LLDB integration loaded --")

View File

@@ -1,5 +0,0 @@
#
# Generated file, do not edit.
#
command script import --relative-to-command-file flutter_lldb_helper.py

View File

@@ -232,44 +232,44 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/url_launcher_ios/ios"
SPEC CHECKSUMS:
app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0
connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db
cupertino_http: 947a233f40cfea55167a49f2facc18434ea117ba
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
app_links: 3da4c36b46cac3bf24eb897f1a6ce80bda109874
connectivity_plus: 3f6c9057f4cd64198dc826edfb0542892f825343
cupertino_http: 94ac07f5ff090b8effa6c5e2c47871d48ab7c86c
device_info_plus: 335f3ce08d2e174b9fdc3db3db0f4e3b1f66bd89
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
fk_user_agent: 1f47ec39291e8372b1d692b50084b0d54103c545
file_picker: 9b3292d7c8bc68c8a7bf8eb78f730e49c8efc517
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
fk_user_agent: 137145b086229251761678fe034da53753f4ce59
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_email_sender: 10a22605f92809a11ef52b2f412db806c6082d40
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
flutter_local_authentication: 1172a4dd88f6306dadce067454e2c4caf07977bb
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
flutter_native_splash: edf599c81f74d093a4daf8e17bd7a018854bc778
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
fluttertoast: e9a18c7be5413da53898f660530c56f35edfba9c
local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3
move_to_background: 39a5b79b26d577b0372cbe8a8c55e7aa9fcd3a2d
flutter_email_sender: 2397f5e84aaacfb61af569637a963e7c687858d8
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
flutter_local_authentication: 989278c681612f1ee0e36019e149137f114b9d7f
flutter_local_notifications: ad39620c743ea4c15127860f4b5641649a988100
flutter_native_splash: 35ddbc7228eafcb3969dcc5f1fbbe27c1145a4f0
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
fluttertoast: 76fea30fcf04176325f6864c87306927bd7d2038
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
move_to_background: 155f7bfbd34d43ad847cb630d2d2d87c17199710
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
objective_c: 77e887b5ba1827970907e10e832eec1683f3431d
objective_c: 89e720c30d716b036faf9c9684022048eee1eee2
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
privacy_screen: 1a131c052ceb3c3659934b003b0d397c2381a24e
qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e
package_info_plus: 580e9a5f1b6ca5594e7c9ed5f92d1dfb2a66b5e1
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
privacy_screen: 3159a541f5d3a31bea916cfd4e58f9dc722b3fd4
qr_code_scanner: d77f94ecc9abf96d9b9b8fc04ef13f611e5a147a
SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868
Sentry: da60d980b197a46db0b35ea12cb8f39af48d8854
sentry_flutter: 2df8b0aab7e4aba81261c230cbea31c82a62dd1b
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sodium_libs: 1faae17af662384acbd13e41867a0008cd2e2318
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
sentry_flutter: 27892878729f42701297c628eb90e7c6529f3684
share_plus: 011d6fb4f9d2576b83179a3a5c5e323202cdabcf
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sodium_libs: 6c6d0e83f4ee427c6464caa1f1bdc2abf3ca0b7f
sqflite: c35dad70033b8862124f8337cc994a809fcd9fa3
sqlite3: 0bb0e6389d824e40296f531b858a2a0b71c0d2fb
sqlite3_flutter_libs: c00457ebd31e59fa6bb830380ddba24d44fbcd3b
sqlite3_flutter_libs: 9379996d65aa23dcda7585a5b58766cebe0aa042
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
PODFILE CHECKSUM: 78f002751f1a8f65042b8da97902ba4124271c5a

View File

@@ -26,7 +26,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
@@ -44,13 +43,11 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">

View File

@@ -40,7 +40,7 @@ class _AppState extends State<App>
late StreamSubscription<SignedOutEvent> _signedOutEvent;
late StreamSubscription<SignedInEvent> _signedInEvent;
Locale? locale;
void setLocale(Locale newLocale) {
setLocale(Locale newLocale) {
setState(() {
locale = newLocale;
});
@@ -82,7 +82,7 @@ class _AppState extends State<App>
UpdateService.instance.getLatestVersionInfo(),
);
},
barrierColor: Colors.black.withValues(alpha: 0.85),
barrierColor: Colors.black.withOpacity(0.85),
);
});
}

View File

@@ -27,8 +27,10 @@ Future<void> bootstrap(FutureOr<Widget> Function() builder) async {
await runZonedGuarded(
() async {
Bloc.observer = AppBlocObserver();
runApp(await builder());
await BlocOverrides.runZoned(
() async => runApp(await builder()),
blocObserver: AppBlocObserver(),
);
},
(error, stackTrace) => log(error.toString(), stackTrace: stackTrace),
);

View File

@@ -39,7 +39,7 @@ final lightThemeData = ThemeData(
bodyLarge: const TextStyle(color: Colors.orange),
),
cardColor: const Color.fromRGBO(250, 250, 250, 1.0),
dialogTheme: const DialogThemeData().copyWith(
dialogTheme: const DialogTheme().copyWith(
backgroundColor: const Color.fromRGBO(250, 250, 250, 1.0), //
titleTextStyle: const TextStyle(
color: Colors.black,
@@ -150,7 +150,7 @@ final darkThemeData = ThemeData(
elevation: 0,
),
cardColor: const Color.fromRGBO(10, 15, 15, 1.0),
dialogTheme: const DialogThemeData().copyWith(
dialogTheme: const DialogTheme().copyWith(
backgroundColor: const Color.fromRGBO(15, 15, 15, 1.0),
titleTextStyle: const TextStyle(
color: Colors.white,
@@ -275,7 +275,7 @@ TextTheme _buildTextTheme(Color textColor) {
fontWeight: FontWeight.w500,
),
bodySmall: TextStyle(
color: textColor.withValues(alpha: 0.4),
color: textColor.withOpacity(0.4),
fontSize: 10,
fontWeight: FontWeight.w500,
),
@@ -343,7 +343,7 @@ extension CustomColorScheme on ColorScheme {
: const Color.fromRGBO(48, 48, 48, 0.5);
Color get iconColor => brightness == Brightness.light
? const Color.fromRGBO(0, 0, 0, 1).withValues(alpha: 0.75)
? const Color.fromRGBO(0, 0, 0, 1).withOpacity(0.75)
: const Color.fromRGBO(255, 255, 255, 1);
Color get bgColorForQuestions => brightness == Brightness.light
@@ -354,7 +354,7 @@ extension CustomColorScheme on ColorScheme {
Color get cupertinoPickerTopColor => brightness == Brightness.light
? const Color.fromARGB(255, 238, 238, 238)
: const Color.fromRGBO(255, 255, 255, 1).withValues(alpha: 0.1);
: const Color.fromRGBO(255, 255, 255, 1).withOpacity(0.1);
Color get stepProgressUnselectedColor => brightness == Brightness.light
? const Color.fromRGBO(196, 196, 196, 0.6)
@@ -381,20 +381,20 @@ extension CustomColorScheme on ColorScheme {
: const Color.fromRGBO(20, 20, 20, 1);
Color get galleryThumbDrawColor => brightness == Brightness.light
? const Color.fromRGBO(0, 0, 0, 1).withValues(alpha: 0.8)
: const Color.fromRGBO(255, 255, 255, 1).withValues(alpha: 0.5);
? const Color.fromRGBO(0, 0, 0, 1).withOpacity(0.8)
: const Color.fromRGBO(255, 255, 255, 1).withOpacity(0.5);
Color get backupEnabledBgColor => brightness == Brightness.light
? const Color.fromRGBO(230, 230, 230, 0.95)
: const Color.fromRGBO(10, 40, 40, 0.3);
Color get dotsIndicatorActiveColor => brightness == Brightness.light
? const Color.fromRGBO(0, 0, 0, 1).withValues(alpha: 0.5)
: const Color.fromRGBO(255, 255, 255, 1).withValues(alpha: 0.5);
? const Color.fromRGBO(0, 0, 0, 1).withOpacity(0.5)
: const Color.fromRGBO(255, 255, 255, 1).withOpacity(0.5);
Color get dotsIndicatorInactiveColor => brightness == Brightness.light
? const Color.fromRGBO(0, 0, 0, 1).withValues(alpha: 0.12)
: const Color.fromRGBO(255, 255, 255, 1).withValues(alpha: 0.12);
? const Color.fromRGBO(0, 0, 0, 1).withOpacity(0.12)
: const Color.fromRGBO(255, 255, 255, 1).withOpacity(0.12);
Color get toastTextColor => brightness == Brightness.light
? const Color.fromRGBO(255, 255, 255, 1)
@@ -409,8 +409,8 @@ extension CustomColorScheme on ColorScheme {
: const Color.fromRGBO(100, 100, 100, 1);
Color get themeSwitchInactiveIconColor => brightness == Brightness.light
? const Color.fromRGBO(0, 0, 0, 1).withValues(alpha: 0.5)
: const Color.fromRGBO(255, 255, 255, 1).withValues(alpha: 0.5);
? const Color.fromRGBO(0, 0, 0, 1).withOpacity(0.5)
: const Color.fromRGBO(255, 255, 255, 1).withOpacity(0.5);
Color get searchResultsColor => brightness == Brightness.light
? const Color.fromRGBO(245, 245, 245, 1.0)
@@ -421,8 +421,8 @@ extension CustomColorScheme on ColorScheme {
: const Color.fromRGBO(150, 150, 150, 1);
Color get searchResultsBackgroundColor => brightness == Brightness.light
? Colors.black.withValues(alpha: 0.32)
: Colors.black.withValues(alpha: 0.64);
? Colors.black.withOpacity(0.32)
: Colors.black.withOpacity(0.64);
Color get codeCardBackgroundColor => brightness == Brightness.light
? const Color.fromRGBO(246, 246, 246, 1)

View File

@@ -78,7 +78,6 @@
"contactSupport": "Звярнуцца ў службу падтрымкі",
"rateUsOnStore": "Ацаніць нас у {storeName}",
"blog": "Блог",
"merchandise": "Тавары",
"verifyPassword": "Праверыць пароль",
"pleaseWait": "Пачакайце...",
"generatingEncryptionKeysTitle": "Генерацыя ключоў шыфравання...",
@@ -86,9 +85,6 @@
"useRecoveryKey": "Выкарыстоўваць ключ аднаўлення",
"incorrectPasswordTitle": "Няправільны пароль",
"welcomeBack": "З вяртаннем!",
"emailAlreadyRegistered": "Электронная пошта ўжо зарэгістравана.",
"emailNotRegistered": "Электронная пошта не зарэгістравана.",
"madeWithLoveAtPrefix": "зроблена з ❤️ у ",
"changeEmail": "Змяніць адрас электроннай пошты",
"changePassword": "Змяніць пароль",
"data": "Даныя",
@@ -98,13 +94,9 @@
"passwordForDecryptingExport": "Пароль для дэшыфроўкі экспартавання",
"passwordEmptyError": "Пароль не можа быць пустым",
"importFromApp": "Імпартаваць коды з {appName}",
"importSelectJsonFile": "Выбраць файл JSON",
"importSelectAppExport": "Выберыце файл экспартавання {appName}",
"exportCodes": "Экспартаваць коды",
"importLabel": "Імпарт",
"selectFile": "Выбраць файл",
"emailVerificationToggle": "Праверка эл. пошты",
"authenticateGeneric": "Прайдзіце аўтэнтыфікацыю",
"ok": "OK",
"cancel": "Скасаваць",
"yes": "Так",
@@ -121,29 +113,19 @@
"enterYourPasswordHint": "Увядзіце ваш пароль",
"forgotPassword": "Забылі пароль",
"oops": "Вой",
"suggestFeatures": "Прапанаваць функцыю",
"faq": "Частыя пытанні",
"leaveFamily": "Пакінуць сямейны план",
"inFamilyPlanMessage": "Вы ўдзельнік сямейнага плана!",
"scan": "Сканіраваць",
"scanACode": "Сканіраваць код",
"verify": "Праверыць",
"verifyEmail": "Праверыць электронную пошту",
"lostDeviceTitle": "Згубілі прыладу?",
"twoFactorAuthTitle": "Двухфактарная аўтэнтыфікацыя",
"passkeyAuthTitle": "Праверка ключа доступу",
"verifyPasskey": "Праверыць ключ доступу",
"loginWithTOTP": "Увайсці з TOTP",
"recoverAccount": "Аднавіць уліковы запіс",
"enterRecoveryKeyHint": "Увядзіце свой ключ аднаўлення",
"recover": "Аднавіць",
"invalidQRCode": "Памылковы QR-код",
"noRecoveryKeyTitle": "Няма ключа аднаўлення?",
"enterEmailHint": "Увядзіце свой адрас электроннай пошты",
"enterNewEmailHint": "Увядзіце свой новы адрас электроннай пошты",
"invalidEmailTitle": "Памылковы адрас электроннай пошты",
"deleteAccount": "Выдаліць уліковы запіс",
"yesSendFeedbackAction": "Так. Адправіць водгук",
"noDeleteAccountAction": "Не, выдаліць уліковы запіс",
"sendEmail": "Адправіць ліст",
"createNewAccount": "Стварыць новы ўліковы запіс",
@@ -158,21 +140,16 @@
"social": "Сацыяльныя сеткі",
"security": "Бяспека",
"lockscreen": "Экран блакіроўкі",
"viewActiveSessions": "Паглядзець актыўныя сеансы",
"searchHint": "Пошук...",
"search": "Пошук",
"noResult": "Няма вынікаў",
"addCode": "Дадаць код",
"scanAQrCode": "Сканіраваць QR-код",
"enterDetailsManually": "Увесці падрабязнасці ўручную",
"edit": "Рэдагаваць",
"share": "Абагуліць",
"shareCodes": "Абагуліць коды",
"restore": "Аднавіць",
"copiedToClipboard": "Скапіявана ў буфер абмену",
"copiedNextToClipboard": "Скапіяваць наступны код у буфер абмену",
"error": "Памылка",
"recoveryKeyCopiedToClipboard": "Ключ аднаўлення скапіяваны ў буфер абмену",
"doThisLater": "Зрабіць гэта пазней",
"saveKey": "Захаваць ключ",
"save": "Захаваць",
@@ -187,27 +164,19 @@
"changePasswordTitle": "Змяніць пароль",
"resetPasswordTitle": "Скінуць пароль",
"encryptionKeys": "Ключы шыфравання",
"passwordChangedSuccessfully": "Пароль паспяхова зменены",
"generatingEncryptionKeys": "Генерацыя ключоў шыфравання...",
"continueLabel": "Працягнуць",
"insecureDevice": "Небяспечная прылада",
"howItWorks": "Як гэта працуе",
"logInLabel": "Увайсці",
"logout": "Выйсці",
"areYouSureYouWantToLogout": "Вы сапраўды хочаце выйсці?",
"yesLogout": "Так, выйсці",
"exit": "Выхад",
"theme": "Тема",
"lightTheme": "Светлая",
"darkTheme": "Цёмная",
"systemTheme": "Сістэманая",
"verifyingRecoveryKey": "Праверка ключа аднаўлення...",
"recoveryKeyVerified": "Ключ аднаўлення правераны",
"recreatePasswordTitle": "Стварыць пароль паўторна",
"invalidKey": "Памылковы ключ",
"tryAgain": "Паспрабуйце яшчэ раз",
"viewRecoveryKey": "Прагледзець ключ аднаўлення",
"confirmRecoveryKey": "Пацвердзіце ключ аднаўлення",
"confirmYourRecoveryKey": "Пацвердзіце свой ключ аднаўлення",
"confirm": "Пацвердзіць",
"emailYourLogs": "Адправіць журналы",
@@ -252,22 +221,15 @@
"pendingSyncs": "Папярэджанне",
"pendingSyncsWarningBody": "Некаторыя вашы коды не былі зарэзерваваны.\n\nПераканайцеся, што ў вас ёсць іх рэзервовая копія перад выхадам з сістэмы.",
"checkInboxAndSpamFolder": "Праверце свае ўваходныя лісты (і спам) для завяршэння праверкі",
"tapToEnterCode": "Націсніце, каб увесці код",
"resendEmail": "Адправіць ліст яшчэ раз",
"manualSort": "Карыстальніцкая",
"editOrder": "Рэдагаваць заказ",
"mostFrequentlyUsed": "Часта выкарыстоўваюцца",
"mostRecentlyUsed": "Нядаўна выкарыстаныя",
"activeSessions": "Актыўныя сеансы",
"terminateSession": "Перарваць сеанс?",
"terminate": "Перарваць",
"thisDevice": "Гэта прылада",
"thisEmailIsAlreadyInUse": "Гэта электронная пошта ўжо выкарыстоўваецца",
"yourVerificationCodeHasExpired": "Ваш праверачны код пратэрмінаваны",
"incorrectCode": "Няправільны код",
"emailChangedTo": "Электронная пошта зменена на {newEmail}",
"authenticationSuccessful": "Аўтэнтыфікацыя паспяхова пройдзена!",
"incorrectRecoveryKey": "Няправільны ключ аднаўлення",
"enterPassword": "Увядзіце пароль",
"selectExportFormat": "Выберыце фармат экспартавання",
"exportDialogDesc": "Зашыфраванае экспартаванне будзе абаронена паролем, які вы выберыце.",
@@ -287,18 +249,10 @@
"focusOnSearchBar": "Сфакусіравацца на пошуку пры запуску праграмы",
"confirmUpdatingkey": "Вы сапраўды хочаце абнавіць сакрэтны ключ?",
"minimizeAppOnCopy": "Згортваць праграму пры капіяванні",
"editCodeAuthMessage": "Прайдзіце аўтэнтыфікацыю, каб рэдагаваць код",
"deleteCodeAuthMessage": "Прайдзіце аўтэнтыфікацыю, каб выдаліць код",
"showQRAuthMessage": "Прайдзіце аўтэнтыфікацыю, каб паказаць QR-код",
"confirmAccountDeleteTitle": "Пацвердзіце выдаленне ўліковага запісу",
"androidBiometricHint": "Праверыць ідэнтыфікацыю",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
},
"androidBiometricNotRecognized": "Не распазнана. Паспрабуйце яшчэ раз.",
"@androidBiometricNotRecognized": {
"description": "Message to let the user know that authentication was failed. It is used on Android side. Maximum 60 characters."
},
"androidBiometricSuccess": "Паспяхова",
"@androidBiometricSuccess": {
"description": "Message to let the user know that authentication was successful. It is used on Android side. Maximum 60 characters."
@@ -307,22 +261,6 @@
"@androidCancelButton": {
"description": "Message showed on a button that the user can click to leave the current dialog. It is used on Android side. Maximum 30 characters."
},
"androidSignInTitle": "Патрабуецца аўтэнтыфікацыя",
"@androidSignInTitle": {
"description": "Message showed as a title in a dialog which indicates the user that they need to scan biometric to continue. It is used on Android side. Maximum 60 characters."
},
"androidBiometricRequiredTitle": "Патрабуецца біяметрыя",
"@androidBiometricRequiredTitle": {
"description": "Message showed as a title in a dialog which indicates the user has not set up biometric authentication on their device. It is used on Android side. Maximum 60 characters."
},
"androidDeviceCredentialsRequiredTitle": "Патрабуюцца ўліковыя даныя прылады",
"@androidDeviceCredentialsRequiredTitle": {
"description": "Message showed as a title in a dialog which indicates the user has not set up credentials authentication on their device. It is used on Android side. Maximum 60 characters."
},
"androidDeviceCredentialsSetupDescription": "Патрабуюцца ўліковыя даныя прылады",
"@androidDeviceCredentialsSetupDescription": {
"description": "Message advising the user to go to the settings and configure device credentials on their device. It shows in a dialog on Android side."
},
"goToSettings": "Перайсці ў налады",
"@goToSettings": {
"description": "Message showed on a button that the user can click to go to settings pages from the current dialog. It is used on both Android and iOS side. Maximum 30 characters."
@@ -331,24 +269,11 @@
"@iOSOkButton": {
"description": "Message showed on a button that the user can click to leave the current dialog. It is used on iOS side. Maximum 30 characters."
},
"noInternetConnection": "Адсутнічае падключэнне да інтэрнэту",
"signOutFromOtherDevices": "Выйсці з іншых прылад",
"signOutOtherDevices": "Выйсці на іншых прыладах",
"doNotSignOut": "Не выходзіць",
"waitingForBrowserRequest": "Чаканне запыту браўзера...",
"waitingForVerification": "Чаканне праверкі...",
"passkey": "Ключ доступу",
"passKeyPendingVerification": "Праверка пакуль яшчэ не завершана",
"loginSessionExpired": "Сеанс завяршыўся",
"developerSettings": "Налады распрацоўшчыка",
"serverEndpoint": "Канцавы пункт сервера",
"invalidEndpoint": "Памылковы канцавы пункт",
"endpointUpdatedMessage": "Канцавы пункт паспяхова абноўлены",
"customEndpoint": "Падключана да {endpoint}",
"pinText": "Замацаваць",
"unpinText": "Адмацаваць",
"pinnedCodeMessage": "{code} быў замацаваны",
"unpinnedCodeMessage": "{code} быў адмацаваны",
"pinned": "Замацавана",
"tags": "Тэгі",
"createNewTag": "Стварыць новы тэг",
@@ -356,38 +281,23 @@
"create": "Стварыць",
"editTag": "Рэдагаванне тэг",
"deleteTagTitle": "Выдаліць тэг?",
"updateNotAvailable": "Абнаўленне недаступна",
"viewRawCodes": "Паглядзець неапрацаваныя коды",
"rawCodes": "Неапрацаваныя коды",
"rawCodeData": "Неапрацаваныя даныя кода",
"appLock": "Блакіроўка праграмы",
"noSystemLockFound": "Сістэма блакіроўкі не знойдзена",
"autoLock": "Аўтаблакіроўка",
"immediately": "Адразу",
"reEnterPassword": "Увядзіце пароль паўторна",
"reEnterPin": "Увядзіце PIN-код яшчэ раз",
"next": "Далей",
"tooManyIncorrectAttempts": "Занадта шмат няўдалых спроб",
"tapToUnlock": "Націсніце для разблакіроўкі",
"setNewPassword": "Задаць новы пароль",
"deviceLock": "Блакіроўка прылады",
"hideContent": "Схаваць змест",
"pinLock": "Блакіроўка PIN'ам",
"enterPin": "Увядзіце PIN-код",
"setNewPin": "Задаць новы PIN",
"appLockNotEnabled": "Блакіроўка праграмы не ўключана",
"duplicateCodes": "Дублікаты кадоў",
"noDuplicates": "✨ Няма дублікатаў",
"deduplicateCodes": "Дубліраваныя кады",
"deselectAll": "Зняць выбар з усіх",
"selectAll": "Выбраць усе",
"deleteDuplicates": "Выдаліць дублікаты",
"plainHTML": "Звычайны HTML",
"tellUsWhatYouThink": "Раскажыце, што вы думаеце",
"dropReviewiOS": "Пакіньце водгук у App Store",
"dropReviewAndroid": "Пакіньце водгук у Play Store",
"giveUsAStarOnGithub": "Адзначце нас зоркай на Github",
"loginWithAuthAccount": "Увайдзіце з дапамогай уліковага запісу Auth",
"advanced": "Пашыраныя",
"algorithm": "Алгарытм",
"type": "Тып",

View File

@@ -173,7 +173,6 @@
"invalidQRCode": "Código QR no válido",
"noRecoveryKeyTitle": "¿No tienes la clave de recuperación?",
"enterEmailHint": "Introduce tu dirección de correo electrónico",
"enterNewEmailHint": "Introduce tu nueva dirección de correo electrónico",
"invalidEmailTitle": "Dirección de correo electrónico no válida",
"invalidEmailMessage": "Por favor, introduce una dirección de correo electrónico válida.",
"deleteAccount": "Eliminar cuenta",
@@ -514,10 +513,5 @@
"free5GB": "5 GB gratis en <bold-green>ente</bold-green> Fotos",
"loginWithAuthAccount": "Inicia sesión con tu cuenta de Auth",
"freeStorageOffer": "10% de descuento en <bold-green>ente</bold-green> fotos",
"freeStorageOfferDescription": "Usa el cupón \"AUTH\" para obtener un 10% de descuento en el primer año",
"advanced": "Avanzado",
"algorithm": "Algoritmo",
"type": "Tipo",
"period": "Periodo",
"digits": "Dígitos"
"freeStorageOfferDescription": "Usa el cupón \"AUTH\" para obtener un 10% de descuento en el primer año"
}

View File

@@ -11,7 +11,6 @@
"setupFirstAccount": "Lisa oma esimene kasutajakonto",
"importScanQrCode": "Skanneeri QR-koodi",
"qrCode": "QR-kood",
"importEnterSetupKey": "Sisesta seadistusvõti",
"importAccountPageTitle": "Sisesta kasutajakonto üksikasjad",
"secretCanNotBeEmpty": "Saladus ei tohi jääda tühjaks",
"bothIssuerAndAccountCanNotBeEmpty": "Nii kasutajakonto kui väljaandja ei tohi tühjaks jääda",
@@ -33,7 +32,6 @@
}
}
},
"codeAccountHint": "Kasutajakonto (sina@domeen.com)",
"codeTagHint": "Silt",
"accountKeyType": "Võtme tüüp",
"sessionExpired": "Sessioon on aegunud",
@@ -42,12 +40,7 @@
},
"pleaseLoginAgain": "Palun logi uuesti sisse",
"loggingOut": "Väljalogimine...",
"timeBasedKeyType": "Ajapõhine (TOTP)",
"counterBasedKeyType": "Loenduripõhine (HOTP)",
"saveAction": "Salvesta",
"nextTotpTitle": "järgmine",
"deleteCodeTitle": "Kas kustutame koodi?",
"deleteCodeMessage": "Kas sa oled kindel, et soovid selle koodi kustutada? Seda tegevust ei saa tagasi pöörata.",
"trash": "Prügikast",
"viewLogsAction": "Vaata logisid",
"preparingLogsTitle": "Valmistan logisid ette...",
@@ -63,18 +56,7 @@
"copyEmailAction": "Kopeeri e-posti aadress",
"exportLogsAction": "Ekspordi logid",
"reportABug": "Teata veast",
"crashAndErrorReporting": "Teatamine vigadest ja kokkujooksmistest",
"reportBug": "Teata veast",
"emailUsMessage": "Saada meile e-kiri aadressile {email}",
"@emailUsMessage": {
"placeholders": {
"email": {
"type": "String"
}
}
},
"contactSupport": "Võta ühendust klienditoega",
"rateUsOnStore": "Arvusta meid rakendustepoes: {storeName}",
"contactSupport": "Võtke ühendust klienditoega",
"blog": "Blogi",
"verifyPassword": "Korda salasõna",
"pleaseWait": "Palun oota...",
@@ -88,13 +70,8 @@
"changeEmail": "Muuda e-posti aadressi",
"changePassword": "Muuda salasõna",
"data": "Andmed",
"importCodes": "Impordi koode",
"importTypePlainText": "Votmindamata tekstina",
"importTypeEnteEncrypted": "Ente krüptitud ekspordina",
"passwordForDecryptingExport": "Salasõna eksporditud andmete dekrüptimiseks",
"passwordEmptyError": "Salasõna väli ei saa olla tühi",
"importFromApp": "Impordi koodid rakendusest {appName}",
"selectFile": "Vali fail",
"ok": "Sobib",
"cancel": "Katkesta",
"yes": "Jah",

View File

@@ -506,7 +506,7 @@
"selectAll": "Chọn tất cả",
"deleteDuplicates": "Xóa trùng lặp",
"plainHTML": "HTML thuần",
"tellUsWhatYouThink": "Cho biết bạn nghĩ gì",
"tellUsWhatYouThink": "Hãy cho chúng tôi biết bạn nghĩ gì",
"dropReviewiOS": "Đánh giá ngay trên App Store",
"dropReviewAndroid": "Đánh giá ngay trên Play Store",
"supportEnte": "Hỗ trợ <bold-green>ente</bold-green>",

View File

@@ -1,8 +1,7 @@
import "package:ente_auth/l10n/arb/app_localizations.dart"
show AppLocalizations;
import "package:flutter/widgets.dart";
export "package:ente_auth/l10n/arb/app_localizations.dart"
show AppLocalizations;
import "package:flutter_gen/gen_l10n/app_localizations.dart";
export "package:flutter_gen/gen_l10n/app_localizations.dart";
extension AppLocalizationsX on BuildContext {
AppLocalizations get l10n => AppLocalizations.of(this);

View File

@@ -2,7 +2,7 @@ import 'dart:convert';
class BillingPlans {
final List<BillingPlan> plans;
final FreePlan? freePlan;
final FreePlan freePlan;
BillingPlans({
required this.plans,
@@ -12,12 +12,12 @@ class BillingPlans {
Map<String, dynamic> toMap() {
return {
'plans': plans.map((x) => x.toMap()).toList(),
'freePlan': freePlan?.toMap(),
'freePlan': freePlan.toMap(),
};
}
static BillingPlans fromMap(Map<String, dynamic>? map) {
if (map == null) return BillingPlans(plans: [], freePlan: null);
static fromMap(Map<String, dynamic>? map) {
if (map == null) return null;
return BillingPlans(
plans: List<BillingPlan>.from(
@@ -49,7 +49,7 @@ class FreePlan {
};
}
static FreePlan? fromMap(Map<String, dynamic>? map) {
static fromMap(Map<String, dynamic>? map) {
if (map == null) return null;
return FreePlan(
@@ -91,7 +91,7 @@ class BillingPlan {
};
}
static BillingPlan? fromMap(Map<String, dynamic>? map) {
static fromMap(Map<String, dynamic>? map) {
if (map == null) return null;
return BillingPlan(

View File

@@ -332,7 +332,7 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
},
);
},
barrierColor: Colors.black.withValues(alpha: 0.85),
barrierColor: Colors.black.withOpacity(0.85),
barrierDismissible: false,
);
},

View File

@@ -75,7 +75,7 @@ class CodeDisplayStore {
builder: (BuildContext context) {
return EditTagDialog(tag: tag);
},
barrierColor: Colors.black.withValues(alpha: 0.85),
barrierColor: Colors.black.withOpacity(0.85),
barrierDismissible: false,
);
}

View File

@@ -147,13 +147,12 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
),
),
child: DottedBorder(
options: const RoundedRectDottedBorderOptions(
padding: EdgeInsets.zero,
strokeWidth: 1,
color: Color(0xFF6B6B6B),
dashPattern: [6, 6],
radius: Radius.circular(8),
),
padding: EdgeInsets.zero,
borderType: BorderType.RRect,
strokeWidth: 1,
color: const Color(0xFF6B6B6B),
dashPattern: const [6, 6],
radius: const Radius.circular(8),
child: SizedBox(
width: double.infinity,
child: Stack(
@@ -315,13 +314,7 @@ class _RecoveryKeyPageState extends State<RecoveryKeyPage> {
await _recoveryKeyFile.delete();
}
_recoveryKeyFile.writeAsStringSync(recoveryKey);
await SharePlus.instance.share(
ShareParams(
files: [
XFile(_recoveryKeyFile.path),
],
),
);
await Share.shareXFiles([XFile(_recoveryKeyFile.path)]);
Future.delayed(const Duration(milliseconds: 500), () {
if (mounted) {
setState(() {

View File

@@ -82,7 +82,7 @@ class _SessionsPageState extends State<SessionsPage> {
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.8),
.withOpacity(0.8),
fontSize: 14,
),
),
@@ -95,7 +95,7 @@ class _SessionsPageState extends State<SessionsPage> {
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.8),
.withOpacity(0.8),
fontSize: 12,
),
),

View File

@@ -54,12 +54,12 @@ class BannerWidget extends StatelessWidget {
dashColor = const Color.fromRGBO(255, 191, 12, 1);
boxShadow = [
BoxShadow(
color: const Color(0xFFFDB816).withValues(alpha: 0.1),
color: const Color(0xFFFDB816).withOpacity(0.1),
blurRadius: 50,
spreadRadius: 80,
),
BoxShadow(
color: const Color(0xFFFDB816).withValues(alpha: 0.2),
color: const Color(0xFFFDB816).withOpacity(0.2),
blurRadius: 25,
),
];
@@ -71,13 +71,12 @@ class BannerWidget extends StatelessWidget {
dashColor = const Color.fromRGBO(233, 233, 233, 1);
boxShadow = [
BoxShadow(
color: const Color.fromRGBO(78, 78, 78, 1).withValues(alpha: 0.2),
color: const Color.fromRGBO(78, 78, 78, 1).withOpacity(0.2),
blurRadius: 50,
spreadRadius: 100,
),
BoxShadow(
color:
const Color.fromRGBO(23, 22, 22, 0.30).withValues(alpha: 0.1),
color: const Color.fromRGBO(23, 22, 22, 0.30).withOpacity(0.1),
blurRadius: 25,
),
];
@@ -88,12 +87,12 @@ class BannerWidget extends StatelessWidget {
dashColor = const Color.fromRGBO(29, 185, 84, 1);
boxShadow = [
BoxShadow(
color: const Color.fromRGBO(38, 203, 95, 1).withValues(alpha: 0.08),
color: const Color.fromRGBO(38, 203, 95, 1).withOpacity(0.08),
blurRadius: 50,
spreadRadius: 100,
),
BoxShadow(
color: const Color.fromRGBO(0, 0, 0, 0.50).withValues(alpha: 0.08),
color: const Color.fromRGBO(0, 0, 0, 0.50).withOpacity(0.08),
blurRadius: 25,
),
];
@@ -104,12 +103,12 @@ class BannerWidget extends StatelessWidget {
imagePath = "assets/discount.png";
boxShadow = [
BoxShadow(
color: const Color.fromRGBO(38, 203, 95, 1).withValues(alpha: 0.08),
color: const Color.fromRGBO(38, 203, 95, 1).withOpacity(0.08),
blurRadius: 50,
spreadRadius: 100,
),
BoxShadow(
color: const Color.fromRGBO(0, 0, 0, 0.50).withValues(alpha: 0.08),
color: const Color.fromRGBO(0, 0, 0, 0.50).withOpacity(0.08),
blurRadius: 25,
),
];
@@ -122,11 +121,10 @@ class BannerWidget extends StatelessWidget {
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(50)),
child: DottedBorder(
options: RoundedRectDottedBorderOptions(
radius: const Radius.circular(50),
dashPattern: <double>[3, 3],
color: dashColor,
),
borderType: BorderType.RRect,
radius: const Radius.circular(50),
dashPattern: const <double>[3, 3],
color: dashColor,
child: Stack(
children: [
if (BannerType.starUs == type)

View File

@@ -28,7 +28,7 @@ class CustomIconWidget extends StatelessWidget {
width: 1.5,
color: getEnteColorScheme(context)
.tagChipSelectedColor
.withValues(alpha: 0.5),
.withOpacity(0.5),
),
borderRadius: SmoothBorderRadius(
cornerRadius: 15.5,
@@ -102,7 +102,7 @@ class CustomIconWidget extends StatelessWidget {
child: Icon(
Icons.edit,
size: 16,
color: Colors.black.withValues(alpha: 0.9),
color: Colors.black.withOpacity(0.9),
),
),
),

View File

@@ -52,7 +52,7 @@ class NotificationWidget extends StatelessWidget {
subTextStyle = textTheme.miniMuted;
strokeColorScheme = colorScheme;
boxShadow = [
BoxShadow(color: Colors.black.withValues(alpha: 0.25), blurRadius: 1),
BoxShadow(color: Colors.black.withOpacity(0.25), blurRadius: 1),
];
break;

View File

@@ -123,7 +123,7 @@ class TitleBarWidget extends StatelessWidget {
);
}
List<Widget> _actionsWithPaddingInBetween() {
_actionsWithPaddingInBetween() {
if (actionIcons == null) {
return <Widget>[const SizedBox.shrink()];
}
@@ -135,7 +135,7 @@ class TitleBarWidget extends StatelessWidget {
return <Widget>[const SizedBox.shrink()];
}
if (length == 1) {
return actionIcons!;
return actionIcons;
}
while (index < length) {
if (!addWhiteSpace) {

View File

@@ -1,7 +1,6 @@
import 'package:ente_auth/ente_theme_data.dart';
import 'package:ente_auth/models/execution_states.dart';
import 'package:ente_auth/models/typedefs.dart';
import 'package:ente_auth/theme/colors.dart';
import 'package:ente_auth/ui/common/loading_widget.dart';
import 'package:ente_auth/utils/debouncer.dart';
import 'package:flutter/material.dart';
@@ -105,7 +104,7 @@ class _ToggleSwitchWidgetState extends State<ToggleSwitchWidget> {
);
}
Widget _stateIcon(EnteColorScheme enteColorScheme) {
Widget _stateIcon(enteColorScheme) {
if (executionState == ExecutionState.idle) {
return const SizedBox(width: 24);
} else if (executionState == ExecutionState.inProgress) {

View File

@@ -23,8 +23,7 @@ class CoachMarkWidget extends StatelessWidget {
Expanded(
child: Container(
width: double.infinity,
color:
Theme.of(context).colorScheme.surface.withValues(alpha: 0.1),
color: Theme.of(context).colorScheme.surface.withOpacity(0.1),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 8, sigmaY: 8),
child: Row(

View File

@@ -77,7 +77,7 @@ class AboutSectionWidget extends StatelessWidget {
UpdateService.instance.getLatestVersionInfo(),
);
},
barrierColor: Colors.black.withValues(alpha: 0.85),
barrierColor: Colors.black.withOpacity(0.85),
);
} else {
showShortToast(

View File

@@ -56,7 +56,7 @@ class AccountSectionWidget extends StatelessWidget {
builder: (BuildContext context) {
return const ChangeEmailDialog();
},
barrierColor: Colors.black.withValues(alpha: 0.85),
barrierColor: Colors.black.withOpacity(0.85),
barrierDismissible: false,
);
}

View File

@@ -83,7 +83,7 @@ class _DuplicateCodePageState extends State<DuplicateCodePage> {
color: Theme.of(context)
.iconTheme
.color!
.withValues(alpha: 0.7),
.withOpacity(0.7),
),
),
const Padding(padding: EdgeInsets.only(left: 4)),

View File

@@ -170,14 +170,9 @@ Future<void> _exportCodes(
}
codeFile.writeAsStringSync(fileContent);
final Size size = MediaQuery.of(context).size;
await SharePlus.instance.share(
ShareParams(
files: <XFile>[
XFile(codeFile.path, mimeType: 'text/plain'),
],
sharePositionOrigin:
Rect.fromLTWH(0, 0, size.width, size.height / 2),
),
await Share.shareXFiles(
[XFile(codeFile.path)],
sharePositionOrigin: Rect.fromLTWH(0, 0, size.width, size.height / 2),
);
Future.delayed(const Duration(seconds: 30), () async {
if (codeFile.existsSync()) {

View File

@@ -116,10 +116,10 @@ class _LockScreenConfirmPasswordState extends State<LockScreenConfirmPassword> {
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [
Colors.grey.shade500.withValues(alpha: 0.2),
Colors.grey.shade50.withValues(alpha: 0.1),
Colors.grey.shade400.withValues(alpha: 0.2),
Colors.grey.shade300.withValues(alpha: 0.4),
Colors.grey.shade500.withOpacity(0.2),
Colors.grey.shade50.withOpacity(0.1),
Colors.grey.shade400.withOpacity(0.2),
Colors.grey.shade300.withOpacity(0.4),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,

View File

@@ -1,9 +1,7 @@
import "dart:io";
import "package:ente_auth/l10n/l10n.dart";
import "package:ente_auth/theme/colors.dart";
import "package:ente_auth/theme/ente_theme.dart";
import "package:ente_auth/theme/text_style.dart";
import "package:ente_auth/ui/settings/lock_screen/custom_pin_keypad.dart";
import "package:ente_auth/utils/lock_screen_settings.dart";
import "package:flutter/material.dart";
@@ -91,7 +89,7 @@ class _LockScreenConfirmPinState extends State<LockScreenConfirmPin> {
);
}
Widget _getBody(EnteColorScheme colorTheme, EnteTextTheme textTheme) {
Widget _getBody(colorTheme, textTheme) {
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
@@ -109,10 +107,10 @@ class _LockScreenConfirmPinState extends State<LockScreenConfirmPin> {
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [
Colors.grey.shade500.withValues(alpha: 0.2),
Colors.grey.shade50.withValues(alpha: 0.1),
Colors.grey.shade400.withValues(alpha: 0.2),
Colors.grey.shade300.withValues(alpha: 0.4),
Colors.grey.shade500.withOpacity(0.2),
Colors.grey.shade50.withOpacity(0.1),
Colors.grey.shade400.withOpacity(0.2),
Colors.grey.shade300.withOpacity(0.4),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,

View File

@@ -127,10 +127,10 @@ class _LockScreenPasswordState extends State<LockScreenPassword> {
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [
Colors.grey.shade500.withValues(alpha: 0.2),
Colors.grey.shade50.withValues(alpha: 0.1),
Colors.grey.shade400.withValues(alpha: 0.2),
Colors.grey.shade300.withValues(alpha: 0.4),
Colors.grey.shade500.withOpacity(0.2),
Colors.grey.shade50.withOpacity(0.1),
Colors.grey.shade400.withOpacity(0.2),
Colors.grey.shade300.withOpacity(0.4),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,

View File

@@ -178,10 +178,10 @@ class _LockScreenPinState extends State<LockScreenPin> {
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [
Colors.grey.shade500.withValues(alpha: 0.2),
Colors.grey.shade50.withValues(alpha: 0.1),
Colors.grey.shade400.withValues(alpha: 0.2),
Colors.grey.shade300.withValues(alpha: 0.4),
Colors.grey.shade500.withOpacity(0.2),
Colors.grey.shade50.withOpacity(0.1),
Colors.grey.shade400.withOpacity(0.2),
Colors.grey.shade300.withOpacity(0.4),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,

View File

@@ -43,7 +43,7 @@ class _SupportSectionWidgetState extends State<SupportSectionWidget> {
trailingIconIsMuted: true,
onTap: () async {
try {
await PlatformUtil.openWebView(
PlatformUtil.openWebView(
context,
context.l10n.faq,
"https://help.ente.io/auth/faq",

View File

@@ -35,7 +35,7 @@ class SortCodeMenuWidget extends StatelessWidget {
text,
style: Theme.of(context).textTheme.titleMedium!.copyWith(
fontSize: 14,
color: Theme.of(context).iconTheme.color!.withValues(alpha: 0.7),
color: Theme.of(context).iconTheme.color!.withOpacity(0.7),
),
);
}

View File

@@ -1,9 +1,9 @@
import 'dart:async';
import 'package:ente_auth/l10n/l10n.dart';
import 'package:ente_auth/locale.dart';
import 'package:ente_auth/utils/lock_screen_settings.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
/// A widget which handles app lifecycle events for showing and hiding a lock screen.
/// This should wrap around a `MyApp` widget (or equivalent).

View File

@@ -96,10 +96,10 @@ class _LockScreenState extends State<LockScreen> with WidgetsBindingObserver {
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [
Colors.grey.shade500.withValues(alpha: 0.2),
Colors.grey.shade50.withValues(alpha: 0.1),
Colors.grey.shade400.withValues(alpha: 0.2),
Colors.grey.shade300.withValues(alpha: 0.4),
Colors.grey.shade500.withOpacity(0.2),
Colors.grey.shade50.withOpacity(0.1),
Colors.grey.shade400.withOpacity(0.2),
Colors.grey.shade300.withOpacity(0.4),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,

View File

@@ -98,9 +98,8 @@ class _TwoFactorRecoveryPageState extends State<TwoFactorRecoveryPage> {
style: TextStyle(
decoration: TextDecoration.underline,
fontSize: 12,
color: getEnteColorScheme(context)
.textBase
.withValues(alpha: 0.9),
color:
getEnteColorScheme(context).textBase.withOpacity(0.9),
),
),
),

View File

@@ -180,7 +180,7 @@ Future<ButtonResult?> showGenericErrorDialog({
context,
context.l10n.faq,
"https://help.ente.io/auth/troubleshooting/windows-login",
).ignore();
);
},
),
ButtonWidget(

View File

@@ -34,7 +34,7 @@ class DirectoryUtils {
}
static String migratedNamingChanges = "migrated_naming_changes.b5";
static Future<void> migrateNamingChanges() async {
static migrateNamingChanges() async {
try {
final sharedPrefs = await SharedPreferences.getInstance();
if (sharedPrefs.containsKey(migratedNamingChanges)) {
@@ -57,7 +57,7 @@ class DirectoryUtils {
Directory oldDataDir;
Directory newDataDir = await getApplicationSupportDirectory();
await newDataDir.create(recursive: true);
if (Platform.isLinux) {
oldDataDir = Directory(
p.join(dataHome.path, "ente_auth"),

View File

@@ -232,13 +232,9 @@ Future<void> exportLogs(
MimeType.zip,
);
} else {
await SharePlus.instance.share(
ShareParams(
files: <XFile>[
XFile(zipFilePath, mimeType: 'application/zip'),
],
sharePositionOrigin: Rect.fromLTWH(0, 0, size.width, size.height / 2),
),
await Share.shareXFiles(
[XFile(zipFilePath, mimeType: 'application/zip')],
sharePositionOrigin: Rect.fromLTWH(0, 0, size.width, size.height / 2),
);
}
}

View File

@@ -28,11 +28,7 @@ class PlatformUtil {
? cupertinoTextSelectionControls
: desktopTextSelectionControls;
static Future<void> openWebView(
BuildContext context,
String title,
String url,
) async {
static openWebView(BuildContext context, String title, String url) async {
if (PlatformUtil.isDesktop()) {
await launchUrlString(url);
return;

View File

@@ -91,11 +91,9 @@ Future<ShareResult> shareText(
}) async {
try {
final sharePosOrigin = _sharePosOrigin(context, key);
return SharePlus.instance.share(
ShareParams(
text: text,
sharePositionOrigin: sharePosOrigin,
),
return Share.share(
text,
sharePositionOrigin: sharePosOrigin,
);
} catch (e, s) {
Logger("ShareUtil").severe("failed to share text", e, s);

View File

@@ -47,6 +47,6 @@ void showToast(
}
}
void showShortToast(BuildContext context, String message) {
void showShortToast(context, String message) {
showToast(context, message, toastLength: Toast.LENGTH_SHORT);
}

View File

@@ -36,7 +36,7 @@ class WindowsProtocolHandler {
hKey,
txtKey,
txtValue,
REG_SZ,
REG_VALUE_TYPE.REG_SZ,
txtData,
txtData.length * 2 + 2,
);

View File

@@ -10,7 +10,7 @@
#include <flutter_local_authentication/flutter_local_authentication_plugin.h>
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
#include <gtk/gtk_plugin.h>
#include <screen_retriever_linux/screen_retriever_linux_plugin.h>
#include <screen_retriever/screen_retriever_plugin.h>
#include <sentry_flutter/sentry_flutter_plugin.h>
#include <sodium_libs/sodium_libs_plugin.h>
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
@@ -31,9 +31,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) gtk_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin");
gtk_plugin_register_with_registrar(gtk_registrar);
g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin");
screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar);
g_autoptr(FlPluginRegistrar) screen_retriever_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
g_autoptr(FlPluginRegistrar) sentry_flutter_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "SentryFlutterPlugin");
sentry_flutter_plugin_register_with_registrar(sentry_flutter_registrar);

View File

@@ -7,7 +7,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
flutter_local_authentication
flutter_secure_storage_linux
gtk
screen_retriever_linux
screen_retriever
sentry_flutter
sodium_libs
sqlite3_flutter_libs

View File

@@ -18,8 +18,6 @@
</screenshot>
</screenshots>
<releases>
<release version="4.4.3" date="2025-06-21" />
<release version="4.4.2" date="2025-06-21" />
<release version="4.4.0" date="2025-05-31" />
<release version="4.3.8" date="2025-05-20" />
<release version="4.2.4" date="2025-01-11" />

View File

@@ -8,7 +8,6 @@ import Foundation
import app_links
import connectivity_plus
import device_info_plus
import file_picker
import file_saver
import flutter_inappwebview_macos
import flutter_local_authentication
@@ -17,12 +16,12 @@ import flutter_secure_storage_macos
import local_auth_darwin
import package_info_plus
import path_provider_foundation
import screen_retriever_macos
import screen_retriever
import sentry_flutter
import share_plus
import shared_preferences_foundation
import sodium_libs
import sqflite_darwin
import sqflite
import sqlite3_flutter_libs
import tray_manager
import url_launcher_macos
@@ -32,16 +31,15 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
FileSaverPlugin.register(with: registry.registrar(forPlugin: "FileSaverPlugin"))
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
FlutterLocalAuthenticationPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalAuthenticationPlugin"))
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
LocalAuthPlugin.register(with: registry.registrar(forPlugin: "LocalAuthPlugin"))
FLALocalAuthPlugin.register(with: registry.registrar(forPlugin: "FLALocalAuthPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin"))
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))

View File

@@ -2,14 +2,13 @@ PODS:
- app_links (1.0.0):
- FlutterMacOS
- connectivity_plus (0.0.1):
- Flutter
- FlutterMacOS
- cupertino_http (0.0.1):
- Flutter
- FlutterMacOS
- device_info_plus (0.0.1):
- FlutterMacOS
- file_picker (0.0.1):
- FlutterMacOS
- file_saver (0.0.1):
- FlutterMacOS
- flutter_inappwebview_macos (0.0.1):
@@ -19,7 +18,7 @@ PODS:
- FlutterMacOS
- flutter_local_notifications (0.0.1):
- FlutterMacOS
- flutter_secure_storage_macos (6.1.3):
- flutter_secure_storage_macos (6.1.1):
- FlutterMacOS
- FlutterMacOS (1.0.0)
- local_auth_darwin (0.0.1):
@@ -33,7 +32,7 @@ PODS:
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- screen_retriever_macos (0.0.1):
- screen_retriever (0.0.1):
- FlutterMacOS
- Sentry/HybridSDK (8.46.0)
- sentry_flutter (8.14.2):
@@ -47,44 +46,39 @@ PODS:
- FlutterMacOS
- sodium_libs (2.2.1):
- FlutterMacOS
- sqflite_darwin (0.0.4):
- sqflite (0.0.3):
- Flutter
- FlutterMacOS
- sqlite3 (3.50.1):
- sqlite3/common (= 3.50.1)
- sqlite3/common (3.50.1)
- sqlite3/dbstatvtab (3.50.1):
- "sqlite3 (3.46.1+1)":
- "sqlite3/common (= 3.46.1+1)"
- "sqlite3/common (3.46.1+1)"
- "sqlite3/dbstatvtab (3.46.1+1)":
- sqlite3/common
- sqlite3/fts5 (3.50.1):
- "sqlite3/fts5 (3.46.1+1)":
- sqlite3/common
- sqlite3/math (3.50.1):
- "sqlite3/perf-threadsafe (3.46.1+1)":
- sqlite3/common
- sqlite3/perf-threadsafe (3.50.1):
- sqlite3/common
- sqlite3/rtree (3.50.1):
- "sqlite3/rtree (3.46.1+1)":
- sqlite3/common
- sqlite3_flutter_libs (0.0.1):
- Flutter
- FlutterMacOS
- sqlite3 (~> 3.50.1)
- "sqlite3 (~> 3.46.0+1)"
- sqlite3/dbstatvtab
- sqlite3/fts5
- sqlite3/math
- sqlite3/perf-threadsafe
- sqlite3/rtree
- tray_manager (0.0.1):
- FlutterMacOS
- url_launcher_macos (0.0.1):
- FlutterMacOS
- window_manager (0.5.0):
- window_manager (0.2.0):
- FlutterMacOS
DEPENDENCIES:
- app_links (from `Flutter/ephemeral/.symlinks/plugins/app_links/macos`)
- connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`)
- connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin`)
- cupertino_http (from `Flutter/ephemeral/.symlinks/plugins/cupertino_http/darwin`)
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
- file_picker (from `Flutter/ephemeral/.symlinks/plugins/file_picker/macos`)
- file_saver (from `Flutter/ephemeral/.symlinks/plugins/file_saver/macos`)
- flutter_inappwebview_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos`)
- flutter_local_authentication (from `Flutter/ephemeral/.symlinks/plugins/flutter_local_authentication/macos`)
@@ -95,13 +89,13 @@ DEPENDENCIES:
- objective_c (from `Flutter/ephemeral/.symlinks/plugins/objective_c/macos`)
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
- screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`)
- screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`)
- sentry_flutter (from `Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos`)
- share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- sodium_libs (from `Flutter/ephemeral/.symlinks/plugins/sodium_libs/macos`)
- sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`)
- sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin`)
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`)
- sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos`)
- tray_manager (from `Flutter/ephemeral/.symlinks/plugins/tray_manager/macos`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)
@@ -116,13 +110,11 @@ EXTERNAL SOURCES:
app_links:
:path: Flutter/ephemeral/.symlinks/plugins/app_links/macos
connectivity_plus:
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin
cupertino_http:
:path: Flutter/ephemeral/.symlinks/plugins/cupertino_http/darwin
device_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
file_picker:
:path: Flutter/ephemeral/.symlinks/plugins/file_picker/macos
file_saver:
:path: Flutter/ephemeral/.symlinks/plugins/file_saver/macos
flutter_inappwebview_macos:
@@ -143,8 +135,8 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
screen_retriever_macos:
:path: Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos
screen_retriever:
:path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos
sentry_flutter:
:path: Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos
share_plus:
@@ -153,10 +145,10 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
sodium_libs:
:path: Flutter/ephemeral/.symlinks/plugins/sodium_libs/macos
sqflite_darwin:
:path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin
sqflite:
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/darwin
sqlite3_flutter_libs:
:path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin
:path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos
tray_manager:
:path: Flutter/ephemeral/.symlinks/plugins/tray_manager/macos
url_launcher_macos:
@@ -165,34 +157,33 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos
SPEC CHECKSUMS:
app_links: afe860c55c7ef176cea7fb630a2b7d7736de591d
connectivity_plus: 4adf20a405e25b42b9c9f87feff8f4b6fde18a4e
app_links: 9028728e32c83a0831d9db8cf91c526d16cc5468
connectivity_plus: 3f6c9057f4cd64198dc826edfb0542892f825343
cupertino_http: 94ac07f5ff090b8effa6c5e2c47871d48ab7c86c
device_info_plus: b0fafc687fb901e2af612763340f1b0d4352f8e5
file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a
file_saver: e35bd97de451dde55ff8c38862ed7ad0f3418d0f
flutter_inappwebview_macos: c2d68649f9f8f1831bfcd98d73fd6256366d9d1d
flutter_local_authentication: 2f9a2682f498abcc12d7e9729b5007a947170fdc
flutter_local_notifications: 13862b132e32eb858dea558a86d45d08daeacfe7
flutter_secure_storage_macos: 7f45e30f838cf2659862a4e4e3ee1c347c2b3b54
flutter_local_notifications: 453432cd6399a07d072885bc7828fb2307868856
flutter_secure_storage_macos: b2d62a774c23b060f0b99d0173b0b36abb4a8632
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
local_auth_darwin: d2e8c53ef0c4f43c646462e3415432c4dab3ae19
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
objective_c: ec13431e45ba099cb734eb2829a5c1cd37986cba
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: f0052d280d17aa382b932f399edf32507174e870
package_info_plus: a8a591e70e87ce97ce5d21b2594f69cea9e0312f
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f
screen_retriever: 4f97c103641aab8ce183fa5af3b87029df167936
Sentry: da60d980b197a46db0b35ea12cb8f39af48d8854
sentry_flutter: 27892878729f42701297c628eb90e7c6529f3684
share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc
share_plus: 11c7b7fa7020465584eca3ff6392c5bc1e399d6e
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sodium_libs: b9459e5bfc1185349f43472e79fc5d8e526b2bda
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
sqlite3: 1d85290c3321153511f6e900ede7a1608718bbd5
sqlite3_flutter_libs: e7fc8c9ea2200ff3271f08f127842131746b70e2
sqflite: c35dad70033b8862124f8337cc994a809fcd9fa3
sqlite3: 0bb0e6389d824e40296f531b858a2a0b71c0d2fb
sqlite3_flutter_libs: 03311aede9d32fb2d24e32bebb8cd01c3b2e6239
tray_manager: a104b5c81b578d83f3c3d0f40a997c8b10810166
url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673
window_manager: b729e31d38fb04905235df9ea896128991cad99e
window_manager: 1d01fa7ac65a6e6f83b965471b1a7fdd3f06166c
PODFILE CHECKSUM: 6ff827273ace187339fc5d3684072a26ad85c298

View File

@@ -48,7 +48,6 @@
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
name: ente_auth
description: ente two-factor authenticator
version: 4.4.3+443
version: 4.4.1+441
publish_to: none
environment:
@@ -10,11 +10,11 @@ environment:
dependencies:
adaptive_theme: ^3.1.0 # done
app_links: ^6.3.3
archive: ^4.0.7
archive: ^3.3.7
auto_size_text: ^3.0.0
base32: ^2.1.3
bip39: ^1.0.6 #done
bloc: ^9.0.0
bloc: ^8.1.2
clipboard: ^0.1.3
collection: ^1.18.0 # dart
confetti: ^0.8.0
@@ -22,7 +22,7 @@ dependencies:
convert: ^3.1.1
device_info_plus: ^9.1.1
dio: ^5.8.0+1
dotted_border: ^3.1.0
dotted_border: ^2.0.0+2
dropdown_button2: ^2.3.9
email_validator: ^3.0.0
ente_crypto_dart:
@@ -32,19 +32,19 @@ dependencies:
expandable: ^5.0.1
expansion_tile_card: ^3.0.0
ffi: ^2.1.0
figma_squircle: ^0.6.3
file_picker: ^10.2.0
figma_squircle: ^0.5.3
file_picker: ^8.1.7
# https://github.com/incrediblezayed/file_saver/issues/86
file_saver: ^0.3.0
file_saver: ^0.2.11
fixnum: ^1.1.0
fk_user_agent: ^2.1.0
flutter:
sdk: flutter
flutter_animate: ^4.1.0
flutter_bloc: ^9.1.1
flutter_bloc: ^8.0.1
flutter_context_menu: ^0.2.0
flutter_displaymode: ^0.6.0
flutter_email_sender: ^7.0.0
flutter_email_sender: ^6.0.2
# revert to pub.dev when merged
# https://github.com/pichillilorenzo/flutter_inappwebview/pull/2548
flutter_inappwebview:
@@ -57,7 +57,7 @@ dependencies:
git:
url: https://github.com/eaceto/flutter_local_authentication
ref: 1ac346a04592a05fd75acccf2e01fa3c7e955d96
flutter_local_notifications: ^18.0.1
flutter_local_notifications: ^17.2.2
flutter_localizations:
sdk: flutter
flutter_native_splash: ^2.2.13
@@ -87,27 +87,30 @@ dependencies:
pinput: ^5.0.0
pointycastle: ^3.7.3
privacy_screen: ^0.0.6
protobuf: ^4.1.0
protobuf: ^3.0.0
qr_code_scanner: ^1.0.1
qr_flutter: ^4.1.0
sentry: ^8.14.2
sentry_flutter: ^8.14.2
share_plus: ^11.0.0
share_plus: ^10.0.2
shared_preferences: ^2.0.5
sqflite: ^2.4.2
sqflite:
git:
url: https://github.com/tekartik/sqflite
path: sqflite
sqflite_common_ffi: ^2.3.0+4
sqlite3: ^2.4.3
sqlite3_flutter_libs: ^0.5.24
steam_totp: ^0.0.1
step_progress_indicator: ^1.0.2
styled_text: ^8.1.0
tray_manager: ^0.5.0
tray_manager: ^0.2.1
tuple: ^2.0.0
url_launcher: ^6.3.1
url_launcher_ios: ^6.3.1
uuid: ^4.2.2
win32: ^5.1.1
window_manager: ^0.5.0
window_manager: ^0.4.2
xdg_directories: ^1.0.4
dev_dependencies:
@@ -115,7 +118,7 @@ dev_dependencies:
flutter_test:
sdk: flutter
json_serializable: ^6.2.0
lints: ^5.1.1
lints: ^5.0.0
mocktail: ^1.0.3
# The following section is specific to Flutter.

View File

@@ -1,4 +1,4 @@
import "package:ente_auth/l10n/arb/app_localizations.dart";
import "package:ente_auth/l10n/l10n.dart";
import "package:flutter/material.dart";
import "package:flutter_localizations/flutter_localizations.dart";
import "package:flutter_test/flutter_test.dart";
@@ -8,6 +8,7 @@ extension PumpApp on WidgetTester {
return pumpWidget(
MaterialApp(
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
],
supportedLocales: AppLocalizations.supportedLocales,

View File

@@ -13,7 +13,7 @@
#include <flutter_local_authentication/flutter_local_authentication_plugin_c_api.h>
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
#include <local_auth_windows/local_auth_plugin.h>
#include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h>
#include <screen_retriever/screen_retriever_plugin.h>
#include <sentry_flutter/sentry_flutter_plugin.h>
#include <share_plus/share_plus_windows_plugin_c_api.h>
#include <sodium_libs/sodium_libs_plugin_c_api.h>
@@ -37,8 +37,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
LocalAuthPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("LocalAuthPlugin"));
ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi"));
ScreenRetrieverPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
SentryFlutterPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SentryFlutterPlugin"));
SharePlusWindowsPluginCApiRegisterWithRegistrar(

View File

@@ -10,7 +10,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
flutter_local_authentication
flutter_secure_storage_windows
local_auth_windows
screen_retriever_windows
screen_retriever
sentry_flutter
share_plus
sodium_libs

View File

@@ -1,3 +0,0 @@
{
"flutter": "3.29.3"
}

View File

@@ -43,6 +43,3 @@ fastlane/report.xml
# Android related
android/app/build/
# FVM Version Cache
.fvm/

View File

@@ -46,25 +46,27 @@ You can alternatively install the build from PlayStore or F-Droid.
## 🧑‍💻 Building from source
1. [Install Flutter v3.29.3](https://flutter.dev/docs/get-started/install).
1. Install [Flutter v3.24.3](https://flutter.dev/docs/get-started/install) and [Rust v1.85.1](https://www.rust-lang.org/tools/install).
2. Pull in all submodules with `git submodule update --init --recursive`
2. Install [Flutter Rust Bridge](https://cjycode.com/flutter_rust_bridge/) with `cargo install flutter_rust_bridge_codegen`
3. Enable repo git hooks `git config core.hooksPath hooks`
3. Pull in all submodules with `git submodule update --init --recursive`
4. If using Visual Studio Code, add the [Flutter
4. Enable repo git hooks `git config core.hooksPath hooks`
5. If using Visual Studio Code, add the [Flutter
Intl](https://marketplace.visualstudio.com/items?itemName=localizely.flutter-intl)
extension
5. On Android:
6. On Android:
* For development, run `flutter run -t lib/main.dart --flavor independent`
- For development, run `flutter run -t lib/main.dart --flavor independent`
* For building APK, [setup your
- For building APK, [setup your
keystore](https://docs.flutter.dev/deployment/android#create-an-upload-keystore)
and run `flutter build apk --release --flavor independent`
6. For iOS, run `flutter build ios`
7. For iOS, run `flutter build ios`
Some common issues and troubleshooting tips are in [docs/dev](docs/dev.md).
@@ -88,11 +90,12 @@ issue](https://github.com/ente-io/ente/issues/new?title=Request+for+New+Language
to have it added.
## Certificate Fingerprints
- **SHA1**: E1:60:10:18:B6:B0:2E:A3:74:6F:90:67:50:30:29:75:0E:EF:6D:39
- **SHA256**: 35:ED:56:81:B7:0B:B3:BD:35:D9:0D:85:6A:F5:69:4C:50:4D:EF:46:AA:D8:3F:77:7B:1C:67:5C:F4:51:35:0B
To verify these fingerprints, use the following command:
```bash
apksigner verify --print-certs <path_to_apk>
```

View File

@@ -31,10 +31,9 @@ if (keystorePropertiesFile.exists()) {
android {
namespace = "io.ente.photos"
compileSdk = 35
ndkVersion = flutter.ndkVersion
ndkVersion = "28.0.13004108"
compileOptions {
coreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
@@ -133,7 +132,7 @@ flutter {
source = "../.."
}
dependencies {
dependencies {
implementation 'io.sentry:sentry-android:2.0.0'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.21'
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0'
@@ -143,7 +142,7 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
constraints {
implementation("androidx.work:work-runtime:2.8.1") {

View File

@@ -1,5 +1,11 @@
package io.ente.photos
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity : FlutterFragmentActivity() {}
class MainActivity : FlutterFragmentActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine)
}
}

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip

View File

@@ -18,7 +18,7 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.6.0" apply false
id "com.android.application" version "8.1.0" apply false
id "org.jetbrains.kotlin.android" version "2.1.10" apply false
}

View File

@@ -0,0 +1,8 @@
rust_input: crate::api
rust_root: rust/
dart_output: lib/src/rust
dart_preamble: |
// ignore_for_file: require_trailing_commas
web: false

View File

@@ -91,10 +91,9 @@ Future<void> dismissUpdateAppDialog(WidgetTester tester) async {
await tester.pumpAndSettle();
}
///Use this widget as floating action buttom in HomeWidget so that frames
///are built and rendered continuously so that timeline trace has continuous
///data. Change the duraiton in `_startTimer()` to control the duraiton of
///are built and rendered continuously so that timeline trace has continuous
///data. Change the duraiton in `_startTimer()` to control the duraiton of
///test on app init.
// class TempWidget extends StatefulWidget {
@@ -127,4 +126,4 @@ Future<void> dismissUpdateAppDialog(WidgetTester tester) async {
// ? const CircularProgressIndicator()
// : const SizedBox.shrink();
// }
// }
// }

View File

@@ -0,0 +1,13 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import "package:photos/src/rust/api/simple.dart";
import 'package:photos/src/rust/frb_generated.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
setUpAll(() async => await RustLib.init());
testWidgets('Can call rust function', (WidgetTester tester) async {
final testString = greet(name: "Tom");
expect(testString.contains('Tom'), true);
});
}

View File

@@ -32,5 +32,3 @@ Flutter/.last_build_id
!default.mode2v3
!default.pbxuser
!default.perspectivev3
Flutter/ephemeral

View File

@@ -1,6 +1,7 @@
source 'https://github.com/ente-io/ffmpeg-kit-custom-repo-ios.git'
# Uncomment this line to define a global platform for your project
platform :ios, '13.0'
source 'https://github.com/ente-io/ffmpeg-kit-custom-repo-ios.git'
source 'https://cdn.cocoapods.org/'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.

View File

@@ -18,37 +18,37 @@ PODS:
- Flutter
- file_saver (0.0.1):
- Flutter
- Firebase/CoreOnly (11.15.0):
- FirebaseCore (~> 11.15.0)
- Firebase/Messaging (11.15.0):
- Firebase/CoreOnly (11.8.0):
- FirebaseCore (~> 11.8.0)
- Firebase/Messaging (11.8.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 11.15.0)
- firebase_core (3.15.1):
- Firebase/CoreOnly (= 11.15.0)
- FirebaseMessaging (~> 11.8.0)
- firebase_core (3.12.0):
- Firebase/CoreOnly (= 11.8.0)
- Flutter
- firebase_messaging (15.2.9):
- Firebase/Messaging (= 11.15.0)
- firebase_messaging (15.2.3):
- Firebase/Messaging (= 11.8.0)
- firebase_core
- Flutter
- FirebaseCore (11.15.0):
- FirebaseCoreInternal (~> 11.15.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreInternal (11.15.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseInstallations (11.15.0):
- FirebaseCore (~> 11.15.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- FirebaseCore (11.8.1):
- FirebaseCoreInternal (~> 11.8.0)
- GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/Logger (~> 8.0)
- FirebaseCoreInternal (11.8.0):
- "GoogleUtilities/NSData+zlib (~> 8.0)"
- FirebaseInstallations (11.8.0):
- FirebaseCore (~> 11.8.0)
- GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/UserDefaults (~> 8.0)
- PromisesObjC (~> 2.4)
- FirebaseMessaging (11.15.0):
- FirebaseCore (~> 11.15.0)
- FirebaseMessaging (11.8.0):
- FirebaseCore (~> 11.8.0)
- FirebaseInstallations (~> 11.0)
- GoogleDataTransport (~> 10.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Reachability (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
- GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/Reachability (~> 8.0)
- GoogleUtilities/UserDefaults (~> 8.0)
- nanopb (~> 3.30910.0)
- Flutter (1.0.0)
- flutter_email_sender (0.0.1):
@@ -127,6 +127,9 @@ 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):
@@ -173,7 +176,7 @@ PODS:
- FlutterMacOS
- permission_handler_apple (9.3.0):
- Flutter
- photo_manager (3.7.1):
- photo_manager (2.0.0):
- Flutter
- FlutterMacOS
- privacy_screen (0.0.1):
@@ -200,26 +203,23 @@ PODS:
- sqflite_darwin (0.0.4):
- Flutter
- FlutterMacOS
- sqlite3 (3.50.1):
- sqlite3/common (= 3.50.1)
- sqlite3/common (3.50.1)
- sqlite3/dbstatvtab (3.50.1):
- sqlite3 (3.49.2):
- sqlite3/common (= 3.49.2)
- sqlite3/common (3.49.2)
- sqlite3/dbstatvtab (3.49.2):
- sqlite3/common
- sqlite3/fts5 (3.50.1):
- sqlite3/fts5 (3.49.2):
- sqlite3/common
- sqlite3/math (3.50.1):
- sqlite3/perf-threadsafe (3.49.2):
- sqlite3/common
- sqlite3/perf-threadsafe (3.50.1):
- sqlite3/common
- sqlite3/rtree (3.50.1):
- sqlite3/rtree (3.49.2):
- sqlite3/common
- sqlite3_flutter_libs (0.0.1):
- Flutter
- FlutterMacOS
- sqlite3 (~> 3.50.1)
- sqlite3 (~> 3.49.0)
- sqlite3/dbstatvtab
- sqlite3/fts5
- sqlite3/math
- sqlite3/perf-threadsafe
- sqlite3/rtree
- system_info_plus (0.0.1):
@@ -269,6 +269,7 @@ 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`)
@@ -287,6 +288,7 @@ DEPENDENCIES:
- photo_manager (from `.symlinks/plugins/photo_manager/ios`)
- privacy_screen (from `.symlinks/plugins/privacy_screen/ios`)
- receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
- rust_lib_photos (from `.symlinks/plugins/rust_lib_photos/ios`)
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
@@ -303,7 +305,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
@@ -376,6 +378,8 @@ 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:
@@ -412,6 +416,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/privacy_screen/ios"
receive_sharing_intent:
:path: ".symlinks/plugins/receive_sharing_intent/ios"
rust_lib_photos:
:path: ".symlinks/plugins/rust_lib_photos/ios"
sentry_flutter:
:path: ".symlinks/plugins/sentry_flutter/ios"
share_plus:
@@ -442,83 +448,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: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
app_links: f3e17e4ee5e357b39d8b95290a9b2c299fca71c6
battery_info: b6c551049266af31556b93c9d9b9452cfec0219f
connectivity_plus: 2a701ffec2c0ae28a48cf7540e279787e77c447d
cupertino_http: 947a233f40cfea55167a49f2facc18434ea117ba
dart_ui_isolate: d5bcda83ca4b04f129d70eb90110b7a567aece14
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
ffmpeg_kit_custom: 682b4f2f1ff1f8abae5a92f6c3540f2441d5be99
ffmpeg_kit_flutter: 915b345acc97d4142e8a9a8549d177ff10f043f5
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
firebase_core: ece862f94b2bc72ee0edbeec7ab5c7cb09fe1ab5
firebase_messaging: e1a5fae495603115be1d0183bc849da748734e2b
FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e
FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4
FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843
FirebaseMessaging: 3b26e2cee503815e01c3701236b020aa9b576f09
ffmpeg_kit_flutter: 9dce4803991478c78c6fb9f972703301101095fe
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
Firebase: d80354ed7f6df5f9aca55e9eb47cc4b634735eaf
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: c32d145d68aeda5502d5f543ee38c192065986cf
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
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_ios: f7a1841beef3151d140a967c2e46f30637cdf451
local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3
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: 1d80ae07a89a67dfbcae95953a1e5a24af7c3e62
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
sqlite3: 1d85290c3321153511f6e900ede7a1608718bbd5
sqlite3_flutter_libs: e7fc8c9ea2200ff3271f08f127842131746b70e2
system_info_plus: 555ce7047fbbf29154726db942ae785c29211740
thermal: d4c48be750d1ddbab36b0e2dcb2471531bc8df41
ua_client_hints: 92fe0d139619b73ec9fcb46cc7e079a26178f586
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b
video_thumbnail: b637e0ad5f588ca9945f6e2c927f73a69a661140
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
workmanager: b89e4e4445d8b57ee2fdbf1c3925696ebe5b8990
sentry_flutter: 2df8b0aab7e4aba81261c230cbea31c82a62dd1b
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
sqlite3: 3c950dc86011117c307eb0b28c4a7bb449dce9f1
sqlite3_flutter_libs: 069c435986dd4b63461aecd68f4b30be4a9e9daa
system_info_plus: 5393c8da281d899950d751713575fbf91c7709aa
thermal: a9261044101ae8f532fa29cab4e8270b51b3f55c
ua_client_hints: aeabd123262c087f0ce151ef96fa3ab77bfc8b38
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
video_thumbnail: 94ba6705afbaa120b77287080424930f23ea0c40
volume_controller: 2e3de73d6e7e81a0067310d17fb70f2f86d71ac7
wakelock_plus: 373cfe59b235a6dd5837d0fb88791d2f13a90d56
workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
PODFILE CHECKSUM: cce2cd3351d3488dca65b151118552b680e23635
PODFILE CHECKSUM: a8ef88ad74ba499756207e7592c6071a96756d18
COCOAPODS: 1.16.2

View File

@@ -548,6 +548,7 @@
"${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",
@@ -565,6 +566,7 @@
"${BUILT_PRODUCTS_DIR}/photo_manager/photo_manager.framework",
"${BUILT_PRODUCTS_DIR}/privacy_screen/privacy_screen.framework",
"${BUILT_PRODUCTS_DIR}/receive_sharing_intent/receive_sharing_intent.framework",
"${BUILT_PRODUCTS_DIR}/rust_lib_photos/rust_lib_photos.framework",
"${BUILT_PRODUCTS_DIR}/sentry_flutter/sentry_flutter.framework",
"${BUILT_PRODUCTS_DIR}/share_plus/share_plus.framework",
"${BUILT_PRODUCTS_DIR}/shared_preferences_foundation/shared_preferences_foundation.framework",
@@ -643,6 +645,7 @@
"${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",
@@ -660,6 +663,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/photo_manager.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/privacy_screen.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/receive_sharing_intent.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/rust_lib_photos.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sentry_flutter.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share_plus.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_foundation.framework",

View File

@@ -26,7 +26,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
@@ -44,13 +43,11 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">

View File

@@ -0,0 +1,3 @@
arb-dir: lib/l10n
template-arb-file: intl_en.arb
output-localization-file: app_localizations.dart

View File

@@ -5,7 +5,7 @@ import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import "package:flutter_localizations/flutter_localizations.dart";
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:home_widget/home_widget.dart' as hw;
import 'package:logging/logging.dart';
import 'package:media_extension/media_extension_action_types.dart';
@@ -20,7 +20,6 @@ import 'package:photos/services/app_lifecycle_service.dart';
import "package:photos/services/home_widget_service.dart";
import "package:photos/services/memory_home_widget_service.dart";
import "package:photos/services/people_home_widget_service.dart";
import "package:photos/services/smart_albums_service.dart";
import 'package:photos/services/sync/sync_service.dart';
import 'package:photos/ui/tabs/home_widget.dart';
import "package:photos/ui/viewer/actions/file_viewer.dart";
@@ -75,10 +74,8 @@ class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
_peopleChangedSubscription = Bus.instance.on<PeopleChangedEvent>().listen(
(event) async {
_changeCallbackDebouncer.run(
() async {
unawaited(PeopleHomeWidgetService.instance.checkPeopleChanged());
unawaited(SmartAlbumsService.instance.syncSmartAlbums());
},
() async =>
unawaited(PeopleHomeWidgetService.instance.checkPeopleChanged()),
);
},
);
@@ -146,10 +143,8 @@ class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
supportedLocales: appSupportedLocales,
localeListResolutionCallback: localResolutionCallBack,
localizationsDelegates: const [
...AppLocalizations.localizationsDelegates,
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
),
),
@@ -171,10 +166,8 @@ class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
supportedLocales: appSupportedLocales,
localeListResolutionCallback: localResolutionCallBack,
localizationsDelegates: const [
...AppLocalizations.localizationsDelegates,
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
),
);

View File

@@ -1,4 +1,3 @@
import "dart:io";
import 'package:photos/core/cache/lru_map.dart';

View File

@@ -1,3 +1,5 @@
library super_logging;
import 'dart:async';
import 'dart:collection';
import 'dart:core';

View File

@@ -58,7 +58,7 @@ bool isHandledSyncError(Object errObj) {
class LockAlreadyAcquiredError extends Error {}
class LockFreedError extends Error{}
class LockFreedError extends Error {}
class UnauthorizedError extends Error {}

View File

@@ -128,21 +128,4 @@ extension EntitiesDB on FilesDB {
}
return maps.values.first as String?;
}
Future<Map<String, int>> getUpdatedAts(
EntityType type,
List<String> ids,
) async {
final db = await sqliteAsyncDB;
final List<Map<String, dynamic>> maps = await db.getAll(
'SELECT id, updatedAt FROM entities WHERE type = ? AND id IN (${List.filled(ids.length, '?').join(',')})',
[type.name, ...ids],
);
return Map<String, int>.fromEntries(
List.generate(
maps.length,
(i) => MapEntry(maps[i]['id'] as String, maps[i]['updatedAt'] as int),
),
);
}
}

View File

@@ -1479,7 +1479,6 @@ class FilesDB with SqlDbBase {
final inParam = ids.map((id) => "'$id'").join(',');
final db = await instance.sqliteAsyncDB;
final results = await db.getAll(
'SELECT * FROM $filesTable WHERE $columnUploadedFileID IN ($inParam) ORDER BY $columnCreationTime $order',
);

View File

@@ -0,0 +1,238 @@
import "dart:typed_data" show Float32List;
import "package:flutter_rust_bridge/flutter_rust_bridge.dart" show Uint64List;
import "package:logging/logging.dart";
import "package:path/path.dart";
import "package:path_provider/path_provider.dart";
import "package:photos/models/ml/vector.dart";
import "package:photos/services/machine_learning/semantic_search/query_result.dart";
import "package:photos/src/rust/api/usearch_api.dart";
class ClipVectorDB {
static final Logger _logger = Logger("ClipVectorDB");
static const _databaseName = "ente.ml.vectordb.clip";
static final BigInt _embeddingDimension = BigInt.from(512);
static Logger get logger => _logger;
// Singleton pattern
ClipVectorDB._privateConstructor();
static final instance = ClipVectorDB._privateConstructor();
factory ClipVectorDB() => instance;
// only have a single app-wide reference to the database
static Future<VectorDb>? _vectorDbFuture;
Future<VectorDb> get _vectorDB async {
_vectorDbFuture ??= _initVectorDB();
return _vectorDbFuture!;
}
Future<VectorDb> _initVectorDB() async {
final documentsDirectory = await getApplicationDocumentsDirectory();
final String databaseDirectory =
join(documentsDirectory.path, _databaseName);
_logger.info("Opening vectorDB access: DB path " + databaseDirectory);
final vectorDB = VectorDb(
filePath: databaseDirectory,
dimensions: _embeddingDimension,
);
final stats = await getIndexStats(vectorDB);
_logger.info("VectorDB connection opened with stats: ${stats.toString()}");
return vectorDB;
}
Future<void> insertEmbedding({
required int fileID,
required List<double> embedding,
}) async {
final db = await _vectorDB;
try {
await db.addVector(key: BigInt.from(fileID), vector: embedding);
} catch (e, s) {
_logger.severe("Error inserting embedding", e, s);
rethrow;
}
}
Future<void> bulkInsertEmbeddings({
required List<int> fileIDs,
required List<Float32List> embeddings,
}) async {
final db = await _vectorDB;
final bigKeys = Uint64List.fromList(fileIDs);
try {
await db.bulkAddVectors(keys: bigKeys, vectors: embeddings);
} catch (e, s) {
_logger.severe("Error bulk inserting embeddings", e, s);
rethrow;
}
}
Future<List<EmbeddingVector>> getEmbeddings(List<int> fileIDs) async {
final db = await _vectorDB;
try {
final keys = Uint64List.fromList(fileIDs);
final vectors = await db.bulkGetVectors(keys: keys);
return List.generate(
vectors.length,
(index) => EmbeddingVector(
fileID: fileIDs[index],
embedding: vectors[index],
),
);
} catch (e, s) {
_logger.severe("Error getting embeddings", e, s);
rethrow;
}
}
Future<void> deleteEmbeddings(List<int> fileIDs) async {
final db = await _vectorDB;
try {
final deletedCount =
await db.bulkRemoveVectors(keys: Uint64List.fromList(fileIDs));
_logger.info(
"Deleted $deletedCount embeddings, from ${fileIDs.length} keys",
);
} catch (e, s) {
_logger.severe("Error bulk deleting specific embeddings", e, s);
rethrow;
}
}
Future<void> deleteAllEmbeddings() async {
final db = await _vectorDB;
try {
await db.resetIndex();
} catch (e, s) {
_logger.severe("Error deleting all embeddings", e, s);
rethrow;
}
}
Future<void> deleteIndex() async {
final db = await _vectorDB;
try {
await db.deleteIndex();
_vectorDbFuture = null;
} catch (e, s) {
_logger.severe("Error deleting index", e, s);
rethrow;
}
}
Future<VectorDbStats> getIndexStats([VectorDb? db]) async {
db ??= await _vectorDB;
try {
final stats = await db.getIndexStats();
return VectorDbStats(
size: stats.$1.toInt(),
capacity: stats.$2.toInt(),
dimensions: stats.$3.toInt(),
fileSize: stats.$4.toInt(),
memoryUsage: stats.$5.toInt(),
expansionAdd: stats.$6.toInt(),
expansionSearch: stats.$7.toInt(),
);
} catch (e, s) {
_logger.severe("Error getting index stats", e, s);
rethrow;
}
}
Future<(Uint64List, Float32List)> searchClosestVectors(
List<double> query,
int count,
) async {
final db = await _vectorDB;
try {
final result =
await db.searchVectors(query: query, count: BigInt.from(count));
return result;
} catch (e, s) {
_logger.severe("Error searching closest vectors", e, s);
rethrow;
}
}
Future<(BigInt, double)> searchClosestVector(
List<double> query,
) async {
final db = await _vectorDB;
try {
final result = await db.searchVectors(query: query, count: BigInt.one);
return (result.$1[0], result.$2[0]);
} catch (e, s) {
_logger.severe("Error searching closest vector", e, s);
rethrow;
}
}
Future<Map<String, List<QueryResult>>> computeBulkSimilarities(
Map<String, List<double>> textQueryToEmbeddingMap,
Map<String, double> minimumSimilarityMap,
) async {
try {
final queryToResults = <String, List<QueryResult>>{};
for (final MapEntry<String, List<double>> entry
in textQueryToEmbeddingMap.entries) {
final query = entry.key;
final minimumSimilarity = minimumSimilarityMap[query]!;
final textEmbedding = entry.value;
final (potentialFileIDs, distances) =
await searchClosestVectors(textEmbedding, 1000);
final queryResults = <QueryResult>[];
for (var i = 0; i < potentialFileIDs.length; i++) {
final similarity = 1 - distances[i];
if (similarity >= minimumSimilarity) {
queryResults
.add(QueryResult(potentialFileIDs[i].toInt(), similarity));
} else {
break;
}
}
queryToResults[query] = queryResults;
}
return queryToResults;
} catch (e, s) {
_logger.severe(
"Could not bulk find embeddings similarities using vector DB",
e,
s,
);
rethrow;
}
}
}
class VectorDbStats {
final int size;
final int capacity;
final int dimensions;
// in bytes
final int fileSize;
final int memoryUsage;
final int expansionAdd;
final int expansionSearch;
VectorDbStats({
required this.size,
required this.capacity,
required this.dimensions,
required this.fileSize,
required this.memoryUsage,
required this.expansionAdd,
required this.expansionSearch,
});
@override
String toString() {
return "VectorDbStats(size: $size, capacity: $capacity, dimensions: $dimensions, file size on disk (bytes): $fileSize, memory usage (bytes): $memoryUsage, expansionAdd: $expansionAdd, expansionSearch: $expansionSearch)";
}
}

View File

@@ -1,4 +1,5 @@
import 'dart:async';
import "dart:io" show File;
import "dart:math";
import "package:collection/collection.dart";
@@ -9,6 +10,7 @@ import 'package:path_provider/path_provider.dart';
import "package:photos/core/event_bus.dart";
import "package:photos/db/common/base.dart";
import "package:photos/db/ml/base.dart";
import "package:photos/db/ml/clip_vector_db.dart";
import "package:photos/db/ml/db_model_mappers.dart";
import 'package:photos/db/ml/schema.dart';
import "package:photos/events/embedding_updated_event.dart";
@@ -18,6 +20,7 @@ import "package:photos/models/ml/face/face.dart";
import "package:photos/models/ml/face/face_with_embedding.dart";
import "package:photos/models/ml/ml_versions.dart";
import "package:photos/models/ml/vector.dart";
import "package:photos/service_locator.dart";
import "package:photos/services/machine_learning/face_ml/face_clustering/face_db_info_for_clustering.dart";
import 'package:photos/services/machine_learning/face_ml/face_filtering/face_filtering_constants.dart';
import "package:photos/services/machine_learning/ml_result.dart";
@@ -84,6 +87,8 @@ class MLDataDB with SqlDbBase implements IMLDataDB<int> {
"MLDataDB Migration took ${stopwatch.elapsedMilliseconds} ms",
);
stopwatch.stop();
_logger.info("Starting CLIP vector DB migration check unawaited");
if (flagService.enableVectorDb) unawaited(checkMigrateFillClipVectorDB());
return asyncDBConnection;
}
@@ -316,48 +321,28 @@ class MLDataDB with SqlDbBase implements IMLDataDB<int> {
// read person from db
final db = await instance.asyncDB;
if (personID != null) {
logger.info("[$recentFileID] Processing personID path: $personID");
final List<int> fileId = [recentFileID];
logger.info("[$recentFileID] Initial fileId list: $fileId");
int? avatarFileId;
if (avatarFaceId != null) {
logger.info(
"[$recentFileID] Looking up avatarFileId for avatarFaceId: $avatarFaceId",
);
avatarFileId = tryGetFileIdFromFaceId(avatarFaceId);
logger.info("[$recentFileID] avatarFileId result: $avatarFileId");
if (avatarFileId != null) {
fileId.add(avatarFileId);
logger.info(
"[$recentFileID] Updated fileId list with avatarFileId: $fileId",
);
}
} else {
logger.info("[$recentFileID] No avatarFaceId provided");
}
const String queryClusterID = '''
SELECT $clusterIDColumn
FROM $clusterPersonTable
WHERE $personIdColumn = ?
''';
logger.info(
"[$recentFileID] Executing cluster query for personID: $personID",
);
final clusterRows = await db.getAll(
queryClusterID,
[personID],
);
logger.info(
"[$recentFileID] Found ${clusterRows.length} cluster rows: $clusterRows",
);
final clusterIDs =
clusterRows.map((e) => e[clusterIDColumn] as String).toList();
logger.info("[$recentFileID] Extracted clusterIDs: $clusterIDs");
final faceQuery = '''
final List<Map<String, dynamic>> faceMaps = await db.getAll(
'''
SELECT * FROM $facesTable
WHERE $faceIDColumn IN (
SELECT $faceIDColumn
@@ -366,193 +351,45 @@ class MLDataDB with SqlDbBase implements IMLDataDB<int> {
)
AND $fileIDColumn IN (${List.filled(fileId.length, '?').join(',')})
ORDER BY $faceScore DESC
''';
final queryParams = [...clusterIDs, ...fileId];
logger.info(
"[$recentFileID] Executing face query with ${clusterIDs.length} clusterIDs and ${fileId.length} fileIDs",
''',
[...clusterIDs, ...fileId],
);
logger.info("[$recentFileID] Face query: $faceQuery");
logger.info("[$recentFileID] Query parameters: $queryParams");
final List<Map<String, dynamic>> faceMaps = await db.getAll(
faceQuery,
queryParams,
);
logger.info("[$recentFileID] Found ${faceMaps.length} face maps");
if (faceMaps.isNotEmpty) {
logger.info(
"[$recentFileID] Found ${faceMaps.length} faces, processing selection",
);
if (avatarFileId != null) {
logger.info(
"[$recentFileID] Looking for face with avatarFileId: $avatarFileId",
);
final row = faceMaps.firstWhereOrNull(
(element) => (element[fileIDColumn] as int) == avatarFileId,
);
if (row != null) {
logger.info(
"[$recentFileID] Found avatar face, returning: ${row[faceIDColumn]}",
);
final face = mapRowToFace(row);
logger.info(
"[$recentFileID] getCoverFaceForPerson SUCCESS (avatar): returning face ${face.faceID}",
);
return face;
} else {
logger.info(
"[$recentFileID] Avatar face not found in results, falling back to first face",
);
return mapRowToFace(row);
}
}
logger.info(
"[$recentFileID] Returning first face: ${faceMaps.first[faceIDColumn]}",
);
final face = mapRowToFace(faceMaps.first);
logger.info(
"[$recentFileID] getCoverFaceForPerson SUCCESS (first): returning face ${face.faceID}",
);
return face;
} else {
// Diagnostic queries to understand why faceMaps is empty
logger.info(
"[$recentFileID] faceMaps is empty, running diagnostic queries",
);
// Test 1: Check if faces exist in faceClustersTable for these clusterIDs
if (clusterIDs.isNotEmpty) {
final faceIDsInClusters = await db.getAll(
'''
SELECT $faceIDColumn
FROM $faceClustersTable
WHERE $clusterIDColumn IN (${List.filled(clusterIDs.length, '?').join(',')})
''',
clusterIDs,
);
logger.info(
"[$recentFileID] Found ${faceIDsInClusters.length} faceIDs in faceClustersTable for clusterIDs: ${faceIDsInClusters.map((e) => e[faceIDColumn]).toList()}",
);
// Test 2: Check if any of those faces exist in facesTable
if (faceIDsInClusters.isNotEmpty) {
final faceIDsFromClusters = faceIDsInClusters
.map((e) => e[faceIDColumn] as String)
.toList();
final facesInFacesTable = await db.getAll(
'''
SELECT $faceIDColumn, $fileIDColumn
FROM $facesTable
WHERE $faceIDColumn IN (${List.filled(faceIDsFromClusters.length, '?').join(',')})
''',
faceIDsFromClusters,
);
logger.info(
"[$recentFileID] Found ${facesInFacesTable.length} faces in facesTable: ${facesInFacesTable.map((e) => '${e[faceIDColumn]}(file:${e[fileIDColumn]})').toList()}",
);
// Test 3: Check if any of those faces are for our target fileIDs
final facesForTargetFiles = facesInFacesTable
.where(
(face) => fileId.contains(face[fileIDColumn] as int),
)
.toList();
logger.info(
"[$recentFileID] Found ${facesForTargetFiles.length} faces for target fileIDs $fileId: ${facesForTargetFiles.map((e) => '${e[faceIDColumn]}(file:${e[fileIDColumn]})').toList()}",
);
} else {
logger.info(
"[$recentFileID] No faceIDs found in faceClustersTable for these clusterIDs",
);
}
} else {
logger.info("[$recentFileID] No clusterIDs to check");
}
// Test 4: Check if there are any faces at all for the target fileIDs
final allFacesForFiles = await db.getAll(
'''
SELECT $faceIDColumn, $fileIDColumn
FROM $facesTable
WHERE $fileIDColumn IN (${List.filled(fileId.length, '?').join(',')})
''',
fileId,
);
logger.info(
"[$recentFileID] Found ${allFacesForFiles.length} total faces for fileIDs $fileId: ${allFacesForFiles.map((e) => '${e[faceIDColumn]}(file:${e[fileIDColumn]})').toList()}",
);
if (clusterID == null) {
logger.severe(
"[$recentFileID] Didn't find any faces for personID $personID in getCoverFaceForPerson. fileID: $fileId, clusterIDs: $clusterIDs",
);
} else {
logger.info(
"[$recentFileID] No faces found for personID, but clusterID provided, will try clusterID path",
);
}
return mapRowToFace(faceMaps.first);
}
}
if (clusterID != null) {
logger.info("[$recentFileID] Processing clusterID path: $clusterID");
const String queryFaceID = '''
SELECT $faceIDColumn
FROM $faceClustersTable
WHERE $clusterIDColumn = ?
''';
logger.info(
"[$recentFileID] Executing faceID query for clusterID: $clusterID",
);
logger.info("[$recentFileID] Query: $queryFaceID");
final List<Map<String, dynamic>> faceMaps = await db.getAll(
queryFaceID,
[clusterID],
);
logger.info(
"[$recentFileID] Found ${faceMaps.length} face mappings for cluster: ${faceMaps.map((e) => e[faceIDColumn]).toList()}",
);
final List<Face>? faces = await getFacesForGivenFileID(recentFileID);
logger.info(
"[$recentFileID] getFacesForGivenFileID returned ${faces?.length ?? 0} faces: ${faces?.map((f) => f.faceID).toList() ?? []}",
);
if (faces != null) {
logger.info(
"[$recentFileID] Searching for matching face in ${faces.length} faces",
);
for (final face in faces) {
final isMatch = faceMaps.any(
if (faceMaps.any(
(element) => (element[faceIDColumn] as String) == face.faceID,
);
logger.info(
"[$recentFileID] Checking face ${face.faceID}: match=$isMatch",
);
if (isMatch) {
logger.info(
"[$recentFileID] getCoverFaceForPerson SUCCESS (cluster): returning face ${face.faceID}",
);
)) {
return face;
}
}
logger.info(
"[$recentFileID] No matching faces found in file for clusterID",
);
} else {
logger.severe(
"[$recentFileID] Didn't find any faces for clusterID $clusterID in getCoverFaceForPerson. faces: $faces",
);
}
}
if (personID == null && clusterID == null) {
logger
.severe("[$recentFileID] personID and clusterID cannot be null both");
throw Exception("personID and clusterID cannot be null");
}
logger.severe(
"[$recentFileID] getCoverFaceForPerson FAILED: No face found (personID: $personID, clusterID: $clusterID)",
);
return null;
}
@@ -1417,6 +1254,121 @@ class MLDataDB with SqlDbBase implements IMLDataDB<int> {
return embeddings;
}
Future<void> checkMigrateFillClipVectorDB({bool force = false}) async {
_logger.info("Waiting for ClipVectorDB to be ready");
await Future.delayed(const Duration(milliseconds: 100));
_logger.info("Checking if ClipVectorDB migration is needed");
// Check if vector DB migration has run
_logger.info("Checking if ClipVectorDB migration has run");
final documentsDirectory = await getApplicationDocumentsDirectory();
final migrationFlagFile =
File(join(documentsDirectory.path, 'clip_vector_migration_done'));
if (await migrationFlagFile.exists() && !force) {
_logger.info("ClipVectorDB migration not needed, already done");
return;
}
// Get total count first to track progress
_logger.info("Getting total count of clip embeddings");
final db = await instance.asyncDB;
final countResult =
await db.getAll('SELECT COUNT($fileIDColumn) as total FROM $clipTable');
final totalCount = countResult.first['total'] as int;
if (totalCount == 0) {
_logger.info("No clip embeddings to migrate");
await migrationFlagFile.create();
return;
}
_logger.info("Total count of clip embeddings: $totalCount");
_logger.info("First time referencing ClipVectorDB in migration");
final clipVectorDB = ClipVectorDB.instance;
_logger.info("ClipVectorDB referenced");
await clipVectorDB.deleteAllEmbeddings();
_logger.info("ClipVectorDB all embeddings cleared");
_logger
.info("Starting migration of $totalCount clip embeddings to vector DB");
const batchSize = 1000;
int offset = 0;
int processedCount = 0;
int weirdCount = 0;
int whileCount = 0;
final stopwatch = Stopwatch()..start();
try {
while (true) {
whileCount++;
_logger.info("$whileCount st round of while loop");
// Allow some time for any GC to finish
await Future.delayed(const Duration(milliseconds: 100));
_logger.info("Reading $batchSize rows from DB");
final List<Map<String, dynamic>> results = await db.getAll('''
SELECT $fileIDColumn, $embeddingColumn
FROM $clipTable
ORDER BY $fileIDColumn DESC
LIMIT $batchSize OFFSET $offset
''');
_logger.info("Got ${results.length} results from DB");
if (results.isEmpty) {
_logger.info("No more results, breaking out of while loop");
break;
}
_logger.info("Processing ${results.length} results");
final List<int> fileIDs = [];
final List<Float32List> embeddings = [];
for (final result in results) {
final embedding =
Float32List.view((result[embeddingColumn] as Uint8List).buffer);
if (embedding.length == 512) {
fileIDs.add(result[fileIDColumn] as int);
embeddings.add(Float32List.view(result[embeddingColumn].buffer));
} else {
weirdCount++;
}
}
_logger.info(
"Got ${fileIDs.length} valid embeddings, $weirdCount weird embeddings",
);
await ClipVectorDB.instance
.bulkInsertEmbeddings(fileIDs: fileIDs, embeddings: embeddings);
_logger.info("Inserted ${fileIDs.length} embeddings to ClipVectorDB");
processedCount += fileIDs.length;
offset += batchSize;
_logger.info(
"migrated $processedCount/$totalCount embeddings to ClipVectorDB",
);
if (processedCount >= totalCount) {
_logger.info("All embeddings migrated, breaking out of while loop");
break;
}
_logger.info("Clearing out embeddings and fileIDs");
embeddings.clear();
fileIDs.clear();
results.clear();
// Allow some time for any GC to finish
_logger.info("Waiting for 100ms for GC to finish");
await Future.delayed(const Duration(milliseconds: 100));
}
_logger.info(
"migrated all $totalCount embeddings to ClipVectorDB in ${stopwatch.elapsed.inMilliseconds} ms, with $weirdCount weird embeddings not migrated",
);
await migrationFlagFile.create();
_logger.info("ClipVectorDB migration done, flag file created");
} catch (e) {
_logger.severe(
"Error migrating ClipVectorDB after ${stopwatch.elapsed.inMilliseconds} ms, clearing out DB again",
e,
);
await clipVectorDB.deleteAllEmbeddings();
rethrow;
} finally {
stopwatch.stop();
}
}
// Get indexed FileIDs
@override
Future<Map<int, int>> clipIndexedFileWithVersion() async {
@@ -1450,12 +1402,25 @@ class MLDataDB with SqlDbBase implements IMLDataDB<int> {
'INSERT OR REPLACE INTO $clipTable ($fileIDColumn, $embeddingColumn, $mlVersionColumn) VALUES (?, ?, ?)',
_getRowFromEmbedding(embeddings.first),
);
if (flagService.enableVectorDb) {
await ClipVectorDB.instance.insertEmbedding(
fileID: embeddings.first.fileID,
embedding: embeddings.first.embedding,
);
}
} else {
final inputs = embeddings.map((e) => _getRowFromEmbedding(e)).toList();
await db.executeBatch(
'INSERT OR REPLACE INTO $clipTable ($fileIDColumn, $embeddingColumn, $mlVersionColumn) values(?, ?, ?)',
inputs,
);
if (flagService.enableVectorDb) {
await ClipVectorDB.instance.bulkInsertEmbeddings(
fileIDs: embeddings.map((e) => e.fileID).toList(),
embeddings:
embeddings.map((e) => Float32List.fromList(e.embedding)).toList(),
);
}
}
Bus.instance.fire(EmbeddingUpdatedEvent());
}
@@ -1466,6 +1431,9 @@ class MLDataDB with SqlDbBase implements IMLDataDB<int> {
await db.execute(
'DELETE FROM $clipTable WHERE $fileIDColumn IN (${fileIDs.join(", ")})',
);
if (flagService.enableVectorDb) {
await ClipVectorDB.instance.deleteEmbeddings(fileIDs);
}
Bus.instance.fire(EmbeddingUpdatedEvent());
}
@@ -1473,6 +1441,9 @@ class MLDataDB with SqlDbBase implements IMLDataDB<int> {
Future<void> deleteClipIndexes() async {
final db = await instance.asyncDB;
await db.execute('DELETE FROM $clipTable');
if (flagService.enableVectorDb) {
await ClipVectorDB.instance.deleteAllEmbeddings();
}
Bus.instance.fire(EmbeddingUpdatedEvent());
}

View File

@@ -42,22 +42,20 @@ final lightThemeData = ThemeData(
bodyLarge: const TextStyle(color: Colors.orange),
),
cardColor: const Color.fromRGBO(250, 250, 250, 1.0),
dialogTheme: const DialogThemeData(
backgroundColor: Color.fromRGBO(250, 250, 250, 1.0), //
titleTextStyle: TextStyle(
dialogTheme: const DialogTheme().copyWith(
backgroundColor: const Color.fromRGBO(250, 250, 250, 1.0), //
titleTextStyle: const TextStyle(
color: Colors.black,
fontSize: 24,
fontWeight: FontWeight.w600,
),
contentTextStyle: TextStyle(
contentTextStyle: const TextStyle(
fontFamily: 'Inter-Medium',
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w500,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8)),
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
inputDecorationTheme: const InputDecorationTheme().copyWith(
focusedBorder: const UnderlineInputBorder(
@@ -119,22 +117,20 @@ final darkThemeData = ThemeData(
elevation: 0,
),
cardColor: const Color.fromRGBO(10, 15, 15, 1.0),
dialogTheme: const DialogThemeData(
backgroundColor: Color.fromRGBO(15, 15, 15, 1.0),
titleTextStyle: TextStyle(
dialogTheme: const DialogTheme().copyWith(
backgroundColor: const Color.fromRGBO(15, 15, 15, 1.0),
titleTextStyle: const TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.w600,
),
contentTextStyle: TextStyle(
contentTextStyle: const TextStyle(
fontFamily: 'Inter-Medium',
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w500,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8)),
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
inputDecorationTheme: const InputDecorationTheme().copyWith(
focusedBorder: const UnderlineInputBorder(
@@ -210,7 +206,7 @@ TextTheme _buildTextTheme(Color textColor) {
fontWeight: FontWeight.w500,
),
bodySmall: TextStyle(
color: textColor.withValues(alpha: 0.6),
color: textColor.withOpacity(0.6),
fontSize: 14,
fontWeight: FontWeight.w500,
),
@@ -282,7 +278,7 @@ extension CustomColorScheme on ColorScheme {
: const Color.fromRGBO(48, 48, 48, 0.5);
Color get iconColor => brightness == Brightness.light
? const Color.fromRGBO(0, 0, 0, 1).withValues(alpha: 0.75)
? const Color.fromRGBO(0, 0, 0, 1).withOpacity(0.75)
: const Color.fromRGBO(255, 255, 255, 1);
Color get bgColorForQuestions => brightness == Brightness.light
@@ -293,7 +289,7 @@ extension CustomColorScheme on ColorScheme {
Color get cupertinoPickerTopColor => brightness == Brightness.light
? const Color.fromARGB(255, 238, 238, 238)
: const Color.fromRGBO(255, 255, 255, 1).withValues(alpha: 0.1);
: const Color.fromRGBO(255, 255, 255, 1).withOpacity(0.1);
Color get stepProgressUnselectedColor => brightness == Brightness.light
? const Color.fromRGBO(196, 196, 196, 0.6)
@@ -304,20 +300,20 @@ extension CustomColorScheme on ColorScheme {
: const Color.fromRGBO(20, 20, 20, 1);
Color get galleryThumbDrawColor => brightness == Brightness.light
? const Color.fromRGBO(0, 0, 0, 1).withValues(alpha: 0.8)
: const Color.fromRGBO(255, 255, 255, 1).withValues(alpha: 0.5);
? const Color.fromRGBO(0, 0, 0, 1).withOpacity(0.8)
: const Color.fromRGBO(255, 255, 255, 1).withOpacity(0.5);
Color get backupEnabledBgColor => brightness == Brightness.light
? const Color.fromRGBO(230, 230, 230, 0.95)
: const Color.fromRGBO(10, 40, 40, 0.3);
Color get dotsIndicatorActiveColor => brightness == Brightness.light
? const Color.fromRGBO(0, 0, 0, 1).withValues(alpha: 0.5)
: const Color.fromRGBO(255, 255, 255, 1).withValues(alpha: 0.5);
? const Color.fromRGBO(0, 0, 0, 1).withOpacity(0.5)
: const Color.fromRGBO(255, 255, 255, 1).withOpacity(0.5);
Color get dotsIndicatorInactiveColor => brightness == Brightness.light
? const Color.fromRGBO(0, 0, 0, 1).withValues(alpha: 0.12)
: const Color.fromRGBO(255, 255, 255, 1).withValues(alpha: 0.12);
? const Color.fromRGBO(0, 0, 0, 1).withOpacity(0.12)
: const Color.fromRGBO(255, 255, 255, 1).withOpacity(0.12);
Color get toastTextColor => brightness == Brightness.light
? const Color.fromRGBO(255, 255, 255, 1)
@@ -340,8 +336,8 @@ extension CustomColorScheme on ColorScheme {
: const Color.fromRGBO(150, 150, 150, 1);
Color get searchResultsBackgroundColor => brightness == Brightness.light
? Colors.black.withValues(alpha: 0.32)
: Colors.black.withValues(alpha: 0.64);
? Colors.black.withOpacity(0.32)
: Colors.black.withOpacity(0.64);
EnteTheme get enteTheme =>
brightness == Brightness.light ? lightTheme : darkTheme;

View File

@@ -37,27 +37,32 @@ class CenterBox extends $pb.GeneratedMessage {
return $result;
}
CenterBox._() : super();
factory CenterBox.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory CenterBox.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
factory CenterBox.fromBuffer($core.List<$core.int> i,
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromBuffer(i, r);
factory CenterBox.fromJson($core.String i,
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'CenterBox', package: const $pb.PackageName(_omitMessageNames ? '' : 'ente.common'), createEmptyInstance: create)
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
_omitMessageNames ? '' : 'CenterBox',
package: const $pb.PackageName(_omitMessageNames ? '' : 'ente.common'),
createEmptyInstance: create)
..a<$core.double>(1, _omitFieldNames ? '' : 'x', $pb.PbFieldType.OF)
..a<$core.double>(2, _omitFieldNames ? '' : 'y', $pb.PbFieldType.OF)
..a<$core.double>(3, _omitFieldNames ? '' : 'height', $pb.PbFieldType.OF)
..a<$core.double>(4, _omitFieldNames ? '' : 'width', $pb.PbFieldType.OF)
..hasRequiredFields = false
;
..hasRequiredFields = false;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
@$core.Deprecated('Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
CenterBox clone() => CenterBox()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
CenterBox copyWith(void Function(CenterBox) updates) => super.copyWith((message) => updates(message as CenterBox)) as CenterBox;
@$core.Deprecated('Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
CenterBox copyWith(void Function(CenterBox) updates) =>
super.copyWith((message) => updates(message as CenterBox)) as CenterBox;
$pb.BuilderInfo get info_ => _i;
@@ -66,13 +71,17 @@ class CenterBox extends $pb.GeneratedMessage {
CenterBox createEmptyInstance() => create();
static $pb.PbList<CenterBox> createRepeated() => $pb.PbList<CenterBox>();
@$core.pragma('dart2js:noInline')
static CenterBox getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CenterBox>(create);
static CenterBox getDefault() =>
_defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CenterBox>(create);
static CenterBox? _defaultInstance;
@$pb.TagNumber(1)
$core.double get x => $_getN(0);
@$pb.TagNumber(1)
set x($core.double v) { $_setFloat(0, v); }
set x($core.double v) {
$_setFloat(0, v);
}
@$pb.TagNumber(1)
$core.bool hasX() => $_has(0);
@$pb.TagNumber(1)
@@ -81,7 +90,10 @@ class CenterBox extends $pb.GeneratedMessage {
@$pb.TagNumber(2)
$core.double get y => $_getN(1);
@$pb.TagNumber(2)
set y($core.double v) { $_setFloat(1, v); }
set y($core.double v) {
$_setFloat(1, v);
}
@$pb.TagNumber(2)
$core.bool hasY() => $_has(1);
@$pb.TagNumber(2)
@@ -90,7 +102,10 @@ class CenterBox extends $pb.GeneratedMessage {
@$pb.TagNumber(3)
$core.double get height => $_getN(2);
@$pb.TagNumber(3)
set height($core.double v) { $_setFloat(2, v); }
set height($core.double v) {
$_setFloat(2, v);
}
@$pb.TagNumber(3)
$core.bool hasHeight() => $_has(2);
@$pb.TagNumber(3)
@@ -99,13 +114,16 @@ class CenterBox extends $pb.GeneratedMessage {
@$pb.TagNumber(4)
$core.double get width => $_getN(3);
@$pb.TagNumber(4)
set width($core.double v) { $_setFloat(3, v); }
set width($core.double v) {
$_setFloat(3, v);
}
@$pb.TagNumber(4)
$core.bool hasWidth() => $_has(3);
@$pb.TagNumber(4)
void clearWidth() => clearField(4);
}
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');
const _omitMessageNames =
$core.bool.fromEnvironment('protobuf.omit_message_names');

View File

@@ -8,4 +8,3 @@
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import

View File

@@ -35,4 +35,3 @@ final $typed_data.Uint8List centerBoxDescriptor = $convert.base64Decode(
'CglDZW50ZXJCb3gSEQoBeBgBIAEoAkgAUgF4iAEBEhEKAXkYAiABKAJIAVIBeYgBARIbCgZoZW'
'lnaHQYAyABKAJIAlIGaGVpZ2h0iAEBEhkKBXdpZHRoGAQgASgCSANSBXdpZHRoiAEBQgQKAl94'
'QgQKAl95QgkKB19oZWlnaHRCCAoGX3dpZHRo');

View File

@@ -11,4 +11,3 @@
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
export 'box.pb.dart';

View File

@@ -29,25 +29,30 @@ class EPoint extends $pb.GeneratedMessage {
return $result;
}
EPoint._() : super();
factory EPoint.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory EPoint.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
factory EPoint.fromBuffer($core.List<$core.int> i,
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromBuffer(i, r);
factory EPoint.fromJson($core.String i,
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'EPoint', package: const $pb.PackageName(_omitMessageNames ? '' : 'ente.common'), createEmptyInstance: create)
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
_omitMessageNames ? '' : 'EPoint',
package: const $pb.PackageName(_omitMessageNames ? '' : 'ente.common'),
createEmptyInstance: create)
..a<$core.double>(1, _omitFieldNames ? '' : 'x', $pb.PbFieldType.OF)
..a<$core.double>(2, _omitFieldNames ? '' : 'y', $pb.PbFieldType.OF)
..hasRequiredFields = false
;
..hasRequiredFields = false;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
@$core.Deprecated('Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
EPoint clone() => EPoint()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
EPoint copyWith(void Function(EPoint) updates) => super.copyWith((message) => updates(message as EPoint)) as EPoint;
@$core.Deprecated('Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
EPoint copyWith(void Function(EPoint) updates) =>
super.copyWith((message) => updates(message as EPoint)) as EPoint;
$pb.BuilderInfo get info_ => _i;
@@ -56,13 +61,17 @@ class EPoint extends $pb.GeneratedMessage {
EPoint createEmptyInstance() => create();
static $pb.PbList<EPoint> createRepeated() => $pb.PbList<EPoint>();
@$core.pragma('dart2js:noInline')
static EPoint getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<EPoint>(create);
static EPoint getDefault() =>
_defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<EPoint>(create);
static EPoint? _defaultInstance;
@$pb.TagNumber(1)
$core.double get x => $_getN(0);
@$pb.TagNumber(1)
set x($core.double v) { $_setFloat(0, v); }
set x($core.double v) {
$_setFloat(0, v);
}
@$pb.TagNumber(1)
$core.bool hasX() => $_has(0);
@$pb.TagNumber(1)
@@ -71,13 +80,16 @@ class EPoint extends $pb.GeneratedMessage {
@$pb.TagNumber(2)
$core.double get y => $_getN(1);
@$pb.TagNumber(2)
set y($core.double v) { $_setFloat(1, v); }
set y($core.double v) {
$_setFloat(1, v);
}
@$pb.TagNumber(2)
$core.bool hasY() => $_has(1);
@$pb.TagNumber(2)
void clearY() => clearField(2);
}
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');
const _omitMessageNames =
$core.bool.fromEnvironment('protobuf.omit_message_names');

View File

@@ -8,4 +8,3 @@
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import

Some files were not shown because too many files have changed in this diff Show More