Compare commits

...

1082 commits

Author SHA1 Message Date
Neeraj Gupta ae61fc9c6f
Wrap add person name banner inside safeArea (#1887)
## Description

## Tests
2024-05-27 18:12:45 +05:30
Neeraj Gupta c291fa70d3 Wrap add person name banner inside safeArea 2024-05-27 18:12:21 +05:30
Laurens Priem 232acfa211
Face (#1885)
## Description

- Several fixes for Faces
2024-05-27 17:46:05 +05:30
laurenspriem f25f119ca1 [mob][photos] Copy 2024-05-27 17:26:14 +05:30
laurenspriem 89a61b3bf7 [mob][photos] Bump 2024-05-27 17:21:29 +05:30
laurenspriem 380d37267b [mob][photos] Don't pop too often 2024-05-27 17:19:06 +05:30
laurenspriem 9cf5691e42 [mob][photos] Delete instead of drop table 2024-05-27 17:09:33 +05:30
laurenspriem 8f474a4500 [mob][photos] Set MLController timer to 10 seconds 2024-05-27 15:54:10 +05:30
Manav Rathi c7be2270ff
[desktop] RC fixes (#1884) 2024-05-27 15:16:04 +05:30
laurenspriem ced1f0bd79 [mob][photos] Don't remove last cluster of person 2024-05-27 14:55:52 +05:30
Manav Rathi 9f58f1eeb3
Fix error on refresh while a folder watch is being set up
Notes:

From QA

> This error mostly happens if i add a watch folder and before watch folders
  start to upload and i refresh the app.

e is undefined in

    let {watches: e, removeWatch: n} = t;
    return 0 === e.length ? (0,...

Results in Next throwing

    Application error: a client-side exception has occurred (see the browser console for more information).
2024-05-27 14:42:56 +05:30
Manav Rathi 04be2b6a2c
Update electron updater
Trying to rule out https://github.com/electron-userland/electron-builder/issues/7127
2024-05-27 14:00:24 +05:30
laurenspriem 9f361237b1 [mob][photos] Fix cluster appbar not showing 2024-05-27 13:04:20 +05:30
Manav Rathi 8cb7cae7b7
[web] Fix display of auth codes on Safari (#1882) 2024-05-27 13:03:19 +05:30
Manav Rathi a2a209a849
[web] Fix display of codes on Safari 2024-05-27 12:59:32 +05:30
ashilkn d413c4f4c1 [mob][photos] Add try catch + logs for debugging in FaceMLDataDB 2024-05-27 12:57:25 +05:30
ashilkn ee8976e92b [mob][photos] Add schema migration easier on FaceMLDataDB 2024-05-27 12:56:20 +05:30
laurenspriem baa90c42ad [mob][photos] Remove stale comments 2024-05-27 11:59:36 +05:30
laurenspriem 30ade541df [mob][photos] Logging 2024-05-27 11:57:46 +05:30
laurenspriem 86fb8ebfaf [mob][photos] Fix indexing issue on iOS 2024-05-27 11:57:40 +05:30
laurenspriem b2e8c3c0eb [mob][photos] Remove restriction for ML for F-Droid 2024-05-27 11:51:20 +05:30
Ashil e203a8378e
[mob][photos] Trigger send logs if app is stuck in spalsh screen for >= 15 seconds (#1796) 2024-05-27 11:31:18 +05:30
laurenspriem b100f1d4bf [mob][photos] Catch and stopwatch on faces db creation 2024-05-27 11:28:05 +05:30
laurenspriem 7b4559f3ca [mob][photos] Reduce clustering frequency 2024-05-27 10:49:42 +05:30
Neeraj Gupta eac142025d
[mob] Increase limit to 50 for adding asset from device (#1873)
## Description

## Tests
2024-05-27 10:31:46 +05:30
Manav Rathi c5aa536c3b
[web] App context refactoring (#1879) 2024-05-26 22:03:33 +05:30
Manav Rathi 05406333e4
Split types 2024-05-26 21:55:16 +05:30
Manav Rathi 8ebd50606a
lf 2024-05-26 21:32:24 +05:30
Manav Rathi cbcfc243fc
lf 2024-05-26 21:02:48 +05:30
Manav Rathi 7d497b5ae1
Revert reimportability 2024-05-26 20:43:53 +05:30
Manav Rathi b28f6c3d8c
reduce auth 2024-05-26 20:31:32 +05:30
Manav Rathi 71a8049a35
reduce accounts 2024-05-26 20:28:59 +05:30
Manav Rathi e95cba0ace
Reduce boilerplate 2024-05-26 20:25:02 +05:30
Manav Rathi e836ada0d6
Refactor 2024-05-26 20:13:53 +05:30
Manav Rathi 19a104374d
Refactor 2024-05-26 19:49:23 +05:30
Manav Rathi 693ef45e2c
Refactor 2024-05-26 19:39:32 +05:30
Manav Rathi 55bdb070ce
Wrap 2024-05-26 19:14:35 +05:30
Manav Rathi 27127ff3d4
2fa 2024-05-26 19:12:12 +05:30
Manav Rathi 345c706814
ce 2024-05-26 19:07:48 +05:30
Manav Rathi 49133b7b86
Move 2024-05-26 19:02:47 +05:30
Manav Rathi 3a5311cdcc
cp 2024-05-26 18:58:57 +05:30
Neeraj Gupta 7182795732
[auth] New translations (#1836)
New translations from
[Crowdin](https://crowdin.com/project/ente-authenticator-app)
2024-05-26 18:55:51 +05:30
Manav Rathi ca00b3b558
creds 2024-05-26 18:55:20 +05:30
Manav Rathi 4bcb765810
[web] Passkey fixes (#1866)
@ua741 Not sure if passkey code is supposed to work on web yet, but I
was doing an unrelated change and noticed that clicking passkeys didn't
even try to redirect to accounts. I don't have a test setup for
passkeys, so don't know if these changes are 100% correct, but at least
now it redirects to accounts. Can test fully when doing final
integration.

- Use correct origin for passkey API requests
- Fix key length error
- Fix param name to match server
- Pass the token instead of a query param
2024-05-26 18:55:11 +05:30
Manav Rathi 17b49595a0
generate 2024-05-26 18:23:55 +05:30
Manav Rathi b99c573d3a
verify 2024-05-26 18:22:07 +05:30
Manav Rathi d3d3e4dbed
signup 2024-05-26 18:19:12 +05:30
Manav Rathi ba1af5eaf0
Move 2024-05-26 18:14:34 +05:30
Manav Rathi 14cf59c1e5
recover 2024-05-26 18:13:02 +05:30
Manav Rathi 452872156a
login 2024-05-26 18:10:22 +05:30
Manav Rathi 4f31bd625d
Context 2024-05-26 18:05:04 +05:30
Manav Rathi 6bf6f78147
Refactor app context types 2024-05-26 17:53:49 +05:30
Neeraj Gupta 5576f99548 [mob] Increase limit to 50 for adding asset from device 2024-05-26 16:55:31 +05:30
Manav Rathi 5bbe768acb
Scaffold 2024-05-26 16:06:29 +05:30
Manav Rathi babe378301
Move 2024-05-26 16:03:16 +05:30
Manav Rathi b2fda16561
Home route 2024-05-26 15:55:41 +05:30
Manav Rathi 6d289d73db
Add a new type 2024-05-26 15:50:02 +05:30
Manav Rathi 17acf4b3ee
[web] New translations (#1872)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2024-05-26 15:33:35 +05:30
Crowdin Bot 4d666d4b01 New Crowdin translations by GitHub Action 2024-05-26 10:00:34 +00:00
Manav Rathi 619f8319ed
[web] Title improvements - P1 (#1871)
Opening the PR to sync the translations, will make other changes
subsequently.
2024-05-26 15:24:51 +05:30
Manav Rathi 3261da3515
title 2024-05-26 15:19:05 +05:30
Manav Rathi d0d491f7f5
Pass the token instead of a query param 2024-05-26 08:36:57 +05:30
Manav Rathi db3764d448
Fix param name to match server 2024-05-26 08:36:57 +05:30
Manav Rathi 5fe5451f5c
Fix key length error
[error] failed to redirect to accounts page: TypeError: invalid key length
2024-05-26 08:36:57 +05:30
Manav Rathi 6d3d5d03f8
Use correct origin for passkey API requests 2024-05-26 08:36:57 +05:30
Manav Rathi 582eb9e1ea
[web] Enable Typescript's strict mode for auth's code (#1865) 2024-05-26 08:35:11 +05:30
Manav Rathi 51770a11ef
Tweak 2024-05-26 08:12:52 +05:30
Manav Rathi 1ea7a8f3a7
tweak 2024-05-26 07:20:52 +05:30
Manav Rathi b4536a7aee
[meta] Update issue template (#1864) 2024-05-26 05:31:17 +05:30
Manav Rathi 9d2be29fad
[meta] Update issue template 2024-05-26 05:16:36 +05:30
Manav Rathi f92a18efca
[server] Mention more details around s3 provider config (#1863) 2024-05-26 04:53:03 +05:30
Manav Rathi af382d483d
[server] Mention more details around s3 provider config 2024-05-26 04:50:44 +05:30
Manav Rathi 99f1ba799d
lhs of && cannot be a number
needs to be false for the hole
2024-05-25 20:56:46 +05:30
Manav Rathi 1548bcd378
Fix dialog 2024-05-25 20:30:43 +05:30
Vishnu Mohandas c2fc0a3d57
Update verification email address (#1855) 2024-05-25 18:48:50 +05:30
vishnukvmd 39a706ea20 Update verification email address 2024-05-25 18:47:19 +05:30
Manav Rathi 38d6464f55
muppets 2024-05-25 18:13:11 +05:30
Manav Rathi c5b6297cea
Wrap 2024-05-25 18:05:22 +05:30
Manav Rathi 390b4b1f81
Towards noUncheckedIndexedAccess 2024-05-25 17:44:49 +05:30
Manav Rathi b19b34b3dc
Prune 2024-05-25 17:39:45 +05:30
Manav Rathi 5690d613bb
tsc 2024-05-25 17:17:21 +05:30
Manav Rathi bb713cfc76
Cannot avoid a undefined initial app context 2024-05-25 17:14:08 +05:30
Manav Rathi 4a0c93373d
st 2024-05-25 17:00:51 +05:30
Manav Rathi b42759d473
tsc 2024-05-25 16:55:31 +05:30
Manav Rathi 2e93281368
tsc 2024-05-25 16:51:58 +05:30
Manav Rathi c18be32c09
Rearrange 2024-05-25 16:48:13 +05:30
Manav Rathi 650163c341
id is always sent be server 2024-05-25 16:40:28 +05:30
Manav Rathi d101208baa
tsc 2024-05-25 16:34:10 +05:30
Manav Rathi 76f7215269
Filter 2024-05-25 16:31:42 +05:30
Manav Rathi 621c482529
tsc 2024-05-25 16:27:46 +05:30
Manav Rathi 314c8f69f2
Comment out 2024-05-25 16:24:14 +05:30
Manav Rathi 1f45cf00c7
tsc 2024-05-25 16:20:47 +05:30
Manav Rathi e0e80ee91f
tsc 2024-05-25 16:08:50 +05:30
Manav Rathi 225278adb7
tsc 2024-05-25 16:06:24 +05:30
Manav Rathi 8d30bfbefa
tsc 2024-05-25 15:43:08 +05:30
Manav Rathi ad96f679c9
tsc 2024-05-25 15:39:20 +05:30
Manav Rathi 4b896d3aab
tsc 2024-05-25 15:37:05 +05:30
Manav Rathi 533e6d06e7
tsc 2024-05-25 15:32:56 +05:30
Manav Rathi e88b5c99ba
tsc 2024-05-25 15:29:01 +05:30
laurenspriem 1ec7e02695 [mob][photos] Copy change 2024-05-25 12:03:34 +05:30
Manav Rathi 19e08cf803
tsc 2024-05-25 10:15:43 +05:30
Manav Rathi 08073b927c
tsc 2024-05-25 10:12:40 +05:30
Manav Rathi 711a44412d
tsc 2024-05-25 10:08:14 +05:30
Manav Rathi c9f94f062b
tsc 2024-05-25 10:04:54 +05:30
Manav Rathi c8205b8475
tsc
The only place I can currently find where this code would run is on the delete
account dialog, where props.color is being passed.
2024-05-25 10:02:09 +05:30
Manav Rathi b0d3fcfe79
tsc 2024-05-25 09:38:45 +05:30
Manav Rathi 11a354c560
tsc 2024-05-25 09:37:07 +05:30
Manav Rathi 823f739c32
tsc 2024-05-25 09:31:09 +05:30
Manav Rathi f8876c8154
[docs] Add steam import guide to sidebar (#1850) 2024-05-25 08:37:35 +05:30
Manav Rathi 90db45d845
uploading 2024-05-25 08:35:41 +05:30
Manav Rathi 6a1f5945b9
pretty 2024-05-25 08:34:36 +05:30
Manav Rathi f7ca838428
Add to sidebar 2024-05-25 08:33:51 +05:30
Manav Rathi 2b065dd68d
yarn pretty 2024-05-25 08:32:00 +05:30
Manav Rathi f168ea9e1e
[docs] Mention troubleshooting tips for 403 forbidden when self-hosting (#1849) 2024-05-25 08:27:46 +05:30
Manav Rathi 58702103f3
Add link to example 2024-05-25 08:26:52 +05:30
Manav Rathi dfb3a6f65c
[docs] Add a section about 403 forbidden 2024-05-25 08:19:12 +05:30
Manav Rathi 491f38b120
tsc 2024-05-25 07:44:16 +05:30
Manav Rathi 79c0880c9c
tsc 2024-05-25 07:40:38 +05:30
Manav Rathi 834b8f78b7
opts 2024-05-25 07:39:24 +05:30
Manav Rathi cbf0336cd0
More 2024-05-25 07:37:53 +05:30
Manav Rathi 431d629641
Start tackling strict null 2024-05-25 07:35:07 +05:30
Manav Rathi 94c1cc011b
lf 2024-05-25 07:26:20 +05:30
Manav Rathi b26b0759d6
tsc 2024-05-25 07:10:47 +05:30
Manav Rathi d51fb99fd3
type for tsc 2024-05-25 06:34:13 +05:30
Manav Rathi 0379216e05
Remove sx prop (in prep for typing) 2024-05-25 06:30:21 +05:30
Manav Rathi ccd486f659
tsc 2024-05-25 06:22:11 +05:30
Manav Rathi ce3ab55069
tsc 2024-05-25 06:21:02 +05:30
Manav Rathi 34effef810
tsc 2024-05-25 06:19:01 +05:30
Manav Rathi 56aceb589d
tsc 2024-05-25 06:06:29 +05:30
Manav Rathi 92a2506f8a
Reduce prop scope 2024-05-25 06:02:47 +05:30
Manav Rathi e23bc2602f
Reorder 2024-05-25 06:01:06 +05:30
Manav Rathi 69beecb7bb
tsc
Omit<...,"inherit"> doesn't resolve

    Element implicitly has an 'any' type because expression of type 'OverridableStringUnion<"error" | "inherit" | "secondary" | "primary" | "info" | "success" | "warning", ButtonPropsColorOverrides>' can't be used to index type 'Palette'.
      Property 'inherit' does not exist on type 'Palette'.
2024-05-25 05:57:33 +05:30
Manav Rathi 880b13f436
Fix 2024-05-24 20:48:07 +05:30
Manav Rathi 9061caac99
Ditto 2024-05-24 20:43:32 +05:30
Manav Rathi 11cc8e46b7
Session storage shouldn't be undefined in newer browsers
Tried FF incognito
2024-05-24 20:41:11 +05:30
Manav Rathi 54820689c2
Towards removing implicit anys 2024-05-24 20:16:55 +05:30
Manav Rathi acebb86fec
Towards strict 2024-05-24 19:49:11 +05:30
Manav Rathi 367e09599d
Enable more 2024-05-24 19:43:10 +05:30
Manav Rathi b9fe509567
Enable noImplicitReturns 2024-05-24 19:41:37 +05:30
Manav Rathi 82bffd81de
[web] Tighten auth's tsconfig.json (#1846)
Ongoing process, just some steps in the direction we wish.
2024-05-24 19:03:53 +05:30
Manav Rathi 7340443b86
lf 2024-05-24 18:57:32 +05:30
Manav Rathi 2cd1dfd720
Chip away 2024-05-24 18:54:16 +05:30
Neeraj Gupta 3c8d29bcdc
[mob] Use custom assetPickerTextDelegate to use en as default (#1844)
## Description

## Tests
Tested locally
2024-05-24 18:24:48 +05:30
Laurens Priem 06a698ddbb
Face wake (#1843)
## Description

- Fix issue with thumbnail decoding in indexing
- Fix show correct cluster progress counter
- Add wakelock to ML settings page
- Show in settings when device health is low

## Tests

Tested in debug on my pixel
2024-05-24 18:22:00 +05:30
Manav Rathi 3b8c48e92d
Create a next specific base
The include still needs to be specified in the importing tsconfig otherwise the
"." is resolved relative to the @/build-config.
2024-05-24 18:17:59 +05:30
Neeraj Gupta 3c0cb20a9b [mob] Use custom assetPickerTextDelegate to use en as default 2024-05-24 18:13:09 +05:30
Manav Rathi 74bb169f0d
Equivalent to "**/*.ts", "**/*.tsx", "**/*.d.ts"
From the docs: https://www.typescriptlang.org/tsconfig/#include

> If the last path segment in a pattern does not contain a file extension or
  wildcard character, then it is treated as a directory, and files with
  supported extensions inside that directory are included (e.g. .ts, .tsx, and
  d.ts by default).
2024-05-24 17:54:05 +05:30
laurenspriem 302890baef [mob][photos] Fix for PlatformException in video thumbnails 2024-05-24 17:48:03 +05:30
Manav Rathi 54e33d3f42
Create a WIP replacement 2024-05-24 17:29:06 +05:30
Manav Rathi 0adb94f405
Link to @/build-config 2024-05-24 17:17:55 +05:30
Manav Rathi 7d634aa703
Add a note 2024-05-24 17:16:16 +05:30
laurenspriem b1e0c83733 [mob][photos] Show pause status copy when device is unhealthy 2024-05-24 17:04:35 +05:30
laurenspriem d4af7792d4 [mob][photos] Forgot this in previous commit 2024-05-24 16:40:14 +05:30
laurenspriem f301ab57f2 [mob][photos] Use EnteWakeLock in ML settings page 2024-05-24 16:39:42 +05:30
laurenspriem 7b0f5909b5 [mob][photos] Ente wakelock utility 2024-05-24 16:39:24 +05:30
laurenspriem e9064f6904 [mob][photos] Correct cluster progress counter 2024-05-24 16:29:00 +05:30
laurenspriem 0d21fc77b5 [mob][photos] Keep ML settings page awake 2024-05-24 14:45:16 +05:30
Manav Rathi b26c6e9c0d
[web] Auth - Improve HOTP support (#1842)
- Use HOTP counter
- Don't advance the bar for HOTPs
2024-05-24 14:43:57 +05:30
Manav Rathi 057d11f39b
Fix typo 2024-05-24 14:38:49 +05:30
Manav Rathi c9de6d7a82
Don't advance the bar for HOTPs 2024-05-24 14:35:59 +05:30
Manav Rathi 698ac9f29e
Use HOTP counter 2024-05-24 14:30:05 +05:30
Manav Rathi a0d26c860c
[web] Fix auth ticker (#1841) 2024-05-24 14:16:32 +05:30
Manav Rathi bd2444d353
[web] Fix auth ticker 2024-05-24 14:11:56 +05:30
Manav Rathi ca24a86179
[web] Steam support on web version of auth (#1840) 2024-05-24 14:01:06 +05:30
Manav Rathi fffe96a4c7
Tweak 2024-05-24 13:49:21 +05:30
Manav Rathi 0ec75c2435
Parse the type 2024-05-24 13:47:11 +05:30
Manav Rathi cb78c848d6
Impl 2024-05-24 13:36:55 +05:30
Manav Rathi 6594db9393
Encode counter 2024-05-24 13:26:16 +05:30
Manav Rathi f6c40ee67d
fromBase32 is exposed in the library API 2024-05-24 13:18:42 +05:30
Manav Rathi 36aa33ed5a
Move to separate file 2024-05-24 13:08:41 +05:30
Neeraj Gupta 776dba4fb0
Face small improvements (#1839)
## Description

- Fix embeddings fetch issue
- Decrypt embeddings in computer
- Change clustering sorting and remove restrictions
- Cleaned up faces status page


## Tests

Tested in debug mode on pixel phone.
2024-05-24 12:52:41 +05:30
laurenspriem 7f49f530c5 [mob][photos] Bump 2024-05-24 12:47:10 +05:30
laurenspriem ef6fe80944 [mob][photos] Fix 400 on embedding fetch 2024-05-24 12:44:01 +05:30
Manav Rathi 370b28f9e4
Type 2024-05-24 12:39:06 +05:30
Manav Rathi 05e737cb11
Add steam as a type 2024-05-24 12:32:58 +05:30
laurenspriem 0fdb58eda1 [mob][photos] Force clustering first if too many unclustered faces 2024-05-24 12:30:22 +05:30
Manav Rathi 1ce90839fe
Remove type from auth UI 2024-05-24 12:18:28 +05:30
Manav Rathi 697946f415
Scaffold 2024-05-24 12:12:06 +05:30
laurenspriem cc91cb8012 [mob][photos] Correct mistake 2024-05-24 11:16:40 +05:30
Manav Rathi 754de7065f
[web] Auth cleanup - Part 3/3 (#1838)
Prep done.
2024-05-24 11:02:45 +05:30
laurenspriem 5587373b42 [mob][photos] Remove clustering restriction based on indexed amount 2024-05-24 11:00:05 +05:30
laurenspriem f1d1a4a9e1 [mob][photos] Clustering sort to cluster new files first 2024-05-24 10:57:27 +05:30
Manav Rathi dc38a8bc9f
Account for node/browser discrepancy 2024-05-24 10:51:19 +05:30
laurenspriem edf9f743f4 [mob][photos] Prefer using getFileIdFromFaceId 2024-05-24 10:27:16 +05:30
Manav Rathi fec040e528
Tweak error report 2024-05-24 10:20:58 +05:30
laurenspriem 86f96a5713 [mob][photos] Show intermediate clustering results 2024-05-24 10:19:24 +05:30
laurenspriem c3fb472287 [mob][photos] Fix clustering progress number 2024-05-24 10:18:17 +05:30
Manav Rathi eaf8b9cebc
Also include same workaround as mobile app 2024-05-24 10:10:59 +05:30
Manav Rathi 2ce9212457
We encodeURIComponent the pathname 2024-05-24 09:58:50 +05:30
laurenspriem 4fa59ce258 [mob][photos] Common ml util for getting indexable files across faces and clip 2024-05-24 09:56:10 +05:30
Manav Rathi 59ed89cba1
.get returns null when the property is not present 2024-05-24 09:49:20 +05:30
Manav Rathi 623b71715d
Wrap 2024-05-24 09:42:23 +05:30
laurenspriem a74943698f Merge remote-tracking branch 'origin/main' into face_small_improvements 2024-05-24 09:37:53 +05:30
Manav Rathi bfe8fd83ac
Take 2 2024-05-24 09:29:54 +05:30
Manav Rathi 0a01cac57b
Take 1 (incorrect) 2024-05-24 09:27:28 +05:30
Crowdin Bot b7f248fa93 New Crowdin translations by GitHub Action 2024-05-24 02:06:42 +00:00
Manav Rathi d814b6cdf0
Use standard URL parsing - WIP 1 2024-05-23 21:01:18 +05:30
Manav Rathi 1712bf60cb
[web] Auth cleanup - Part 2/x (#1834)
Preparing for steam support (sibling of
https://github.com/ente-io/ente/pull/1820)
2024-05-23 20:36:08 +05:30
Manav Rathi 369a5a5233
lf 2024-05-23 20:19:20 +05:30
Manav Rathi 9bae31d748
Parse 2024-05-23 19:38:23 +05:30
Manav Rathi 11453b327f
Improve docs with hints from otpauth
https://github.com/hectorm/otpauth
2024-05-23 19:34:53 +05:30
Manav Rathi 7780c1c7b7
Move to the correct place 2024-05-23 19:29:56 +05:30
Manav Rathi 0f1c98d0d0
Reword 2024-05-23 19:22:45 +05:30
Manav Rathi 48fcbdc98c
Reword 2024-05-23 19:10:42 +05:30
Manav Rathi 90d0196d47
Extract logic 2024-05-23 19:06:06 +05:30
Ashil 30a8691c7f
[mob][photos] Fix infinite loading on searching (#1830)
## Description

Search was infinitely loading even after all search results are ready.
2024-05-23 18:59:36 +05:30
Manav Rathi 69cea6786d
Redistr 2024-05-23 18:54:55 +05:30
laurenspriem ccac5e73a3 [mob][photos] Remove found faces from status 2024-05-23 18:13:47 +05:30
laurenspriem 3e79c8cf28 [mob][photos] Decrypt remote embeddings in computer 2024-05-23 18:12:41 +05:30
Neeraj Gupta 31dee1249d
Steam Authenticator migration guide (#1825)
A quick guide on how to use steamguard-cli to generate a Steam 2FA QR
code for Ente Auth

Inspired by
https://github.com/beemdevelopment/Aegis/wiki/Adding-Steam-to-Aegis-from-steamguard-cli,
but updated to utilize the latest flags provide by the steamguard-cli

addresses this:
https://github.com/ente-io/ente/discussions/1038#discussioncomment-9520070
2024-05-23 17:13:50 +05:30
Neeraj Gupta e5a293a6ab
Dart UI isolate fix (#1829)
## Description

Forgot to bump version in previous PR
2024-05-23 17:10:08 +05:30
laurenspriem ffcb68b32f [mob][photos] Bump 2024-05-23 17:05:15 +05:30
laurenspriem a8af90dfee [mob][photos] Bump 2024-05-23 17:02:47 +05:30
Neeraj Gupta 6ee38cb291
Dart UI isolate fix (#1828)
## Description

- Fix for using dart_ui_isolate package properly

## Test

Neeraj tested it
2024-05-23 16:45:17 +05:30
laurenspriem 3810df1b20 [mob][photos] Fix for dart_ui_isolate 2024-05-23 16:37:34 +05:30
laurenspriem cc8e345a17 Revert "[mob][photos] Revert back to FlutterIsolate"
This reverts commit c4a6011621.
2024-05-23 16:35:45 +05:30
laurenspriem 63653411b8 [mob][photos] Logs 2024-05-23 16:33:21 +05:30
laurenspriem c4a6011621 [mob][photos] Revert back to FlutterIsolate 2024-05-23 16:32:25 +05:30
Manav Rathi 1ee52c780f
[desktop] Allow refreshing when inside an album (#1827)
Steps to reproduce on Linux:

- Open an album
- Open a photo
- View > Reload

Causes a 404 page to be displayed.
2024-05-23 16:17:41 +05:30
Manav Rathi b402662c09
[desktop] Allow refreshing when inside an album
Steps to reproduce on Linux:

- Open an album
- Open a photo
- View > Reload

Causes a 404 page to be displayed.
2024-05-23 16:13:21 +05:30
Rex Ng 51756d45d9
Steam Authenticator migration guide
guide on how to use steamguard-cli to generate a qr code for Ente Auth
2024-05-23 17:41:15 +08:00
Neeraj Gupta a3bb7ad85a
[mob][photos] Use flutter 3.22 for internal build (#1824) 2024-05-23 14:51:44 +05:30
laurenspriem 17058299c1 [mob][photos] Use flutter 3.22 for internal build 2024-05-23 14:50:37 +05:30
Laurens Priem 65de02d8d9
Face fix (#1823)
## Description

- Bug fixes
- Logging

## Tests

Tested on my pixel phone with remote embedding fetch disabled.
2024-05-23 14:42:04 +05:30
Laurens Priem 1f9e222d6e
Merge branch 'main' into face_fix 2024-05-23 14:40:26 +05:30
Manav Rathi 3d96be6c27
[desktop] Keep integral millisecond precision for modified time (#1822)
Fixes the following upload:

> metadata: {title: xxx.jpeg, creationTime: 1715925330480368.8,
modificationTime: 1715925330480368.8, latitude: null, longitude: null,
fileType: 0, hash: ...}

Related: https://github.com/ente-io/ente/pull/1821
2024-05-23 14:38:31 +05:30
laurenspriem 1bbe495306 [mob][photos] Bump 2024-05-23 14:36:17 +05:30
laurenspriem a76f3ca1b3 [mob][photos] Logging 2024-05-23 14:35:22 +05:30
laurenspriem 7800b7db32 [mob][photos] Regularly check for wifi 2024-05-23 14:35:15 +05:30
Manav Rathi ea2a355bcc
Revert to the behaviour of the existing 1.6.63 client 2024-05-23 14:34:24 +05:30
laurenspriem d585b75514 [mob][photos] Logging 2024-05-23 14:27:29 +05:30
Manav Rathi 5caa32b1e0
Also add for zip reading 2024-05-23 14:27:17 +05:30
laurenspriem 11402d7819 [mob][photos] Fix indexing pausing 2024-05-23 14:27:12 +05:30
Ashil a41f705dad
Upgrade to flutter 3.22.0 (#1804) 2024-05-23 14:17:47 +05:30
Neeraj Gupta 69b808e62c
[mobile] New translations (#1788)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-app)
2024-05-23 14:10:39 +05:30
laurenspriem 1e1e629891 [mob][photos] Set parallel fetch to five 2024-05-23 14:07:04 +05:30
Manav Rathi a7e96d055c
[web] Auth cleanup - Part 1/x (#1820)
In preparation for adding steam support
2024-05-23 13:42:34 +05:30
Manav Rathi 5e2261f793
Unclass 2024-05-23 13:36:44 +05:30
Manav Rathi 206be5c16f
Document 2024-05-23 13:19:05 +05:30
Manav Rathi 41c87efc5a
Use the union 2024-05-23 13:07:33 +05:30
Manav Rathi 171af35d85
Reword 2024-05-23 13:06:27 +05:30
Manav Rathi 99f47dc1ae
Move into the function 2024-05-23 13:03:31 +05:30
Neeraj Gupta cc7a516eba
[mob][photos] Bump (#1819)
## Description

## Tests
2024-05-23 13:00:41 +05:30
Manav Rathi 26436f116f
Nonopt 2024-05-23 12:58:47 +05:30
laurenspriem 9eab415906 [mob][photos] Bump 2024-05-23 12:58:42 +05:30
Manav Rathi 14655e5633
Fix 2024-05-23 12:47:29 +05:30
Manav Rathi 51dc8d1de6
Rearrange 2024-05-23 12:40:35 +05:30
Manav Rathi 51568e6c56
non optional 2024-05-23 12:20:04 +05:30
Manav Rathi d2743f4121
Unclass 2024-05-23 12:16:02 +05:30
Neeraj Gupta 05c50e78bc
Face flag (#1818)
## Description

Changes faces flag to use beta flag.
2024-05-23 12:13:46 +05:30
laurenspriem 9ac7b29e96 [mob][photos] Bump 2024-05-23 12:12:37 +05:30
laurenspriem 42106a72b3 [mob][photos] Change faces flag 2024-05-23 12:12:19 +05:30
Manav Rathi 2504046e26
Move 2024-05-23 12:11:11 +05:30
Manav Rathi a104f36561
Inline 2024-05-23 12:06:54 +05:30
Manav Rathi b26afdcf2e
Inline 2024-05-23 11:43:35 +05:30
Manav Rathi bf707ae02d
Inline 2024-05-23 11:37:55 +05:30
Manav Rathi 68648d2f6c
Remove nesting 2024-05-23 11:35:44 +05:30
Manav Rathi 371b8bf9cc
[web] Rework the video chunk decryptor stream logic (#1817) 2024-05-23 10:56:24 +05:30
Manav Rathi 3b89471b87
Use a standard converter 2024-05-23 10:17:11 +05:30
Manav Rathi 8a2117f9d4
Chunk 2024-05-23 10:09:47 +05:30
Manav Rathi 132ddd3648
Rework the video chunk decryptor stream logic
When running on Ubuntu 24 arm64 in the desktop app (didn't test on web0, trying
to open certain videos fails with:

> [rndr] [error] Failed to process file stream: TypeError: Failed to execute
  'enqueue' on 'ReadableStreamDefaultController': Cannot enqueue a chunk into a
  closed readable stream

While not specifically fixing that issue, I'm first rewriting this to use the
more normal (recommended?) approach of implementing a pull instead of doing
everything in start. Maybe that fixes the issue, otherwise at least one less
ghost for me to worry about.
2024-05-23 09:51:29 +05:30
Neeraj Gupta 048aaee40d
[mob][photos] Bump (#1814)
## Description

Bump for internal release, which I forgot in previous PR.
2024-05-22 18:58:35 +05:30
laurenspriem 04475110ce [mob][photos] Bump 2024-05-22 17:56:43 +05:30
Laurens Priem 02366eb27f
[mob][photos] Small fix in index scheduling (#1813)
## Description

- Small fix for scenario where MLController fired quicker than we could
pause

## Tests

Tested on my pixel phone.
2024-05-22 17:21:30 +05:30
laurenspriem 6c3953e855 [mob][photos] Small fix in index scheduling 2024-05-22 17:11:11 +05:30
Laurens Priem 201286f59a
Ml fixes (#1812)
## Description

- Fixed some issues in face indexing
- Cleaned up some functions in FaceMlService
- Hooked iOS onto MLController for battery check, for faces and clip

## Tests

Tested on my Pixel phone only
2024-05-22 16:56:16 +05:30
Prateek Sunal b00bffd785
Ente Auth: Add support for Steam domain (steampowered.com) as an issuer (#1809)
## Description
I don't think I'm the only one using website domains as issuers of TOTP
codes. This change will add support for the Steam domain
(steampowered.com) as an issuer.
2024-05-22 16:32:33 +05:30
laurenspriem d477b55071 [mob][photos] Bump 2024-05-22 16:23:15 +05:30
Vladyslav Pashynskykh 227b7ddba0
Use uri.host instead of issuer in _GetDigits 2024-05-22 13:51:07 +03:00
laurenspriem d12f570178 [mob][photos] Logging 2024-05-22 16:15:30 +05:30
Vladyslav 70dc660f5a
Merge branch 'ente-io:main' into main 2024-05-22 13:37:42 +03:00
laurenspriem e4c379963f [mob][photos] Logging 2024-05-22 16:04:26 +05:30
laurenspriem e44be63586 [mob][photos] Logs 2024-05-22 15:54:56 +05:30
laurenspriem 6d5436c885 [mob][photos] Hook iOS into MLController for temperature check only 2024-05-22 15:50:14 +05:30
Vladyslav Pashynskykh d75abcf6a7
Ente Auth: Add support for Steam domain used as issuer 2024-05-22 13:02:11 +03:00
laurenspriem b3229785a0 [mob][photos] Small fix 2024-05-22 15:26:03 +05:30
Prateek Sunal bd8757bbb8
[FIX (Auth)] Destroy window on exit, Color scheme fix, Hide code for steam fix (#1810)
## Description

## Tests
2024-05-22 15:24:08 +05:30
laurenspriem 92bafa7c38 [mob][photos] Temp fix for double assigned persons 2024-05-22 15:19:07 +05:30
laurenspriem df756076e8 [mob][photos] Small cleanup of FaceMlService 2024-05-22 14:52:13 +05:30
laurenspriem ffc9eecbd1 [mob][photos] Move listeners inside init 2024-05-22 14:45:16 +05:30
laurenspriem 678efd1e8b [mob][photos] Refactor of flags for faceMlService 2024-05-22 14:41:44 +05:30
Prateek Sunal 9ab82621b9 fix(auth): hide codes reg ex, match every non-whitespace character 2024-05-22 14:08:09 +05:30
Prateek Sunal 59c2c7e343 fix(auth): color scheme for pinned 2024-05-22 14:06:41 +05:30
Prateek Sunal 8c3c0b2128 fix(auth): destroy window when exiting from tray 2024-05-22 13:30:42 +05:30
Vladyslav Pashynskykh 954581093d
Ente Auth: Add support for Steam domain used as issuer 2024-05-22 09:51:12 +03:00
laurenspriem 78afae4013 [mob][photos] Lower file download limit 2024-05-22 11:40:22 +05:30
laurenspriem 7811c58214 [mob][photos] Inline 2024-05-22 11:08:51 +05:30
laurenspriem 85a8f6b7cf [mob][photos] MLController lower interaction times for now 2024-05-22 10:47:08 +05:30
Manav Rathi f60e750848
[web] Inline sidebar code (#1803)
... to make it more manageable.
2024-05-21 20:04:02 +05:30
Manav Rathi a086f36433
Fix type 2024-05-21 19:38:42 +05:30
Manav Rathi 4cb49c0b4a
Fix warning about required key 2024-05-21 19:31:52 +05:30
Manav Rathi 334587474f
Inline 2024-05-21 19:20:50 +05:30
Manav Rathi 0d52737c49
Inline 2024-05-21 19:18:54 +05:30
Manav Rathi d4dc080231
Inline 2024-05-21 19:14:50 +05:30
Manav Rathi f8d35c3dcf
Inline 2024-05-21 19:10:29 +05:30
Manav Rathi c20b9fa5fa
Rename 2024-05-21 19:07:04 +05:30
Manav Rathi 6a8fa727a9
Inline 2024-05-21 19:06:30 +05:30
Manav Rathi 7712a8bd10
Inline 2024-05-21 18:45:53 +05:30
Manav Rathi 4feb8fd1f1
Inline 2024-05-21 18:44:36 +05:30
Manav Rathi 994876911a
Inline 2024-05-21 18:42:42 +05:30
Manav Rathi d6398bd8fc
Inline 2024-05-21 18:39:42 +05:30
Manav Rathi 43064b617a
Inline 2024-05-21 18:36:26 +05:30
Manav Rathi 789783a370
Inline 2024-05-21 18:34:06 +05:30
Manav Rathi 9db1197c19
Inline 2024-05-21 18:33:08 +05:30
Manav Rathi 56a71c2cd8
Inline 2024-05-21 18:31:55 +05:30
Neeraj Gupta 608c97603b
Mobile face (#1799)
## Description

One fix related to DB, rest just more logging
2024-05-21 17:02:40 +05:30
laurenspriem a9721e7744 [mob][photos] Bump 2024-05-21 17:02:14 +05:30
Neeraj Gupta 44e5af0434
[mob] Fix bug during logout (#1800)
## Description

## Tests
Tested locally
2024-05-21 16:59:20 +05:30
Neeraj Gupta dfbdc94e61 [mob] Fix bug during logout 2024-05-21 16:58:54 +05:30
laurenspriem 71d3427879 [mob][photos] Logging 2024-05-21 16:56:00 +05:30
laurenspriem d235ff1035 [mob][photos] Inline 2024-05-21 16:53:52 +05:30
laurenspriem ee5be7f339 [mob][photos] Make sure faces tables are initialized 2024-05-21 16:43:55 +05:30
Neeraj Gupta 9b0e8b265d
[auth] New translations (#1789)
New translations from
[Crowdin](https://crowdin.com/project/ente-authenticator-app)
2024-05-21 16:43:18 +05:30
laurenspriem c0f243cee0 [mob][photos] Logging 2024-05-21 16:37:06 +05:30
laurenspriem 1bd2033a63 [mob][photos] Make sure clustering can run again after exception 2024-05-21 16:34:46 +05:30
Manav Rathi 982f0d8f77
[web] Improve consistency with mobile impl (#1797) 2024-05-21 16:12:57 +05:30
Manav Rathi 9e26b81adf
We don't need them 2024-05-21 16:03:47 +05:30
Manav Rathi 94cc26aead
xMin, yMin to x, y in the remote format 2024-05-21 15:51:55 +05:30
Neeraj Gupta d4b4007d96
[Auth] Fix parsing of code display when issuer/account contains special character (#1795)
## Description

## Tests
2024-05-21 14:48:12 +05:30
Neeraj Gupta 2daf5c8fde [auth] Bump version 3.0.4+304 2024-05-21 14:45:19 +05:30
Neeraj Gupta 7a5d4cedf6 Add log 2024-05-21 14:42:51 +05:30
Neeraj Gupta 2abc57f981 Minor refactor 2024-05-21 14:36:53 +05:30
Manav Rathi 2d5894c5d6
Convert point and box to regular objects 2024-05-21 14:28:33 +05:30
laurenspriem 0d43c0d326 Merge remote-tracking branch 'origin/main' into mobile_face 2024-05-21 14:06:04 +05:30
laurenspriem 1b46e159da [mob][photos] Put x and y instead of xMin and yMin in embeddingsJSON 2024-05-21 14:03:19 +05:30
Neeraj Gupta a4d6fece41 Fix OTPAuthUrl format 2024-05-21 13:50:18 +05:30
Neeraj Gupta 86b24a4ccf [auth] Add safe parsing of code display 2024-05-21 13:34:01 +05:30
Neeraj Gupta 8520cdd1bb Gracefully handle failure in codeDisplay parsing 2024-05-21 13:05:10 +05:30
Neeraj Gupta 0655617a9e Improve log 2024-05-21 12:59:39 +05:30
Manav Rathi 4dbc8ab31e
[web] ML prune todos (#1791) 2024-05-21 11:56:13 +05:30
Manav Rathi 1a376a1a9b
Update deps 2024-05-21 11:52:01 +05:30
Manav Rathi 6e82964bf2
Post rebase 2024-05-21 11:50:13 +05:30
Manav Rathi fdd5ffd45c
Rename 2024-05-21 11:48:07 +05:30
Manav Rathi ccb5c48c7d
Comment 2024-05-21 11:46:49 +05:30
Manav Rathi 074d315c9f
We need both 2024-05-21 11:46:48 +05:30
Manav Rathi b8734fcc6c
Add TODO 2024-05-21 11:46:27 +05:30
Manav Rathi a8229f325d
Document and move 2024-05-21 11:46:27 +05:30
Manav Rathi 5768edb3a5
Thank you Laurens! 2024-05-21 11:46:27 +05:30
Manav Rathi 8bc80d2821
Merge 2024-05-21 11:46:26 +05:30
Manav Rathi 825f5ff88d
Inline 2024-05-21 11:45:56 +05:30
Manav Rathi 5aee42d59d
Remove calculation 2024-05-21 11:45:56 +05:30
Manav Rathi c8be764f35
Remove unused rotation 2024-05-21 11:45:55 +05:30
Manav Rathi 4e2f7c95e3
[web][photos] solve TODOs (#1790)
## Description

- Removed redundant rotation parameter in cropping
- Reviewed TODO regarding dependency: no changes
- Included proper Non-Max Suppression for filtering faces, same as on
Mobile
2024-05-21 11:42:26 +05:30
laurenspriem 56cd3a9949 [web][photos] Rename cropWithRotation to cropImage 2024-05-21 11:39:46 +05:30
Manav Rathi 12ce21cd08
[web] New translations (#1787)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2024-05-21 11:38:47 +05:30
laurenspriem ae5496f306 [web][photos] solve TODOs 2024-05-21 11:35:07 +05:30
Crowdin Bot d23638c30d New Crowdin translations by GitHub Action 2024-05-21 02:05:40 +00:00
Crowdin Bot 5724fad813 New Crowdin translations by GitHub Action 2024-05-21 01:57:44 +00:00
Crowdin Bot ffe54f591c New Crowdin translations by GitHub Action 2024-05-21 01:40:33 +00:00
Prateek Sunal 13f9358a4f
[FIX] Auth desktop icons and steam code (#1783)
## Description

## Tests
2024-05-20 23:06:34 +05:30
Prateek Sunal 4289ab2393 chore(auth): capitalize app name 2024-05-20 23:01:32 +05:30
Prateek Sunal 4032952168 fix(auth): show progress for steam too 2024-05-20 22:59:44 +05:30
Prateek Sunal d104fc6788 fix(auth): support stream codes completely 2024-05-20 22:59:22 +05:30
Prateek Sunal 85396158aa chore(auth): bump version 2024-05-20 21:22:35 +05:30
Prateek Sunal 3d91b548db Merge remote-tracking branch 'origin' into auth-deskicons 2024-05-20 21:18:11 +05:30
Prateek Sunal e500347fc5 fix(auth): update all desktop icons 2024-05-20 21:17:37 +05:30
Manav Rathi 9c667efee5
[web] Don't sync CLIP emeddings in the web app (#1782) 2024-05-20 21:10:21 +05:30
Manav Rathi 0877d9c788
[web] Don't sync CLIP emeddings in the web app 2024-05-20 20:59:05 +05:30
Manav Rathi be9f8b8b1d
[desktop] App name is always ente now
Fixed in 7049a901f8
2024-05-20 20:09:42 +05:30
Neeraj Gupta b1314729b1
Mobile faces v0 (#1776) 2024-05-20 17:46:38 +05:30
Neeraj Gupta c84acfd588
[auth] Bump version (#1779)
## Description

## Tests
2024-05-20 17:37:49 +05:30
Neeraj Gupta 41ba5b79e3 [auth] Bump version 2024-05-20 17:37:28 +05:30
Neeraj Gupta 0e957cbecb [photos] Bump version 0.8.97+617 2024-05-20 17:33:22 +05:30
Manav Rathi 6676c67cc3
[desktop] Fix logout (#1778) 2024-05-20 17:31:11 +05:30
Neeraj Gupta 57e9ef10af Fix lint 2024-05-20 17:30:57 +05:30
Neeraj Gupta ee7c1bafc3 Enable remote fetch 2024-05-20 17:29:09 +05:30
Manav Rathi dae9bdd583
[desktop] Fix logout 2024-05-20 17:21:10 +05:30
Neeraj Gupta 93473ebd12 Lint fix 2024-05-20 17:17:37 +05:30
Neeraj Gupta e9be2b46a1 Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-05-20 17:09:46 +05:30
Neeraj Gupta e4bec56ea3 Remove unused isar submodule 2024-05-20 17:09:23 +05:30
Neeraj Gupta 1e3fca2835 Remove unused submodule 2024-05-20 17:09:00 +05:30
Neeraj Gupta 58851f2d6e Remove unused submodule 2024-05-20 17:08:01 +05:30
laurenspriem 5172ce3126 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-05-20 16:56:53 +05:30
laurenspriem 3e1e26feb0 [mob][photos] Bigger and separate resources pool for face generation 2024-05-20 16:54:22 +05:30
Neeraj Gupta aa8e128c44 Merge branch 'main' into mobile_face 2024-05-20 16:42:11 +05:30
Neeraj Gupta cacb50b040 Fix git submodule 2024-05-20 16:40:21 +05:30
laurenspriem 58dcceca9f [mob][photos] Revert regression 2024-05-20 15:12:12 +05:30
laurenspriem 84f7d20966 [mob][photos] Put faces behind feature flag 2024-05-20 14:51:35 +05:30
Manav Rathi 41b22abc66
[desktop] ML touchups (#1777) 2024-05-20 14:49:50 +05:30
Manav Rathi 7049a901f8
Fix the app version in debug mode 2024-05-20 14:46:18 +05:30
Manav Rathi cb86ab84f3
Send user agent 2024-05-20 14:28:27 +05:30
laurenspriem 76848c826e [mob][photos] Change embeddings server structure 2024-05-20 14:18:34 +05:30
Manav Rathi 69b4fde936
Update TODOs based on discussion 2024-05-20 13:57:52 +05:30
Manav Rathi c2edac6192
Fix error I observed in logs
> TypeError: Cannot read properties of undefined (reading 'method')
2024-05-20 11:43:10 +05:30
Manav Rathi d7bd0f0200
[desktop] Fix ML put error 2024-05-20 11:33:43 +05:30
Manav Rathi 07ba9ef1d6
[desktop] ML: Clarify that existing indexed people will not show in this update (#1775) 2024-05-20 10:48:22 +05:30
Manav Rathi 10934b08a8
Handle first search on app start 2024-05-20 10:39:11 +05:30
laurenspriem 09b2732d76 [mob][photos] Use hidden cached files for count 2024-05-20 10:23:07 +05:30
Manav Rathi 34a8bdcf47
Remove unnecessary rounding 2024-05-20 10:15:41 +05:30
Manav Rathi 78420f65ab
Case 2024-05-20 10:09:41 +05:30
Manav Rathi 20dcf3e473
Annotate 2024-05-20 10:04:33 +05:30
Manav Rathi e97225fa10
Remove 2024-05-20 09:57:42 +05:30
Manav Rathi 476edd8cf5
Remove unused code paths
Only internal users come into such scenarios currently
2024-05-20 09:52:32 +05:30
Manav Rathi a3aa3755c6
[desktop] Clarify that existing indexed people will not show
These auto complete suggestions and the list of people in the photo details are
not shown when ML search is disabled, and it is disabled for non-internal users,
so updated the description.
2024-05-20 09:45:55 +05:30
laurenspriem a48c8b481e [mob][photos] Small changes 2024-05-20 09:41:11 +05:30
Manav Rathi 531547cd48
[web] Fix race condition in initialization of search worker (#1772)
During app init, two worker instances would get created in some cases
and two getInstances raced because of the await. This was causing the
search results to be empty until the page is reloaded (since the files
array was empty in the worker that got assigned, but the files would get
set to the other worker instance that lost the race).
2024-05-19 20:26:34 +05:30
Manav Rathi 97b964fd6c
[web] Fix race condition in initialization of search worker
During app init, two worker instances would get created in some cases and two
getInstances raced because of the await. This was causing the search results to
be empty until the page is reloaded (since the files array was empty in the
worker that got assigned, but the files would get set to the other worker
instance that lost the race).
2024-05-19 20:21:37 +05:30
Manav Rathi 69f06f753c
[web] ML cleanup - Part 7/x (#1771) 2024-05-19 20:19:59 +05:30
Manav Rathi e5a96222b9
Use 2024-05-19 19:14:48 +05:30
Manav Rathi 5c92bc5b89
Reduce scope 2024-05-19 19:08:07 +05:30
Manav Rathi f692638ede
Try to find a split point 2024-05-19 19:03:25 +05:30
Manav Rathi c2e42266a6
Remove unused 2024-05-19 18:57:35 +05:30
Manav Rathi 2db8c779b4
Convert to function (in preparation of declassing) 2024-05-19 18:56:42 +05:30
Manav Rathi 2d9831bc59
Move 2024-05-19 18:15:56 +05:30
Manav Rathi b026d861ff
Relative 2024-05-19 18:10:13 +05:30
Manav Rathi d9ba96b928
lf 2024-05-19 17:58:37 +05:30
Manav Rathi ffcf015e1c
lf 2024-05-19 16:58:24 +05:30
Manav Rathi b71b6142c5
Tweak 2024-05-19 16:57:19 +05:30
Manav Rathi 568e470752
Inline 2024-05-19 16:51:07 +05:30
Manav Rathi faf415277e
Trim 2024-05-19 16:46:01 +05:30
Manav Rathi bfc81b1ab6
Inline 2024-05-19 16:44:19 +05:30
Manav Rathi d99c10c15e
Inline 2024-05-19 16:41:42 +05:30
Manav Rathi d39cf15f26
Prune 2024-05-19 16:31:43 +05:30
Manav Rathi 37abeac87b
Comment out 2024-05-19 15:36:37 +05:30
Manav Rathi 7f5c951910
Split 2024-05-19 15:34:43 +05:30
Manav Rathi 87c7999370
Reduce API surface for migration 2024-05-19 15:21:45 +05:30
Manav Rathi ee894a668c
Reduce distance to server type 2024-05-19 13:23:08 +05:30
Manav Rathi 6b5788539b
Move out 2024-05-19 13:17:58 +05:30
Manav Rathi 9346ce3255
Prune 2024-05-19 13:12:27 +05:30
Manav Rathi 40dfeb5bca
Tweak 2024-05-19 12:57:47 +05:30
Manav Rathi 2e46f993f0
Remove duplicate alignment calculation 2024-05-19 12:50:31 +05:30
Manav Rathi ded2402483
Rearrange 2024-05-19 12:43:24 +05:30
Manav Rathi 393a8f11dd
Rearrange 2024-05-19 12:28:54 +05:30
Manav Rathi 82485ef9a1
Tweak 2024-05-19 12:24:17 +05:30
Manav Rathi b36d3befe0
Split 2024-05-19 12:10:53 +05:30
Manav Rathi e6ed6b4916
Tinker 2024-05-19 12:06:59 +05:30
Manav Rathi 6427c09f52
Don't let face crop save failures abort the entire indexing 2024-05-19 11:59:03 +05:30
Manav Rathi 9abc22ade5
Remove unused 2024-05-19 11:57:13 +05:30
Manav Rathi 1466ece701
Cache the caches 2024-05-19 11:54:00 +05:30
Neeraj Gupta 33a3eeb9b4
[server] Improve log (#1769)
## Description

## Tests
2024-05-19 08:35:29 +05:30
Neeraj Gupta 0949102959 Improve logs 2024-05-19 08:33:29 +05:30
Neeraj Gupta 367431bef8 Improve log 2024-05-19 08:31:32 +05:30
Neeraj Gupta 3bdb1e6277
[server] Remove fallback check as dc column was added with default dc b2 (#1768)
## Description

## Tests
2024-05-19 08:23:38 +05:30
Neeraj Gupta 113b776aea [server] Remove fallback check as dc column was added with default dc b2 2024-05-19 08:21:32 +05:30
Manav Rathi 99ed1bc9af
Show saved crops 2024-05-19 07:18:18 +05:30
Manav Rathi c1f0f67656
[meta] Prune gitignore (#1767)
About the auth dbs, discussed in chat: These files got created once when
debugging auth build for linux. They were probably accidental, so
removing them for now (will add back if there is a workflow when they
actively get recreated).
2024-05-18 21:28:22 +05:30
Manav Rathi 894acda782
[meta] Prune
About the auth dbs, discussed in chat: These files got created once when
debugging auth build for linux. They were probably accidental, so removing them
for now (will add back if there is a workflow when they actively get recreated).
2024-05-18 21:23:47 +05:30
Manav Rathi b6a2985432
[web] ML cleanup - Part 6/x (#1766) 2024-05-18 20:57:24 +05:30
Manav Rathi 3ade7b797e
Fix duplicate check 2024-05-18 20:50:35 +05:30
Manav Rathi 93c498b0f4
Remove unused context 2024-05-18 20:39:57 +05:30
Manav Rathi 6849041735
Tweak 2024-05-18 20:26:20 +05:30
Manav Rathi a4494f5c6a
Tweak 2024-05-18 20:23:31 +05:30
Manav Rathi 97adb89494
Tweak 2024-05-18 20:18:39 +05:30
Manav Rathi fe8ff0a12a
Remove redundant 2024-05-18 20:16:00 +05:30
Manav Rathi 8975546294
Simplify 2024-05-18 20:13:43 +05:30
Manav Rathi acd3568dc6
Tinker 2024-05-18 20:06:29 +05:30
Manav Rathi 3b6760c65e
Remove unused blazeflaze landmarks 2024-05-18 19:55:51 +05:30
Manav Rathi 6304d90b52
Inline 2024-05-18 19:50:13 +05:30
Manav Rathi 410b6e7d3e
Tinker 2024-05-18 19:41:34 +05:30
Manav Rathi a161203d0b
Inline 2024-05-18 19:32:34 +05:30
Manav Rathi c8623bab12
Cleanup 2024-05-18 17:42:27 +05:30
Manav Rathi aa76448747
Shorten 2024-05-18 17:32:42 +05:30
Manav Rathi 139370c997
Shorten 2024-05-18 17:31:39 +05:30
Manav Rathi 4d5ba47be4
Sugar 2024-05-18 17:27:41 +05:30
Manav Rathi 3f18fb84a1
Rearrange 2024-05-18 17:20:42 +05:30
Manav Rathi 39a75430a5
Inline 2024-05-18 17:19:29 +05:30
Manav Rathi c557e4a7a5
Inline 2024-05-18 16:56:18 +05:30
laurenspriem bd28254021 [mob][photos] Fix fix trigger for iOS 2024-05-18 16:54:46 +05:30
Manav Rathi a2e7231c37
Prune 2024-05-18 16:52:54 +05:30
Manav Rathi 9ba028b79d
Isolate 2024-05-18 16:52:25 +05:30
laurenspriem 7263c45300 [mob][photos] More debug 2024-05-18 16:50:11 +05:30
Manav Rathi 8f43c3d712
Simplify 2024-05-18 16:19:55 +05:30
Manav Rathi 76cfae12a5
Point of use 2024-05-18 16:02:27 +05:30
Manav Rathi b29436e160
Prune 2024-05-18 16:00:07 +05:30
Manav Rathi bcbd805404
Inline 2024-05-18 15:58:41 +05:30
laurenspriem 613dffa03f [mob][photos] Small refactor 2024-05-18 15:58:03 +05:30
Manav Rathi 433d0e81fc
Prune 2024-05-18 15:57:36 +05:30
Manav Rathi bef7574c29
Trim 2024-05-18 15:53:10 +05:30
laurenspriem 131108a6db [mob][photos] Debug option to run indexing 2024-05-18 15:23:24 +05:30
laurenspriem 90c0ad08da [mob][photos] Remove jank 2024-05-18 15:22:41 +05:30
laurenspriem a222e06634 [mob][photos] Fix breakup cluster for large clusters 2024-05-18 12:05:54 +05:30
laurenspriem bcf78fb4b9 [mob][photos] generated intl 2024-05-18 12:05:00 +05:30
Manav Rathi 996d9ccda5
[web] ML cleanup - Part 5/x (#1762) 2024-05-18 11:06:04 +05:30
Manav Rathi 772215eddc
Rearrange 2024-05-18 10:59:18 +05:30
Manav Rathi e13f59606f
Inline 2024-05-18 10:56:19 +05:30
Manav Rathi 4840214d89
Rearrange 2024-05-18 10:51:31 +05:30
Manav Rathi b3b79c2b90
Rearrange 2024-05-18 10:48:09 +05:30
Manav Rathi f25b4b37d0
Site of use 2024-05-18 10:46:34 +05:30
Manav Rathi 8a5bffc3e9
Remove unused 2024-05-18 10:43:44 +05:30
Manav Rathi 2791eeb270
Remove unused 2024-05-18 10:42:39 +05:30
Manav Rathi bd3bdf64c2
Tweak 2024-05-18 10:40:49 +05:30
Manav Rathi 56aaad62be
Tweak 2024-05-18 10:33:32 +05:30
Manav Rathi 88f9186be0
Split 2024-05-18 10:25:35 +05:30
Manav Rathi 9fa828e384
Restrict 2024-05-18 10:23:50 +05:30
Manav Rathi 42d767cac3
Shorten 2024-05-18 10:18:09 +05:30
Manav Rathi 17d78f23bb
Shorten 2024-05-18 10:14:15 +05:30
Manav Rathi 246d44648b
Reify 2024-05-18 10:11:16 +05:30
Manav Rathi 33d3428222
Move 2024-05-18 10:07:39 +05:30
Manav Rathi 295717ac2f
Simplify 2024-05-18 09:59:53 +05:30
Manav Rathi 9808dce44d
Pretty 2024-05-18 09:56:20 +05:30
Manav Rathi fb81a59d4b
Site of use 2024-05-18 09:51:42 +05:30
Manav Rathi 1edafd3568
[web] ML cleanup - Part 4/x (#1761) 2024-05-18 09:28:02 +05:30
Manav Rathi 0188749692
Prune 2024-05-18 09:21:17 +05:30
Manav Rathi 46ad045ed4
Merge 2024-05-18 09:19:14 +05:30
Manav Rathi 58193c0d7f
Remove unused exports 2024-05-18 09:18:32 +05:30
Manav Rathi 87f60149e1
Remove DB dependency from indexer 2024-05-18 09:16:53 +05:30
Manav Rathi ae70eb33dd
Inline 2024-05-18 09:13:48 +05:30
Manav Rathi e224ad19d3
Separate 2024-05-18 09:12:49 +05:30
Manav Rathi f9346c56e9
Inline 2024-05-18 09:02:59 +05:30
Manav Rathi e15460684d
Inline 2024-05-18 08:51:57 +05:30
Manav Rathi 93cdf73a66
Inline 2024-05-18 08:50:48 +05:30
Manav Rathi eaadc54184
Inline 2024-05-18 08:48:37 +05:30
Manav Rathi 5eb21fafbe
Extract indexer 2024-05-18 08:43:01 +05:30
Manav Rathi 8edb506b29
Prune 2024-05-18 08:07:49 +05:30
Manav Rathi a7e6b1bf5b
Prune 2024-05-18 08:04:09 +05:30
Manav Rathi 0109602168
Inline 2024-05-18 08:03:17 +05:30
Manav Rathi 25ced9ce9d
Prune 2024-05-18 08:00:42 +05:30
Manav Rathi fcd4459e6d
Move currently unused cluster stuff out of the way 2024-05-18 07:49:15 +05:30
Manav Rathi 295f4a0c2a
Essence 2024-05-18 07:27:58 +05:30
Manav Rathi 512766ebed
Essence 2024-05-18 07:21:43 +05:30
Manav Rathi d4449d0f0b
Remove noise 2024-05-18 07:10:24 +05:30
Manav Rathi 85562806a3
Prune 2024-05-18 07:07:48 +05:30
Manav Rathi a18566ff86
Remove error message persistence 2024-05-18 07:05:47 +05:30
Manav Rathi 5c7361262d
Prune 2024-05-18 07:00:46 +05:30
Neeraj Gupta b00ee96dde [mob] Fix indexing trigger for iOS 2024-05-18 05:31:20 +05:30
Neeraj Gupta ea587b6ccd [mob] Index hidden files 2024-05-18 05:31:04 +05:30
laurenspriem af88756b5d [mob][photos] Don't show people results until clustering is mostly done 2024-05-17 18:39:07 +05:30
laurenspriem df867b5957 [mob][photos] Undo change 2024-05-17 18:33:48 +05:30
laurenspriem 4bfb69dcc4 [mob][photos] Debug 2024-05-17 18:32:23 +05:30
laurenspriem b1ccc39178 [mob][photos] More debug options 2024-05-17 18:15:43 +05:30
laurenspriem b0ef3a070e Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-05-17 17:52:48 +05:30
Neeraj Gupta e331443691 [mob] Enable ml run on iOS 2024-05-17 17:47:10 +05:30
Neeraj Gupta 285b1f9527 Merge branch 'main' into mobile_face 2024-05-17 17:34:18 +05:30
laurenspriem 7a37eca4e6 [mob][photos] Refresh people section on people changed event 2024-05-17 17:33:31 +05:30
Prateek Sunal 19874e2186 chore: bump version to 301 2024-05-17 17:27:34 +05:30
Prateek Sunal 718b78adf0 chore(auth): update Podfile 2024-05-17 17:27:34 +05:30
Neeraj Gupta fd63597ef3
[auth] iOS build changes (#1758)
## Description

## Tests
2024-05-17 17:27:11 +05:30
Neeraj Gupta 38ab7ae157 [auth] iOS build changes 2024-05-17 17:26:42 +05:30
laurenspriem cd9db4d10f [mob][photos] Revert to SearchService just for now 2024-05-17 17:21:48 +05:30
laurenspriem 460025ce4a [mob][photos] Higher fetch limit 2024-05-17 17:16:49 +05:30
Neeraj Gupta d00a032b17
[auth] New translations (#1751)
New translations from
[Crowdin](https://crowdin.com/project/ente-authenticator-app)
2024-05-17 16:50:47 +05:30
laurenspriem b0fe3946ef [mob][photos] On empty people section go to ML status page 2024-05-17 16:19:38 +05:30
laurenspriem 8a2e2a8f80 [mob][photos] Copy change 2024-05-17 16:19:07 +05:30
laurenspriem c8efc5fca0 [mob][photos] Debug DB call timings 2024-05-17 15:52:08 +05:30
Neeraj Gupta 401cf92695
Make embedding bucket configurable (#1726)
## Description

## Tests
- [x] New ml data is doing to new bucket
- [x] For existing embedding, fall back logic is working as expected, we
are returning the object immediately and copying the object to new
bucket in an async manner.
- [x] Verified that the dc values were getting updated correctly on copy
or insert.
- [x] Verified that on deletion, we are deleting files from all dcs
where the derived file is present.
2024-05-17 15:45:41 +05:30
laurenspriem 992ca1c4de [mob][photos] Rename parallelism variables for clarity 2024-05-17 15:42:38 +05:30
Neeraj Gupta 89b01f0a39 Query DB to get fallback DC 2024-05-17 15:40:09 +05:30
laurenspriem baf24aca99 [mob][photos] Faces update status 2024-05-17 15:38:33 +05:30
Manav Rathi b7bdd89708
[desktop] Add note about xdg-open bug on Ubuntu (#1756)
Was able to reproduce the issue in Ubuntu 24.04 LTS

Ref: https://github.com/electron/electron/issues/31485
2024-05-17 15:27:08 +05:30
laurenspriem 76a10fb84c [mob][photos] Index hidden for faces last 2024-05-17 15:26:12 +05:30
Manav Rathi b420eece38
[desktop] Add note about xdg-open bug on Ubuntu
Ref: https://github.com/electron/electron/issues/31485
2024-05-17 15:24:42 +05:30
Neeraj Gupta e33d85412c Fix query for add new DC 2024-05-17 15:08:57 +05:30
Neeraj Gupta da155464fa Remove updated_at trigger for embeddings table 2024-05-17 15:08:48 +05:30
laurenspriem 1f78f71d0d [mob][photos] Include hidden for indexable count 2024-05-17 15:08:06 +05:30
laurenspriem 88b75c1191 [mob][photos] Migrate some db calls to async 2024-05-17 15:05:34 +05:30
laurenspriem 372fdd8a05 [mob][photos] Partly revert previous commit 2024-05-17 15:01:48 +05:30
Manav Rathi 32b12dbc09
[web] Fail to start if the port is taken (#1755)
This prevents cases say where the web app is running in a terminal, but
when we try to run the desktop app it silently switches to a different
and then failing to load in a manner that is harder to debug compared to
if it'd failed outright.

Ref:
-
https://github.com/vercel/next.js/discussions/23932#discussioncomment-599284
2024-05-17 14:44:15 +05:30
Manav Rathi 103d907781
[web] Fail to start if the port is taken
This prevents cases say where the web app is running in a terminal, but when we
try to run the desktop app it silently switches to a different and then failing
to load in a manner that is harder to debug compared to if it'd failed outright.

Ref:
- https://github.com/vercel/next.js/discussions/23932#discussioncomment-599284
2024-05-17 14:35:10 +05:30
Manav Rathi 61683713e9
[desktop] RC (#1754) 2024-05-17 14:24:37 +05:30
Manav Rathi af7c2edf98
Remove debugging lines 2024-05-17 14:21:37 +05:30
laurenspriem 63618f00b2 [mob][photos] Clip don't index hidden files 2024-05-17 14:10:05 +05:30
laurenspriem 41edee7d04 [mob][photos] Update people section after clustering 2024-05-17 12:30:11 +05:30
laurenspriem 9e8a127d4a [mob][photos] Only cluster when indexing is nearly done 2024-05-17 12:28:57 +05:30
Manav Rathi 58d8f131da
[desktop] Add a CORS workaround for uploads to arbitrary testing buckets (#1753)
This workaround already existed in older versions (See
`addAllowOriginHeader`), I had recently removed it, now putting it back.
2024-05-17 11:58:31 +05:30
Manav Rathi f61b5118ba
Add a CORS workaround for uploads to arbitrary testing buckets
Workaround for the following error when trying to upload from the desktop app to a staging bucket

> ente://app/gallery:1 Access to XMLHttpRequest at
  'https://xxx-staging-xxx.s3.xxx.backblazeb2.com/...' from origin 'ente://app'
  has been blocked by CORS policy: Response to preflight request doesn't pass
  access control check: The 'Access-Control-Allow-Origin' header has a value
  'null' that is not equal to the supplied origin.
2024-05-17 11:56:10 +05:30
Neeraj Gupta d847d0601b
[auth] Bump version to v3.0.0 (#1752)
## Description

## Tests
2024-05-17 11:48:08 +05:30
Neeraj Gupta e7607160a0 [auth] Bump version to v3.0.0 2024-05-17 11:46:14 +05:30
laurenspriem 1299e12d92 [mob][photos] Cleanup face debug options 2024-05-17 11:27:42 +05:30
Neeraj Gupta fd50461214 Add dc in the log ctx 2024-05-17 10:52:00 +05:30
laurenspriem a8da045a32 [mob][photos] Inline 2024-05-17 10:33:19 +05:30
laurenspriem d7e7aaa26f [mob][photos] Small refactor 2024-05-17 10:32:37 +05:30
laurenspriem 1f82599fb6 [mob][photos] use spinner 2024-05-17 10:21:33 +05:30
laurenspriem 345eed5209 [mob][photos] Remove old TODOs 2024-05-17 10:17:01 +05:30
Manav Rathi 4160be30b9
Fix tag 2024-05-17 10:14:29 +05:30
laurenspriem 725e628537 [mob][photos] Show clustering progress 2024-05-17 10:09:27 +05:30
Manav Rathi 4c3d549bbf
[web] New translations (#1750)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2024-05-17 09:35:10 +05:30
Crowdin Bot 22cd8df340 New Crowdin translations by GitHub Action 2024-05-17 02:05:34 +00:00
Crowdin Bot 3d9aa05b07 New Crowdin translations by GitHub Action 2024-05-17 01:41:51 +00:00
laurenspriem 579239ad54 [mob][photos] Disable edit faces from file info for now 2024-05-16 18:52:29 +05:30
laurenspriem 288adb2e7c [mob][photos] Make faces loading in file info less ugly 2024-05-16 18:48:46 +05:30
laurenspriem f441a0b456 [mob][photos] Don't show the option to assign suggestion to different person 2024-05-16 18:16:42 +05:30
laurenspriem d9232c1b83 [mob][photos] Show faces index status in settings 2024-05-16 17:28:09 +05:30
laurenspriem 1932a92cb8 [mob][photos] Require indexing 80% done before clustering 2024-05-16 16:39:58 +05:30
laurenspriem 9251fd8196 [mob][photos] Small change 2024-05-16 16:39:29 +05:30
laurenspriem 7f358c4bff [mob][photos] Better db query 2024-05-16 16:36:32 +05:30
Neeraj Gupta 698ceca49e Lint fix 2024-05-16 16:21:55 +05:30
Neeraj Gupta 51138e9263 Increase initial timeout val for b2 dc 2024-05-16 16:21:08 +05:30
laurenspriem e9392d8f33 [mob][photos] Automatic sync 2024-05-16 16:11:12 +05:30
Neeraj Gupta 08555954d2 Document 2024-05-16 16:10:51 +05:30
Neeraj Gupta b404b77da3 Update dc while copying derived file 2024-05-16 16:08:38 +05:30
Neeraj Gupta a522631c2b Refactor 2024-05-16 15:19:22 +05:30
laurenspriem e414128f18 [mob][photos] Initial settings screen for face recognition 2024-05-16 14:30:45 +05:30
Neeraj Gupta 20e9a6a1fc Refactor 2024-05-16 13:39:47 +05:30
Neeraj Gupta 3485b31475 Clean up & new line 2024-05-16 12:58:42 +05:30
Neeraj Gupta b53a70cf65 Avoid retry if object is missing 2024-05-16 12:57:31 +05:30
Neeraj Gupta 3f1ee82ec5 Inline 2024-05-16 12:52:20 +05:30
Neeraj Gupta 4cc866fa12 Refactor 2024-05-16 12:49:23 +05:30
Neeraj Gupta e0738db6ae Minor refactor 2024-05-16 12:23:25 +05:30
Neeraj Gupta 3c7d86da8d Minor refactor 2024-05-16 11:35:46 +05:30
Neeraj Gupta 6e204d828c Delete derived data from all datacenters 2024-05-16 11:33:01 +05:30
Neeraj Gupta 64ecdfa153 Store dc during insert or update 2024-05-16 10:58:00 +05:30
Neeraj Gupta da188aa753 Add datacenter column for embeddings 2024-05-16 10:19:58 +05:30
Neeraj Gupta 851f914ef8 Add wasabi-derived in list of dcs 2024-05-15 17:50:05 +05:30
laurenspriem ccec166fa0 [mob][photos] Copy change for empty people section 2024-05-15 17:01:08 +05:30
laurenspriem 1e5512b36f [mob][photos] Don't show PeopleSection when faces is disabled 2024-05-15 16:54:34 +05:30
Neeraj Gupta 7eabea3884 Rename embedding dc to derived storage 2024-05-15 16:37:23 +05:30
laurenspriem 3d906490a6 [mob][photos] Rename 2024-05-15 16:33:31 +05:30
laurenspriem 9946d08697 [mob][photos] Check wifi before indexing 2024-05-15 16:10:50 +05:30
laurenspriem 83a873672f [mob][photos] Remove double face debug widget 2024-05-15 14:43:31 +05:30
Neeraj Gupta cc457eca98 Add log when embedding is fetched after retry 2024-05-15 14:25:28 +05:30
laurenspriem cdf3d0e037 [mob][photos] Automatic clustering after indexing 2024-05-15 13:31:12 +05:30
laurenspriem eef18ca054 [mob][photos] Logs 2024-05-15 13:27:19 +05:30
laurenspriem c142ed07b8 [mob][photos] Don't show empty faces in debug 2024-05-15 12:04:10 +05:30
laurenspriem 6ab1371077 [mob][photos] Internally keep track of MLController status 2024-05-15 11:33:35 +05:30
laurenspriem b2c274e73b [mob][photos] Extra safety checks for hooking MLController 2024-05-15 11:03:31 +05:30
laurenspriem 48e78d170d [mob][photos] Regression dumb fix 2024-05-14 19:45:55 +05:30
laurenspriem df1ca5d583 [mob][photos] Hook faces into MachineLearningController 2024-05-14 18:09:38 +05:30
Neeraj Gupta 835a773f13 Add fallback logic to read embedding from hot bucket 2024-05-14 17:00:16 +05:30
laurenspriem 17696c6665 [mob][photos] Separate debug breakupCluster for cluster 2024-05-14 16:36:33 +05:30
laurenspriem 4f9fc9fb6a [mob][photos] Fix banner for light theme 2024-05-14 16:19:12 +05:30
laurenspriem ef33754108 [mob][photos] Review suggestions banner 2024-05-14 16:04:44 +05:30
laurenspriem 3724ea0af1 [mob][photos] Add a name banner 2024-05-14 16:04:33 +05:30
laurenspriem cb51e3e5b5 [mob][photos] PeopleBanner widget 2024-05-14 16:04:15 +05:30
laurenspriem 848b9c3b1b [mob][photos] Change copy 2024-05-14 15:39:31 +05:30
laurenspriem 71ca8a414c [mob][photos] Copy change 2024-05-14 15:22:08 +05:30
Neeraj Gupta 87b087f295 Minor refactor 2024-05-14 14:52:07 +05:30
laurenspriem 4af9d46111 [mob][photos] Copy change 2024-05-14 14:45:22 +05:30
Neeraj Gupta 74a6e32538 Fix error check for no-object found 2024-05-14 14:37:24 +05:30
laurenspriem 2dc17dcec8 [mob][photos] Remove padding for banner 2024-05-14 14:24:35 +05:30
Neeraj Gupta 18d1bb60ca Delete embeddings from hot bucket if different from embedding bucket 2024-05-14 14:18:50 +05:30
Neeraj Gupta 3e7b16288f Add support for configuring diff bucket for embeddings 2024-05-14 14:03:35 +05:30
laurenspriem a7bcd62a9d [mob][photos] Move banners to bottom of cluster/people page 2024-05-14 13:03:06 +05:30
laurenspriem 3b8cae068e [mob][photos] Retries for fetching face embeddings 2024-05-14 12:03:15 +05:30
laurenspriem f4024d2007 [mob][photos] Suggestion option to assign to different person 2024-05-14 11:51:50 +05:30
Neeraj Gupta bce3f40a16 Avoid retry for 404 error 2024-05-14 11:44:41 +05:30
laurenspriem a3eba12ccf [mob][photos] Feedback buttons untappable when loading faces 2024-05-14 11:19:17 +05:30
laurenspriem 2cf193c2d0 [mob][photos] Avoid redundant db calls 2024-05-13 21:49:02 +05:30
laurenspriem ed23286331 [mob][photos] Single spinner in suggestion page 2024-05-13 21:20:49 +05:30
laurenspriem 36ac637206 [mob][photos] Precompute max 8 face thumbnails 2024-05-13 20:47:33 +05:30
laurenspriem 2205d21770 [mob][photos] No double taps allowed when assigning cluster 2024-05-13 16:41:06 +05:30
Neeraj Gupta acd61fc084 Fixed typo 2024-05-13 16:33:48 +05:30
Neeraj Gupta be44665128 [server] Refactor embedding fetch 2024-05-13 16:33:36 +05:30
laurenspriem 5815b57fe3 [mob][photos] Cannot make up mind on copy 2024-05-13 15:22:37 +05:30
laurenspriem 7c7ee6c432 [mob][photos] Copy change 2024-05-13 15:18:54 +05:30
laurenspriem bb9c0673a8 [mob][photos] Don't use spinner in people section 2024-05-13 14:58:09 +05:30
laurenspriem 022d89b4a0 [mob][photos] Copy change 2024-05-13 14:47:30 +05:30
laurenspriem e188382f09 [mob][photos] Suggestion yes no button in row not column 2024-05-13 14:42:41 +05:30
laurenspriem 75f0b0481b [mob][photos] Show spinner when generating face 2024-05-13 14:08:55 +05:30
laurenspriem d7bd735f7b [mob][photos] Make add new person better tapable 2024-05-13 13:46:00 +05:30
laurenspriem 1f2c3f73df [mob][photos] Prevent dubble tap add person 2024-05-13 13:36:59 +05:30
laurenspriem 6652125804 [mob][photos] Change copy 2024-05-11 18:15:35 +05:30
laurenspriem c28f6c36bb [mob][photos] Experiment higher distance for big suggestions 2024-05-11 16:54:29 +05:30
laurenspriem 605112eeb9 [mob][photos] Make naming banner dismissible 2024-05-11 16:35:58 +05:30
laurenspriem a05d7d8660 [mob][photos] Rename var 2024-05-11 16:31:45 +05:30
laurenspriem 05f5e8a175 [mob][photos] Make suggestion banner dismissible 2024-05-11 16:30:39 +05:30
laurenspriem 8e341310a2 [mob][photos] Change icon 2024-05-11 16:15:59 +05:30
laurenspriem 45d46d5ca8 [mob][photos] Show banner for suggestions 2024-05-11 16:10:41 +05:30
laurenspriem 7045dbaeff [mob][photos] Remove padding around naming banner 2024-05-11 15:38:48 +05:30
laurenspriem fc6830bdaf [mob][photos] Big cluster suggestions first 2024-05-11 15:20:28 +05:30
laurenspriem abff589c21 [mob][photos] Increase "Add name" hitpoint 2024-05-11 14:53:19 +05:30
laurenspriem 3ab2535193 [mob][photos] Show face thumbnail in naming sheet 2024-05-11 13:57:15 +05:30
Neeraj Gupta da5ceea0db [mob] decrease remoteFetch constant to 100 2024-05-10 16:44:11 +05:30
Neeraj Gupta c235fb85b4 [mob] Increase remoteFetch constant to 200 2024-05-10 16:41:00 +05:30
Neeraj Gupta 5ba46a0707 [mob] Use diff constant for fetch & parallelism 2024-05-10 16:31:07 +05:30
Neeraj Gupta 38d622825b [mob] Handle indexed files with no embedding data 2024-05-10 16:17:40 +05:30
Neeraj Gupta eee168837e [mob] Use diff val for fetch & parallel indexing 2024-05-10 16:16:56 +05:30
Neeraj Gupta c906480dee [mob] Handle missing fileIDs during clustering 2024-05-10 13:25:22 +05:30
Neeraj Gupta 4db3c9fe95 [mob] FaceInfoForClustering add fileID getter 2024-05-10 13:10:27 +05:30
Neeraj Gupta 7623e69de3 [mob] Return list instead of set 2024-05-10 13:07:24 +05:30
Neeraj Gupta 33a0641c52 Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-05-10 11:48:17 +05:30
laurenspriem 5c85fe764a [mob][photos] Show "Add name" for clusters in discovery tab 2024-05-09 19:57:15 +05:30
laurenspriem b74a572f1a [mob][photos] Debug experiment for detecting mixed clusters 2024-05-09 19:52:05 +05:30
Neeraj Gupta acf8fd6e63 [mob] Enable cast for iOS in debug 2024-05-09 17:22:44 +05:30
laurenspriem d08edacb66 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-05-09 16:38:35 +05:30
laurenspriem b78a65dc51 [mob][photos] Breakup cluster function 2024-05-09 15:46:52 +05:30
laurenspriem 54e1198088 [mob][photos] Delete old cluster summary for removed clusters 2024-05-09 15:44:21 +05:30
laurenspriem 6eb34937b8 [mob][photos] Use normalized embeddings in complete clustering 2024-05-09 14:51:59 +05:30
Neeraj Gupta 089aa16bc6 Merge branch 'main' into mobile_face 2024-05-09 14:49:25 +05:30
laurenspriem 8c373857a2 [mob][photos] Don't show emptyCTA for faces in people full page 2024-05-08 15:32:13 +05:30
laurenspriem 63f22680f4 [mob][photos] Show add name button on discovery tab 2024-05-08 14:27:15 +05:30
laurenspriem 5e2f689265 [mob][photos] View history from suggestions 2024-05-08 12:20:48 +05:30
laurenspriem bcac9b9ce9 [mob][photos] Cluster merge parameter change 2024-05-08 11:59:48 +05:30
laurenspriem 9ff4fc1b81 [mob][photos] Don't show memory count twice for clusters 2024-05-08 11:47:44 +05:30
laurenspriem ee9eaedd99 [mob][photos] Prefer linear scan for clustering within cluster 2024-05-08 11:13:56 +05:30
laurenspriem dd29e55b53 [mob][photos] Lower threshold for auto merges 2024-05-08 11:05:36 +05:30
laurenspriem 8027579080 [mob][photos] Lower threshold for automatic merges 2024-05-07 17:14:43 +05:30
laurenspriem cb4fa38004 [mob][photos] Better suggestion parameter 2024-05-07 16:12:05 +05:30
laurenspriem aff27a2211 [mob][photos] Show dialog on removing person label 2024-05-07 16:11:46 +05:30
laurenspriem dc5a8ebd44 [mob][photos] More robust automatic merges 2024-05-07 13:38:55 +05:30
laurenspriem 0ecbb73f1e [mob][photos] Only check automatic merges on big clusters 2024-05-07 12:27:01 +05:30
laurenspriem 115f1bd42e [mob][photos] Delete people and their mapping 2024-05-07 11:59:25 +05:30
laurenspriem 68be7f69d8 [mob][photos] Don't drop cluster summaries when dropping feedback 2024-05-07 11:22:44 +05:30
laurenspriem bd495c3860 [mob][photos] Assert that embeddings are always normalized 2024-05-06 17:16:58 +05:30
laurenspriem b4736fb1d6 [mob][photos] Normalize weighted embeddings for cluster summary 2024-05-06 17:03:06 +05:30
laurenspriem 71b572917e [mob][photos] More debug logging on clusters 2024-05-06 16:45:27 +05:30
laurenspriem 3c24345b68 [mob][photos] Add method for safe cosine distance 2024-05-06 16:38:19 +05:30
laurenspriem ea8846ee0c [mob][photos] Properly sort faces on fileCreationTime for clustering 2024-05-06 10:38:26 +05:30
laurenspriem 077b46e490 [mob][photos] Small copy change 2024-05-04 14:04:34 +05:30
laurenspriem cf6b311c14 [mob][photos] Fix person gallery random dates ordering 2024-05-04 13:57:28 +05:30
laurenspriem ade70f40a9 [mob][photos] Use separate isIgnored getter instead of isHidden 2024-05-03 17:25:30 +05:30
laurenspriem 35aed07bc6 [mob][photos] Rename "remove" to "remove label" for person 2024-05-03 16:59:51 +05:30
laurenspriem 319dc055de [mob][photos] Rename "hidden" to "ignored" 2024-05-03 16:17:56 +05:30
laurenspriem 662dc1a32b [mob][photos] Make sure hidden doesn't show in naming sheet 2024-05-03 15:09:29 +05:30
laurenspriem 38a40a5ace [mob][photos] Make sure hidden faces are displayed last in file info 2024-05-03 15:05:02 +05:30
laurenspriem 915a3f646d [mob][photos] Small fix 2024-05-03 14:59:25 +05:30
laurenspriem f275761c4b [mob][photos] Refresh file info on changed person 2024-05-03 14:49:06 +05:30
laurenspriem cfd656b360 [mob][photos] Unhide person feedback 2024-05-03 14:42:33 +05:30
laurenspriem 95ba8a368b [mob][photos] Show (hidden) in file info for hidden persons 2024-05-03 12:45:21 +05:30
laurenspriem 8c27eb59ce [mob][photos] Show dialog before hiding person 2024-05-03 12:40:27 +05:30
laurenspriem 267b3669f2 [mob][photos] Don't show hidden clusters in clusters page 2024-05-03 12:25:14 +05:30
laurenspriem 1ab42640d9 [mob][photos] UI for triggering hide method 2024-05-03 12:16:48 +05:30
laurenspriem cdc6972d53 [mob][photos] Remove validateCluster option 2024-05-03 12:10:58 +05:30
laurenspriem 5c1bc220e9 [mob][photos] Method for hiding cluster 2024-05-03 12:07:23 +05:30
laurenspriem 7e60e8532f [mob][photos] Don't show naming banner on suggestions 2024-05-02 17:22:46 +05:30
laurenspriem 4bafdf8922 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-05-02 17:12:29 +05:30
laurenspriem 6ea8b972bd [mob][photos] Put serialization for suggestions in computer 2024-05-02 17:01:10 +05:30
laurenspriem 793fc3aa46 [mob][photos] Cluster suggestion calculation in computer 2024-05-02 16:08:19 +05:30
Neeraj Gupta 6b70c721d4 Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-05-02 14:22:31 +05:30
Neeraj Gupta 88bdb06d05 [mob] Keep original files order intact 2024-05-02 14:22:24 +05:30
laurenspriem 2e17e2b78d [mob][photos] Trailing comma 2024-05-02 12:38:05 +05:30
laurenspriem c6129c32da Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-05-02 12:36:43 +05:30
laurenspriem d650bac501 [mob][photos] Small changes in suggestion calculation 2024-05-02 12:35:52 +05:30
Neeraj Gupta 745daf39f7 [mob] Sort suggestion by creationTime to fix gallery grouping bug 2024-05-02 12:14:08 +05:30
Neeraj Gupta 9ecd406e56 [mob]Fix refresh bug in all sections for people 2024-05-02 11:56:20 +05:30
laurenspriem 74ae4ea74f [mob][photos] Fix regression in suggestion calculation 2024-05-02 11:18:06 +05:30
Neeraj Gupta ca3172c33e [mobile] Add method to reconsile mappings 2024-05-02 07:04:31 +05:30
laurenspriem 689833d8aa Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-04-30 17:13:39 +05:30
laurenspriem 09fadecd7a [mob][photos] Make sure precomputes also use thumbnail for face generation 2024-04-30 17:02:14 +05:30
laurenspriem 10b04c6ad3 [mob][photos] Make sure face in face thumbnail is always centered 2024-04-30 16:31:36 +05:30
Neeraj Gupta f80f7a03e1 [mob] Fix query 2024-04-30 16:11:51 +05:30
laurenspriem 4cff6b1299 [mob][photos] Simplify face generation code 2024-04-30 15:44:32 +05:30
Neeraj Gupta 7e5561e5cd [mob] Use EntePopupMenuItem 2024-04-30 14:59:55 +05:30
Neeraj Gupta b1cbf8526b Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-04-30 14:48:28 +05:30
Neeraj Gupta 49d5370d47 Merge branch 'ente_popup_menu' into mobile_face 2024-04-30 14:48:12 +05:30
laurenspriem 8d4f9fe966 [mob][photos] Move code 2024-04-30 14:29:25 +05:30
laurenspriem 29b9bee1be [mob][photos] Use thumbnails for generating face crop in suggestions 2024-04-30 14:20:21 +05:30
laurenspriem a80c9dd589 [mob][photos] Rename method 2024-04-30 12:35:05 +05:30
laurenspriem 046a96f586 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-04-30 11:57:03 +05:30
laurenspriem 740ca907f2 [mob][photos] Prevent face cropping out of image bounds 2024-04-30 11:38:39 +05:30
laurenspriem c783735e86 [mob][photos] Log clustering time for each bucket 2024-04-30 11:24:06 +05:30
Neeraj Gupta cbf2a77d5b refactor 2024-04-30 11:06:41 +05:30
laurenspriem 9f5c5fde49 [mob][photos] Parallelize the cropping and encoding of faces 2024-04-30 10:59:45 +05:30
laurenspriem 1cd31d2cab [mob][photos] Only decode image once for face thumbnails in file info 2024-04-30 10:46:16 +05:30
Neeraj Gupta 4b6ecbdd30 Merge branch 'main' of https://github.com/ente-io/auth into mobile_face 2024-04-30 10:17:13 +05:30
Neeraj Gupta 7d2633190f Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-04-29 17:18:32 +05:30
Neeraj Gupta 52f605831f Merge branch 'main' into mobile_face 2024-04-29 17:18:16 +05:30
laurenspriem 8b1545239c [mob][photos] Use canvas again for generating face thumbnail 2024-04-29 16:28:19 +05:30
laurenspriem aad1327705 [mob][photos] Small cleanup 2024-04-29 15:29:00 +05:30
laurenspriem 8058c6b621 [mob][photos] Remove unnecessary write transactions 2024-04-29 15:20:01 +05:30
laurenspriem d03d8d564d [mob][photos] Fix DB issue 2024-04-29 15:13:51 +05:30
laurenspriem 87571159cc [mob][photos] Fix faces db conflict 2024-04-27 14:30:34 +05:30
laurenspriem 97d8c5f83e Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-04-27 14:03:40 +05:30
laurenspriem a2023bd457 [mob][photos] Fix database issue 2024-04-27 13:38:34 +05:30
Vishnu Mohandas a16910a4ee
[mob][photos] Remove unnecessary optional parameter (#1543) 2024-04-27 13:20:52 +05:30
ashilkn 54d3ad9743 [mob][photos] Remove unnecessary optional parameter 2024-04-27 12:37:42 +05:30
laurenspriem 6235f7ee78 [mob][photos] Move FaceBoxImage to face_util 2024-04-27 12:19:29 +05:30
Laurens Priem 9eeab36392
[mob][photos] Generate face crops faster (#1542)
## Description

Have written two new methods, `generateImgFaceThumbnails()` and
`generateJpgFaceThumbnails()`.
Using `generateJpgFaceThumbnails()` now since it returns
`Future<List<Uint8List>>` and is easier to integrate within the code
base because the return type remains the same with the older
`generateFaceThumbnailsForImage()`

There is performance improvement with `generateImgFaceThumbnails()`, but
it's not very significant and it requires changes in codebase to work
with it's return type `Future<List<Image>>` (`Image` from the `Image`
package). Can consider using it if it feels necessary in future.

If multiple faces are being generated from the same image, the image can
be decoded once and passed to `generateImgFaceThumbnails()` or
`generateJpgFaceThumbnails()` to avoid repeated decoding of the same
image.

`generateImgFaceThumbnails()` and `generateJpgFaceThumbnails()` uses the
isolates available from the pool of 4 spawned by `Computer` and
processes multiple faces in parallel unlike
`generateImgFaceThumbnails()`, which processes only one at a time.
2024-04-27 12:05:32 +05:30
laurenspriem f422e30a8e [mob][photos] Migrate fully to sqlite async for faces, removing sqflite fully 2024-04-27 11:13:52 +05:30
ashilkn 58cd9350c0 Merge branch 'mobile_face' into fix_face_thumbnail 2024-04-27 11:10:10 +05:30
ashilkn ab5985a08b [mob][photos] Use generated face crops and crop it using the new method 2024-04-27 11:06:54 +05:30
ashilkn 19f2c5f00a [mob][photos] remove negation 2024-04-27 11:02:38 +05:30
ashilkn 707916f677 [mob][photos] Add method to convert Image from Image package to UI image 2024-04-27 10:57:49 +05:30
ashilkn 8b236cde09 [mob][photos] When cropping a face from an image, make the image a square and add some buffer around it 2024-04-27 09:59:16 +05:30
laurenspriem 968eaaf5f6 [mob][photos] Better error logging 2024-04-27 09:39:12 +05:30
ashilkn caa72ba830 [mob][photos] add option to pass decoded image to face thumbnail generation methods to avoid unnecessary decoding when possible 2024-04-26 15:44:07 +05:30
laurenspriem 2692d0a34f [mob][photos] Fix issue in displaying face thumbnails for videos 2024-04-26 14:50:14 +05:30
laurenspriem 44898415e7 [mob][photos] Index videos using thumbnails 2024-04-26 14:43:19 +05:30
laurenspriem 811ffe0117 [mob][photos] Create new cluster when tapping unassigned face 2024-04-26 14:13:00 +05:30
laurenspriem 43f01c31da [mob][photos] Prevent sqlite disk corruption issue 2024-04-26 12:58:27 +05:30
ashilkn a0e9913f43 Revert "[mob] Crop image instead of using scale and translate transforms on OG image in CroppedFaceImageView widget"
This reverts commit b022ef6d1e.
2024-04-26 12:56:12 +05:30
ashilkn b256bb2757 Revert "[mob] perf: Decode images from which face is to be cropped, in an isolate to avoid jank"
This reverts commit 2f7e0cd1ef.
2024-04-26 12:55:29 +05:30
ashilkn 3eebfdd037 Revert "[mob] Two varients of CroppedFaceImageView for testing out which is more performant"
This reverts commit 7617817798.
2024-04-26 12:54:29 +05:30
ashilkn a577611e65 [mob] merge mobile_face to fix_face_thumbnail 2024-04-26 11:32:33 +05:30
laurenspriem b2a2078045 [mob][photos] Moving more methods to sqlite async 2024-04-25 17:06:40 +05:30
ashilkn 7617817798 [mob] Two varients of CroppedFaceImageView for testing out which is more performant 2024-04-25 16:58:58 +05:30
ashilkn f173bc4038 [mob] Wrote util methods to generate face thumbnails from an image path
Need to decide on which util method to use of the two after performance testing
2024-04-25 16:56:43 +05:30
laurenspriem 3828fa328e [mob][photos] Increase conservative clustering threshold slightly 2024-04-25 16:41:23 +05:30
laurenspriem f101468a8d [mob][photos] Show faces in file info regardless of blur value 2024-04-25 16:30:00 +05:30
laurenspriem 52a7f2753e [mob][photos] Tiny change 2024-04-25 16:15:04 +05:30
laurenspriem 7fd5ffc0e6 [mob][photos] Forgot method 2024-04-25 16:14:16 +05:30
laurenspriem 43cbfbfa33 [mob][photos] Automatically reject overlapping suggestions 2024-04-25 16:13:29 +05:30
laurenspriem 7370557b08 [mob][photos] More use of sqlite async 2024-04-25 15:41:26 +05:30
laurenspriem f0ebdb211c [mob][photos] Functionality to remove selected images from suggestion 2024-04-25 14:13:58 +05:30
ashilkn 2f7e0cd1ef [mob] perf: Decode images from which face is to be cropped, in an isolate to avoid jank 2024-04-25 12:29:29 +05:30
laurenspriem d429efaf14 [mob][photos] Trailing commas 2024-04-25 12:19:19 +05:30
laurenspriem 7b8816a4bf [mob][photos] Higher conservative clustering threshold 2024-04-25 10:54:49 +05:30
laurenspriem 7e00a470aa [mob][photos] Lower both hard and soft blur thresholds 2024-04-25 10:54:19 +05:30
laurenspriem 1ae4482fe5 [mob][photos] Always check big clusters first for suggestions 2024-04-25 10:53:42 +05:30
laurenspriem d0420ce477 [mob][photos] Better sorting of faces in file info 2024-04-25 10:03:05 +05:30
ashilkn b022ef6d1e [mob] Crop image instead of using scale and translate transforms on OG image in CroppedFaceImageView widget 2024-04-25 09:35:55 +05:30
laurenspriem 244d562207 [mob][photos] Increase the pool for face thumbnail generation 2024-04-25 08:50:44 +05:30
laurenspriem 3fbfa8c0e6 [mob][photos] Precompute face thumbnails for suggestions 2024-04-24 18:59:08 +05:30
laurenspriem 6f6f976dec [mob][photos] Fix bug 2024-04-24 18:33:00 +05:30
laurenspriem 07458fb247 [mob][photos] Recompute suggestions on rejected suggestion 2024-04-24 17:15:11 +05:30
laurenspriem 72ff6e2cf3 [mob][photos] Tiny change 2024-04-24 17:07:28 +05:30
laurenspriem e0fbb2620b [mob][photos] Correct suggestion logic again 2024-04-24 17:06:35 +05:30
laurenspriem 462d1d4854 [mob][photos] Use cosineDistanceSIMD 2024-04-24 16:37:39 +05:30
laurenspriem 05a4e9f90b [mob][photos] Remove redundant logging 2024-04-24 16:31:36 +05:30
laurenspriem 3806ee3232 [mob][photos] Use SIMD in sorting suggestions too 2024-04-24 16:19:10 +05:30
laurenspriem e829f7b62f [mob][photos] Use vectors everywhere in cluster suggestion 2024-04-24 16:01:03 +05:30
laurenspriem 4b6641d7d8 [mob][photos] Speed up suggestion calculation 2024-04-24 15:46:00 +05:30
laurenspriem 093f48fb63 [mob][photos] Sort found suggestions based on distance 2024-04-24 11:24:25 +05:30
laurenspriem 759c8aa404 [mob][photos] Extra check in sorting suggestions 2024-04-24 10:01:07 +05:30
laurenspriem c80208e754 [mob][photos] Fix in sorting suggestions 2024-04-24 09:53:42 +05:30
laurenspriem 7097ce3cf4 [mob][photos] Faster DB call when sorting suggestions 2024-04-24 09:06:20 +05:30
laurenspriem efb1170b44 [mob][photos] unawait network call when accepting suggestion 2024-04-24 08:39:45 +05:30
laurenspriem 7312633e02 [mob][photos] Only sort big suggestions 2024-04-23 14:26:30 +05:30
laurenspriem 3786c9def9 [mob][photos] Suggestions change parameters 2024-04-23 13:37:53 +05:30
laurenspriem 6fe8dc7c66 [mob][photos] Check big and medium clusters first for suggestions 2024-04-23 12:18:19 +05:30
laurenspriem 9e87b4a2cc [mob][photos] Highlight face in cluster 2024-04-23 11:58:39 +05:30
Laurens Priem dad427a498
[mob][photos] Fix issues with face thumbnail (#1523)
## Description

See commits.
2024-04-23 11:21:38 +05:30
ashilkn 4c25997bb6 [mob] use layoutBuilder in face thumbnail 2024-04-23 11:15:46 +05:30
laurenspriem 6a0a9bad1e [mob][photos] Clustering time logs 2024-04-23 09:56:46 +05:30
ashilkn 731610ed94 [mob] Refactor 2024-04-23 08:30:59 +05:30
ashilkn e875eb1389 [mob] Remove unnecessary ShapeDecoration and width constrain 2024-04-23 08:27:47 +05:30
ashilkn 3253a2bf26 [mob] Remove unnecessary LayoutBuilder 2024-04-23 08:26:29 +05:30
ashilkn 8225697e43 Merge branch 'mobile_face' into fix_face_thumbnail 2024-04-23 07:49:59 +05:30
laurenspriem f49ede4a74 [mob][photos] Small fix in detecting sideways faces 2024-04-22 18:07:50 +05:30
laurenspriem 9cdd4fd713 [mob][photos] Face thumbnail generation from widgets 2024-04-22 17:24:34 +05:30
laurenspriem fa466d715f [mob][photos] Improve suggestions by improving speed and preferring big clusters 2024-04-22 16:40:31 +05:30
ashilkn c1587cc5ea [mob] Remove redundant clippling and anti aliasing for performance gain 2024-04-22 11:52:39 +05:30
ashilkn ae046e33b4 [mob] fix: face thumbnails getting cropped on the edges because the image uses BoxFit.cover 2024-04-22 11:45:54 +05:30
laurenspriem 37ab467da5 [mob][photos] Remove blur ranking debug option 2024-04-22 11:35:40 +05:30
Neeraj Gupta cc682a0a09 Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-04-20 16:01:08 +05:30
Neeraj Gupta 864f8444d5 Merge branch 'main' into mobile_face 2024-04-20 15:59:36 +05:30
laurenspriem edf99385dc [mob][photos] Precompute cluster summaries incrementally during clustering 2024-04-20 14:38:46 +05:30
laurenspriem cde17441d6 [mob][photos] Forgot one import 2024-04-20 13:35:53 +05:30
laurenspriem 4ac295e1e2 [mob][photos] Remove ClusterResult old deprecated code 2024-04-20 13:35:02 +05:30
laurenspriem a0502886b6 [mob] Minimum size argument for getting all cluster summaries 2024-04-20 13:26:47 +05:30
laurenspriem 7be1b63822 [mob] Clean up linear clustering method 2024-04-20 12:24:20 +05:30
laurenspriem 01aecb9742 [mob] store sideways face boolean in local face table 2024-04-19 18:13:35 +05:30
laurenspriem a0fa90cb50 [mob] Remove faceArea and faceVisibility from local DB 2024-04-19 16:43:41 +05:30
laurenspriem 6d3e1325c4 [mob] Update face widget 2024-04-19 16:35:33 +05:30
laurenspriem 4095b14589 [mob] Conservative threshold for combination of low score and blur 2024-04-19 15:57:11 +05:30
laurenspriem a92081e703 [mob] Only analyze clustering in debugMode 2024-04-19 15:20:29 +05:30
laurenspriem f3f85e81ca [mob] Rename constant 2024-04-19 15:08:10 +05:30
laurenspriem ecc1bc9980 [mob] Use more conservative cluster threshold for sideways faces 2024-04-19 14:58:52 +05:30
laurenspriem 2b88daa15f [mob] Method for detecting sideways faces 2024-04-19 14:00:15 +05:30
laurenspriem a9ca8a4a24 [mob] Better handling of cluster update 2024-04-19 12:19:10 +05:30
laurenspriem ab0a99cf76 [mob] Make sure cluster page is updated after file removal 2024-04-19 11:42:39 +05:30
laurenspriem e20f13f02b [mob] Re-cluster when removing file from person/cluster 2024-04-18 17:57:14 +05:30
laurenspriem 34798c344c [mob] Fix typo 2024-04-18 16:32:11 +05:30
laurenspriem e7992674d5 [mob] Use async sqlite for getting file creation times 2024-04-18 16:17:04 +05:30
laurenspriem 74247c4563 [mob] Use async sqlite for getting faceID from cluster 2024-04-18 16:00:47 +05:30
laurenspriem be1b4b359c [mob] Fix typo 2024-04-18 15:32:59 +05:30
laurenspriem 79e763bf16 [mob] Small changes 2024-04-18 15:29:02 +05:30
laurenspriem afbb1c69c2 [mob] More clustering methods in Computer within cluster 2024-04-18 15:20:28 +05:30
laurenspriem 417c5eab1c [mob] Rename cluster method to clarify use of Computer 2024-04-18 14:48:57 +05:30
laurenspriem ba58ac1358 [mob] Add merges to predictComplete method 2024-04-18 14:44:12 +05:30
laurenspriem 7a5e1263e0 [mob] Use complete clustering for breaking up clusters 2024-04-18 11:26:24 +05:30
laurenspriem 45d18b187c [mob] Add completeClustering functionality 2024-04-18 11:25:48 +05:30
laurenspriem e3fd836901 [mob] clustering make it difficult for good faces to link to bad faces 2024-04-17 17:46:53 +05:30
laurenspriem 51d15cc441 [mob] Clustering with dynamic threshold based on face blur and score 2024-04-17 16:38:47 +05:30
laurenspriem 72e677e9e5 [mob] Minimum cluster size of 20 2024-04-17 16:36:45 +05:30
laurenspriem 6f26901073 [mob] Minor refactor of clustering methods 2024-04-17 14:54:31 +05:30
laurenspriem f61a5f91b6 [mob] Debug option to get clusters of blur values 2024-04-16 19:22:27 +05:30
laurenspriem d4d9253f1a [mob] Minor changes 2024-04-16 15:22:59 +05:30
laurenspriem b1eb6c11b2 [mob] Show face direction in face widget in debug mode 2024-04-16 15:11:51 +05:30
laurenspriem 618b152f17 [mob] FaceMlService static method for full pipeline 2024-04-16 15:04:15 +05:30
laurenspriem e3b8d8975f [mob] Better blur detection handling background noise 2024-04-16 14:51:23 +05:30
laurenspriem 624a06c3f8 [mob] Deprecate methods 2024-04-16 14:37:56 +05:30
laurenspriem e3b1cb8014 [mob] Debug log blur values of cluster when opening cluster page 2024-04-16 14:33:13 +05:30
Neeraj Gupta e09b77770d [mob] Upgrade sqlite_async 2024-04-13 16:55:21 +05:30
laurenspriem ef4135f378 [mob] tiny change 2024-04-13 16:41:51 +05:30
laurenspriem 38381f6bb0 [mob] Tiny face widget debug change 2024-04-13 16:02:49 +05:30
laurenspriem 7d414a7b7d [mob] Increase activity timer of cluster isolate 2024-04-13 15:55:04 +05:30
laurenspriem 2ce078e173 [mob] Fix too many clustering rounds/buckets 2024-04-13 15:54:36 +05:30
laurenspriem 8801dc1a7a [mob] Show clustered percentage in UI 2024-04-13 15:11:12 +05:30
laurenspriem 5cf10c9c9b [mob] Rename face clustering service 2024-04-13 13:10:20 +05:30
laurenspriem c58a8dc773 [mob] Better face clustering logging 2024-04-13 13:08:34 +05:30
laurenspriem c67a1fa52a [mob] Make clustering in buckets the default 2024-04-13 11:32:03 +05:30
laurenspriem 5a5cdc8b6b [mob] Slightly faster indexed file count 2024-04-12 18:15:01 +05:30
laurenspriem da7302b677 [mob] Remove incorrect log 2024-04-12 18:12:31 +05:30
laurenspriem d65264e8e8 [mob] move fetching related code inside fetching block 2024-04-12 17:46:12 +05:30
Neeraj Gupta 2cb08569c9 Switch to older version of share_plus 2024-04-12 16:54:47 +05:30
Neeraj Gupta 5fec61fc1b [mob] Persist setting for disabling remote fetch 2024-04-12 16:20:09 +05:30
Neeraj Gupta 107b79eae6 [mob] Reduce invalid pixel noise 2024-04-12 16:19:51 +05:30
Neeraj Gupta 2302b930d3 [mob] Remove unsued section 2024-04-12 16:08:18 +05:30
Neeraj Gupta fbec7db865 Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-04-12 15:53:34 +05:30
Neeraj Gupta 96b9019fff Flutter gradle plugin changes 2024-04-12 15:53:22 +05:30
laurenspriem 21451efa6b Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-04-12 15:11:15 +05:30
Neeraj Gupta 259787ff41 [mob] Upgrade to flutter 3.19.5 2024-04-12 14:55:07 +05:30
laurenspriem 481410f183 [mob] Increase inactivity counter for clustering isolate 2024-04-12 14:38:36 +05:30
laurenspriem eb8294ce95 [mob] Limit amount of sqlite read isolates for FaceMl DB 2024-04-12 14:33:48 +05:30
laurenspriem 9c09af54b3 [mob] Use sqlite async for getting all indexed fileIDs 2024-04-12 13:22:25 +05:30
laurenspriem 642e36b050 [mob] Use sqlite async for getting total face count 2024-04-12 13:21:38 +05:30
laurenspriem 38c0c44331 [mob] Remove GC from debug options 2024-04-12 13:13:20 +05:30
laurenspriem 3860d0a230 [mob] Read face embeddings using sqlite async 2024-04-12 12:57:03 +05:30
laurenspriem ba107c2d25 [mob] Fix in clustering without buckets 2024-04-12 12:01:17 +05:30
Neeraj Gupta f3647df1e9 [mob]Improve handling of multiple assignment of same faceID to different clusters 2024-04-12 11:49:40 +05:30
laurenspriem 01914ed3ce [mob] Option for indexing without fetching 2024-04-12 11:49:38 +05:30
Neeraj Gupta 5710cb2d35 Merge branch 'main' into mobile_face 2024-04-12 10:38:14 +05:30
laurenspriem 6df5559d75 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-04-11 16:44:40 +05:30
laurenspriem b90aed0b4b [mob] Switch from FlutterIsolate to DartUiIsolate 2024-04-11 16:43:52 +05:30
laurenspriem 0eb876c985 [mob] Update dependency lock 2024-04-11 15:41:56 +05:30
laurenspriem 5996981c13 [mob] Remove empty asset directories 2024-04-11 15:41:23 +05:30
Neeraj Gupta f459b1c2dd Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-04-11 13:17:15 +05:30
Neeraj Gupta 3ba6aea827 [mob] Enable impeller and wide Gamut color for iOS 2024-04-11 13:16:18 +05:30
laurenspriem 90db558498 Merge branch 'update_deps_and_flutter' into mobile_face 2024-04-11 12:39:54 +05:30
laurenspriem cab649ef77 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-04-11 11:52:31 +05:30
laurenspriem 5b6df99486 [mob] Remove onnx models from local assets 2024-04-11 11:44:11 +05:30
laurenspriem c902f24e63 [mob] Better organization of face detection code. 2024-04-11 11:42:31 +05:30
laurenspriem aad0a5a1d4 [mob] More documentation 2024-04-11 11:15:37 +05:30
Neeraj Gupta b18734f63e Merge branch 'main' into mobile_face 2024-04-11 11:10:54 +05:30
laurenspriem 21adb91c2f [mob] Rename face embedding service 2024-04-11 11:03:43 +05:30
laurenspriem d4086357ec [mob] Remove all tflite models 2024-04-11 11:01:22 +05:30
laurenspriem efaf869e95 [mob] Remove tflite dependency 2024-04-11 10:52:16 +05:30
laurenspriem 74f8f7aaf3 [mob] Remove debug option 2024-04-10 17:36:34 +05:30
laurenspriem 222716f6f9 [mob] Make methods private 2024-04-10 14:44:08 +05:30
laurenspriem af8d919ff2 [mob] Documentation 2024-04-10 12:21:28 +05:30
laurenspriem f3d18edf98 [mob] Better logging of face landmarks 2024-04-10 12:21:15 +05:30
Neeraj Gupta fac087c81b [mob] Fix person entity update 2024-04-10 10:59:27 +05:30
Neeraj Gupta c920aacd1b [mob] Reduce noise in the logs 2024-04-10 10:59:18 +05:30
Neeraj Gupta 16da5056ea [mob] Improve log 2024-04-10 10:53:18 +05:30
Neeraj Gupta 73007ee541 [mob] Improve log 2024-04-10 10:43:49 +05:30
Neeraj Gupta 915da41c86 [mob] generated changes 2024-04-10 10:21:07 +05:30
Neeraj Gupta c224e38ddf Merge branch 'main' into mobile_face 2024-04-10 10:15:40 +05:30
Neeraj Gupta e82cda1e82 [mob] Fix bug in discarding remote embedding 2024-04-10 10:10:53 +05:30
Neeraj Gupta c8154784f1 [mob] Minor fixes 2024-04-09 16:37:54 +05:30
Neeraj Gupta 52038b8972 [mob] Sync removed clusters from a person 2024-04-09 15:00:57 +05:30
Neeraj Gupta d43ed15cdf [mob] Add support for syncing multile clusters for a person 2024-04-09 14:48:05 +05:30
Neeraj Gupta 24f7b191b4 [mob] reduce clustering threshold 2024-04-09 09:04:07 +05:30
laurenspriem acb3e05fc8 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-04-08 15:25:50 +05:30
laurenspriem 4cb15268e9 [mob] Cleaner handling of decoded image dimensions 2024-04-08 15:24:14 +05:30
Neeraj Gupta 250cb33bc9 [mob] Use localFileserver to serving files 2024-04-08 14:37:30 +05:30
laurenspriem eeedf8b3c2 [mob] Trailing commas 2024-04-08 14:05:38 +05:30
Neeraj Gupta b6aec20b22 [mob] Update log 2024-04-08 09:45:34 +05:30
Neeraj Gupta 0b08afdbe2 [mob] Use linear clustring for breaking up clusters 2024-04-08 08:52:00 +05:30
Neeraj Gupta 412e93c9fa [mob][face] Fix handling of case when noCluster id is assigned 2024-04-08 08:18:58 +05:30
Neeraj Gupta 67f26a1551 [mob][face] Add debug hook to delete all people to cluster mapping 2024-04-08 07:46:22 +05:30
Neeraj Gupta 2d58558737 [mob] Add support for removing people to cluster mapping 2024-04-08 07:43:08 +05:30
Neeraj Gupta 4a2b5fe27d [mob] Face: Ignore embeddings without image dims & bad landmarks 2024-04-07 16:12:59 +05:30
Neeraj Gupta 3d452c4e98 [mob] Logging changes 2024-04-07 16:11:07 +05:30
Neeraj Gupta b00ab0541e [mob] Handle error and empty face in visibility detector 2024-04-07 16:09:34 +05:30
Neeraj Gupta cbc7034d47 [mob] Discard old fileEmbeddings 2024-04-06 04:00:48 +05:30
Neeraj Gupta d19d7ffe79 [mob][face] Storage width/height along with area and visibility 2024-04-06 03:49:03 +05:30
Neeraj Gupta 6c02b03426 [mob] Lint fixes 2024-04-06 01:50:45 +05:30
Neeraj Gupta 2ae37682e7 [mob] Fix bug in handling err for clustering 2024-04-05 18:49:01 +05:30
Neeraj Gupta f261ee7184 [mob] Hide smaller clusters only when there are more than 2 clusters 2024-04-05 18:48:44 +05:30
Neeraj Gupta add66569dd Merge branch 'main' into mobile_face 2024-04-05 18:24:44 +05:30
Neeraj Gupta bb3a37adf5 [mob] Fetch remote entities before running clustering 2024-04-05 16:04:58 +05:30
Neeraj Gupta 7c6001321f Merge branch 'mobile_face' into mobile_face_feedback_sync 2024-04-05 16:03:32 +05:30
Neeraj Gupta 1b9c81c50c Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-04-05 16:00:09 +05:30
Neeraj Gupta 1996d86835 [mob] Persist remote feedback before running clustering 2024-04-05 15:59:53 +05:30
laurenspriem 0c72fd2a69 [mob] Add more validation for clustering 2024-04-05 15:50:52 +05:30
laurenspriem 723253a12c [mob] Fix issue with random photo entering cluster 2024-04-05 15:49:35 +05:30
Neeraj Gupta 18f202d3e4 [mob] Fixed bug in parsing json 2024-04-05 14:37:59 +05:30
laurenspriem 0777013b93 [mob] Show face area info in debug mode 2024-04-05 14:34:47 +05:30
laurenspriem 04a33e6f65 [mob] Show face visibility score in debug mode 2024-04-05 14:20:28 +05:30
laurenspriem f1a7256a14 [mob] Fix wrong y-coordiantes being stored for faces 2024-04-05 14:01:26 +05:30
laurenspriem 78af84450a [mob] Show debug info on blur 2024-04-05 13:45:19 +05:30
Neeraj Gupta 2456c02956 [mob] Remove personEntity dependency from faceDB 2024-04-05 12:52:01 +05:30
Neeraj Gupta 199dad3705 [mob] Make linter happy 2024-04-05 11:59:19 +05:30
laurenspriem ad73496c4d [mob] Minor change 2024-04-05 11:04:05 +05:30
Neeraj Gupta ef03c6f40a [mob] Remove debug code 2024-04-05 08:09:57 +05:30
Neeraj Gupta bd4c506fdd [mob] Remove fields & code related to person table 2024-04-05 07:50:03 +05:30
Neeraj Gupta be06d45e3a [mob] Fix person custom avatar rendering 2024-04-05 07:21:48 +05:30
Neeraj Gupta 7429791a19 [mob] Persist person update on remote 2024-04-05 07:13:15 +05:30
Neeraj Gupta 49671cbda3 [mob] Undo local changes 2024-04-05 07:04:17 +05:30
Neeraj Gupta 81c94b1e73 [mob] Remove unused method 2024-04-05 06:58:32 +05:30
Neeraj Gupta 3fb323ef29 [mob] Read person info from entity 2024-04-05 00:24:05 +05:30
Neeraj Gupta d8bf0ad2d5 [mob] Persist cluster information during person assignment 2024-04-04 22:04:19 +05:30
laurenspriem b48cb84100 [mob] better cluster analysis visualization 2024-04-04 18:47:30 +05:30
laurenspriem f1fd74b119 [mob] Option to add/remove face to cluster from file info 2024-04-04 18:47:09 +05:30
Neeraj Gupta f5a9679c0e [mob] Rename and add more attr to PersonEntity 2024-04-04 17:27:28 +05:30
laurenspriem 19007c38b5 [mob] await removal and fire event 2024-04-04 16:03:17 +05:30
laurenspriem 583c09155b [mob] Rename file 2024-04-04 15:40:38 +05:30
laurenspriem 5bce9abb5c [mob] Rename PeopleClustersPage 2024-04-04 15:39:35 +05:30
laurenspriem c6f9bbbbda [mob] Use rounded rectangle for cluster thumbnails 2024-04-04 15:38:23 +05:30
laurenspriem 517b099de8 [mob] better visualization of cluster analysis 2024-04-04 15:10:10 +05:30
Neeraj Gupta 2163201046 [mob] Increase the batch & bucket size 2024-04-04 14:46:56 +05:30
laurenspriem dd3b0be8f2 [mob] Tune analysis parameter 2024-04-04 13:17:43 +05:30
laurenspriem 6a9b670d52 [mob] thinner highlight of face in file info 2024-04-04 12:58:58 +05:30
laurenspriem 0176b01fea [mob] Add basic debug UI for breaking up cluster 2024-04-04 12:14:18 +05:30
laurenspriem 15f9176208 [mob] More logs on breaking cluster 2024-04-03 21:31:16 +05:30
laurenspriem 744ded4922 [mob] Add DBSCAN clustering for intra-cluster analysis 2024-04-03 18:49:43 +05:30
laurenspriem b21466bf13 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-04-03 17:02:39 +05:30
laurenspriem 6a240ee030 Highlight relevant face 2024-04-03 16:59:38 +05:30
Neeraj Gupta 922550b1a3 Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-04-03 13:57:58 +05:30
Neeraj Gupta fb3a77bf94 Merge branch 'main' of https://github.com/ente-io/auth into mobile_face 2024-04-03 13:57:39 +05:30
laurenspriem 934d0bb3a0 [mob] Add todo 2024-04-03 13:19:12 +05:30
laurenspriem 11937a42b4 [mob] cluster suggestion class 2024-04-03 13:18:24 +05:30
laurenspriem cb8f66fcaa [mob][wip] break up cluster method 2024-04-03 13:06:46 +05:30
laurenspriem 786ddf438b Add distance parameter to clustering 2024-04-03 13:06:08 +05:30
Neeraj Gupta e10cb5d456 [mob] Fix person cover photo 2024-04-03 05:26:08 +05:30
Neeraj Gupta a8b154b46e Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-04-02 17:39:19 +05:30
Neeraj Gupta 172678dc42 [mob] Lint fixes 2024-04-02 17:39:03 +05:30
laurenspriem 8fefc22180 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-04-02 17:30:50 +05:30
Neeraj Gupta 8e6617eed5 [mob] Speed up cluster avg calculation 2024-04-02 17:29:20 +05:30
Neeraj Gupta faa07a0704 [mob] compute suggestion in small batches 2024-04-02 16:56:55 +05:30
laurenspriem 57fec06d73 [mob] Bump minimum face score for clustering to 0.8 2024-04-02 16:44:34 +05:30
Neeraj Gupta e2ed836b16 Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-04-02 14:07:18 +05:30
Neeraj Gupta bdb7ce2f03 [mob] Store image height and width 2024-04-02 14:07:02 +05:30
laurenspriem 255b566342 View faces with highest distance in cluster suggestion 2024-04-02 13:46:42 +05:30
Neeraj Gupta c85692360c [mob] Fix face cluster suggestion 2024-04-02 13:35:32 +05:30
Neeraj Gupta 8e322114b7 [mob] Fix reset queries for feedback & clusters 2024-04-02 12:21:14 +05:30
Neeraj Gupta 226808aadb [mob] Use vector for cosine dist 2024-04-02 11:53:40 +05:30
Neeraj Gupta 4cb7334868 [mob] Remove unused method 2024-04-02 10:43:50 +05:30
Neeraj Gupta 814c0ad4b6 [mob] Drop cluster colum from files table 2024-04-02 10:41:28 +05:30
Neeraj Gupta 51b51ff2b1 [mob] Use separate table for storing clusters 2024-04-01 17:34:35 +05:30
Neeraj Gupta 323521d496 [mob] Rename face tables 2024-04-01 16:05:23 +05:30
Neeraj Gupta baec7a2af8 [mob] Remove unused column from facesTable 2024-04-01 15:49:15 +05:30
Neeraj Gupta 7e9c6a7f81 [mob] Rename 2024-04-01 15:44:25 +05:30
Neeraj Gupta 5b339fc30e Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-04-01 15:37:41 +05:30
Neeraj Gupta f663bbfc53 [mob] Rename 2024-04-01 15:37:25 +05:30
laurenspriem 1af3d2d2db [mob] Big cleanup of old code 2024-04-01 15:34:45 +05:30
Neeraj Gupta 29c58d5554 [mob] Remove unused code 2024-04-01 15:31:50 +05:30
laurenspriem e7670bfee6 [mob] complete remove from cluster feedback 2024-04-01 15:14:28 +05:30
Neeraj Gupta a75c440dc2 [mob] sync person entity type 2024-04-01 15:10:19 +05:30
laurenspriem 768fa3d1ce [mob][wip] remove from cluster feedback 2024-03-30 18:35:46 +05:30
laurenspriem a3b6a72315 [mob] Debug option to reset feedback 2024-03-30 17:13:54 +05:30
laurenspriem 7f66bd2ed0 [mob] constant increments in bucket clustering 2024-03-30 15:17:26 +05:30
laurenspriem f5ea834fad [mob] delete old file 2024-03-30 14:41:15 +05:30
laurenspriem aa79c4ee24 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-03-29 18:27:32 +05:30
laurenspriem 8c6bb30578 Change faceID generation 2024-03-29 18:26:28 +05:30
laurenspriem 8aed14ace6 [mob] Change text 2024-03-29 17:33:29 +05:30
laurenspriem b56b0c47d0 Show debug info for cluster suggestions 2024-03-29 17:26:58 +05:30
laurenspriem 2a04192b3c [mob] temp fix 2024-03-29 17:24:50 +05:30
Neeraj Gupta 67134db3a4 [mob] Fixed typo 2024-03-29 15:43:13 +05:30
Neeraj Gupta 44a5b97de1 [mob] Storge cluster summary in batches 2024-03-29 15:39:12 +05:30
Neeraj Gupta ab875ea9a9 [mob] Use epochTime as clusterID 2024-03-29 14:33:11 +05:30
Neeraj Gupta 5f468e6c63 [mob] Trim face score 2024-03-29 12:49:20 +05:30
laurenspriem 1d527f9e02 Add face score in debugMode 2024-03-29 12:18:21 +05:30
laurenspriem afa8a372d2 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-03-29 12:14:33 +05:30
Neeraj Gupta 6c287775d4 [mob] Add logs for cluster feedback suggestions 2024-03-28 16:25:09 +05:30
Neeraj Gupta 9aafe137a1 Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-03-28 16:13:25 +05:30
Neeraj Gupta d6db3de6b1 [mob] Log time to fetch in debugMode 2024-03-28 13:40:15 +05:30
Neeraj Gupta 03e5f06bf2 [mob][face] Add delay before starting faceIndexing 2024-03-28 13:27:16 +05:30
Neeraj Gupta aa58989299 [mob] Remove commented out code 2024-03-28 13:23:39 +05:30
Neeraj Gupta 5b94cbf912 [face][mob] Log db batch update progress 2024-03-28 13:22:32 +05:30
laurenspriem 3869802e4c Use alternative face thumbnails in suggestions 2024-03-27 16:08:23 +05:30
laurenspriem a09b71cc15 [mob] Faster face cropping method 2024-03-23 17:02:22 +05:30
laurenspriem b1b3bcc534 Support for clustering in buckets 2024-03-22 11:49:23 +05:30
laurenspriem 85f76497b4 More debug info 2024-03-22 11:31:33 +05:30
laurenspriem 005ab0814f [mob] Remove empty CTA icon when there are people 2024-03-21 18:59:45 +05:30
laurenspriem b8813161a1 Add faces count 2024-03-21 18:23:21 +05:30
laurenspriem f94aa400bf [mob] Minor changes to clustering 2024-03-21 18:07:12 +05:30
laurenspriem b5cff212bb Refactor of clustering 2024-03-21 16:59:55 +05:30
laurenspriem 212208ae01 Add debugPrint 2024-03-21 16:53:22 +05:30
laurenspriem fc8122b18e Add indexing debug cooldown 2024-03-21 16:52:52 +05:30
laurenspriem a2bca84b91 [mob] Sort clustering on fileCreationTime asc 2024-03-21 15:41:34 +05:30
laurenspriem a9fdee96a8 More debug options 2024-03-21 12:40:03 +05:30
laurenspriem 125a4de66a Deprecate function 2024-03-20 16:20:55 +05:30
laurenspriem a4582c0e55 Move FaceML inside Machine Learning directory 2024-03-20 15:51:57 +05:30
laurenspriem 1819ea834a Forgot to delete debug stuff 2024-03-20 14:44:28 +05:30
laurenspriem a443ac1680 Better use of constants 2024-03-20 14:42:42 +05:30
laurenspriem 39f16ff517 Only show high quality faces in file info 2024-03-20 14:34:12 +05:30
laurenspriem 974b7c7329 Increase blur threshold 2024-03-20 14:15:59 +05:30
laurenspriem af1a6fc9fa [mob] Log actually analyzed count 2024-03-20 12:03:08 +05:30
laurenspriem 2573328c30 [mob] Minor change 2024-03-20 11:28:59 +05:30
laurenspriem eaea4f81b7 [mob] update server on old FaceMlVersion 2024-03-20 11:28:37 +05:30
laurenspriem 17fa64aa5e Remove unused import 2024-03-20 10:43:02 +05:30
laurenspriem 83d8d7ae7a [mob] empty constructor for Face 2024-03-19 18:24:46 +05:30
Neeraj Gupta 4d4bdb99df Remove auth/flutter submodule 2024-03-19 16:20:34 +05:30
Neeraj Gupta a79b14db78 [mob] use ml version when to decide need for re-index 2024-03-19 16:16:08 +05:30
Neeraj Gupta e83e8cdb6e [mob] minor refactor 2024-03-19 15:18:07 +05:30
Neeraj Gupta 3e4cf4b4f2 [mob] Skip already indexed files on remote 2024-03-19 15:06:32 +05:30
Neeraj Gupta 8a4ca15eb8 [mob] generated strings 2024-03-19 13:44:57 +05:30
Neeraj Gupta 79acd166b7 [mob] Enable magic search in face 2024-03-19 12:37:24 +05:30
Neeraj Gupta f78eb703ef [mob] Add support for pushing embeddings to remote 2024-03-16 23:02:44 +05:30
laurenspriem 58c85c8c13 Deprecating some methods 2024-03-15 18:22:40 +05:30
laurenspriem 0b0a0cec26 [mob] Only run decoding of images once 2024-03-15 18:15:57 +05:30
laurenspriem 470a3da7b0 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-03-15 17:10:16 +05:30
laurenspriem 9285baace2 Change Face to use relative coordinates 2024-03-15 17:07:17 +05:30
Neeraj Gupta bcfe05f16a [mob] Remove unused import 2024-03-15 15:20:49 +05:30
laurenspriem ca16c6f0d6 Merge remote-tracking branch 'origin/mobile_face' into mobile_face 2024-03-15 14:58:21 +05:30
laurenspriem cdd8929bc6 Cleanup 2024-03-15 14:53:46 +05:30
laurenspriem 05f188080b Remove image package in thumbnail generation 2024-03-15 14:53:40 +05:30
Neeraj Gupta 85ed93e374 [mob] Remove unused files 2024-03-15 14:52:57 +05:30
Neeraj Gupta 3007c4c7dd Remove unused model 2024-03-15 14:41:57 +05:30
laurenspriem 847a99d0e9 Fix cutoff face thumbnails 2024-03-15 12:52:27 +05:30
laurenspriem 52b787f71e Face thumbnail generation without canvas 2024-03-15 12:48:01 +05:30
Neeraj Gupta 9f3fe7b05b Merge branch 'main' into mobile_face 2024-03-14 17:11:53 +05:30
laurenspriem 8ef673fe58 Clean up logs 2024-03-14 16:13:42 +05:30
laurenspriem 74d1cbb01f Use full file on face detection 2024-03-14 16:13:27 +05:30
laurenspriem f0ad363895 elliptical rounding on face widget 2024-03-14 16:04:08 +05:30
Neeraj Gupta c643876955 [mob][face] Fix clear table query 2024-03-14 11:12:22 +05:30
laurenspriem 17684a112e [mob] green banner for adding name to cluster 2024-03-13 19:00:23 +05:30
laurenspriem aad4bd3b79 Better logging for face detection 2024-03-13 18:32:57 +05:30
Neeraj Gupta 614db863bc [mob] Fix search tab 2024-03-13 17:49:10 +05:30
Neeraj Gupta f239959067 Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-03-13 16:39:27 +05:30
laurenspriem 83b9afa5c8 custom interpolation for face detection 2024-03-13 16:36:45 +05:30
Neeraj Gupta 33a0a3511a Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face 2024-03-13 12:06:53 +05:30
Neeraj Gupta f9dd509d61 Merge branch 'main' of https://github.com/ente-io/auth into mobile_face 2024-03-13 12:06:33 +05:30
laurenspriem af978e1e36 Banner to add name to cluster 2024-03-12 18:52:31 +05:30
laurenspriem a00a8bb0a9 RRect for faces in file info 2024-03-12 18:48:21 +05:30
laurenspriem 3b2fa3ba10 bicubic interpolation 2024-03-12 17:06:42 +05:30
laurenspriem 5b3519ea38 Align faces with bilinear interpolation in dart 2024-03-11 18:50:00 +05:30
laurenspriem ebc69b645e Enable faces section quick and dirty fix 2024-03-11 18:18:45 +05:30
laurenspriem db4b1a8767 Deprecate TFLite preprocessing methods 2024-03-11 17:10:16 +05:30
Neeraj Gupta 350e02f348 Lint fixes 2024-03-08 12:00:39 +05:30
Neeraj Gupta d2bf4846a5 [mobile] Patch faces mvp from photos-app repo 2024-03-08 09:36:03 +05:30
520 changed files with 23711 additions and 7364 deletions

View file

@ -4,11 +4,12 @@ labels: ["triage"]
body:
- type: markdown
attributes:
value: >
Before opening a new issue, please ensure you are on the latest
version (it might've already been fixed), and that you've searched
for existing issues (please add you observations as a comment
there instead of creating a duplicate).
value: |
Before opening a new bug report, please ensure
1. you are on the latest version (it might've already been fixed),
2. you've searched for existing issues (please add your observations as a comment there instead of creating a duplicate).
If you are self hosting, please create a community [Q&A](https://github.com/ente-io/ente/discussions/categories/q-a) instead.
- type: textarea
attributes:
label: Description
@ -16,7 +17,8 @@ body:
Please describe the bug. If possible, also include the steps to
reproduce the behaviour, and the expected behaviour (sometimes
bugs are just expectation mismatches, in which case this would be
a good fit for Discussions).
a good fit for [feature
requests](https://github.com/ente-io/ente/discussions/categories/feature-requests)).
validations:
required: true
- type: input

View file

@ -4,7 +4,7 @@ on:
workflow_dispatch: # Allow manually running the action
env:
FLUTTER_VERSION: "3.19.3"
FLUTTER_VERSION: "3.22.0"
jobs:
build:

View file

@ -9,7 +9,7 @@ on:
- ".github/workflows/mobile-lint.yml"
env:
FLUTTER_VERSION: "3.19.5"
FLUTTER_VERSION: "3.22.0"
jobs:
lint:

6
.gitignore vendored
View file

@ -1,8 +1,6 @@
# Let folks use their custom .vscode settings
# Let folks use their custom editor settings
.vscode
.idea
# macOS
.DS_Store
.idea
.ente.authenticator.db
.ente.offline_authenticator.db

View file

@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application android:name="${applicationName}"
android:label="auth"
android:label="Auth"
android:icon="@mipmap/launcher_icon"
android:usesCleartextTraffic="true"
android:requestLegacyExternalStorage="true"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 801 KiB

View file

@ -85,20 +85,16 @@ PODS:
- SDWebImage (5.19.2):
- SDWebImage/Core (= 5.19.2)
- SDWebImage/Core (5.19.2)
- Sentry/HybridSDK (8.21.0):
- SentryPrivate (= 8.21.0)
- sentry_flutter (0.0.1):
- Sentry/HybridSDK (8.25.0)
- sentry_flutter (7.20.1):
- Flutter
- FlutterMacOS
- Sentry/HybridSDK (= 8.21.0)
- SentryPrivate (8.21.0)
- Sentry/HybridSDK (= 8.25.0)
- share_plus (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- smart_auth (0.0.1):
- Flutter
- sodium_libs (2.2.1):
- Flutter
- sqflite (0.0.3):
@ -115,7 +111,7 @@ PODS:
- sqlite3/common
- sqlite3_flutter_libs (0.0.1):
- Flutter
- sqlite3 (~> 3.45.1)
- "sqlite3 (~> 3.45.3+1)"
- sqlite3/fts5
- sqlite3/perf-threadsafe
- sqlite3/rtree
@ -148,7 +144,6 @@ DEPENDENCIES:
- 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`)
- smart_auth (from `.symlinks/plugins/smart_auth/ios`)
- sodium_libs (from `.symlinks/plugins/sodium_libs/ios`)
- sqflite (from `.symlinks/plugins/sqflite/darwin`)
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/ios`)
@ -163,7 +158,6 @@ SPEC REPOS:
- ReachabilitySwift
- SDWebImage
- Sentry
- SentryPrivate
- sqlite3
- SwiftyGif
- Toast
@ -215,8 +209,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/share_plus/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
smart_auth:
:path: ".symlinks/plugins/smart_auth/ios"
sodium_libs:
:path: ".symlinks/plugins/sodium_libs/ios"
sqflite:
@ -236,13 +228,13 @@ SPEC CHECKSUMS:
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
fk_user_agent: 1f47ec39291e8372b1d692b50084b0d54103c545
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_email_sender: 02d7443217d8c41483223627972bfdc09f74276b
flutter_email_sender: 10a22605f92809a11ef52b2f412db806c6082d40
flutter_inappwebview_ios: 97215cf7d4677db55df76782dbd2930c5e1c1ea0
flutter_local_authentication: 1172a4dd88f6306dadce067454e2c4caf07977bb
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
flutter_native_splash: edf599c81f74d093a4daf8e17bd7a018854bc778
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265
fluttertoast: 9f2f8e81bb5ce18facb9748d7855bf5a756fe3db
local_auth_darwin: c7e464000a6a89e952235699e32b329457608d98
move_to_background: 39a5b79b26d577b0372cbe8a8c55e7aa9fcd3a2d
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
@ -253,16 +245,14 @@ SPEC CHECKSUMS:
qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e
ReachabilitySwift: 2128f3a8c9107e1ad33574c6e58e8285d460b149
SDWebImage: dfe95b2466a9823cf9f0c6d01217c06550d7b29a
Sentry: ebc12276bd17613a114ab359074096b6b3725203
sentry_flutter: dff1df05dc39c83d04f9330b36360fc374574c5e
SentryPrivate: d651efb234cf385ec9a1cdd3eff94b5e78a0e0fe
Sentry: cd86fc55628f5b7c572cabe66cc8f95a9d2f165a
sentry_flutter: 4cb24c1055c556d7b27262ab2e179d1e5a0b9b0c
share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
smart_auth: 4bedbc118723912d0e45a07e8ab34039c19e04f2
sodium_libs: 1faae17af662384acbd13e41867a0008cd2e2318
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
sqlite3: 02d1f07eaaa01f80a1c16b4b31dfcbb3345ee01a
sqlite3_flutter_libs: af0e8fe9bce48abddd1ffdbbf839db0302d72d80
sqlite3_flutter_libs: 9bfe005308998aeca155330bbc2ea6dddf834a3b
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586

View file

@ -20,7 +20,7 @@
<string>es</string>
</array>
<key>CFBundleName</key>
<string>auth</string>
<string>Auth</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>

View file

@ -189,7 +189,7 @@ class _AppState extends State<App> with WindowListener, TrayListener {
windowManager.show();
break;
case 'exit_app':
windowManager.close();
windowManager.destroy();
break;
}
}

View file

@ -20,6 +20,8 @@
"codeIssuerHint": "発行者",
"codeSecretKeyHint": "秘密鍵",
"codeAccountHint": "アカウント (you@domain.com)",
"codeTagHint": "タグ",
"accountKeyType": "鍵の種類",
"sessionExpired": "セッションが失効しました",
"@sessionExpired": {
"description": "Title of the dialog when the users current session is invalid/expired"
@ -77,6 +79,7 @@
"data": "データ",
"importCodes": "コードをインポート",
"importTypePlainText": "プレーンテキスト",
"importTypeEnteEncrypted": "Ente 暗号化されたエクスポート",
"passwordForDecryptingExport": "復号化用パスワード",
"passwordEmptyError": "パスワードは空欄にできません",
"importFromApp": "{appName} からコードをインポート",
@ -121,6 +124,7 @@
"suggestFeatures": "機能を提案",
"faq": "FAQ",
"faq_q_1": "Authはどのくらい安全ですか",
"faq_a_1": "Ente Authでバックアップされたコードはすべてエンドツーエンドで暗号化されて保存されます。つまり、コードにアクセスできるのはあなただけです。当社のアプリはオープンソースであり、暗号化技術は外部監査を受けています。",
"faq_q_2": "パソコンから私のコードにアクセスできますか?",
"faq_a_2": "auth.ente.io で Web からコードにアクセス可能です。",
"faq_q_3": "コードを削除するにはどうすればいいですか?",
@ -154,6 +158,7 @@
}
}
},
"invalidQRCode": "QRコードが無効です",
"noRecoveryKeyTitle": "回復キーがありませんか?",
"enterEmailHint": "メールアドレスを入力してください",
"invalidEmailTitle": "メールアドレスが無効です",
@ -347,6 +352,7 @@
"deleteCodeAuthMessage": "コードを削除するためには認証が必要です",
"showQRAuthMessage": "QR コードを表示するためには認証が必要です",
"confirmAccountDeleteTitle": "アカウントの削除に同意",
"confirmAccountDeleteMessage": "このアカウントは他のEnteアプリも使用している場合はそれらにも紐づけされています。\nすべてのEnteアプリでアップロードされたデータは削除され、アカウントは完全に削除されます。",
"androidBiometricHint": "本人を確認する",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
@ -417,5 +423,18 @@
"invalidEndpoint": "無効なエンドポイントです",
"invalidEndpointMessage": "入力されたエンドポイントは無効です。有効なエンドポイントを入力して再試行してください。",
"endpointUpdatedMessage": "エンドポイントの更新に成功しました",
"customEndpoint": "{endpoint} に接続しました"
"customEndpoint": "{endpoint} に接続しました",
"pinText": "固定",
"unpinText": "固定を解除",
"pinnedCodeMessage": "{code} を固定しました",
"unpinnedCodeMessage": "{code} の固定が解除されました",
"tags": "タグ",
"createNewTag": "新しいタグの作成",
"tag": "タグ",
"create": "作成",
"editTag": "タグの編集",
"deleteTagTitle": "タグを削除しますか?",
"deleteTagMessage": "このタグを削除してもよろしいですか?この操作は取り消しできません。",
"somethingWentWrongParsingCode": "{x} のコードを解析できませんでした。",
"updateNotAvailable": "アップデートは利用できません"
}

View file

@ -20,6 +20,8 @@
"codeIssuerHint": "Emissor",
"codeSecretKeyHint": "Chave secreta",
"codeAccountHint": "Conta (voce@dominio.com)",
"codeTagHint": "Etiqueta",
"accountKeyType": "Tipo de chave",
"sessionExpired": "Sessão expirada",
"@sessionExpired": {
"description": "Title of the dialog when the users current session is invalid/expired"
@ -156,6 +158,7 @@
}
}
},
"invalidQRCode": "QR Code inválido",
"noRecoveryKeyTitle": "Sem chave de recuperação?",
"enterEmailHint": "Insira o seu endereço de e-mail",
"invalidEmailTitle": "Endereço de e-mail inválido",
@ -420,5 +423,16 @@
"invalidEndpoint": "Endpoint inválido",
"invalidEndpointMessage": "Desculpe, o endpoint que você inseriu é inválido. Por favor, insira um endpoint válido e tente novamente.",
"endpointUpdatedMessage": "Endpoint atualizado com sucesso",
"customEndpoint": "Conectado a {endpoint}"
"customEndpoint": "Conectado a {endpoint}",
"pinText": "Fixar",
"pinnedCodeMessage": "{code} foi fixado",
"tags": "Etiquetas",
"createNewTag": "Criar etiqueta",
"tag": "Etiqueta",
"create": "Criar",
"editTag": "Editar etiqueta",
"deleteTagTitle": "Excluir etiqueta?",
"deleteTagMessage": "Tem certeza de que deseja excluir esta etiqueta? Essa ação é irreversível.",
"somethingWentWrongParsingCode": "Não foi possível analisar os códigos {x}.",
"updateNotAvailable": "Atualização não está disponível"
}

View file

@ -188,6 +188,8 @@
"recoveryKeySaveDescription": "Мы не храним этот ключ, пожалуйста, сохраните этот ключ в безопасном месте.",
"doThisLater": "Сделать позже",
"saveKey": "Сохранить ключ",
"save": "Сохранить",
"send": "Отправить",
"back": "Вернуться",
"createAccount": "Создать аккаунт",
"passwordStrength": "Мощность пароля: {passwordStrengthValue}",
@ -394,5 +396,13 @@
"signOutOtherDevices": "Выйти из других устройств",
"doNotSignOut": "Не выходить",
"hearUsWhereTitle": "Как вы узнали о Ente? (необязательно)",
"hearUsExplanation": "Будет полезно, если вы укажете, где нашли нас, так как мы не отслеживаем установки приложения"
"hearUsExplanation": "Будет полезно, если вы укажете, где нашли нас, так как мы не отслеживаем установки приложения",
"waitingForVerification": "Ожидание подтверждения...",
"developerSettingsWarning": "Вы уверены, что хотите изменить настройки разработчика?",
"developerSettings": "Настройки разработчика",
"serverEndpoint": "Конечная точка сервера",
"invalidEndpoint": "Неверная конечная точка",
"invalidEndpointMessage": "Извините, введенная вами конечная точка неверна. Пожалуйста, введите корректную конечную точку и повторите попытку.",
"endpointUpdatedMessage": "Конечная точка успешно обновлена",
"customEndpoint": "Подключено к {endpoint}"
}

View file

@ -20,6 +20,8 @@
"codeIssuerHint": "发行人",
"codeSecretKeyHint": "私钥",
"codeAccountHint": "账户 (you@domain.com)",
"codeTagHint": "标签",
"accountKeyType": "密钥类型",
"sessionExpired": "会话已过期",
"@sessionExpired": {
"description": "Title of the dialog when the users current session is invalid/expired"
@ -156,6 +158,7 @@
}
}
},
"invalidQRCode": "二维码无效",
"noRecoveryKeyTitle": "没有恢复密钥吗?",
"enterEmailHint": "请输入您的电子邮件地址",
"invalidEmailTitle": "无效的电子邮件地址",
@ -420,5 +423,18 @@
"invalidEndpoint": "端点无效",
"invalidEndpointMessage": "抱歉,您输入的端点无效。请输入有效的端点,然后重试。",
"endpointUpdatedMessage": "端点更新成功",
"customEndpoint": "已连接至 {endpoint}"
"customEndpoint": "已连接至 {endpoint}",
"pinText": "置顶",
"unpinText": "取消置顶",
"pinnedCodeMessage": "{code} 已被置顶",
"unpinnedCodeMessage": "{code} 已被取消置顶",
"tags": "标签",
"createNewTag": "创建新标签",
"tag": "标签",
"create": "创建",
"editTag": "编辑标签",
"deleteTagTitle": "要删除标签吗?",
"deleteTagMessage": "您确定要删除此标签吗?此操作是不可逆的。",
"somethingWentWrongParsingCode": "我们无法解析 {x} 代码。",
"updateNotAvailable": "更新不可用"
}

View file

@ -125,10 +125,10 @@ class Code {
final issuer = _getIssuer(uri);
try {
return Code(
final code = Code(
_getAccount(uri),
issuer,
_getDigits(uri, issuer),
_getDigits(uri),
_getPeriod(uri),
getSanitizedSecret(uri.queryParameters['secret']!),
_getAlgorithm(uri),
@ -137,6 +137,7 @@ class Code {
rawData,
display: CodeDisplay.fromUri(uri) ?? CodeDisplay(),
);
return code;
} catch (e) {
// if account name contains # without encoding,
// rest of the url are treated as url fragment
@ -174,12 +175,11 @@ class Code {
}
String toOTPAuthUrlFormat() {
final uri = Uri.parse(rawData);
final uri = Uri.parse(rawData.replaceAll("#", '%23'));
final query = {...uri.queryParameters};
query["codeDisplay"] = jsonEncode(display.toJson());
final newUri = uri.replace(queryParameters: query);
return jsonEncode(newUri.toString());
}
@ -201,11 +201,11 @@ class Code {
}
}
static int _getDigits(Uri uri, String issuer) {
static int _getDigits(Uri uri) {
try {
return int.parse(uri.queryParameters['digits']!);
} catch (e) {
if (issuer.toLowerCase() == "steam") {
if (uri.host == "steam") {
return steamDigits;
}
return defaultDigits;

View file

@ -1,6 +1,7 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
/// Used to store the display settings of a code.
class CodeDisplay {
@ -54,13 +55,34 @@ class CodeDisplay {
);
}
static CodeDisplay? fromUri(Uri uri) {
/// Converts the [CodeDisplay] to a json object.
/// When [safeParsing] is true, the json will be parsed safely.
/// If we fail to parse the json, we will return an empty [CodeDisplay].
static CodeDisplay? fromUri(Uri uri, {bool safeParsing = false}) {
if (!uri.queryParameters.containsKey("codeDisplay")) return null;
final String codeDisplay =
uri.queryParameters['codeDisplay']!.replaceAll('%2C', ',');
final decodedDisplay = jsonDecode(codeDisplay);
return _parseCodeDisplayJson(codeDisplay, safeParsing);
}
return CodeDisplay.fromJson(decodedDisplay);
static CodeDisplay _parseCodeDisplayJson(String json, bool safeParsing) {
try {
final decodedDisplay = jsonDecode(json);
return CodeDisplay.fromJson(decodedDisplay);
} catch (e, s) {
Logger("CodeDisplay")
.severe("Could not parse code display from json", e, s);
// (ng/prateek) Handle the case where we have fragment in the rawDataUrl
if (!json.endsWith("}") && json.contains("}#")) {
Logger("CodeDisplay").warning("ignoring code display as it's invalid");
return CodeDisplay();
}
if (safeParsing) {
return CodeDisplay();
} else {
rethrow;
}
}
}
Map<String, dynamic> toJson() {

View file

@ -240,7 +240,7 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
final account = _accountController.text.trim();
final issuer = _issuerController.text.trim();
final secret = _secretController.text.trim().replaceAll(' ', '');
final isStreamCode = issuer.toLowerCase() == "steam";
final isStreamCode = issuer.toLowerCase() == "steam" || issuer.toLowerCase().contains('steampowered.com');
if (widget.code != null && widget.code!.secret != secret) {
ButtonResult? result = await showChoiceActionSheet(
context,

View file

@ -41,9 +41,9 @@ class CodeStore {
} else {
code = Code.fromExportJson(decodeJson);
}
} catch (e) {
} catch (e, s) {
code = Code.withError(e, entity.rawData);
_logger.severe("Could not parse code", code.err);
_logger.severe("Could not parse code", e, s);
}
code.generatedID = entity.generatedID;
code.hasSynced = entity.hasSynced;

View file

@ -48,7 +48,6 @@ class _CodeWidgetState extends State<CodeWidget> {
late bool _shouldShowLargeIcon;
late bool _hideCode;
bool isMaskingEnabled = false;
late final colorScheme = getEnteColorScheme(context);
@override
void initState() {
@ -78,6 +77,7 @@ class _CodeWidgetState extends State<CodeWidget> {
@override
Widget build(BuildContext context) {
final colorScheme = getEnteColorScheme(context);
if (isMaskingEnabled != PreferenceService.instance.shouldHideCodes()) {
isMaskingEnabled = PreferenceService.instance.shouldHideCodes();
_hideCode = isMaskingEnabled;
@ -91,6 +91,100 @@ class _CodeWidgetState extends State<CodeWidget> {
_isInitialized = true;
}
final l10n = context.l10n;
Widget getCardContents(AppLocalizations l10n) {
return Stack(
children: [
if (widget.code.isPinned)
Align(
alignment: Alignment.topRight,
child: CustomPaint(
painter: PinBgPainter(
color: colorScheme.pinnedBgColor,
),
size: const Size(39, 39),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (widget.code.type.isTOTPCompatible)
CodeTimerProgress(
period: widget.code.period,
),
const SizedBox(height: 16),
Row(
children: [
_shouldShowLargeIcon ? _getIcon() : const SizedBox.shrink(),
Expanded(
child: Column(
children: [
_getTopRow(),
const SizedBox(height: 4),
_getBottomRow(l10n),
],
),
),
],
),
const SizedBox(
height: 20,
),
],
),
if (widget.code.isPinned) ...[
Align(
alignment: Alignment.topRight,
child: Padding(
padding: const EdgeInsets.only(right: 6, top: 6),
child: SvgPicture.asset("assets/svg/pin-card.svg"),
),
),
],
],
);
}
Widget clippedCard(AppLocalizations l10n) {
return Container(
height: 132,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Theme.of(context).colorScheme.codeCardBackgroundColor,
boxShadow:
widget.code.isPinned ? colorScheme.pinnedCardBoxShadow : [],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Material(
color: Colors.transparent,
child: InkWell(
customBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
onTap: () {
_copyCurrentOTPToClipboard();
},
onDoubleTap: isMaskingEnabled
? () {
setState(
() {
_hideCode = !_hideCode;
},
);
}
: null,
onLongPress: () {
_copyCurrentOTPToClipboard();
},
child: getCardContents(l10n),
),
),
),
);
}
return Container(
margin: const EdgeInsets.only(left: 16, right: 16, bottom: 8, top: 8),
child: Builder(
@ -126,7 +220,7 @@ class _CodeWidgetState extends State<CodeWidget> {
],
padding: const EdgeInsets.all(8.0),
),
child: _clippedCard(l10n),
child: clippedCard(l10n),
);
}
@ -216,7 +310,7 @@ class _CodeWidgetState extends State<CodeWidget> {
],
),
child: Builder(
builder: (context) => _clippedCard(l10n),
builder: (context) => clippedCard(l10n),
),
);
},
@ -224,98 +318,6 @@ class _CodeWidgetState extends State<CodeWidget> {
);
}
Widget _clippedCard(AppLocalizations l10n) {
return Container(
height: 132,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Theme.of(context).colorScheme.codeCardBackgroundColor,
boxShadow: widget.code.isPinned ? colorScheme.pinnedCardBoxShadow : [],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Material(
color: Colors.transparent,
child: InkWell(
customBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
onTap: () {
_copyCurrentOTPToClipboard();
},
onDoubleTap: isMaskingEnabled
? () {
setState(
() {
_hideCode = !_hideCode;
},
);
}
: null,
onLongPress: () {
_copyCurrentOTPToClipboard();
},
child: _getCardContents(l10n),
),
),
),
);
}
Widget _getCardContents(AppLocalizations l10n) {
return Stack(
children: [
if (widget.code.isPinned)
Align(
alignment: Alignment.topRight,
child: CustomPaint(
painter: PinBgPainter(
color: colorScheme.pinnedBgColor,
),
size: const Size(39, 39),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (widget.code.type == Type.totp)
CodeTimerProgress(
period: widget.code.period,
),
const SizedBox(height: 16),
Row(
children: [
_shouldShowLargeIcon ? _getIcon() : const SizedBox.shrink(),
Expanded(
child: Column(
children: [
_getTopRow(),
const SizedBox(height: 4),
_getBottomRow(l10n),
],
),
),
],
),
const SizedBox(
height: 20,
),
],
),
if (widget.code.isPinned) ...[
Align(
alignment: Alignment.topRight,
child: Padding(
padding: const EdgeInsets.only(right: 6, top: 6),
child: SvgPicture.asset("assets/svg/pin-card.svg"),
),
),
],
],
);
}
Widget _getBottomRow(AppLocalizations l10n) {
return Container(
padding: const EdgeInsets.only(left: 16, right: 16),
@ -585,7 +587,7 @@ class _CodeWidgetState extends State<CodeWidget> {
String _getFormattedCode(String code) {
if (_hideCode) {
// replace all digits with
code = code.replaceAll(RegExp(r'\d'), '');
code = code.replaceAll(RegExp(r'\S'), '');
}
if (code.length == 6) {
return "${code.substring(0, 3)} ${code.substring(3, 6)}";

View file

@ -1,8 +1,12 @@
import 'package:ente_auth/models/code.dart';
import 'package:flutter/foundation.dart';
import 'package:otp/otp.dart' as otp;
import 'package:steam_totp/steam_totp.dart';
String getOTP(Code code) {
if (code.type == Type.steam) {
return _getSteamCode(code);
}
if (code.type == Type.hotp) {
return _getHOTPCode(code);
}
@ -26,7 +30,18 @@ String _getHOTPCode(Code code) {
);
}
String _getSteamCode(Code code, [bool isNext = false]) {
final SteamTOTP steamtotp = SteamTOTP(secret: code.secret);
return steamtotp.generate(
DateTime.now().millisecondsSinceEpoch ~/ 1000 + (isNext ? code.period : 0),
);
}
String getNextTotp(Code code) {
if (code.type == Type.steam) {
return _getSteamCode(code, true);
}
return otp.OTP.generateTOTPCodeString(
getSanitizedSecret(code.secret),
DateTime.now().millisecondsSinceEpoch + code.period * 1000,

View file

@ -29,20 +29,16 @@ PODS:
- ReachabilitySwift (5.2.2)
- screen_retriever (0.0.1):
- FlutterMacOS
- Sentry/HybridSDK (8.21.0):
- SentryPrivate (= 8.21.0)
- sentry_flutter (0.0.1):
- Sentry/HybridSDK (8.25.0)
- sentry_flutter (7.20.1):
- Flutter
- FlutterMacOS
- Sentry/HybridSDK (= 8.21.0)
- SentryPrivate (8.21.0)
- Sentry/HybridSDK (= 8.25.0)
- share_plus (0.0.1):
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- smart_auth (0.0.1):
- FlutterMacOS
- sodium_libs (2.2.1):
- FlutterMacOS
- sqflite (0.0.3):
@ -59,7 +55,7 @@ PODS:
- sqlite3/common
- sqlite3_flutter_libs (0.0.1):
- FlutterMacOS
- sqlite3 (~> 3.45.1)
- "sqlite3 (~> 3.45.3+1)"
- sqlite3/fts5
- sqlite3/perf-threadsafe
- sqlite3/rtree
@ -87,7 +83,6 @@ DEPENDENCIES:
- 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`)
- smart_auth (from `Flutter/ephemeral/.symlinks/plugins/smart_auth/macos`)
- sodium_libs (from `Flutter/ephemeral/.symlinks/plugins/sodium_libs/macos`)
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`)
- sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos`)
@ -100,7 +95,6 @@ SPEC REPOS:
- OrderedSet
- ReachabilitySwift
- Sentry
- SentryPrivate
- sqlite3
EXTERNAL SOURCES:
@ -136,8 +130,6 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos
shared_preferences_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
smart_auth:
:path: Flutter/ephemeral/.symlinks/plugins/smart_auth/macos
sodium_libs:
:path: Flutter/ephemeral/.symlinks/plugins/sodium_libs/macos
sqflite:
@ -167,16 +159,14 @@ SPEC CHECKSUMS:
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
ReachabilitySwift: 2128f3a8c9107e1ad33574c6e58e8285d460b149
screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38
Sentry: ebc12276bd17613a114ab359074096b6b3725203
sentry_flutter: dff1df05dc39c83d04f9330b36360fc374574c5e
SentryPrivate: d651efb234cf385ec9a1cdd3eff94b5e78a0e0fe
Sentry: cd86fc55628f5b7c572cabe66cc8f95a9d2f165a
sentry_flutter: 4cb24c1055c556d7b27262ab2e179d1e5a0b9b0c
share_plus: 76dd39142738f7a68dd57b05093b5e8193f220f7
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
smart_auth: b38e3ab4bfe089eacb1e233aca1a2340f96c28e9
sodium_libs: d39bd76697736cb11ce4a0be73b9b4bc64466d6f
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
sqlite3: 02d1f07eaaa01f80a1c16b4b31dfcbb3345ee01a
sqlite3_flutter_libs: 06a05802529659a272beac4ee1350bfec294f386
sqlite3_flutter_libs: 8d204ef443cf0d5c1c8b058044eab53f3943a9c5
tray_manager: 9064e219c56d75c476e46b9a21182087930baf90
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 B

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 628 B

After

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -745,6 +745,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.0"
hashlib:
dependency: transitive
description:
name: hashlib
sha256: "67e640e19cc33070113acab3125cd48ebe480a0300e15554dec089b8878a729f"
url: "https://pub.dev"
source: hosted
version: "1.16.0"
hashlib_codecs:
dependency: transitive
description:
name: hashlib_codecs
sha256: "49e2a471f74b15f1854263e58c2ac11f2b631b5b12c836f9708a35397d36d626"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
hex:
dependency: transitive
description:
@ -1439,6 +1455,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.11.1"
steam_totp:
dependency: "direct main"
description:
name: steam_totp
sha256: "3c09143c983f6bb05bb53e9232f9d40bbcc01c596ba0273c3e6bb246729abfa1"
url: "https://pub.dev"
source: hosted
version: "0.0.1"
step_progress_indicator:
dependency: "direct main"
description:

View file

@ -1,6 +1,6 @@
name: ente_auth
description: ente two-factor authenticator
version: 2.0.58+258
version: 3.0.4+304
publish_to: none
environment:
@ -94,6 +94,7 @@ dependencies:
sqflite_common_ffi: ^2.3.0+4
sqlite3: ^2.1.0
sqlite3_flutter_libs: ^0.5.19+1
steam_totp: ^0.0.1
step_progress_indicator: ^1.0.2
styled_text: ^8.1.0
tray_manager: ^0.2.1

View file

@ -14,7 +14,7 @@
"build:ci": "yarn build-renderer && tsc",
"build:quick": "yarn build-renderer && yarn build-main:quick",
"dev": "concurrently --kill-others --success first --names 'main,rndr' \"yarn dev-main\" \"yarn dev-renderer\"",
"dev-main": "tsc && electron app/main.js",
"dev-main": "tsc && electron .",
"dev-renderer": "cd ../web && yarn install && yarn dev:photos",
"postinstall": "electron-builder install-app-deps",
"lint": "yarn prettier --check --log-level warn . && eslint --ext .ts src && yarn tsc",
@ -30,7 +30,7 @@
"compare-versions": "^6.1",
"electron-log": "^5.1",
"electron-store": "^8.2",
"electron-updater": "^6.1",
"electron-updater": "^6.2",
"ffmpeg-static": "^5.2",
"html-entities": "^2.5",
"jpeg-js": "^0.4",

View file

@ -241,7 +241,7 @@ const uniqueSavePath = (dirPath: string, fileName: string) => {
*
* @param webContents The renderer to configure.
*/
export const allowExternalLinks = (webContents: WebContents) => {
export const allowExternalLinks = (webContents: WebContents) =>
// By default, if the user were open a link, say
// https://github.com/ente-io/ente/discussions, then it would open a _new_
// BrowserWindow within our app.
@ -253,13 +253,37 @@ export const allowExternalLinks = (webContents: WebContents) => {
// Returning `action` "deny" accomplishes this.
webContents.setWindowOpenHandler(({ url }) => {
if (!url.startsWith(rendererURL)) {
// This does not work in Ubuntu currently: mailto links seem to just
// get ignored, and HTTP links open in the text editor instead of in
// the browser.
// https://github.com/electron/electron/issues/31485
void shell.openExternal(url);
return { action: "deny" };
} else {
return { action: "allow" };
}
});
};
/**
* Allow uploading to arbitrary S3 buckets.
*
* The files in the desktop app are served over the ente:// protocol. During
* testing or self-hosting, we might be using a S3 bucket that does not allow
* whitelisting a custom URI scheme. To avoid requiring the bucket to set an
* "Access-Control-Allow-Origin: *" or do a echo-back of `Origin`, we add a
* workaround here instead, intercepting the ACAO header and allowing `*`.
*/
export const allowAllCORSOrigins = (webContents: WebContents) =>
webContents.session.webRequest.onHeadersReceived(
({ responseHeaders }, callback) => {
const headers: NonNullable<typeof responseHeaders> = {};
for (const [key, value] of Object.entries(responseHeaders ?? {}))
if (key.toLowerCase() != "access-control-allow-origin")
headers[key] = value;
headers["Access-Control-Allow-Origin"] = ["*"];
callback({ responseHeaders: headers });
},
);
/**
* Add an icon for our app in the system tray.
@ -291,32 +315,18 @@ const setupTrayItem = (mainWindow: BrowserWindow) => {
/**
* Older versions of our app used to maintain a cache dir using the main
* process. This has been removed in favor of cache on the web layer.
* process. This has been removed in favor of cache on the web layer. Delete the
* old cache dir if it exists.
*
* Delete the old cache dir if it exists.
*
* This will happen in two phases. The cache had three subdirectories:
*
* - Two of them, "thumbs" and "files", will be removed now (v1.7.0, May 2024).
*
* - The third one, "face-crops" will be removed once we finish the face search
* changes. See: [Note: Legacy face crops].
*
* This migration code can be removed after some time once most people have
* upgraded to newer versions.
* Added May 2024, v1.7.0. This migration code can be removed after some time
* once most people have upgraded to newer versions.
*/
const deleteLegacyDiskCacheDirIfExists = async () => {
const removeIfExists = async (dirPath: string) => {
if (existsSync(dirPath)) {
log.info(`Removing legacy disk cache from ${dirPath}`);
await fs.rm(dirPath, { recursive: true });
}
};
// [Note: Getting the cache path]
//
// The existing code was passing "cache" as a parameter to getPath.
//
// However, "cache" is not a valid parameter to getPath. It works! (for
// However, "cache" is not a valid parameter to getPath. It works (for
// example, on macOS I get `~/Library/Caches`), but it is intentionally not
// documented as part of the public API:
//
@ -329,8 +339,8 @@ const deleteLegacyDiskCacheDirIfExists = async () => {
// @ts-expect-error "cache" works but is not part of the public API.
const cacheDir = path.join(app.getPath("cache"), "ente");
if (existsSync(cacheDir)) {
await removeIfExists(path.join(cacheDir, "thumbs"));
await removeIfExists(path.join(cacheDir, "files"));
log.info(`Removing legacy disk cache from ${cacheDir}`);
await fs.rm(cacheDir, { recursive: true });
}
};
@ -390,8 +400,10 @@ const main = () => {
registerStreamProtocol();
// Configure the renderer's environment.
setDownloadPath(mainWindow.webContents);
allowExternalLinks(mainWindow.webContents);
const webContents = mainWindow.webContents;
setDownloadPath(webContents);
allowExternalLinks(webContents);
allowAllCORSOrigins(webContents);
// Start loading the renderer.
void mainWindow.loadURL(rendererURL);

View file

@ -24,7 +24,6 @@ import {
updateOnNextRestart,
} from "./services/app-update";
import {
legacyFaceCrop,
openDirectory,
openLogDirectory,
selectDirectory,
@ -43,10 +42,10 @@ import {
import { convertToJPEG, generateImageThumbnail } from "./services/image";
import { logout } from "./services/logout";
import {
clipImageEmbedding,
clipTextEmbeddingIfAvailable,
computeCLIPImageEmbedding,
computeCLIPTextEmbeddingIfAvailable,
} from "./services/ml-clip";
import { detectFaces, faceEmbeddings } from "./services/ml-face";
import { computeFaceEmbeddings, detectFaces } from "./services/ml-face";
import { encryptionKey, saveEncryptionKey } from "./services/store";
import {
clearPendingUploads,
@ -170,24 +169,22 @@ export const attachIPCHandlers = () => {
// - ML
ipcMain.handle("clipImageEmbedding", (_, jpegImageData: Uint8Array) =>
clipImageEmbedding(jpegImageData),
ipcMain.handle(
"computeCLIPImageEmbedding",
(_, jpegImageData: Uint8Array) =>
computeCLIPImageEmbedding(jpegImageData),
);
ipcMain.handle("clipTextEmbeddingIfAvailable", (_, text: string) =>
clipTextEmbeddingIfAvailable(text),
ipcMain.handle("computeCLIPTextEmbeddingIfAvailable", (_, text: string) =>
computeCLIPTextEmbeddingIfAvailable(text),
);
ipcMain.handle("detectFaces", (_, input: Float32Array) =>
detectFaces(input),
);
ipcMain.handle("faceEmbeddings", (_, input: Float32Array) =>
faceEmbeddings(input),
);
ipcMain.handle("legacyFaceCrop", (_, faceID: string) =>
legacyFaceCrop(faceID),
ipcMain.handle("computeFaceEmbeddings", (_, input: Float32Array) =>
computeFaceEmbeddings(input),
);
// - Upload

View file

@ -70,8 +70,9 @@ const logInfo = (...params: unknown[]) => {
const message = params
.map((p) => (typeof p == "string" ? p : util.inspect(p)))
.join(" ");
log.info(`[main] ${message}`);
if (isDev) console.log(`[info] ${message}`);
const m = `[info] ${message}`;
if (isDev) console.log(m);
log.info(`[main] ${m}`);
};
const logDebug = (param: () => unknown) => {

View file

@ -163,7 +163,7 @@ const checkForUpdatesAndNotify = async (mainWindow: BrowserWindow) => {
};
/**
* Return the version of the desktop app
* Return the version of the desktop app.
*
* The return value is of the form `v1.2.3`.
*/

View file

@ -1,7 +1,5 @@
import { shell } from "electron/common";
import { app, dialog } from "electron/main";
import { existsSync } from "fs";
import fs from "node:fs/promises";
import path from "node:path";
import { posixPath } from "../utils/electron";
@ -53,14 +51,6 @@ export const openLogDirectory = () => openDirectory(logDirectoryPath());
* "userData" directory. This is the **primary** place applications are meant to
* store user's data, e.g. various configuration files and saved state.
*
* During development, our app name is "Electron", so this'd be, for example,
* `~/Library/Application Support/Electron` if we run using `yarn dev`. For the
* packaged production app, our app name is "ente", so this would be:
*
* - Windows: `%APPDATA%\ente`, e.g. `C:\Users\<username>\AppData\Local\ente`
* - Linux: `~/.config/ente`
* - macOS: `~/Library/Application Support/ente`
*
* Note that Chromium also stores the browser state, e.g. localStorage or disk
* caches, in userData.
*
@ -73,21 +63,7 @@ export const openLogDirectory = () => openDirectory(logDirectoryPath());
* "ente.log", it can be found at:
*
* - macOS: ~/Library/Logs/ente/ente.log (production)
* - macOS: ~/Library/Logs/Electron/ente.log (dev)
* - Linux: ~/.config/ente/logs/ente.log
* - Windows: %USERPROFILE%\AppData\Roaming\ente\logs\ente.log
*/
const logDirectoryPath = () => app.getPath("logs");
/**
* See: [Note: Legacy face crops]
*/
export const legacyFaceCrop = async (
faceID: string,
): Promise<Uint8Array | undefined> => {
// See: [Note: Getting the cache path]
// @ts-expect-error "cache" works but is not part of the public API.
const cacheDir = path.join(app.getPath("cache"), "ente");
const filePath = path.join(cacheDir, "face-crops", faceID);
return existsSync(filePath) ? await fs.readFile(filePath) : undefined;
};

View file

@ -3,7 +3,6 @@
import fs from "node:fs/promises";
import path from "node:path";
import { CustomErrorMessage, type ZipItem } from "../../types/ipc";
import log from "../log";
import { execAsync, isDev } from "../utils/electron";
import {
deleteTempFileIgnoringErrors,
@ -93,9 +92,6 @@ export const generateImageThumbnail = async (
let thumbnail: Uint8Array;
do {
await execAsync(command);
// TODO(MR): release 1.7
// TODO(MR): imagemagick debugging. Remove me after verifying logs.
log.info(`Generated thumbnail using ${command.join(" ")}`);
thumbnail = new Uint8Array(await fs.readFile(outputFilePath));
quality -= 10;
command = generateImageThumbnailCommand(

View file

@ -11,7 +11,7 @@ import * as ort from "onnxruntime-node";
import Tokenizer from "../../thirdparty/clip-bpe-ts/mod";
import log from "../log";
import { writeStream } from "../stream";
import { ensure } from "../utils/common";
import { ensure, wait } from "../utils/common";
import { deleteTempFile, makeTempFilePath } from "../utils/temp";
import { makeCachedInferenceSession } from "./ml";
@ -20,7 +20,7 @@ const cachedCLIPImageSession = makeCachedInferenceSession(
351468764 /* 335.2 MB */,
);
export const clipImageEmbedding = async (jpegImageData: Uint8Array) => {
export const computeCLIPImageEmbedding = async (jpegImageData: Uint8Array) => {
const tempFilePath = await makeTempFilePath();
const imageStream = new Response(jpegImageData.buffer).body;
await writeStream(tempFilePath, ensure(imageStream));
@ -42,7 +42,7 @@ const clipImageEmbedding_ = async (jpegFilePath: string) => {
const results = await session.run(feeds);
log.debug(
() =>
`onnx/clip image embedding took ${Date.now() - t1} ms (prep: ${t2 - t1} ms, inference: ${Date.now() - t2} ms)`,
`ONNX/CLIP image embedding took ${Date.now() - t1} ms (prep: ${t2 - t1} ms, inference: ${Date.now() - t2} ms)`,
);
/* Need these model specific casts to type the result */
const imageEmbedding = ensure(results.output).data as Float32Array;
@ -140,21 +140,23 @@ const getTokenizer = () => {
return _tokenizer;
};
export const clipTextEmbeddingIfAvailable = async (text: string) => {
const sessionOrStatus = await Promise.race([
export const computeCLIPTextEmbeddingIfAvailable = async (text: string) => {
const sessionOrSkip = await Promise.race([
cachedCLIPTextSession(),
"downloading-model",
// Wait for a tick to get the session promise to resolved the first time
// this code runs on each app start (and the model has been downloaded).
wait(0).then(() => 1),
]);
// Don't wait for the download to complete
if (typeof sessionOrStatus == "string") {
// Don't wait for the download to complete.
if (typeof sessionOrSkip == "number") {
log.info(
"Ignoring CLIP text embedding request because model download is pending",
);
return undefined;
}
const session = sessionOrStatus;
const session = sessionOrSkip;
const t1 = Date.now();
const tokenizer = getTokenizer();
const tokenizedText = Int32Array.from(tokenizer.encodeForCLIP(text));
@ -165,7 +167,7 @@ export const clipTextEmbeddingIfAvailable = async (text: string) => {
const results = await session.run(feeds);
log.debug(
() =>
`onnx/clip text embedding took ${Date.now() - t1} ms (prep: ${t2 - t1} ms, inference: ${Date.now() - t2} ms)`,
`ONNX/CLIP text embedding took ${Date.now() - t1} ms (prep: ${t2 - t1} ms, inference: ${Date.now() - t2} ms)`,
);
const textEmbedding = ensure(results.output).data as Float32Array;
return normalizeEmbedding(textEmbedding);

View file

@ -23,7 +23,7 @@ export const detectFaces = async (input: Float32Array) => {
input: new ort.Tensor("float32", input, [1, 3, 640, 640]),
};
const results = await session.run(feeds);
log.debug(() => `onnx/yolo face detection took ${Date.now() - t} ms`);
log.debug(() => `ONNX/YOLO face detection took ${Date.now() - t} ms`);
return ensure(results.output).data;
};
@ -32,7 +32,7 @@ const cachedFaceEmbeddingSession = makeCachedInferenceSession(
5286998 /* 5 MB */,
);
export const faceEmbeddings = async (input: Float32Array) => {
export const computeFaceEmbeddings = async (input: Float32Array) => {
// Dimension of each face (alias)
const mobileFaceNetFaceSize = 112;
// Smaller alias
@ -45,7 +45,7 @@ export const faceEmbeddings = async (input: Float32Array) => {
const t = Date.now();
const feeds = { img_inputs: inputTensor };
const results = await session.run(feeds);
log.debug(() => `onnx/yolo face embedding took ${Date.now() - t} ms`);
log.debug(() => `ONNX/MFNT face embedding took ${Date.now() - t} ms`);
/* Need these model specific casts to extract and type the result */
return (results.embeddings as unknown as Record<string, unknown>)
.cpuData as Float32Array;

View file

@ -18,10 +18,7 @@ export const clearStores = () => {
* [Note: Safe storage keys]
*
* On macOS, `safeStorage` stores our data under a Keychain entry named
* "<app-name> Safe Storage". Which resolves to:
*
* - Electron Safe Storage (dev)
* - ente Safe Storage (prod)
* "<app-name> Safe Storage". In our case, "ente Safe Storage".
*/
export const saveEncryptionKey = (encryptionKey: string) => {
const encryptedKey = safeStorage.encryptString(encryptionKey);

View file

@ -106,7 +106,7 @@ const handleRead = async (path: string) => {
res.headers.set("Content-Length", `${fileSize}`);
// Add the file's last modified time (as epoch milliseconds).
const mtimeMs = stat.mtimeMs;
const mtimeMs = stat.mtime.getTime();
res.headers.set("X-Last-Modified-Ms", `${mtimeMs}`);
}
return res;
@ -132,6 +132,13 @@ const handleReadZip = async (zipPath: string, entryName: string) => {
// Close the zip handle when the underlying stream closes.
stream.on("end", () => void zip.close());
// While it is documented that entry.time is the modification time,
// the units are not mentioned. By seeing the source code, we can
// verify that it is indeed epoch milliseconds. See `parseZipTime`
// in the node-stream-zip source,
// https://github.com/antelle/node-stream-zip/blob/master/node_stream_zip.js
const modifiedMs = entry.time;
return new Response(webReadableStream, {
headers: {
// We don't know the exact type, but it doesn't really matter, just
@ -139,12 +146,7 @@ const handleReadZip = async (zipPath: string, entryName: string) => {
// doesn't tinker with it thinking of it as text.
"Content-Type": "application/octet-stream",
"Content-Length": `${entry.size}`,
// While it is documented that entry.time is the modification time,
// the units are not mentioned. By seeing the source code, we can
// verify that it is indeed epoch milliseconds. See `parseZipTime`
// in the node-stream-zip source,
// https://github.com/antelle/node-stream-zip/blob/master/node_stream_zip.js
"X-Last-Modified-Ms": `${entry.time}`,
"X-Last-Modified-Ms": `${modifiedMs}`,
},
});
};

View file

@ -13,3 +13,12 @@ export const ensure = <T>(v: T | null | undefined): T => {
if (v === undefined) throw new Error("Required value was not found");
return v;
};
/**
* Wait for {@link ms} milliseconds
*
* This function is a promisified `setTimeout`. It returns a promise that
* resolves after {@link ms} milliseconds.
*/
export const wait = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));

View file

@ -55,9 +55,7 @@ export const execAsync = async (command: string | string[]) => {
: command;
const startTime = Date.now();
const result = await execAsync_(escapedCommand);
log.debug(
() => `${escapedCommand} (${Math.round(Date.now() - startTime)} ms)`,
);
log.debug(() => `${escapedCommand} (${Date.now() - startTime} ms)`);
return result;
};

View file

@ -65,7 +65,7 @@ const selectDirectory = () => ipcRenderer.invoke("selectDirectory");
const logout = () => {
watchRemoveListeners();
ipcRenderer.send("logout");
return ipcRenderer.invoke("logout");
};
const encryptionKey = () => ipcRenderer.invoke("encryptionKey");
@ -153,20 +153,17 @@ const ffmpegExec = (
// - ML
const clipImageEmbedding = (jpegImageData: Uint8Array) =>
ipcRenderer.invoke("clipImageEmbedding", jpegImageData);
const computeCLIPImageEmbedding = (jpegImageData: Uint8Array) =>
ipcRenderer.invoke("computeCLIPImageEmbedding", jpegImageData);
const clipTextEmbeddingIfAvailable = (text: string) =>
ipcRenderer.invoke("clipTextEmbeddingIfAvailable", text);
const computeCLIPTextEmbeddingIfAvailable = (text: string) =>
ipcRenderer.invoke("computeCLIPTextEmbeddingIfAvailable", text);
const detectFaces = (input: Float32Array) =>
ipcRenderer.invoke("detectFaces", input);
const faceEmbeddings = (input: Float32Array) =>
ipcRenderer.invoke("faceEmbeddings", input);
const legacyFaceCrop = (faceID: string) =>
ipcRenderer.invoke("legacyFaceCrop", faceID);
const computeFaceEmbeddings = (input: Float32Array) =>
ipcRenderer.invoke("computeFaceEmbeddings", input);
// - Watch
@ -340,11 +337,10 @@ contextBridge.exposeInMainWorld("electron", {
// - ML
clipImageEmbedding,
clipTextEmbeddingIfAvailable,
computeCLIPImageEmbedding,
computeCLIPTextEmbeddingIfAvailable,
detectFaces,
faceEmbeddings,
legacyFaceCrop,
computeFaceEmbeddings,
// - Watch

View file

@ -743,10 +743,10 @@ buffer@^5.1.0, buffer@^5.5.0:
base64-js "^1.3.1"
ieee754 "^1.1.13"
builder-util-runtime@9.2.3:
version "9.2.3"
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.3.tgz#0a82c7aca8eadef46d67b353c638f052c206b83c"
integrity sha512-FGhkqXdFFZ5dNC4C+yuQB9ak311rpGAw+/ASz8ZdxwODCv1GGMWgLDeofRkdi0F3VCHQEWy/aXcJQozx2nOPiw==
builder-util-runtime@9.2.4:
version "9.2.4"
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz#13cd1763da621e53458739a1e63f7fcba673c42a"
integrity sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==
dependencies:
debug "^4.3.4"
sax "^1.2.4"
@ -1251,12 +1251,12 @@ electron-store@^8.2:
conf "^10.2.0"
type-fest "^2.17.0"
electron-updater@^6.1:
version "6.1.8"
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.1.8.tgz#17637bca165322f4e526b13c99165f43e6f697d8"
integrity sha512-hhOTfaFAd6wRHAfUaBhnAOYc+ymSGCWJLtFkw4xJqOvtpHmIdNHnXDV9m1MHC+A6q08Abx4Ykgyz/R5DGKNAMQ==
electron-updater@^6.2:
version "6.2.1"
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.2.1.tgz#1c9adb9ba2a21a5dc50a8c434c45360d5e9fe6c9"
integrity sha512-83eKIPW14qwZqUUM6wdsIRwVKZyjmHxQ4/8G+1C6iS5PdDt7b1umYQyj1/qPpH510GmHEQe4q0kCPe3qmb3a0Q==
dependencies:
builder-util-runtime "9.2.3"
builder-util-runtime "9.2.4"
fs-extra "^10.1.0"
js-yaml "^4.1.0"
lazy-val "^1.0.5"

View file

@ -163,6 +163,10 @@ export const sidebar = [
text: "From Authy",
link: "/auth/migration-guides/authy/",
},
{
text: "From Steam",
link: "/auth/migration-guides/steam/",
},
{
text: "Exporting your data",
link: "/auth/migration-guides/export",

View file

@ -7,4 +7,5 @@ description:
# Migrating to/from Ente Auth
- [Migrating from Authy](authy/)
- [Importing codes from Steam](steam/)
- [Exporting your data out of Ente Auth](export)

View file

@ -0,0 +1,79 @@
---
title: Migrating from Steam Authenticator
description: Guide for importing from Steam Authenticator to Ente Auth
---
# Migrating from Steam Authenticator
A guide written by an ente.io lover
> [!WARNING]
>
> Steam Authenticator code is only supported after auth-v3.0.3, check the app's
> version number before migration.
One way to migrate is to
[use this tool by dyc3](https://github.com/dyc3/steamguard-cli/releases/latest)
to simplify the process and skip directly to generating a qr code to Ente
Authenticator.
## Download/Install steamguard-cli
### Windows
1. Download `steamguard.exe` from the [releases page][releases].
2. Place `steamguard.exe` in a folder of your choice. For this example, we will
use `%USERPROFILE%\Desktop`.
3. Open Powershell or Command Prompt. The prompt should be at `%USERPROFILE%`
(eg. `C:\Users\<username>`).
4. Use `cd` to change directory into the folder where you placed
`steamguard.exe`. For this example, it would be `cd Desktop`.
5. You should now be able to run `steamguard.exe` by typing
`.\steamguard.exe --help` and pressing enter.
### Linux
#### Ubuntu/Debian
1. Download the `.deb` from the [releases page][releases].
2. Open a terminal and run this to install it:
```bash
sudo dpkg -i ./steamguard-cli_<version>_amd64.deb
```
#### Other Linux
1. Download `steamguard` from the [releases page][releases]
2. Make it executable, and move `steamguard` to `/usr/local/bin` or any other
directory in your `$PATH`.
```bash
chmod +x ./steamguard
sudo mv ./steamguard /usr/local/bin
```
3. You should now be able to run `steamguard` by typing `steamguard --help` and
pressing enter.
## Login to Steam account
Set up a new account with steamguard-cli
```bash
steamguard setup # set up a new account with steamguard-cli
```
## Generate & importing QR codes
steamguard-cli can then generate a QR code for your 2FA secret.
```bash
steamguard qr # print QR code for the first account in your maFiles
steamguard -u <account name> qr # print QR code for a specific account
```
Open Ente Auth, press the '+' button, select `Scan a QR code`, and scan the qr
code.
You should now have your steam code inside Ente Auth

View file

@ -78,3 +78,23 @@ To summarize:
Set the S3 bucket `endpoint` in `credentials.yaml` to a `yourserverip:3200` or
some such IP/hostname that accessible from both where you are running the Ente
clients (e.g. the mobile app) and also from within the Docker compose cluster.
### 403 Forbidden
If museum (`2`) is able to make a network connection to your S3 bucket (`3`) but
uploads are still failing, it could be a credentials or permissions issue. A
telltale sign of this is that in the museum logs you can see `403 Forbidden`
errors about it not able to find the size of a file even though the
corresponding object exists in the S3 bucket.
To fix these, you should ensure the following:
1. The bucket CORS rules do not allow museum to access these objects.
> For uploading files from the browser, you will need to currently set
> allowedOrigins to "\*", and allow the "X-Auth-Token", "X-Client-Package"
> headers configuration too.
> [Here is an example of a working configuration](https://github.com/ente-io/ente/discussions/1764#discussioncomment-9478204).
2. The credentials are not being picked up (you might be setting the correct
creds, but not in the place where museum picks them from).

View file

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

View file

@ -43,7 +43,7 @@ android {
defaultConfig {
applicationId "io.ente.photos"
minSdkVersion 21
minSdkVersion 26
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
@ -70,6 +70,10 @@ android {
dimension "default"
applicationIdSuffix ".dev"
}
face {
dimension "default"
applicationIdSuffix ".face"
}
playstore {
dimension "default"
}

View file

@ -0,0 +1,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.ente.photos">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

View file

@ -0,0 +1,4 @@
<resources>
<string name="app_name">ente face</string>
<string name="backup">backup face</string>
</resources>

View file

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

View file

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

View file

@ -6,6 +6,8 @@ PODS:
- connectivity_plus (0.0.1):
- Flutter
- FlutterMacOS
- dart_ui_isolate (0.0.1):
- Flutter
- device_info_plus (0.0.1):
- Flutter
- file_saver (0.0.1):
@ -226,6 +228,7 @@ DEPENDENCIES:
- background_fetch (from `.symlinks/plugins/background_fetch/ios`)
- battery_info (from `.symlinks/plugins/battery_info/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/darwin`)
- dart_ui_isolate (from `.symlinks/plugins/dart_ui_isolate/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_saver (from `.symlinks/plugins/file_saver/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
@ -302,6 +305,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/battery_info/ios"
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/darwin"
dart_ui_isolate:
:path: ".symlinks/plugins/dart_ui_isolate/ios"
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
file_saver:
@ -397,6 +402,7 @@ SPEC CHECKSUMS:
background_fetch: 2319bf7e18237b4b269430b7f14d177c0df09c5a
battery_info: 09f5c9ee65394f2291c8c6227bedff345b8a730c
connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db
dart_ui_isolate: d5bcda83ca4b04f129d70eb90110b7a567aece14
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
Firebase: 91fefd38712feb9186ea8996af6cbdef41473442
@ -421,7 +427,7 @@ SPEC CHECKSUMS:
home_widget: 0434835a4c9a75704264feff6be17ea40e0f0d57
image_editor_common: d6f6644ae4a6de80481e89fe6d0a8c49e30b4b43
in_app_purchase_storekit: 0e4b3c2e43ba1e1281f4f46dd71b0593ce529892
integration_test: 13825b8a9334a850581300559b8839134b124670
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
local_auth_darwin: c7e464000a6a89e952235699e32b329457608d98
local_auth_ios: 5046a18c018dd973247a0564496c8898dbb5adf9

View file

@ -293,6 +293,7 @@
"${BUILT_PRODUCTS_DIR}/background_fetch/background_fetch.framework",
"${BUILT_PRODUCTS_DIR}/battery_info/battery_info.framework",
"${BUILT_PRODUCTS_DIR}/connectivity_plus/connectivity_plus.framework",
"${BUILT_PRODUCTS_DIR}/dart_ui_isolate/dart_ui_isolate.framework",
"${BUILT_PRODUCTS_DIR}/device_info_plus/device_info_plus.framework",
"${BUILT_PRODUCTS_DIR}/file_saver/file_saver.framework",
"${BUILT_PRODUCTS_DIR}/fk_user_agent/fk_user_agent.framework",
@ -374,6 +375,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/background_fetch.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/battery_info.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity_plus.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/dart_ui_isolate.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info_plus.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_saver.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fk_user_agent.framework",

View file

@ -65,9 +65,9 @@
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>FLTEnableImpeller</key>
<false />
<true />
<key>FLTEnableWideGamut</key>
<false/>
<true/>
<key>NSFaceIDUsageDescription</key>
<string>Please allow ente to lock itself with FaceID or TouchID</string>
<key>NSCameraUsageDescription</key>

View file

@ -19,6 +19,7 @@ import 'package:photos/db/upload_locks_db.dart';
import "package:photos/events/endpoint_updated_event.dart";
import 'package:photos/events/signed_in_event.dart';
import 'package:photos/events/user_logged_out_event.dart';
import "package:photos/face/db.dart";
import 'package:photos/models/key_attributes.dart';
import 'package:photos/models/key_gen_result.dart';
import 'package:photos/models/private_key_attributes.dart';
@ -34,10 +35,10 @@ import 'package:photos/services/sync_service.dart';
import 'package:photos/utils/crypto_util.dart';
import 'package:photos/utils/file_uploader.dart';
import 'package:photos/utils/validator_util.dart';
import "package:photos/utils/wakelock_util.dart";
import 'package:shared_preferences/shared_preferences.dart';
import "package:tuple/tuple.dart";
import 'package:uuid/uuid.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
class Configuration {
Configuration._privateConstructor();
@ -187,6 +188,7 @@ class Configuration {
: null;
await CollectionsDB.instance.clearTable();
await MemoriesDB.instance.clearTable();
await FaceMLDataDB.instance.clearTable();
await UploadLocksDB.instance.clearTable();
await IgnoredFilesService.instance.reset();
@ -583,7 +585,7 @@ class Configuration {
Future<void> setShouldKeepDeviceAwake(bool value) async {
await _preferences.setBool(keyShouldKeepDeviceAwake, value);
await WakelockPlus.toggle(enable: value);
await EnteWakeLock.toggle(enable: value);
}
Future<void> setShouldBackupVideos(bool value) async {

View file

@ -69,6 +69,8 @@ const galleryGridSpacing = 2.0;
const kSearchSectionLimit = 9;
const maxPickAssetLimit = 50;
const iOSGroupID = "group.io.ente.frame.SlideshowWidget";
const blackThumbnailBase64 = '/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEB'
@ -99,6 +101,9 @@ const blackThumbnailBase64 = '/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEB'
'AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo' +
'AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD/9k=';
const localFileServer =
String.fromEnvironment("localFileServer", defaultValue: "");
const uploadTempFilePrefix = "upload_file_";
final tempDirCleanUpInterval = kDebugMode
? const Duration(seconds: 30).inMicroseconds

View file

@ -54,7 +54,7 @@ class EmbeddingsDB {
Future<void> clearTable() async {
final db = await _database;
await db.execute('DELETE * FROM $tableName');
await db.execute('DELETE FROM $tableName');
}
Future<List<Embedding>> getAll(Model model) async {

View file

@ -9,7 +9,7 @@ extension EntitiesDB on FilesDB {
List<LocalEntityData> data, {
ConflictAlgorithm conflictAlgorithm = ConflictAlgorithm.replace,
}) async {
debugPrint("Inserting missing PathIDToLocalIDMapping");
debugPrint("entitiesDB: upsertEntities ${data.length} entities");
final db = await database;
var batch = db.batch();
int batchCounter = 0;
@ -62,4 +62,17 @@ extension EntitiesDB on FilesDB {
return LocalEntityData.fromJson(maps[i]);
});
}
Future<LocalEntityData?> getEntity(EntityType type, String id) async {
final db = await database;
final List<Map<String, dynamic>> maps = await db.query(
"entities",
where: "type = ? AND id = ?",
whereArgs: [type.typeToString(), id],
);
if (maps.isEmpty) {
return null;
}
return LocalEntityData.fromJson(maps.first);
}
}

View file

@ -491,6 +491,18 @@ class FilesDB {
return convertToFiles(results)[0];
}
Future<EnteFile?> getAnyUploadedFile(int uploadedID) async {
final db = await instance.sqliteAsyncDB;
final results = await db.getAll(
'SELECT * FROM $filesTable WHERE $columnUploadedFileID = ?',
[uploadedID],
);
if (results.isEmpty) {
return null;
}
return convertToFiles(results)[0];
}
Future<Set<int>> getUploadedFileIDs(int collectionID) async {
final db = await instance.sqliteAsyncDB;
final results = await db.getAll(
@ -683,6 +695,17 @@ class FilesDB {
return files;
}
Future<List<EnteFile>> getAllFilesFromCollections(
Iterable<int> collectionID,
) async {
final db = await instance.sqliteAsyncDB;
final String sql =
'SELECT * FROM $filesTable WHERE $columnCollectionID IN (${collectionID.join(',')})';
final results = await db.getAll(sql);
final files = convertToFiles(results);
return files;
}
Future<List<EnteFile>> getNewFilesInCollection(
int collectionID,
int addedTime,
@ -1304,6 +1327,23 @@ class FilesDB {
return result;
}
Future<Map<int, int>> getFileIDToCreationTime() async {
final db = await instance.sqliteAsyncDB;
final rows = await db.getAll(
'''
SELECT $columnUploadedFileID, $columnCreationTime
FROM $filesTable
WHERE
($columnUploadedFileID IS NOT NULL AND $columnUploadedFileID IS NOT -1);
''',
);
final result = <int, int>{};
for (final row in rows) {
result[row[columnUploadedFileID] as int] = row[columnCreationTime] as int;
}
return result;
}
// getCollectionFileFirstOrLast returns the first or last uploaded file in
// the collection based on the given collectionID and the order.
Future<EnteFile?> getCollectionFileFirstOrLast(
@ -1643,13 +1683,14 @@ class FilesDB {
}
Future<List<int>> getOwnedFileIDs(int ownerID) async {
final db = await instance.database;
final results = await db.query(
filesTable,
columns: [columnUploadedFileID],
where:
'($columnOwnerID = $ownerID AND $columnUploadedFileID IS NOT NULL AND $columnUploadedFileID IS NOT -1)',
distinct: true,
final db = await instance.sqliteAsyncDB;
final results = await db.getAll(
'''
SELECT DISTINCT $columnUploadedFileID FROM $filesTable
WHERE ($columnOwnerID = ? AND $columnUploadedFileID IS NOT NULL AND
$columnUploadedFileID IS NOT -1)
''',
[ownerID],
);
final ids = <int>[];
for (final result in results) {
@ -1659,16 +1700,17 @@ class FilesDB {
}
Future<List<EnteFile>> getUploadedFiles(List<int> uploadedIDs) async {
final db = await instance.database;
final db = await instance.sqliteAsyncDB;
String inParam = "";
for (final id in uploadedIDs) {
inParam += "'" + id.toString() + "',";
}
inParam = inParam.substring(0, inParam.length - 1);
final results = await db.query(
filesTable,
where: '$columnUploadedFileID IN ($inParam)',
groupBy: columnUploadedFileID,
final results = await db.getAll(
'''
SELECT * FROM $filesTable WHERE $columnUploadedFileID IN ($inParam)
GROUP BY $columnUploadedFileID
''',
);
if (results.isEmpty) {
return <EnteFile>[];

View file

@ -26,4 +26,6 @@ enum EventType {
hide,
unhide,
coverChanged,
peopleChanged,
peopleClusterChanged,
}

View file

@ -0,0 +1,22 @@
import "package:photos/events/event.dart";
import "package:photos/models/file/file.dart";
class PeopleChangedEvent extends Event {
final List<EnteFile>? relevantFiles;
final PeopleEventType type;
final String source;
PeopleChangedEvent({
this.relevantFiles,
this.type = PeopleEventType.defaultType,
this.source = "",
});
@override
String get reason => '$runtimeType{type: ${type.name}, "via": $source}';
}
enum PeopleEventType {
defaultType,
removedFilesFromCluster,
}

View file

@ -0,0 +1,193 @@
import 'dart:math' as math show sin, cos, atan2, sqrt, pow;
import 'package:ml_linalg/linalg.dart';
extension SetVectorValues on Vector {
Vector setValues(int start, int end, Iterable<double> values) {
if (values.length > length) {
throw Exception('Values cannot be larger than vector');
} else if (end - start != values.length) {
throw Exception('Values must be same length as range');
} else if (start < 0 || end > length) {
throw Exception('Range must be within vector');
}
final tempList = toList();
tempList.replaceRange(start, end, values);
final newVector = Vector.fromList(tempList);
return newVector;
}
}
extension SetMatrixValues on Matrix {
Matrix setSubMatrix(
int startRow,
int endRow,
int startColumn,
int endColumn,
Iterable<Iterable<double>> values,
) {
if (values.length > rowCount) {
throw Exception('New values cannot have more rows than original matrix');
} else if (values.elementAt(0).length > columnCount) {
throw Exception(
'New values cannot have more columns than original matrix',
);
} else if (endRow - startRow != values.length) {
throw Exception('Values (number of rows) must be same length as range');
} else if (endColumn - startColumn != values.elementAt(0).length) {
throw Exception(
'Values (number of columns) must be same length as range',
);
} else if (startRow < 0 ||
endRow > rowCount ||
startColumn < 0 ||
endColumn > columnCount) {
throw Exception('Range must be within matrix');
}
final tempList = asFlattenedList
.toList(); // You need `.toList()` here to make sure the list is growable, otherwise `replaceRange` will throw an error
for (var i = startRow; i < endRow; i++) {
tempList.replaceRange(
i * columnCount + startColumn,
i * columnCount + endColumn,
values.elementAt(i).toList(),
);
}
final newMatrix = Matrix.fromFlattenedList(tempList, rowCount, columnCount);
return newMatrix;
}
Matrix setValues(
int startRow,
int endRow,
int startColumn,
int endColumn,
Iterable<double> values,
) {
if ((startRow - endRow) * (startColumn - endColumn) != values.length) {
throw Exception('Values must be same length as range');
} else if (startRow < 0 ||
endRow > rowCount ||
startColumn < 0 ||
endColumn > columnCount) {
throw Exception('Range must be within matrix');
}
final tempList = asFlattenedList
.toList(); // You need `.toList()` here to make sure the list is growable, otherwise `replaceRange` will throw an error
var index = 0;
for (var i = startRow; i < endRow; i++) {
for (var j = startColumn; j < endColumn; j++) {
tempList[i * columnCount + j] = values.elementAt(index);
index++;
}
}
final newMatrix = Matrix.fromFlattenedList(tempList, rowCount, columnCount);
return newMatrix;
}
Matrix setValue(int row, int column, double value) {
if (row < 0 || row > rowCount || column < 0 || column > columnCount) {
throw Exception('Index must be within range of matrix');
}
final tempList = asFlattenedList;
tempList[row * columnCount + column] = value;
final newMatrix = Matrix.fromFlattenedList(tempList, rowCount, columnCount);
return newMatrix;
}
Matrix appendRow(List<double> row) {
final oldNumberOfRows = rowCount;
final oldNumberOfColumns = columnCount;
if (row.length != oldNumberOfColumns) {
throw Exception('Row must have same number of columns as matrix');
}
final flatListMatrix = asFlattenedList;
flatListMatrix.addAll(row);
return Matrix.fromFlattenedList(
flatListMatrix,
oldNumberOfRows + 1,
oldNumberOfColumns,
);
}
}
extension MatrixCalculations on Matrix {
double determinant() {
final int length = rowCount;
if (length != columnCount) {
throw Exception('Matrix must be square');
}
if (length == 1) {
return this[0][0];
} else if (length == 2) {
return this[0][0] * this[1][1] - this[0][1] * this[1][0];
} else {
throw Exception('Determinant for Matrix larger than 2x2 not implemented');
}
}
/// Computes the singular value decomposition of a matrix, using https://lucidar.me/en/mathematics/singular-value-decomposition-of-a-2x2-matrix/ as reference, but with slightly different signs for the second columns of U and V
Map<String, dynamic> svd() {
if (rowCount != 2 || columnCount != 2) {
throw Exception('Matrix must be 2x2');
}
final a = this[0][0];
final b = this[0][1];
final c = this[1][0];
final d = this[1][1];
// Computation of U matrix
final tempCalc = a * a + b * b - c * c - d * d;
final theta = 0.5 * math.atan2(2 * a * c + 2 * b * d, tempCalc);
final U = Matrix.fromList([
[math.cos(theta), math.sin(theta)],
[math.sin(theta), -math.cos(theta)],
]);
// Computation of S matrix
// ignore: non_constant_identifier_names
final S1 = a * a + b * b + c * c + d * d;
// ignore: non_constant_identifier_names
final S2 =
math.sqrt(math.pow(tempCalc, 2) + 4 * math.pow(a * c + b * d, 2));
final sigma1 = math.sqrt((S1 + S2) / 2);
final sigma2 = math.sqrt((S1 - S2) / 2);
final S = Vector.fromList([sigma1, sigma2]);
// Computation of V matrix
final tempCalc2 = a * a - b * b + c * c - d * d;
final phi = 0.5 * math.atan2(2 * a * b + 2 * c * d, tempCalc2);
final s11 = (a * math.cos(theta) + c * math.sin(theta)) * math.cos(phi) +
(b * math.cos(theta) + d * math.sin(theta)) * math.sin(phi);
final s22 = (a * math.sin(theta) - c * math.cos(theta)) * math.sin(phi) +
(-b * math.sin(theta) + d * math.cos(theta)) * math.cos(phi);
final V = Matrix.fromList([
[s11.sign * math.cos(phi), s22.sign * math.sin(phi)],
[s11.sign * math.sin(phi), -s22.sign * math.cos(phi)],
]);
return {
'U': U,
'S': S,
'V': V,
};
}
int matrixRank() {
final svdResult = svd();
final Vector S = svdResult['S']!;
final rank = S.toList().where((element) => element > 1e-10).length;
return rank;
}
}
extension TransformMatrix on Matrix {
List<List<double>> to2DList() {
final List<List<double>> outerList = [];
for (var i = 0; i < rowCount; i++) {
final innerList = this[i].toList();
outerList.add(innerList);
}
return outerList;
}
}

View file

@ -23,4 +23,9 @@ class EnteWatch extends Stopwatch {
reset();
previousElapsed = 0;
}
void stopWithLog(String msg) {
log(msg);
stop();
}
}

1083
mobile/lib/face/db.dart Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,97 @@
// Faces Table Fields & Schema Queries
import 'package:photos/services/machine_learning/face_ml/face_filtering/face_filtering_constants.dart';
const facesTable = 'faces';
const fileIDColumn = 'file_id';
const faceIDColumn = 'face_id';
const faceDetectionColumn = 'detection';
const faceEmbeddingBlob = 'eBlob';
const faceScore = 'score';
const faceBlur = 'blur';
const isSideways = 'is_sideways';
const imageWidth = 'width';
const imageHeight = 'height';
const faceClusterId = 'cluster_id';
const mlVersionColumn = 'ml_version';
const createFacesTable = '''CREATE TABLE IF NOT EXISTS $facesTable (
$fileIDColumn INTEGER NOT NULL,
$faceIDColumn TEXT NOT NULL UNIQUE,
$faceDetectionColumn TEXT NOT NULL,
$faceEmbeddingBlob BLOB NOT NULL,
$faceScore REAL NOT NULL,
$faceBlur REAL NOT NULL DEFAULT $kLapacianDefault,
$isSideways INTEGER NOT NULL DEFAULT 0,
$imageHeight INTEGER NOT NULL DEFAULT 0,
$imageWidth INTEGER NOT NULL DEFAULT 0,
$mlVersionColumn INTEGER NOT NULL DEFAULT -1,
PRIMARY KEY($fileIDColumn, $faceIDColumn)
);
''';
const deleteFacesTable = 'DELETE FROM $facesTable';
// End of Faces Table Fields & Schema Queries
//##region Face Clusters Table Fields & Schema Queries
const faceClustersTable = 'face_clusters';
const fcClusterID = 'cluster_id';
const fcFaceId = 'face_id';
// fcClusterId & fcFaceId are the primary keys and fcClusterId is a foreign key to faces table
const createFaceClustersTable = '''
CREATE TABLE IF NOT EXISTS $faceClustersTable (
$fcFaceId TEXT NOT NULL,
$fcClusterID INTEGER NOT NULL,
PRIMARY KEY($fcFaceId)
);
''';
// -- Creating a non-unique index on clusterID for query optimization
const fcClusterIDIndex =
'''CREATE INDEX IF NOT EXISTS idx_fcClusterID ON $faceClustersTable($fcClusterID);''';
const deleteFaceClustersTable = 'DELETE FROM $faceClustersTable';
//##endregion
// Clusters Table Fields & Schema Queries
const clusterPersonTable = 'cluster_person';
const personIdColumn = 'person_id';
const clusterIDColumn = 'cluster_id';
const createClusterPersonTable = '''
CREATE TABLE IF NOT EXISTS $clusterPersonTable (
$personIdColumn TEXT NOT NULL,
$clusterIDColumn INTEGER NOT NULL,
PRIMARY KEY($personIdColumn, $clusterIDColumn)
);
''';
const deleteClusterPersonTable = 'DELETE FROM $clusterPersonTable';
// End Clusters Table Fields & Schema Queries
/// Cluster Summary Table Fields & Schema Queries
const clusterSummaryTable = 'cluster_summary';
const avgColumn = 'avg';
const countColumn = 'count';
const createClusterSummaryTable = '''
CREATE TABLE IF NOT EXISTS $clusterSummaryTable (
$clusterIDColumn INTEGER NOT NULL,
$avgColumn BLOB NOT NULL,
$countColumn INTEGER NOT NULL,
PRIMARY KEY($clusterIDColumn)
);
''';
const deleteClusterSummaryTable = 'DELETE FROM $clusterSummaryTable';
/// End Cluster Summary Table Fields & Schema Queries
/// notPersonFeedback Table Fields & Schema Queries
const notPersonFeedback = 'not_person_feedback';
const createNotPersonFeedbackTable = '''
CREATE TABLE IF NOT EXISTS $notPersonFeedback (
$personIdColumn TEXT NOT NULL,
$clusterIDColumn INTEGER NOT NULL,
PRIMARY KEY($personIdColumn, $clusterIDColumn)
);
''';
const deleteNotPersonFeedbackTable = 'DELETE FROM $notPersonFeedback';
// End Clusters Table Fields & Schema Queries

View file

@ -0,0 +1,57 @@
import "dart:convert";
import 'package:photos/face/db_fields.dart';
import "package:photos/face/model/detection.dart";
import "package:photos/face/model/face.dart";
import "package:photos/generated/protos/ente/common/vector.pb.dart";
import "package:photos/models/ml/ml_versions.dart";
int boolToSQLInt(bool? value, {bool defaultValue = false}) {
final bool v = value ?? defaultValue;
if (v == false) {
return 0;
} else {
return 1;
}
}
bool sqlIntToBool(int? value, {bool defaultValue = false}) {
final int v = value ?? (defaultValue ? 1 : 0);
if (v == 0) {
return false;
} else {
return true;
}
}
Map<String, dynamic> mapRemoteToFaceDB(Face face) {
return {
faceIDColumn: face.faceID,
fileIDColumn: face.fileID,
faceDetectionColumn: json.encode(face.detection.toJson()),
faceEmbeddingBlob: EVector(
values: face.embedding,
).writeToBuffer(),
faceScore: face.score,
faceBlur: face.blur,
isSideways: face.detection.faceIsSideways() ? 1 : 0,
mlVersionColumn: faceMlVersion,
imageWidth: face.fileInfo?.imageWidth ?? 0,
imageHeight: face.fileInfo?.imageHeight ?? 0,
};
}
Face mapRowToFace(Map<String, dynamic> row) {
return Face(
row[faceIDColumn] as String,
row[fileIDColumn] as int,
EVector.fromBuffer(row[faceEmbeddingBlob] as List<int>).values,
row[faceScore] as double,
Detection.fromJson(json.decode(row[faceDetectionColumn] as String)),
row[faceBlur] as double,
fileInfo: FileInfo(
imageWidth: row[imageWidth] as int,
imageHeight: row[imageHeight] as int,
),
);
}

View file

@ -0,0 +1,35 @@
/// Bounding box of a face.
///
/// [ x] and [y] are the minimum coordinates, so the top left corner of the box.
/// [width] and [height] are the width and height of the box.
///
/// WARNING: All values are relative to the original image size, so in the range [0, 1].
class FaceBox {
final double x;
final double y;
final double width;
final double height;
FaceBox({
required this.x,
required this.y,
required this.width,
required this.height,
});
factory FaceBox.fromJson(Map<String, dynamic> json) {
return FaceBox(
x: (json['x'] as double?) ?? (json['xMin'] as double),
y: (json['y'] as double?) ?? (json['yMin'] as double),
width: json['width'] as double,
height: json['height'] as double,
);
}
Map<String, dynamic> toJson() => {
'x': x,
'y': y,
'width': width,
'height': height,
};
}

View file

@ -0,0 +1,120 @@
import "dart:math" show min, max;
import "package:photos/face/model/box.dart";
import "package:photos/face/model/landmark.dart";
import "package:photos/services/machine_learning/face_ml/face_detection/detection.dart";
/// Stores the face detection data, notably the bounding box and landmarks.
///
/// - Bounding box: [FaceBox] with x, y (minimum, so top left corner), width, height
/// - Landmarks: list of [Landmark]s, namely leftEye, rightEye, nose, leftMouth, rightMouth
///
/// WARNING: All coordinates are relative to the image size, so in the range [0, 1]!
class Detection {
FaceBox box;
List<Landmark> landmarks;
Detection({
required this.box,
required this.landmarks,
});
bool get isEmpty => box.width == 0 && box.height == 0 && landmarks.isEmpty;
// empty box
Detection.empty()
: box = FaceBox(
x: 0,
y: 0,
width: 0,
height: 0,
),
landmarks = [];
Map<String, dynamic> toJson() => {
'box': box.toJson(),
'landmarks': landmarks.map((x) => x.toJson()).toList(),
};
factory Detection.fromJson(Map<String, dynamic> json) {
return Detection(
box: FaceBox.fromJson(json['box'] as Map<String, dynamic>),
landmarks: List<Landmark>.from(
json['landmarks']
.map((x) => Landmark.fromJson(x as Map<String, dynamic>)),
),
);
}
int getFaceArea(int imageWidth, int imageHeight) {
return (box.width * imageWidth * box.height * imageHeight).toInt();
}
FaceDirection getFaceDirection() {
if (isEmpty) {
return FaceDirection.straight;
}
final leftEye = [landmarks[0].x, landmarks[0].y];
final rightEye = [landmarks[1].x, landmarks[1].y];
final nose = [landmarks[2].x, landmarks[2].y];
final leftMouth = [landmarks[3].x, landmarks[3].y];
final rightMouth = [landmarks[4].x, landmarks[4].y];
final double eyeDistanceX = (rightEye[0] - leftEye[0]).abs();
final double eyeDistanceY = (rightEye[1] - leftEye[1]).abs();
final double mouthDistanceY = (rightMouth[1] - leftMouth[1]).abs();
final bool faceIsUpright =
(max(leftEye[1], rightEye[1]) + 0.5 * eyeDistanceY < nose[1]) &&
(nose[1] + 0.5 * mouthDistanceY < min(leftMouth[1], rightMouth[1]));
final bool noseStickingOutLeft = (nose[0] < min(leftEye[0], rightEye[0])) &&
(nose[0] < min(leftMouth[0], rightMouth[0]));
final bool noseStickingOutRight =
(nose[0] > max(leftEye[0], rightEye[0])) &&
(nose[0] > max(leftMouth[0], rightMouth[0]));
final bool noseCloseToLeftEye =
(nose[0] - leftEye[0]).abs() < 0.2 * eyeDistanceX;
final bool noseCloseToRightEye =
(nose[0] - rightEye[0]).abs() < 0.2 * eyeDistanceX;
// if (faceIsUpright && (noseStickingOutLeft || noseCloseToLeftEye)) {
if (noseStickingOutLeft || (faceIsUpright && noseCloseToLeftEye)) {
return FaceDirection.left;
// } else if (faceIsUpright && (noseStickingOutRight || noseCloseToRightEye)) {
} else if (noseStickingOutRight || (faceIsUpright && noseCloseToRightEye)) {
return FaceDirection.right;
}
return FaceDirection.straight;
}
bool faceIsSideways() {
if (isEmpty) {
return false;
}
final leftEye = [landmarks[0].x, landmarks[0].y];
final rightEye = [landmarks[1].x, landmarks[1].y];
final nose = [landmarks[2].x, landmarks[2].y];
final leftMouth = [landmarks[3].x, landmarks[3].y];
final rightMouth = [landmarks[4].x, landmarks[4].y];
final double eyeDistanceX = (rightEye[0] - leftEye[0]).abs();
final double eyeDistanceY = (rightEye[1] - leftEye[1]).abs();
final double mouthDistanceY = (rightMouth[1] - leftMouth[1]).abs();
final bool faceIsUpright =
(max(leftEye[1], rightEye[1]) + 0.5 * eyeDistanceY < nose[1]) &&
(nose[1] + 0.5 * mouthDistanceY < min(leftMouth[1], rightMouth[1]));
final bool noseStickingOutLeft =
(nose[0] < min(leftEye[0], rightEye[0]) - 0.5 * eyeDistanceX) &&
(nose[0] < min(leftMouth[0], rightMouth[0]));
final bool noseStickingOutRight =
(nose[0] > max(leftEye[0], rightEye[0]) + 0.5 * eyeDistanceX) &&
(nose[0] > max(leftMouth[0], rightMouth[0]));
return faceIsUpright && (noseStickingOutLeft || noseStickingOutRight);
}
}

View file

@ -0,0 +1,25 @@
class Dimensions {
final int width;
final int height;
const Dimensions({required this.width, required this.height});
@override
String toString() {
return 'Dimensions(width: $width, height: $height})';
}
Map<String, int> toJson() {
return {
'width': width,
'height': height,
};
}
factory Dimensions.fromJson(Map<String, dynamic> json) {
return Dimensions(
width: json['width'] as int,
height: json['height'] as int,
);
}
}

View file

@ -0,0 +1,85 @@
import "package:photos/face/model/detection.dart";
import 'package:photos/services/machine_learning/face_ml/face_filtering/face_filtering_constants.dart';
import "package:photos/services/machine_learning/face_ml/face_ml_result.dart";
// FileInfo contains the image width and height of the image the face was detected in.
class FileInfo {
int? imageWidth;
int? imageHeight;
FileInfo({
this.imageWidth,
this.imageHeight,
});
}
class Face {
final String faceID;
final List<double> embedding;
Detection detection;
final double score;
final double blur;
///#region Local DB fields
// This is not stored on the server, using it for local DB row
FileInfo? fileInfo;
final int fileID;
///#endregion
bool get isBlurry => blur < kLaplacianHardThreshold;
bool get hasHighScore => score > kMinimumQualityFaceScore;
bool get isHighQuality => (!isBlurry) && hasHighScore;
int area({int? w, int? h}) {
return detection.getFaceArea(
fileInfo?.imageWidth ?? w ?? 0,
fileInfo?.imageHeight ?? h ?? 0,
);
}
Face(
this.faceID,
this.fileID,
this.embedding,
this.score,
this.detection,
this.blur, {
this.fileInfo,
});
factory Face.empty(int fileID, {bool error = false}) {
return Face(
"$fileID-0",
fileID,
<double>[],
error ? -1.0 : 0.0,
Detection.empty(),
0.0,
);
}
factory Face.fromJson(Map<String, dynamic> json) {
final String faceID = json['faceID'] as String;
final int fileID = getFileIdFromFaceId(faceID);
return Face(
faceID,
fileID,
List<double>.from((json['embedding'] ?? json['embeddings']) as List),
json['score'] as double,
Detection.fromJson(json['detection'] as Map<String, dynamic>),
// high value means t
(json['blur'] ?? kLapacianDefault) as double,
);
}
// Note: Keep the information in toJson minimum. Keep in sync with desktop.
// Derive fields like fileID from other values whenever possible
Map<String, dynamic> toJson() => {
'faceID': faceID,
'embedding': embedding,
'detection': detection.toJson(),
'score': score,
'blur': blur,
};
}

View file

@ -0,0 +1,33 @@
/// Landmark coordinate data.
///
/// WARNING: All coordinates are relative to the image size, so in the range [0, 1]!
class Landmark {
double x;
double y;
Landmark({
required this.x,
required this.y,
});
Map<String, dynamic> toJson() => {
'x': x,
'y': y,
};
factory Landmark.fromJson(Map<String, dynamic> json) {
return Landmark(
x: (json['x'] is int
? (json['x'] as int).toDouble()
: json['x'] as double),
y: (json['y'] is int
? (json['y'] as int).toDouble()
: json['y'] as double),
);
}
@override
toString() {
return '(x: ${x.toStringAsFixed(4)}, y: ${y.toStringAsFixed(4)})';
}
}

View file

@ -0,0 +1,139 @@
// PersonEntity represents information about a Person in the context of FaceClustering that is stored.
// On the remote server, the PersonEntity is stored as {Entity} with type person.
// On the device, this information is stored as [LocalEntityData] with type person.
import "package:flutter/foundation.dart";
class PersonEntity {
final String remoteID;
final PersonData data;
PersonEntity(
this.remoteID,
this.data,
);
// copyWith
PersonEntity copyWith({
String? remoteID,
PersonData? data,
}) {
return PersonEntity(
remoteID ?? this.remoteID,
data ?? this.data,
);
}
}
class ClusterInfo {
final int id;
final Set<String> faces;
ClusterInfo({
required this.id,
required this.faces,
});
// toJson
Map<String, dynamic> toJson() => {
'id': id,
'faces': faces.toList(),
};
// from Json
factory ClusterInfo.fromJson(Map<String, dynamic> json) {
return ClusterInfo(
id: json['id'] as int,
faces: (json['faces'] as List<dynamic>).map((e) => e as String).toSet(),
);
}
}
class PersonData {
final String name;
final bool isHidden;
String? avatarFaceId;
List<ClusterInfo>? assigned = List<ClusterInfo>.empty();
List<ClusterInfo>? rejected = List<ClusterInfo>.empty();
final String? birthDate;
bool hasAvatar() => avatarFaceId != null;
bool get isIgnored =>
(name.isEmpty || name == '(hidden)' || name == '(ignored)');
PersonData({
required this.name,
this.assigned,
this.rejected,
this.avatarFaceId,
this.isHidden = false,
this.birthDate,
});
// copyWith
PersonData copyWith({
String? name,
List<ClusterInfo>? assigned,
String? avatarFaceId,
bool? isHidden,
int? version,
String? birthDate,
}) {
return PersonData(
name: name ?? this.name,
assigned: assigned ?? this.assigned,
avatarFaceId: avatarFaceId ?? this.avatarFaceId,
isHidden: isHidden ?? this.isHidden,
birthDate: birthDate ?? this.birthDate,
);
}
void logStats() {
if (kDebugMode == false) return;
// log number of assigned and rejected clusters and total number of faces in each cluster
final StringBuffer sb = StringBuffer();
sb.writeln('Person: $name');
int assignedCount = 0;
for (final a in (assigned ?? <ClusterInfo>[])) {
assignedCount += a.faces.length;
}
sb.writeln('Assigned: ${assigned?.length} withFaces $assignedCount');
sb.writeln('Rejected: ${rejected?.length}');
if (assigned != null) {
for (var cluster in assigned!) {
sb.writeln('Cluster: ${cluster.id} - ${cluster.faces.length}');
}
}
debugPrint(sb.toString());
}
// toJson
Map<String, dynamic> toJson() => {
'name': name,
'assigned': assigned?.map((e) => e.toJson()).toList(),
'rejected': rejected?.map((e) => e.toJson()).toList(),
'avatarFaceId': avatarFaceId,
'isHidden': isHidden,
'birthDate': birthDate,
};
// fromJson
factory PersonData.fromJson(Map<String, dynamic> json) {
final assigned = (json['assigned'] == null || json['assigned'].length == 0)
? <ClusterInfo>[]
: List<ClusterInfo>.from(
json['assigned'].map((x) => ClusterInfo.fromJson(x)),
);
final rejected = (json['rejected'] == null || json['rejected'].length == 0)
? <ClusterInfo>[]
: List<ClusterInfo>.from(
json['rejected'].map((x) => ClusterInfo.fromJson(x)),
);
return PersonData(
name: json['name'] as String,
assigned: assigned,
rejected: rejected,
avatarFaceId: json['avatarFaceId'] as String?,
isHidden: json['isHidden'] as bool? ?? false,
birthDate: json['birthDate'] as String?,
);
}
}

View file

@ -34,6 +34,8 @@ class MessageLookup extends MessageLookupByLibrary {
"addViewers": m1,
"changeLocationOfSelectedItems": MessageLookupByLibrary.simpleMessage(
"Change location of selected items?"),
"clusteringProgress":
MessageLookupByLibrary.simpleMessage("Clustering progress"),
"contacts": MessageLookupByLibrary.simpleMessage("Contacts"),
"createCollaborativeLink":
MessageLookupByLibrary.simpleMessage("Create collaborative link"),
@ -44,7 +46,16 @@ class MessageLookup extends MessageLookupByLibrary {
"editsToLocationWillOnlyBeSeenWithinEnte":
MessageLookupByLibrary.simpleMessage(
"Edits to location will only be seen within Ente"),
"enterPersonName":
MessageLookupByLibrary.simpleMessage("Enter person name"),
"faceRecognition":
MessageLookupByLibrary.simpleMessage("Face recognition"),
"faceRecognitionIndexingDescription": MessageLookupByLibrary.simpleMessage(
"Please note that this will result in a higher bandwidth and battery usage until all items are indexed."),
"fileTypes": MessageLookupByLibrary.simpleMessage("File types"),
"foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"),
"indexingIsPaused": MessageLookupByLibrary.simpleMessage(
"Indexing is paused, will automatically resume when device is ready"),
"joinDiscord": MessageLookupByLibrary.simpleMessage("Join Discord"),
"locations": MessageLookupByLibrary.simpleMessage("Locations"),
"longPressAnEmailToVerifyEndToEndEncryption":
@ -55,6 +66,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Modify your query, or try searching for"),
"moveToHiddenAlbum":
MessageLookupByLibrary.simpleMessage("Move to hidden album"),
"removePersonLabel":
MessageLookupByLibrary.simpleMessage("Remove person label"),
"search": MessageLookupByLibrary.simpleMessage("Search"),
"selectALocation":
MessageLookupByLibrary.simpleMessage("Select a location"),

View file

@ -227,6 +227,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Ich verstehe, dass ich meine Daten verlieren kann, wenn ich mein Passwort vergesse, da meine Daten <underline>Ende-zu-Ende-verschlüsselt</underline> sind."),
"activeSessions":
MessageLookupByLibrary.simpleMessage("Aktive Sitzungen"),
"addAName": MessageLookupByLibrary.simpleMessage("Add a name"),
"addANewEmail": MessageLookupByLibrary.simpleMessage(
"Neue E-Mail-Adresse hinzufügen"),
"addCollaborator":
@ -435,6 +436,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Nach Aufnahmezeit gruppieren"),
"clubByFileName":
MessageLookupByLibrary.simpleMessage("Nach Dateiname gruppieren"),
"clusteringProgress":
MessageLookupByLibrary.simpleMessage("Clustering progress"),
"codeAppliedPageTitle":
MessageLookupByLibrary.simpleMessage("Code eingelöst"),
"codeCopiedToClipboard": MessageLookupByLibrary.simpleMessage(
@ -675,6 +678,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Passwort eingeben"),
"enterPasswordToEncrypt": MessageLookupByLibrary.simpleMessage(
"Gib ein Passwort ein, mit dem wir deine Daten verschlüsseln können"),
"enterPersonName":
MessageLookupByLibrary.simpleMessage("Enter person name"),
"enterReferralCode": MessageLookupByLibrary.simpleMessage(
"Gib den Weiterempfehlungs-Code ein"),
"enterThe6digitCodeFromnyourAuthenticatorApp":
@ -699,6 +704,10 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Protokolle exportieren"),
"exportYourData":
MessageLookupByLibrary.simpleMessage("Daten exportieren"),
"faceRecognition":
MessageLookupByLibrary.simpleMessage("Face recognition"),
"faceRecognitionIndexingDescription": MessageLookupByLibrary.simpleMessage(
"Please note that this will result in a higher bandwidth and battery usage until all items are indexed."),
"faces": MessageLookupByLibrary.simpleMessage("Gesichter"),
"failedToApplyCode": MessageLookupByLibrary.simpleMessage(
"Der Code konnte nicht aktiviert werden"),
@ -738,11 +747,14 @@ class MessageLookup extends MessageLookupByLibrary {
"filesBackedUpInAlbum": m23,
"filesDeleted":
MessageLookupByLibrary.simpleMessage("Dateien gelöscht"),
"findPeopleByName": MessageLookupByLibrary.simpleMessage(
"Find people quickly by searching by name"),
"flip": MessageLookupByLibrary.simpleMessage("Spiegeln"),
"forYourMemories":
MessageLookupByLibrary.simpleMessage("Als Erinnerung"),
"forgotPassword":
MessageLookupByLibrary.simpleMessage("Passwort vergessen"),
"foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"),
"freeStorageClaimed": MessageLookupByLibrary.simpleMessage(
"Kostenlos hinzugefügter Speicherplatz"),
"freeStorageOnReferralSuccess": m24,
@ -807,6 +819,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Falscher Wiederherstellungs-Schlüssel"),
"indexedItems":
MessageLookupByLibrary.simpleMessage("Indizierte Elemente"),
"indexingIsPaused": MessageLookupByLibrary.simpleMessage(
"Indexing is paused, will automatically resume when device is ready"),
"insecureDevice":
MessageLookupByLibrary.simpleMessage("Unsicheres Gerät"),
"installManually":
@ -1164,6 +1178,8 @@ class MessageLookup extends MessageLookupByLibrary {
"removeParticipant":
MessageLookupByLibrary.simpleMessage("Teilnehmer entfernen"),
"removeParticipantBody": m43,
"removePersonLabel":
MessageLookupByLibrary.simpleMessage("Remove person label"),
"removePublicLink":
MessageLookupByLibrary.simpleMessage("Öffentlichen Link entfernen"),
"removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(

View file

@ -132,7 +132,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Please talk to ${providerName} support if you were charged";
static String m38(endDate) =>
"Free trial valid till ${endDate}.\nYou can purchase a paid plan afterwards.";
"Free trial valid till ${endDate}.\nYou can choose a paid plan afterwards.";
static String m39(toEmail) => "Please email us at ${toEmail}";
@ -225,6 +225,7 @@ class MessageLookup extends MessageLookupByLibrary {
"I understand that if I lose my password, I may lose my data since my data is <underline>end-to-end encrypted</underline>."),
"activeSessions":
MessageLookupByLibrary.simpleMessage("Active sessions"),
"addAName": MessageLookupByLibrary.simpleMessage("Add a name"),
"addANewEmail": MessageLookupByLibrary.simpleMessage("Add a new email"),
"addCollaborator":
MessageLookupByLibrary.simpleMessage("Add collaborator"),
@ -434,6 +435,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Club by capture time"),
"clubByFileName":
MessageLookupByLibrary.simpleMessage("Club by file name"),
"clusteringProgress":
MessageLookupByLibrary.simpleMessage("Clustering progress"),
"codeAppliedPageTitle":
MessageLookupByLibrary.simpleMessage("Code applied"),
"codeCopiedToClipboard":
@ -675,6 +678,8 @@ class MessageLookup extends MessageLookupByLibrary {
"enterPassword": MessageLookupByLibrary.simpleMessage("Enter password"),
"enterPasswordToEncrypt": MessageLookupByLibrary.simpleMessage(
"Enter a password we can use to encrypt your data"),
"enterPersonName":
MessageLookupByLibrary.simpleMessage("Enter person name"),
"enterReferralCode":
MessageLookupByLibrary.simpleMessage("Enter referral code"),
"enterThe6digitCodeFromnyourAuthenticatorApp":
@ -697,6 +702,10 @@ class MessageLookup extends MessageLookupByLibrary {
"exportLogs": MessageLookupByLibrary.simpleMessage("Export logs"),
"exportYourData":
MessageLookupByLibrary.simpleMessage("Export your data"),
"faceRecognition":
MessageLookupByLibrary.simpleMessage("Face recognition"),
"faceRecognitionIndexingDescription": MessageLookupByLibrary.simpleMessage(
"Please note that this will result in a higher bandwidth and battery usage until all items are indexed."),
"faces": MessageLookupByLibrary.simpleMessage("Faces"),
"failedToApplyCode":
MessageLookupByLibrary.simpleMessage("Failed to apply code"),
@ -736,11 +745,14 @@ class MessageLookup extends MessageLookupByLibrary {
"filesDeleted": MessageLookupByLibrary.simpleMessage("Files deleted"),
"filesSavedToGallery":
MessageLookupByLibrary.simpleMessage("Files saved to gallery"),
"findPeopleByName":
MessageLookupByLibrary.simpleMessage("Find people quickly by name"),
"flip": MessageLookupByLibrary.simpleMessage("Flip"),
"forYourMemories":
MessageLookupByLibrary.simpleMessage("for your memories"),
"forgotPassword":
MessageLookupByLibrary.simpleMessage("Forgot password"),
"foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"),
"freeStorageClaimed":
MessageLookupByLibrary.simpleMessage("Free storage claimed"),
"freeStorageOnReferralSuccess": m24,
@ -801,6 +813,8 @@ class MessageLookup extends MessageLookupByLibrary {
"incorrectRecoveryKeyTitle":
MessageLookupByLibrary.simpleMessage("Incorrect recovery key"),
"indexedItems": MessageLookupByLibrary.simpleMessage("Indexed items"),
"indexingIsPaused": MessageLookupByLibrary.simpleMessage(
"Indexing is paused. It will automatically resume when device is ready."),
"insecureDevice":
MessageLookupByLibrary.simpleMessage("Insecure device"),
"installManually":
@ -1022,6 +1036,7 @@ class MessageLookup extends MessageLookupByLibrary {
"paymentFailedTalkToProvider": m37,
"pendingItems": MessageLookupByLibrary.simpleMessage("Pending items"),
"pendingSync": MessageLookupByLibrary.simpleMessage("Pending sync"),
"people": MessageLookupByLibrary.simpleMessage("People"),
"peopleUsingYourCode":
MessageLookupByLibrary.simpleMessage("People using your code"),
"permDeleteWarning": MessageLookupByLibrary.simpleMessage(
@ -1151,6 +1166,8 @@ class MessageLookup extends MessageLookupByLibrary {
"removeParticipant":
MessageLookupByLibrary.simpleMessage("Remove participant"),
"removeParticipantBody": m43,
"removePersonLabel":
MessageLookupByLibrary.simpleMessage("Remove person label"),
"removePublicLink":
MessageLookupByLibrary.simpleMessage("Remove public link"),
"removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(
@ -1208,8 +1225,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Add descriptions like \"#trip\" in photo info to quickly find them here"),
"searchDatesEmptySection": MessageLookupByLibrary.simpleMessage(
"Search by a date, month or year"),
"searchFaceEmptySection":
MessageLookupByLibrary.simpleMessage("Find all photos of a person"),
"searchFaceEmptySection": MessageLookupByLibrary.simpleMessage(
"Persons will be shown here once indexing is done"),
"searchFileTypesAndNamesEmptySection":
MessageLookupByLibrary.simpleMessage("File types and names"),
"searchHint1":

View file

@ -367,6 +367,8 @@ class MessageLookup extends MessageLookupByLibrary {
"close": MessageLookupByLibrary.simpleMessage("Cerrar"),
"clubByCaptureTime": MessageLookupByLibrary.simpleMessage(
"Agrupar por tiempo de captura"),
"clusteringProgress":
MessageLookupByLibrary.simpleMessage("Clustering progress"),
"codeAppliedPageTitle":
MessageLookupByLibrary.simpleMessage("Código aplicado"),
"codeCopiedToClipboard": MessageLookupByLibrary.simpleMessage(
@ -585,6 +587,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Introduzca contraseña"),
"enterPasswordToEncrypt": MessageLookupByLibrary.simpleMessage(
"Introduzca una contraseña que podamos usar para cifrar sus datos"),
"enterPersonName":
MessageLookupByLibrary.simpleMessage("Enter person name"),
"enterReferralCode": MessageLookupByLibrary.simpleMessage(
"Ingresar código de referencia"),
"enterThe6digitCodeFromnyourAuthenticatorApp":
@ -609,6 +613,10 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Exportar registros"),
"exportYourData":
MessageLookupByLibrary.simpleMessage("Exportar tus datos"),
"faceRecognition":
MessageLookupByLibrary.simpleMessage("Face recognition"),
"faceRecognitionIndexingDescription": MessageLookupByLibrary.simpleMessage(
"Please note that this will result in a higher bandwidth and battery usage until all items are indexed."),
"failedToApplyCode":
MessageLookupByLibrary.simpleMessage("Error al aplicar el código"),
"failedToCancel":
@ -647,6 +655,7 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("para tus recuerdos"),
"forgotPassword":
MessageLookupByLibrary.simpleMessage("Olvidé mi contraseña"),
"foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"),
"freeStorageClaimed": MessageLookupByLibrary.simpleMessage(
"Almacenamiento gratuito reclamado"),
"freeStorageOnReferralSuccess": m24,
@ -690,6 +699,8 @@ class MessageLookup extends MessageLookupByLibrary {
"La clave de recuperación introducida es incorrecta"),
"incorrectRecoveryKeyTitle": MessageLookupByLibrary.simpleMessage(
"Clave de recuperación incorrecta"),
"indexingIsPaused": MessageLookupByLibrary.simpleMessage(
"Indexing is paused, will automatically resume when device is ready"),
"insecureDevice":
MessageLookupByLibrary.simpleMessage("Dispositivo inseguro"),
"installManually":
@ -997,6 +1008,8 @@ class MessageLookup extends MessageLookupByLibrary {
"removeParticipant":
MessageLookupByLibrary.simpleMessage("Quitar participante"),
"removeParticipantBody": m43,
"removePersonLabel":
MessageLookupByLibrary.simpleMessage("Remove person label"),
"removePublicLink":
MessageLookupByLibrary.simpleMessage("Quitar enlace público"),
"removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(

View file

@ -425,6 +425,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Grouper par durée"),
"clubByFileName":
MessageLookupByLibrary.simpleMessage("Grouper par nom de fichier"),
"clusteringProgress":
MessageLookupByLibrary.simpleMessage("Clustering progress"),
"codeAppliedPageTitle":
MessageLookupByLibrary.simpleMessage("Code appliqué"),
"codeCopiedToClipboard": MessageLookupByLibrary.simpleMessage(
@ -665,6 +667,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Saisissez le mot de passe"),
"enterPasswordToEncrypt": MessageLookupByLibrary.simpleMessage(
"Entrez un mot de passe que nous pouvons utiliser pour chiffrer vos données"),
"enterPersonName":
MessageLookupByLibrary.simpleMessage("Enter person name"),
"enterReferralCode": MessageLookupByLibrary.simpleMessage(
"Entrez le code de parrainage"),
"enterThe6digitCodeFromnyourAuthenticatorApp":
@ -688,6 +692,10 @@ class MessageLookup extends MessageLookupByLibrary {
"exportLogs": MessageLookupByLibrary.simpleMessage("Exporter les logs"),
"exportYourData":
MessageLookupByLibrary.simpleMessage("Exportez vos données"),
"faceRecognition":
MessageLookupByLibrary.simpleMessage("Face recognition"),
"faceRecognitionIndexingDescription": MessageLookupByLibrary.simpleMessage(
"Please note that this will result in a higher bandwidth and battery usage until all items are indexed."),
"faces": MessageLookupByLibrary.simpleMessage("Visages"),
"failedToApplyCode": MessageLookupByLibrary.simpleMessage(
"Impossible d\'appliquer le code"),
@ -732,6 +740,7 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("pour vos souvenirs"),
"forgotPassword":
MessageLookupByLibrary.simpleMessage("Mot de passe oublié"),
"foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"),
"freeStorageClaimed":
MessageLookupByLibrary.simpleMessage("Stockage gratuit réclamé"),
"freeStorageOnReferralSuccess": m24,
@ -795,6 +804,8 @@ class MessageLookup extends MessageLookupByLibrary {
"La clé de secours que vous avez entrée est incorrecte"),
"incorrectRecoveryKeyTitle":
MessageLookupByLibrary.simpleMessage("Clé de secours non valide"),
"indexingIsPaused": MessageLookupByLibrary.simpleMessage(
"Indexing is paused, will automatically resume when device is ready"),
"insecureDevice":
MessageLookupByLibrary.simpleMessage("Appareil non sécurisé"),
"installManually":
@ -1129,6 +1140,8 @@ class MessageLookup extends MessageLookupByLibrary {
"removeParticipant":
MessageLookupByLibrary.simpleMessage("Supprimer le participant"),
"removeParticipantBody": m43,
"removePersonLabel":
MessageLookupByLibrary.simpleMessage("Remove person label"),
"removePublicLink":
MessageLookupByLibrary.simpleMessage("Supprimer le lien public"),
"removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(

View file

@ -411,6 +411,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Club per tempo di cattura"),
"clubByFileName":
MessageLookupByLibrary.simpleMessage("Unisci per nome file"),
"clusteringProgress":
MessageLookupByLibrary.simpleMessage("Clustering progress"),
"codeAppliedPageTitle":
MessageLookupByLibrary.simpleMessage("Codice applicato"),
"codeCopiedToClipboard": MessageLookupByLibrary.simpleMessage(
@ -644,6 +646,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Inserisci password"),
"enterPasswordToEncrypt": MessageLookupByLibrary.simpleMessage(
"Inserisci una password per criptare i tuoi dati"),
"enterPersonName":
MessageLookupByLibrary.simpleMessage("Enter person name"),
"enterReferralCode": MessageLookupByLibrary.simpleMessage(
"Inserisci il codice di invito"),
"enterThe6digitCodeFromnyourAuthenticatorApp":
@ -665,6 +669,10 @@ class MessageLookup extends MessageLookupByLibrary {
"Questo link è scaduto. Si prega di selezionare un nuovo orario di scadenza o disabilitare la scadenza del link."),
"exportLogs": MessageLookupByLibrary.simpleMessage("Esporta log"),
"exportYourData": MessageLookupByLibrary.simpleMessage("Esporta dati"),
"faceRecognition":
MessageLookupByLibrary.simpleMessage("Face recognition"),
"faceRecognitionIndexingDescription": MessageLookupByLibrary.simpleMessage(
"Please note that this will result in a higher bandwidth and battery usage until all items are indexed."),
"failedToApplyCode": MessageLookupByLibrary.simpleMessage(
"Impossibile applicare il codice"),
"failedToCancel":
@ -704,6 +712,7 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("per i tuoi ricordi"),
"forgotPassword":
MessageLookupByLibrary.simpleMessage("Password dimenticata"),
"foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"),
"freeStorageClaimed":
MessageLookupByLibrary.simpleMessage("Spazio gratuito richiesto"),
"freeStorageOnReferralSuccess": m24,
@ -764,6 +773,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Il codice che hai inserito non è corretto"),
"incorrectRecoveryKeyTitle":
MessageLookupByLibrary.simpleMessage("Chiave di recupero errata"),
"indexingIsPaused": MessageLookupByLibrary.simpleMessage(
"Indexing is paused, will automatically resume when device is ready"),
"insecureDevice":
MessageLookupByLibrary.simpleMessage("Dispositivo non sicuro"),
"installManually":
@ -1090,6 +1101,8 @@ class MessageLookup extends MessageLookupByLibrary {
"removeParticipant":
MessageLookupByLibrary.simpleMessage("Rimuovi partecipante"),
"removeParticipantBody": m43,
"removePersonLabel":
MessageLookupByLibrary.simpleMessage("Remove person label"),
"removePublicLink":
MessageLookupByLibrary.simpleMessage("Rimuovi link pubblico"),
"removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(

View file

@ -34,6 +34,8 @@ class MessageLookup extends MessageLookupByLibrary {
"addViewers": m1,
"changeLocationOfSelectedItems": MessageLookupByLibrary.simpleMessage(
"Change location of selected items?"),
"clusteringProgress":
MessageLookupByLibrary.simpleMessage("Clustering progress"),
"contacts": MessageLookupByLibrary.simpleMessage("Contacts"),
"createCollaborativeLink":
MessageLookupByLibrary.simpleMessage("Create collaborative link"),
@ -44,7 +46,16 @@ class MessageLookup extends MessageLookupByLibrary {
"editsToLocationWillOnlyBeSeenWithinEnte":
MessageLookupByLibrary.simpleMessage(
"Edits to location will only be seen within Ente"),
"enterPersonName":
MessageLookupByLibrary.simpleMessage("Enter person name"),
"faceRecognition":
MessageLookupByLibrary.simpleMessage("Face recognition"),
"faceRecognitionIndexingDescription": MessageLookupByLibrary.simpleMessage(
"Please note that this will result in a higher bandwidth and battery usage until all items are indexed."),
"fileTypes": MessageLookupByLibrary.simpleMessage("File types"),
"foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"),
"indexingIsPaused": MessageLookupByLibrary.simpleMessage(
"Indexing is paused, will automatically resume when device is ready"),
"joinDiscord": MessageLookupByLibrary.simpleMessage("Join Discord"),
"locations": MessageLookupByLibrary.simpleMessage("Locations"),
"longPressAnEmailToVerifyEndToEndEncryption":
@ -55,6 +66,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Modify your query, or try searching for"),
"moveToHiddenAlbum":
MessageLookupByLibrary.simpleMessage("Move to hidden album"),
"removePersonLabel":
MessageLookupByLibrary.simpleMessage("Remove person label"),
"search": MessageLookupByLibrary.simpleMessage("Search"),
"selectALocation":
MessageLookupByLibrary.simpleMessage("Select a location"),

View file

@ -447,6 +447,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Samenvoegen op tijd"),
"clubByFileName":
MessageLookupByLibrary.simpleMessage("Samenvoegen op bestandsnaam"),
"clusteringProgress":
MessageLookupByLibrary.simpleMessage("Clustering progress"),
"codeAppliedPageTitle":
MessageLookupByLibrary.simpleMessage("Code toegepast"),
"codeCopiedToClipboard": MessageLookupByLibrary.simpleMessage(
@ -723,6 +725,10 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Logboek exporteren"),
"exportYourData":
MessageLookupByLibrary.simpleMessage("Exporteer je gegevens"),
"faceRecognition":
MessageLookupByLibrary.simpleMessage("Face recognition"),
"faceRecognitionIndexingDescription": MessageLookupByLibrary.simpleMessage(
"Please note that this will result in a higher bandwidth and battery usage until all items are indexed."),
"faces": MessageLookupByLibrary.simpleMessage("Gezichten"),
"failedToApplyCode":
MessageLookupByLibrary.simpleMessage("Code toepassen mislukt"),
@ -771,6 +777,7 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("voor uw herinneringen"),
"forgotPassword":
MessageLookupByLibrary.simpleMessage("Wachtwoord vergeten"),
"foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"),
"freeStorageClaimed":
MessageLookupByLibrary.simpleMessage("Gratis opslag geclaimd"),
"freeStorageOnReferralSuccess": m24,
@ -833,6 +840,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Onjuiste herstelsleutel"),
"indexedItems":
MessageLookupByLibrary.simpleMessage("Geïndexeerde bestanden"),
"indexingIsPaused": MessageLookupByLibrary.simpleMessage(
"Indexing is paused, will automatically resume when device is ready"),
"insecureDevice":
MessageLookupByLibrary.simpleMessage("Onveilig apparaat"),
"installManually":

View file

@ -39,6 +39,8 @@ class MessageLookup extends MessageLookupByLibrary {
"cancel": MessageLookupByLibrary.simpleMessage("Avbryt"),
"changeLocationOfSelectedItems": MessageLookupByLibrary.simpleMessage(
"Change location of selected items?"),
"clusteringProgress":
MessageLookupByLibrary.simpleMessage("Clustering progress"),
"confirmAccountDeletion":
MessageLookupByLibrary.simpleMessage("Bekreft sletting av konto"),
"confirmDeletePrompt": MessageLookupByLibrary.simpleMessage(
@ -57,12 +59,21 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage(
"Edits to location will only be seen within Ente"),
"email": MessageLookupByLibrary.simpleMessage("E-post"),
"enterPersonName":
MessageLookupByLibrary.simpleMessage("Enter person name"),
"enterValidEmail": MessageLookupByLibrary.simpleMessage(
"Vennligst skriv inn en gyldig e-postadresse."),
"enterYourEmailAddress": MessageLookupByLibrary.simpleMessage(
"Skriv inn e-postadressen din"),
"faceRecognition":
MessageLookupByLibrary.simpleMessage("Face recognition"),
"faceRecognitionIndexingDescription": MessageLookupByLibrary.simpleMessage(
"Please note that this will result in a higher bandwidth and battery usage until all items are indexed."),
"feedback": MessageLookupByLibrary.simpleMessage("Tilbakemelding"),
"fileTypes": MessageLookupByLibrary.simpleMessage("File types"),
"foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"),
"indexingIsPaused": MessageLookupByLibrary.simpleMessage(
"Indexing is paused, will automatically resume when device is ready"),
"invalidEmailAddress":
MessageLookupByLibrary.simpleMessage("Ugyldig e-postadresse"),
"joinDiscord": MessageLookupByLibrary.simpleMessage("Join Discord"),
@ -77,6 +88,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Modify your query, or try searching for"),
"moveToHiddenAlbum":
MessageLookupByLibrary.simpleMessage("Move to hidden album"),
"removePersonLabel":
MessageLookupByLibrary.simpleMessage("Remove person label"),
"search": MessageLookupByLibrary.simpleMessage("Search"),
"selectALocation":
MessageLookupByLibrary.simpleMessage("Select a location"),

View file

@ -49,6 +49,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Zmień hasło"),
"checkInboxAndSpamFolder": MessageLookupByLibrary.simpleMessage(
"Sprawdź swoją skrzynkę odbiorczą (i spam), aby zakończyć weryfikację"),
"clusteringProgress":
MessageLookupByLibrary.simpleMessage("Clustering progress"),
"codeCopiedToClipboard": MessageLookupByLibrary.simpleMessage(
"Kod został skopiowany do schowka"),
"confirm": MessageLookupByLibrary.simpleMessage("Potwierdź"),
@ -101,6 +103,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Wprowadź nowe hasło, którego możemy użyć do zaszyfrowania Twoich danych"),
"enterPasswordToEncrypt": MessageLookupByLibrary.simpleMessage(
"Wprowadź hasło, którego możemy użyć do zaszyfrowania Twoich danych"),
"enterPersonName":
MessageLookupByLibrary.simpleMessage("Enter person name"),
"enterValidEmail": MessageLookupByLibrary.simpleMessage(
"Podaj poprawny adres e-mail."),
"enterYourEmailAddress":
@ -109,10 +113,15 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Wprowadź hasło"),
"enterYourRecoveryKey": MessageLookupByLibrary.simpleMessage(
"Wprowadź swój klucz odzyskiwania"),
"faceRecognition":
MessageLookupByLibrary.simpleMessage("Face recognition"),
"faceRecognitionIndexingDescription": MessageLookupByLibrary.simpleMessage(
"Please note that this will result in a higher bandwidth and battery usage until all items are indexed."),
"feedback": MessageLookupByLibrary.simpleMessage("Informacja zwrotna"),
"fileTypes": MessageLookupByLibrary.simpleMessage("File types"),
"forgotPassword":
MessageLookupByLibrary.simpleMessage("Nie pamiętam hasła"),
"foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"),
"generatingEncryptionKeys": MessageLookupByLibrary.simpleMessage(
"Generowanie kluczy szyfrujących..."),
"howItWorks": MessageLookupByLibrary.simpleMessage("Jak to działa"),
@ -122,6 +131,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Kod jest nieprawidłowy"),
"incorrectRecoveryKeyTitle": MessageLookupByLibrary.simpleMessage(
"Nieprawidłowy klucz odzyskiwania"),
"indexingIsPaused": MessageLookupByLibrary.simpleMessage(
"Indexing is paused, will automatically resume when device is ready"),
"invalidEmailAddress":
MessageLookupByLibrary.simpleMessage("Nieprawidłowy adres e-mail"),
"joinDiscord": MessageLookupByLibrary.simpleMessage("Join Discord"),
@ -166,6 +177,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Jeśli zapomnisz hasła, jedynym sposobem odzyskania danych jest ten klucz."),
"recoverySuccessful":
MessageLookupByLibrary.simpleMessage("Odzyskano pomyślnie!"),
"removePersonLabel":
MessageLookupByLibrary.simpleMessage("Remove person label"),
"resendEmail":
MessageLookupByLibrary.simpleMessage("Wyślij e-mail ponownie"),
"resetPasswordTitle":

View file

@ -98,7 +98,7 @@ class MessageLookup extends MessageLookupByLibrary {
"${storageAmountInGB} GB cada vez que alguém se inscrever para um plano pago e aplica o seu código";
static String m25(freeAmount, storageUnit) =>
"${freeAmount} ${storageUnit} grátis";
"${freeAmount} ${storageUnit} livre";
static String m26(endDate) => "Teste gratuito acaba em ${endDate}";
@ -225,6 +225,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Eu entendo que se eu perder minha senha, posso perder meus dados, já que meus dados são <underline>criptografados de ponta a ponta</underline>."),
"activeSessions":
MessageLookupByLibrary.simpleMessage("Sessões ativas"),
"addAName": MessageLookupByLibrary.simpleMessage("Adicione um nome"),
"addANewEmail":
MessageLookupByLibrary.simpleMessage("Adicionar um novo email"),
"addCollaborator":
@ -445,6 +446,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Agrupar por tempo de captura"),
"clubByFileName": MessageLookupByLibrary.simpleMessage(
"Agrupar pelo nome de arquivo"),
"clusteringProgress":
MessageLookupByLibrary.simpleMessage("Progresso de agrupamento"),
"codeAppliedPageTitle":
MessageLookupByLibrary.simpleMessage("Código aplicado"),
"codeCopiedToClipboard": MessageLookupByLibrary.simpleMessage(
@ -587,7 +590,7 @@ class MessageLookup extends MessageLookupByLibrary {
"descriptions": MessageLookupByLibrary.simpleMessage("Descrições"),
"deselectAll": MessageLookupByLibrary.simpleMessage("Desmarcar todos"),
"designedToOutlive":
MessageLookupByLibrary.simpleMessage("Feito para ter logenvidade"),
MessageLookupByLibrary.simpleMessage("Feito para ter longevidade"),
"details": MessageLookupByLibrary.simpleMessage("Detalhes"),
"devAccountChanged": MessageLookupByLibrary.simpleMessage(
"A conta de desenvolvedor que usamos para publicar o Ente na App Store foi alterada. Por esse motivo, você precisará fazer entrar novamente.\n\nPedimos desculpas pelo inconveniente, mas isso era inevitável."),
@ -690,6 +693,8 @@ class MessageLookup extends MessageLookupByLibrary {
"enterPassword": MessageLookupByLibrary.simpleMessage("Digite a senha"),
"enterPasswordToEncrypt": MessageLookupByLibrary.simpleMessage(
"Insira a senha para criptografar seus dados"),
"enterPersonName":
MessageLookupByLibrary.simpleMessage("Inserir nome da pessoa"),
"enterReferralCode": MessageLookupByLibrary.simpleMessage(
"Insira o código de referência"),
"enterThe6digitCodeFromnyourAuthenticatorApp":
@ -714,6 +719,10 @@ class MessageLookup extends MessageLookupByLibrary {
"exportLogs": MessageLookupByLibrary.simpleMessage("Exportar logs"),
"exportYourData":
MessageLookupByLibrary.simpleMessage("Exportar seus dados"),
"faceRecognition":
MessageLookupByLibrary.simpleMessage("Reconhecimento facial"),
"faceRecognitionIndexingDescription": MessageLookupByLibrary.simpleMessage(
"Por favor, note que isso resultará em uma largura de banda maior e uso de bateria até que todos os itens sejam indexados."),
"faces": MessageLookupByLibrary.simpleMessage("Rostos"),
"failedToApplyCode":
MessageLookupByLibrary.simpleMessage("Falha ao aplicar o código"),
@ -755,11 +764,15 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Arquivos excluídos"),
"filesSavedToGallery":
MessageLookupByLibrary.simpleMessage("Arquivos salvos na galeria"),
"findPeopleByName": MessageLookupByLibrary.simpleMessage(
"Encontre pessoas rapidamente por nome"),
"flip": MessageLookupByLibrary.simpleMessage("Inverter"),
"forYourMemories":
MessageLookupByLibrary.simpleMessage("para suas memórias"),
"forgotPassword":
MessageLookupByLibrary.simpleMessage("Esqueceu sua senha"),
"foundFaces":
MessageLookupByLibrary.simpleMessage("Rostos encontrados"),
"freeStorageClaimed": MessageLookupByLibrary.simpleMessage(
"Armazenamento gratuito reivindicado"),
"freeStorageOnReferralSuccess": m24,
@ -823,6 +836,8 @@ class MessageLookup extends MessageLookupByLibrary {
"incorrectRecoveryKeyTitle": MessageLookupByLibrary.simpleMessage(
"Chave de recuperação incorreta"),
"indexedItems": MessageLookupByLibrary.simpleMessage("Itens indexados"),
"indexingIsPaused": MessageLookupByLibrary.simpleMessage(
"Indexing is paused, will automatically resume when device is ready"),
"insecureDevice":
MessageLookupByLibrary.simpleMessage("Dispositivo não seguro"),
"installManually":
@ -1057,6 +1072,7 @@ class MessageLookup extends MessageLookupByLibrary {
"pendingItems": MessageLookupByLibrary.simpleMessage("Itens pendentes"),
"pendingSync":
MessageLookupByLibrary.simpleMessage("Sincronização pendente"),
"people": MessageLookupByLibrary.simpleMessage("Pessoas"),
"peopleUsingYourCode":
MessageLookupByLibrary.simpleMessage("Pessoas que usam seu código"),
"permDeleteWarning": MessageLookupByLibrary.simpleMessage(
@ -1190,6 +1206,8 @@ class MessageLookup extends MessageLookupByLibrary {
"removeParticipant":
MessageLookupByLibrary.simpleMessage("Remover participante"),
"removeParticipantBody": m43,
"removePersonLabel":
MessageLookupByLibrary.simpleMessage("Remover etiqueta da pessoa"),
"removePublicLink":
MessageLookupByLibrary.simpleMessage("Remover link público"),
"removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(
@ -1253,7 +1271,7 @@ class MessageLookup extends MessageLookupByLibrary {
"searchDatesEmptySection": MessageLookupByLibrary.simpleMessage(
"Pesquisar por data, mês ou ano"),
"searchFaceEmptySection": MessageLookupByLibrary.simpleMessage(
"Encontre todas as fotos de uma pessoa"),
"Pessoas serão exibidas aqui uma vez que a indexação é feita"),
"searchFileTypesAndNamesEmptySection":
MessageLookupByLibrary.simpleMessage("Tipos de arquivo e nomes"),
"searchHint1": MessageLookupByLibrary.simpleMessage(

View file

@ -382,6 +382,8 @@ class MessageLookup extends MessageLookupByLibrary {
"close": MessageLookupByLibrary.simpleMessage("关闭"),
"clubByCaptureTime": MessageLookupByLibrary.simpleMessage("按拍摄时间分组"),
"clubByFileName": MessageLookupByLibrary.simpleMessage("按文件名排序"),
"clusteringProgress":
MessageLookupByLibrary.simpleMessage("Clustering progress"),
"codeAppliedPageTitle": MessageLookupByLibrary.simpleMessage("代码已应用"),
"codeCopiedToClipboard":
MessageLookupByLibrary.simpleMessage("代码已复制到剪贴板"),
@ -543,7 +545,7 @@ class MessageLookup extends MessageLookupByLibrary {
"emailVerificationToggle":
MessageLookupByLibrary.simpleMessage("电子邮件验证"),
"emailYourLogs": MessageLookupByLibrary.simpleMessage("通过电子邮件发送您的日志"),
"empty": MessageLookupByLibrary.simpleMessage(""),
"empty": MessageLookupByLibrary.simpleMessage(""),
"emptyTrash": MessageLookupByLibrary.simpleMessage("要清空回收站吗?"),
"enableMaps": MessageLookupByLibrary.simpleMessage("启用地图"),
"enableMapsDesc": MessageLookupByLibrary.simpleMessage(
@ -592,6 +594,10 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("此链接已过期。请选择新的过期时间或禁用链接有效期。"),
"exportLogs": MessageLookupByLibrary.simpleMessage("导出日志"),
"exportYourData": MessageLookupByLibrary.simpleMessage("导出您的数据"),
"faceRecognition":
MessageLookupByLibrary.simpleMessage("Face recognition"),
"faceRecognitionIndexingDescription": MessageLookupByLibrary.simpleMessage(
"Please note that this will result in a higher bandwidth and battery usage until all items are indexed."),
"faces": MessageLookupByLibrary.simpleMessage("人脸"),
"failedToApplyCode": MessageLookupByLibrary.simpleMessage("无法使用此代码"),
"failedToCancel": MessageLookupByLibrary.simpleMessage("取消失败"),
@ -626,6 +632,7 @@ class MessageLookup extends MessageLookupByLibrary {
"flip": MessageLookupByLibrary.simpleMessage("上下翻转"),
"forYourMemories": MessageLookupByLibrary.simpleMessage("为您的回忆"),
"forgotPassword": MessageLookupByLibrary.simpleMessage("忘记密码"),
"foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"),
"freeStorageClaimed": MessageLookupByLibrary.simpleMessage("已领取的免费存储"),
"freeStorageOnReferralSuccess": m24,
"freeStorageSpace": m25,
@ -679,6 +686,8 @@ class MessageLookup extends MessageLookupByLibrary {
"incorrectRecoveryKeyTitle":
MessageLookupByLibrary.simpleMessage("不正确的恢复密钥"),
"indexedItems": MessageLookupByLibrary.simpleMessage("已索引项目"),
"indexingIsPaused": MessageLookupByLibrary.simpleMessage(
"Indexing is paused, will automatically resume when device is ready"),
"insecureDevice": MessageLookupByLibrary.simpleMessage("设备不安全"),
"installManually": MessageLookupByLibrary.simpleMessage("手动安装"),
"invalidEmailAddress":

View file

@ -4034,10 +4034,10 @@ class S {
);
}
/// `Free trial valid till {endDate}.\nYou can purchase a paid plan afterwards.`
/// `Free trial valid till {endDate}.\nYou can choose a paid plan afterwards.`
String playStoreFreeTrialValidTill(Object endDate) {
return Intl.message(
'Free trial valid till $endDate.\nYou can purchase a paid plan afterwards.',
'Free trial valid till $endDate.\nYou can choose a paid plan afterwards.',
name: 'playStoreFreeTrialValidTill',
desc: '',
args: [endDate],
@ -6969,10 +6969,10 @@ class S {
);
}
/// `Find all photos of a person`
/// `Persons will be shown here once indexing is done`
String get searchFaceEmptySection {
return Intl.message(
'Find all photos of a person',
'Persons will be shown here once indexing is done',
name: 'searchFaceEmptySection',
desc: '',
args: [],
@ -8168,6 +8168,16 @@ class S {
);
}
/// `People`
String get people {
return Intl.message(
'People',
name: 'people',
desc: '',
args: [],
);
}
/// `Contents`
String get contents {
return Intl.message(
@ -8388,26 +8398,6 @@ class S {
);
}
/// `Auto pair`
String get autoPair {
return Intl.message(
'Auto pair',
name: 'autoPair',
desc: '',
args: [],
);
}
/// `Pair with PIN`
String get pairWithPin {
return Intl.message(
'Pair with PIN',
name: 'pairWithPin',
desc: '',
args: [],
);
}
/// `Device not found`
String get deviceNotFound {
return Intl.message(
@ -8468,6 +8458,26 @@ class S {
);
}
/// `Add a name`
String get addAName {
return Intl.message(
'Add a name',
name: 'addAName',
desc: '',
args: [],
);
}
/// `Find people quickly by name`
String get findPeopleByName {
return Intl.message(
'Find people quickly by name',
name: 'findPeopleByName',
desc: '',
args: [],
);
}
/// `{count, plural, zero {Add viewer} one {Add viewer} other {Add viewers}}`
String addViewers(num count) {
return Intl.plural(
@ -8594,6 +8604,26 @@ class S {
);
}
/// `Enter person name`
String get enterPersonName {
return Intl.message(
'Enter person name',
name: 'enterPersonName',
desc: '',
args: [],
);
}
/// `Remove person label`
String get removePersonLabel {
return Intl.message(
'Remove person label',
name: 'removePersonLabel',
desc: '',
args: [],
);
}
/// `Auto pair works only with devices that support Chromecast.`
String get autoPairDesc {
return Intl.message(
@ -8703,6 +8733,76 @@ class S {
args: [],
);
}
/// `Auto pair`
String get autoPair {
return Intl.message(
'Auto pair',
name: 'autoPair',
desc: '',
args: [],
);
}
/// `Pair with PIN`
String get pairWithPin {
return Intl.message(
'Pair with PIN',
name: 'pairWithPin',
desc: '',
args: [],
);
}
/// `Face recognition`
String get faceRecognition {
return Intl.message(
'Face recognition',
name: 'faceRecognition',
desc: '',
args: [],
);
}
/// `Please note that this will result in a higher bandwidth and battery usage until all items are indexed.`
String get faceRecognitionIndexingDescription {
return Intl.message(
'Please note that this will result in a higher bandwidth and battery usage until all items are indexed.',
name: 'faceRecognitionIndexingDescription',
desc: '',
args: [],
);
}
/// `Found faces`
String get foundFaces {
return Intl.message(
'Found faces',
name: 'foundFaces',
desc: '',
args: [],
);
}
/// `Clustering progress`
String get clusteringProgress {
return Intl.message(
'Clustering progress',
name: 'clusteringProgress',
desc: '',
args: [],
);
}
/// `Indexing is paused. It will automatically resume when device is ready.`
String get indexingIsPaused {
return Intl.message(
'Indexing is paused. It will automatically resume when device is ready.',
name: 'indexingIsPaused',
desc: '',
args: [],
);
}
}
class AppLocalizationDelegate extends LocalizationsDelegate<S> {

View file

@ -0,0 +1,111 @@
//
// Generated code. Do not modify.
// source: ente/common/box.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// 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
import 'dart:core' as $core;
import 'package:protobuf/protobuf.dart' as $pb;
/// CenterBox is a box where x,y is the center of the box
class CenterBox extends $pb.GeneratedMessage {
factory CenterBox({
$core.double? x,
$core.double? y,
$core.double? height,
$core.double? width,
}) {
final $result = create();
if (x != null) {
$result.x = x;
}
if (y != null) {
$result.y = y;
}
if (height != null) {
$result.height = height;
}
if (width != null) {
$result.width = width;
}
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);
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
;
@$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;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static CenterBox create() => CenterBox._();
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? _defaultInstance;
@$pb.TagNumber(1)
$core.double get x => $_getN(0);
@$pb.TagNumber(1)
set x($core.double v) { $_setFloat(0, v); }
@$pb.TagNumber(1)
$core.bool hasX() => $_has(0);
@$pb.TagNumber(1)
void clearX() => clearField(1);
@$pb.TagNumber(2)
$core.double get y => $_getN(1);
@$pb.TagNumber(2)
set y($core.double v) { $_setFloat(1, v); }
@$pb.TagNumber(2)
$core.bool hasY() => $_has(1);
@$pb.TagNumber(2)
void clearY() => clearField(2);
@$pb.TagNumber(3)
$core.double get height => $_getN(2);
@$pb.TagNumber(3)
set height($core.double v) { $_setFloat(2, v); }
@$pb.TagNumber(3)
$core.bool hasHeight() => $_has(2);
@$pb.TagNumber(3)
void clearHeight() => clearField(3);
@$pb.TagNumber(4)
$core.double get width => $_getN(3);
@$pb.TagNumber(4)
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');

View file

@ -0,0 +1,11 @@
//
// Generated code. Do not modify.
// source: ente/common/box.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// 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

@ -0,0 +1,38 @@
//
// Generated code. Do not modify.
// source: ente/common/box.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// 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
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use centerBoxDescriptor instead')
const CenterBox$json = {
'1': 'CenterBox',
'2': [
{'1': 'x', '3': 1, '4': 1, '5': 2, '9': 0, '10': 'x', '17': true},
{'1': 'y', '3': 2, '4': 1, '5': 2, '9': 1, '10': 'y', '17': true},
{'1': 'height', '3': 3, '4': 1, '5': 2, '9': 2, '10': 'height', '17': true},
{'1': 'width', '3': 4, '4': 1, '5': 2, '9': 3, '10': 'width', '17': true},
],
'8': [
{'1': '_x'},
{'1': '_y'},
{'1': '_height'},
{'1': '_width'},
],
};
/// Descriptor for `CenterBox`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List centerBoxDescriptor = $convert.base64Decode(
'CglDZW50ZXJCb3gSEQoBeBgBIAEoAkgAUgF4iAEBEhEKAXkYAiABKAJIAVIBeYgBARIbCgZoZW'
'lnaHQYAyABKAJIAlIGaGVpZ2h0iAEBEhkKBXdpZHRoGAQgASgCSANSBXdpZHRoiAEBQgQKAl94'
'QgQKAl95QgkKB19oZWlnaHRCCAoGX3dpZHRo');

View file

@ -0,0 +1,14 @@
//
// Generated code. Do not modify.
// source: ente/common/box.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names
// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
export 'box.pb.dart';

View file

@ -0,0 +1,83 @@
//
// Generated code. Do not modify.
// source: ente/common/point.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// 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
import 'dart:core' as $core;
import 'package:protobuf/protobuf.dart' as $pb;
/// EPoint is a point in 2D space
class EPoint extends $pb.GeneratedMessage {
factory EPoint({
$core.double? x,
$core.double? y,
}) {
final $result = create();
if (x != null) {
$result.x = x;
}
if (y != null) {
$result.y = y;
}
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);
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
;
@$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;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static EPoint create() => EPoint._();
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? _defaultInstance;
@$pb.TagNumber(1)
$core.double get x => $_getN(0);
@$pb.TagNumber(1)
set x($core.double v) { $_setFloat(0, v); }
@$pb.TagNumber(1)
$core.bool hasX() => $_has(0);
@$pb.TagNumber(1)
void clearX() => clearField(1);
@$pb.TagNumber(2)
$core.double get y => $_getN(1);
@$pb.TagNumber(2)
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');

View file

@ -0,0 +1,11 @@
//
// Generated code. Do not modify.
// source: ente/common/point.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// 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

@ -0,0 +1,33 @@
//
// Generated code. Do not modify.
// source: ente/common/point.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// 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
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use ePointDescriptor instead')
const EPoint$json = {
'1': 'EPoint',
'2': [
{'1': 'x', '3': 1, '4': 1, '5': 2, '9': 0, '10': 'x', '17': true},
{'1': 'y', '3': 2, '4': 1, '5': 2, '9': 1, '10': 'y', '17': true},
],
'8': [
{'1': '_x'},
{'1': '_y'},
],
};
/// Descriptor for `EPoint`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List ePointDescriptor = $convert.base64Decode(
'CgZFUG9pbnQSEQoBeBgBIAEoAkgAUgF4iAEBEhEKAXkYAiABKAJIAVIBeYgBAUIECgJfeEIECg'
'JfeQ==');

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