Compare commits

...

880 Commits

Author SHA1 Message Date
Prateek Sunal
109ac573c9 [mob] remove NativeAdapter to support big file upload (#5843)
## Description

Big file uploads fail when using NativeAdapter, this PR:
- [x] Removes NativeAdapter http client adapter

## Tests
2025-05-08 12:45:53 +05:30
Prateek Sunal
23559252e6 chore: bump version 2025-05-08 12:45:22 +05:30
Prateek Sunal
31b31b1a52 chore: lint update 2025-05-08 12:45:11 +05:30
Prateek Sunal
8333e2ad7b fix: not remove it for enteDio 2025-05-08 12:42:59 +05:30
Prateek Sunal
cb5c9f3170 chore: lint fix 2025-05-08 12:38:58 +05:30
Prateek Sunal
7b2e6cb1bd fix(network): remove NativeAdapter to support big file upload 2025-05-08 12:38:42 +05:30
Neeraj
d18d939489 [mob] Navigate to BackupSettings when tapping "Waiting for network" status (#5835)
## Description

## Tests
2025-05-08 11:28:59 +05:30
Neeraj Gupta
b3376f27aa Fixed typo 2025-05-08 11:27:01 +05:30
Vishnu Mohandas
f238b55df3 [docs] env, ports and more docs in /self-hosting (#5823) 2025-05-07 19:10:54 +05:30
mngshm
d15a034869 consistency (2) 2025-05-07 19:09:07 +05:30
mngshm
7b3ae417e8 consistency 2025-05-07 18:56:00 +05:30
Neeraj Gupta
e322958b25 Navigate to BackupSettings when tapping "Waiting for network" status 2025-05-07 16:53:02 +05:30
Neeraj
0d660f239f [mob] Bump version v1.0.9 (#5834)
## Description

Bumping version to prepare for next release.

## Tests
2025-05-07 16:24:46 +05:30
Prateek Sunal
c4a50fc9fb chore: bump version to 1039 2025-05-07 16:15:41 +05:30
mngshm
8856ad1520 Sidebar 2025-05-07 13:30:40 +05:30
mangesh
e8158ef45a [staff] show family member storage quota (#5770) 2025-05-07 10:55:02 +05:30
Manav Rathi
4fa0bf76e8 [desktop] Generisize the creation of utility processes (#5829)
ffmpeg code about to become one
2025-05-06 18:58:41 +05:30
Manav Rathi
92a9b34836 Generisize 2025-05-06 18:52:03 +05:30
Manav Rathi
10d7162d6e Rename 2025-05-06 18:00:10 +05:30
Manav Rathi
2a1b8ae18e Generalize 2025-05-06 17:39:48 +05:30
Manav Rathi
5abf2cb35e Extract 2025-05-06 17:24:03 +05:30
Manav Rathi
367170be95 [desktop] Video stream generation - WIP Part x/x (#5827) 2025-05-06 17:05:48 +05:30
Manav Rathi
4d7cfee60f Fix slowness 2025-05-06 16:03:13 +05:30
Prateek Sunal
29152d1f85 [mob] bump to 1038 (#5817)
## Description

Bump version to 1038

## Tests
2025-05-06 15:39:25 +05:30
Neeraj
6b4ffa4822 [mob][photos] Fix share to Ente (#5821)
## Description

Fix [issue with sharing to
Ente](https://github.com/ente-io/ente/discussions/5755)

## Tests
2025-05-06 15:38:32 +05:30
Manav Rathi
2883f4bed6 Tweak 2025-05-06 15:08:52 +05:30
laurenspriem
c96275cdd1 Update load message 2025-05-06 14:48:57 +05:30
Manav Rathi
9db8324ffd Sketch 2025-05-06 14:42:23 +05:30
mngshm
0c664b94b9 Make storageLimit nullable and display 'NA' 2025-05-06 14:41:42 +05:30
Manav Rathi
c087e419d5 Outline 2025-05-06 13:00:41 +05:30
mngshm
5ba5cae5ef mark redirection info as IMPORTANT in doc 2025-05-06 12:50:27 +05:30
Manav Rathi
4ea211d923 Sketch interruptible loop 2025-05-06 12:32:57 +05:30
mngshm
8d8202adab Env and Ports 2025-05-06 12:13:48 +05:30
mngshm
267f93e41e Merge branch 'main' into fam 2025-05-06 11:05:10 +05:30
Manav Rathi
260ec952b4 Not needed 2025-05-06 10:14:28 +05:30
Prateek Sunal
5e311c2813 fix: bump to 1038 2025-05-05 20:53:51 +05:30
Prateek Sunal
1d3268916f [mob] fix ffmpeg-kit android compilation (#5813)
## Description

- [x] Fix failing android build
- [x] Don't redirect to Backup Status screen when "Preview Failed"
status is pressed.

## Tests

- [x] Test if app works and everything is fine
2025-05-05 20:23:22 +05:30
Prateek Sunal
73192cd0fd fix: remove unused import and simplify navigation logic in PreviewStatusWidget 2025-05-05 20:21:55 +05:30
Prateek Sunal
9c886b3fa3 fix: update ffmpeg kit resolved reference in pubspec.lock 2025-05-05 20:01:39 +05:30
Prateek Sunal
017832f11e feat: update ffmpeg kit source 2025-05-05 18:38:49 +05:30
Prateek Sunal
67e76bc42f chore: update locals 2025-05-05 18:38:37 +05:30
laurenspriem
9a6579c55c Refactor 2025-05-05 17:30:12 +05:30
laurenspriem
17c0cdef14 Fix backup share issue 2025-05-05 17:21:39 +05:30
mngshm
dd0cc71f36 Minor 2025-05-05 16:37:29 +05:30
mangesh
21fd6ab463 [staff] match title casing to key in the UserData interface (#5812) 2025-05-05 16:36:43 +05:30
mngshm
6e2142c605 match title casing to key in the UserData interface 2025-05-05 16:28:23 +05:30
Manav Rathi
16338682ed [docs] Mention UNC path workaround to create network drive (#5811) 2025-05-05 15:58:05 +05:30
Manav Rathi
a7e8d3dfa6 [docs] Mention UNC path workaround to create network drive 2025-05-05 15:51:03 +05:30
Manav Rathi
6e9014b915 [desktop] Tweak the backfill behaviour in case of transients (#5809) 2025-05-05 15:34:24 +05:30
Neeraj
b5e7a3f83f [mob] Bump version v1.0.7 (#5810)
## Description

## Tests
2025-05-05 15:24:19 +05:30
Neeraj Gupta
d8d76f452d Bump version v1.0.7 2025-05-05 15:23:14 +05:30
Laurens Priem
c2e475c666 Face thumbnail logging (#5808)
## Description

Change logging flow for face thumbnail generation
2025-05-05 15:03:06 +05:30
Manav Rathi
9a4bc898f0 [desktop] Tweak the backfill behaviour in case of transients 2025-05-05 15:02:28 +05:30
laurenspriem
ca92aa8c62 Include delay 2025-05-05 14:59:53 +05:30
laurenspriem
56c6d7ed3c Remove redundant reset 2025-05-05 14:49:57 +05:30
mangesh
6ee4bce676 Merge branch 'main' into fam 2025-05-05 14:47:44 +05:30
laurenspriem
ff3f01af56 Increase queue size 2025-05-05 14:47:05 +05:30
Laurens Priem
b5ba81e22b [mob][photos] Fix memories update regression (#5807)
## Description

Fixed regression in memories update scheme.
2025-05-05 14:23:04 +05:30
laurenspriem
d5aab7c6df Fix memories update regression 2025-05-05 14:18:58 +05:30
Manav Rathi
2749457611 [web] Ensure copy as PNG option is reset when we get the original (#5806)
Fixes: https://github.com/ente-io/ente/discussions/5802
2025-05-05 14:02:22 +05:30
Manav Rathi
883b14e96a [web] Ensure copy as PNG option is reset when we get the original
Fixes: https://github.com/ente-io/ente/discussions/5802
2025-05-05 13:58:13 +05:30
Neeraj
59d7e0acac [mobile] New translations (#5799)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-app)
2025-05-05 13:39:10 +05:30
Neeraj
68ac3503ed [server] Use access ctrl for verifying access (#5801)
## Description

## Tests
2025-05-05 13:33:26 +05:30
mngshm
58649db181 fix Linters in UpdateSubscription Component 2025-05-05 13:25:21 +05:30
mangesh
92ca4eeb15 [staff] consolidate and separate interfaces (#5765)
The codebase was too cluttered with interfaces spread all over the
codebase. Separated all the commonly usable types into a single
`types/index.ts` file. Some types which are only usable in that
particular component are left untouched.

P.S: Inspiration from families codebase.
2025-05-05 13:21:12 +05:30
Manav Rathi
d3e06e6cc9 [web] Ensure ellipsizing of caption (#5805)
`text-align: right` causes the ellipsizing to sometimes work, sometimes
not, depending on the exact contents of the line (tested in current
Chrome). Tweak the design to work with the normal text align to try and
ensure the elision is always ellipsized.
2025-05-05 13:19:22 +05:30
Manav Rathi
3cef3e9bdc [web] Ensure ellipsizing of caption
`text-align: right` causes the ellipsizing to sometimes work, sometimes not,
depending on the exact contents of the line (tested in current Chrome). Tweak
the design to work with the normal text align to try and ensure the ellision is
always ellipsized.
2025-05-05 13:12:58 +05:30
mangesh
d318952feb [quickstart] Gracefully handle case when docker compose is not present (#5804)
When docker is present but docker compose is not present, the `docker
compose` invocation would fail. We want the early exit (`set -e`), so
instead do a fallback to set dcv to an empty string so that it later
fails in the `test -z dcv` case below and prints the intended error
message.
2025-05-05 13:08:49 +05:30
Manav Rathi
6d8051dfa0 [quickstart] Gracefully handle case when docker compose is not present
When docker is present but docker compose is not present, the `docker compose`
invocation would fail. We want the early exit (`set -e`), so instead do a
fallback to set dcv to an empty string so that it later fails in the `test -z
dcv` case below and prints the intended error message.
2025-05-05 12:37:48 +05:30
Laurens Priem
6acb9cf23f [mob][photos] Deletion fixes (#5792)
## Description

- Fix issue where user is not able to delete own files in a shared album
- Fix issue where deletion of not yet uploaded files leads to showing
grey boxes in gallery

## Tests

Tested in debug mode on my pixel phone.
2025-05-05 11:46:03 +05:30
Manav Rathi
87e5457eb0 [web] New translations (#5798)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-05-05 11:43:11 +05:30
laurenspriem
5ee23118ff Don't show delete on public collection 2025-05-05 10:06:46 +05:30
Neeraj Gupta
d198f0c273 Use access ctrl for verifying access 2025-05-05 10:01:33 +05:30
Crowdin Bot
a88249de09 New Crowdin translations by GitHub Action 2025-05-05 01:05:08 +00:00
Crowdin Bot
89ded523f8 New Crowdin translations by GitHub Action 2025-05-05 00:40:34 +00:00
laurenspriem
f132a1359f Fix deletions when not uploaded yet 2025-05-03 18:59:20 +05:30
Manav Rathi
48d9d03b32 [web] Rearrange upload code - Part 2/2 (#5786)
Fix most (but not all) of the temporary escape hatches added during
https://github.com/ente-io/ente/pull/5779.
2025-05-02 20:04:17 +05:30
Manav Rathi
11aba9df96 Update 2025-05-02 19:42:38 +05:30
Manav Rathi
2c0fb5e584 Update 2025-05-02 19:39:58 +05:30
Prateek Sunal
69c6adcd06 [workflow] auth linux packages (#5783)
## Description

- [x] Rename libtiff6 to libtiff5 to be backward compatible.
- [x] Update the locks for pubspec and Podfile

## Tests
2025-05-02 19:38:06 +05:30
Manav Rathi
e6c72baef7 Fix 2025-05-02 19:35:46 +05:30
Manav Rathi
83853e579f lint 2025-05-02 19:33:23 +05:30
Manav Rathi
02652d3cfa lint 2025-05-02 19:32:33 +05:30
Manav Rathi
fe60dbbb08 lint 2025-05-02 19:30:55 +05:30
Manav Rathi
a1842be6e1 lint 2025-05-02 19:16:50 +05:30
Manav Rathi
5f644ae96d Fix 2025-05-02 19:09:16 +05:30
Manav Rathi
3f5043a104 transform doesn't require await
ref: https://developer.mozilla.org/en-US/docs/Web/API/TransformStream/TransformStream#transformchunk_controller
2025-05-02 19:03:39 +05:30
Manav Rathi
df55492984 Scope 2025-05-02 18:59:52 +05:30
Manav Rathi
b73171a329 Scope 2025-05-02 18:50:15 +05:30
Manav Rathi
b0b02e2ffe Undot
- Have forgotten why I'd reverted this

- Tested manually with a sample that it works, including a malformed JSON file
  containing `null`, `"null"`, `["null"]`.
2025-05-02 18:35:54 +05:30
Manav Rathi
7b79a42cc9 A 2025-05-02 18:20:55 +05:30
Prateek Sunal
54d1363b58 chore: bump locks 2025-05-02 18:09:40 +05:30
Prateek Sunal
8a9afc40a8 fix: auth workflow packages 2025-05-02 18:07:01 +05:30
Prateek Sunal
958f569969 [mob] update backup-failed dialog (#5780)
## Description

- [x] Make Upload Backup Failed Dialog UX better

## Tests

- [x] Tested the new dialog
2025-05-02 17:35:16 +05:30
Ashil
a64214ae15 [Auth] Remove dependency override (#5781)
## Description

The dependency was overridden for [this
change](https://github.com/juliansteenbakker/flutter_secure_storage/pull/673)
which is merged now and available from flutter_secure_storage version
9.1.0.
2025-05-02 17:29:17 +05:30
ashilkn
69e8ba6743 bump up auth to 4.3.6 2025-05-02 17:27:28 +05:30
Manav Rathi
0b73c92ee6 Audit (and minor fix) 2025-05-02 17:25:51 +05:30
Ashil
196e601929 [workflow] revert to ubuntu 22.04 runner for auth-release (#5782)
## Description

- [x] Auth is dependent on GLIB 2.38 due to ubuntu latest runner, this
downgrades the ubuntu runner to fix this and support atleast GLIB 2.35

## Tests
2025-05-02 17:12:56 +05:30
Manav Rathi
6252b2c267 R 2025-05-02 17:08:19 +05:30
Manav Rathi
9f462f90ab Now it is 2025-05-02 16:43:22 +05:30
Manav Rathi
0e19f5d8b3 R 2025-05-02 16:41:06 +05:30
Prateek Sunal
3ff77ee9c0 fix: revert to ubuntu 22.04 runner 2025-05-02 16:40:54 +05:30
Manav Rathi
65c2eda941 R 2025-05-02 16:36:36 +05:30
ashilkn
f6a2deb763 Remove dependency override 2025-05-02 16:35:32 +05:30
laurenspriem
08ee4c1351 Show delete action inside collaborative album 2025-05-02 16:33:07 +05:30
laurenspriem
c713e1c22b Fix bug in deleting from collaborative album 2025-05-02 16:31:27 +05:30
Manav Rathi
c76a7c75ea Use 2025-05-02 16:30:14 +05:30
Manav Rathi
a56a086dc4 1 2025-05-02 16:20:12 +05:30
Prateek Sunal
c1903c7016 fix(backup-item-card): log warning when contact support is clicked 2025-05-02 15:54:09 +05:30
Prateek Sunal
4dfadc535f chore: bump locks 2025-05-02 15:36:18 +05:30
Prateek Sunal
8e01a5038e chore: update generated locals 2025-05-02 15:35:57 +05:30
Prateek Sunal
05a42efb1b fix: update backup failed dialog to make UX better 2025-05-02 15:35:43 +05:30
mangesh
3d924ab514 [docs] self-hosting revamp and cleanup (#5746)
1. Un-index DB Migration and Mobile Builds
2. Move Frequently Answered S3 problems to `/troubleshooting/uploads`
which was a common file for documenting fixes around uploads to Ente.
3. Un-index Yarn troubleshooting as we default most of the support
versions in the getting-started script and encourage the use of the
one=liner command more.
4. `/troubleshooting/bucket-cors` as the single document for setting up
Bucket CORS. And clean the duplicated guidelins from `/external-s3`.
2025-05-02 15:01:58 +05:30
Manav Rathi
ae34a4c41a [web] Rearrange upload code - Part 1/2 (#5779)
This does the move of the files to the gallery package (so that they can
be reused by the future separate albums app) while trying to touch
minimal code. Will make a pass over the disabled lints in as subsequent
PR.
2025-05-02 14:29:51 +05:30
Neeraj
6bc9230dc8 [server] Fix jwt token expiry time (#5778)
## Description

## Tests
2025-05-02 14:14:54 +05:30
Neeraj Gupta
93186421b1 Fix jwt token expiry time 2025-05-02 14:12:33 +05:30
Manav Rathi
8dce58713f ign 2025-05-02 14:04:27 +05:30
Laurens Priem
7b391ba08f [mob][photos] Faces queue (#5767)
## Description

Use custom task queue instead of pool package for face thumbnail
generation

## Tests

Tested in debug mode on my pixel phone.
2025-05-02 14:02:42 +05:30
Manav Rathi
199df72cf6 ign 2025-05-02 13:58:09 +05:30
Neeraj
59e998f5be [server] Render html responses for account recovery (#5772) 2025-05-02 13:53:51 +05:30
Manav Rathi
bf3373697f Update 2025-05-02 13:51:29 +05:30
Manav Rathi
509955f8c1 Move 2025-05-02 13:31:42 +05:30
laurenspriem
62279ce72f Lower amount of concurrent tasks 2025-05-02 12:28:20 +05:30
Manav Rathi
0c80c88548 [web][desktop] Routine dependency updates feat Electron 36 (#5776) 2025-05-02 09:54:07 +05:30
Manav Rathi
ce3b980e27 Newer 2025-05-02 09:49:10 +05:30
Manav Rathi
7b25e65da4 Electron 36 2025-05-02 09:45:39 +05:30
Neeraj Gupta
3510c01e6e Rename 2025-05-01 17:00:36 +05:30
Neeraj
d20a8495d8 [mob] re-encode audio ffmpeg & update backup status screen (#5769)
## Description

- [x] Re-encode audio to aac when video is already re-encoding to
libx264
- [x] Update Backup Status screen to show the uploaded items as well.

## Tests

- [x] Backup screen now shows uploaded items correctly
2025-05-01 00:55:19 +05:30
Neeraj Gupta
b8cf6012bd Modify dockerfile to include templates 2025-05-01 00:46:23 +05:30
Neeraj Gupta
70dc4db1c5 Return happy response when account is already recovered 2025-05-01 00:45:24 +05:30
Neeraj Gupta
1fb30ceafd Render html template for account recovery 2025-05-01 00:36:14 +05:30
Neeraj Gupta
38ec62a23b Add account recovery templates 2025-05-01 00:24:02 +05:30
mngshm
0a3abb20a1 making linters happy 2025-04-30 20:10:29 +05:30
mngshm
9f9288a5c0 show family member storage quota 2025-04-30 19:59:11 +05:30
Manav Rathi
d047e05bc8 Routine dependency updates 2025-04-30 19:43:33 +05:30
mngshm
e939b06339 Minor 2025-04-30 19:13:14 +05:30
Prateek Sunal
2eaeb759c5 fix: show uploaded items in backup status correctly 2025-04-30 19:11:29 +05:30
Prateek Sunal
2f2346286d fix: use copy aac for case 2 2025-04-30 19:07:26 +05:30
Manav Rathi
8ed1d34301 [desktop] Use the live processing queue in more cases (#5766)
...to reduce the need for redownloading the source files.
2025-04-30 16:28:08 +05:30
Manav Rathi
e38152051c Minor 2025-04-30 16:05:59 +05:30
mngshm
100c1d3803 use nullish coalescing to avoid optional chaining 2025-04-30 15:57:24 +05:30
laurenspriem
7cc3ab1004 Cancel face crop task if not needed 2025-04-30 15:56:52 +05:30
Manav Rathi
0c86c53a96 Fix 2025-04-30 15:35:26 +05:30
Manav Rathi
130e751072 typo 2025-04-30 15:32:14 +05:30
mngshm
408cc05f7c fix: usage conversion import 2025-04-30 15:28:36 +05:30
mngshm
9f70aab9b5 refactor: consolidate and separate interfaces 2025-04-30 15:24:51 +05:30
Manav Rathi
39f63b6339 Remove thresholds since it is now just fs paths 2025-04-30 14:37:36 +05:30
Manav Rathi
81e3c41749 flip 2025-04-30 14:30:17 +05:30
Manav Rathi
831563317e Import 2025-04-30 14:05:18 +05:30
Manav Rathi
a3c43cb54e Use 2 2025-04-30 14:04:33 +05:30
Manav Rathi
83373c4424 Use 1 2025-04-30 13:38:33 +05:30
Manav Rathi
ad47dda614 Convert reverse 2025-04-30 13:24:28 +05:30
Manav Rathi
4466136776 Tweak 2025-04-30 12:58:51 +05:30
Manav Rathi
bc874a2292 Ontology 2025-04-30 12:43:27 +05:30
Manav Rathi
e52816feb1 Note special case 2025-04-30 11:43:54 +05:30
Neeraj
3a34fa4257 [mob] Fix: Add missing check for widget mount (#5764)
## Description
```
FlutterError (A ValueNotifier<bool> was used after being disposed.
                       Once you have called dispose() on a ValueNotifier<bool>, it can no longer be used.)
[sentry.platformError] #0      ChangeNotifier.debugAssertNotDisposed.<anonymous closure> (package:flutter/src/foundation/change_notifier.dart:183:9)
                          1  ChangeNotifier.debugAssertNotDisposed (package:flutter/src/foundation/change_notifier.dart:190:6)
change_notifier.dart:190
                         2    ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:416:27)
change_notifier.dart:416
                       3      ValueNotifier.value= (package:flutter/src/foundation/change_notifier.dart:559:5)
change_notifier.dart:559
                       4      _LoadingPhotosWidgetState.initState.<anonymous closure> (package:photos/ui/home/loading_photos_widget.dart:42:25)
```
## Tests
2025-04-30 11:42:15 +05:30
Manav Rathi
216a3e3e10 Move and cases 2025-04-30 11:24:39 +05:30
Neeraj
c5f02a0116 [mob] Fix Splash screens stuck issues during dev with iOS simulator (#5763)
## Description

## Tests
2025-04-30 11:13:02 +05:30
Neeraj Gupta
7975de0a9a Catch uncaught exception to avoid splash screen issue 2025-04-30 11:08:19 +05:30
Neeraj Gupta
bba262e164 Disable iOS battery check in debugmode 2025-04-30 11:07:36 +05:30
laurenspriem
03a16119b9 Simplify code snippet taskqueue in thumbnails 2025-04-30 10:56:00 +05:30
Manav Rathi
2e657d88f4 sketch web side 1 2025-04-30 10:52:36 +05:30
laurenspriem
ede5e0be90 Remove old pool dependency 2025-04-30 10:52:05 +05:30
laurenspriem
e6981a8c47 Switch to task queue 2025-04-30 10:50:40 +05:30
Manav Rathi
0883ed39e3 node side 2025-04-30 10:42:33 +05:30
bilgilendir
223961bf78 Add 3 Auth Provider Icons (#5660)
**Description:**

- Added icons for the following auth providers:  
  - ImmoScout24  
  - Bonify  
  - Agentur für Arbeit

- Updated `assets/custom-icons/_data/custom-icons.json` accordingly.

- Reordered one icon name ascending
2025-04-30 09:26:20 +05:30
Neeraj
f50b3743f5 [mob] Surface storage utilisation for pending sync section (#5754)
## Description

## Tests

---------

Co-authored-by: Prateek Sunal <prtksunal@gmail.com>
2025-04-30 09:25:39 +05:30
Manav Rathi
10a7c1172b Keep both concepts 2025-04-30 09:16:09 +05:30
Manav Rathi
da60436e91 specific 2025-04-30 08:20:15 +05:30
Manav Rathi
9405d549c7 [desktop] Bifurcate the desktop upload case earlier (#5761) 2025-04-29 19:38:45 +05:30
Manav Rathi
47ee46b440 Use 2025-04-29 19:27:37 +05:30
Manav Rathi
a9d9173364 assert 2025-04-29 19:18:24 +05:30
Manav Rathi
088ebdb7b5 Clarify 2025-04-29 19:10:13 +05:30
Manav Rathi
7a85fb2e72 [web] Tonemap HDR thumbnails (#5758) 2025-04-29 17:21:39 +05:30
Manav Rathi
c63ae6fc1f Use 2025-04-29 17:14:05 +05:30
Manav Rathi
8bf9607bb8 Parse 2025-04-29 17:14:05 +05:30
Manav Rathi
dabae19cf2 ffprobe returns -1 on success 2025-04-29 17:14:05 +05:30
Neeraj Gupta
da930976ef Show pending sync breakup on long press 2025-04-29 16:59:40 +05:30
Neeraj Gupta
0c57ae3b58 Fix path prefix 2025-04-29 16:58:00 +05:30
Neeraj Gupta
543f4c43b3 Clean up names 2025-04-29 16:55:16 +05:30
Neeraj Gupta
5a8f8b8449 Fix: Pass prefix value 2025-04-29 16:54:59 +05:30
Manav Rathi
64363b70e3 Sketch 2025-04-29 16:17:55 +05:30
Manav Rathi
c84b6f6824 Route 2025-04-29 15:43:22 +05:30
Manav Rathi
fb6751a439 Use 2025-04-29 15:25:54 +05:30
Manav Rathi
802dd21200 Potential HDR check
Refs:
- https://github.com/amietn/vcsi/pull/135/files#diff-ad9111f3166bc9321ffb8c8dcd22a624457d6591fc4e9f72ec9821a644459927R535
- https://github.com/photoprism/photoprism/issues/4488#issuecomment-2495851302
2025-04-29 15:10:35 +05:30
Manav Rathi
782008e5d3 Sketch 2025-04-29 14:51:30 +05:30
Manav Rathi
94de25cb26 Handle even px requirement 2025-04-29 13:29:27 +05:30
Manav Rathi
b1efd289d3 tm thumb 2025-04-29 13:10:28 +05:30
Manav Rathi
1e1b3e9d74 Fix 2025-04-29 13:10:28 +05:30
eark39
ba0bf3dd5b [auth] Add BitKub custom icon (#5753)
## Description

## Tests
2025-04-29 12:51:14 +05:30
Neeraj Gupta
a9a2e89e49 Merge branch 'main' into pending-sync-info 2025-04-29 12:49:12 +05:30
Manav Rathi
cc1240b43c [desktop] HLS gen - WIP - Part x/x (#5752)
Four cases:

    H.264, <= 10 MB             - Skip
    H.264, <= 4000 kb/s bitrate - Don't re-encode video stream
    <= 2000 kb/s bitrate        - Don't apply the scale+fps filter
    !BT.709                     - Apply tonemap (zscale+tonemap+zscale)

Example invocation:

ffmpeg -i in.mov -vf
'scale=-2:720,fps=30,zscale=transfer=linear,tonemap=tonemap=hable:desat=0,zscale=primaries=709:transfer=709:matrix=709,format=yuv420p'
-c:v libx264 -c:a aac -f hls -hls_key_info_file out.m3u8.info
-hls_list_size 0 -hls_flags single_file out.m3u8
2025-04-29 11:57:39 +05:30
Neeraj
06830c3881 [mob] Hide ref promo banner for non-ente instance (#5740)
## Description

## Tests
2025-04-29 11:54:48 +05:30
Manav Rathi
918a7bad68 Deal with lines where res is not followed by comma 2025-04-29 11:40:03 +05:30
Manav Rathi
356f98bf52 204 requires body to be null
Otherwise the Response constructor throws
2025-04-29 11:26:36 +05:30
Manav Rathi
2d3734bf14 Relay 2025-04-29 11:18:01 +05:30
Manav Rathi
73a8d4dcda Cases 2025-04-29 11:04:28 +05:30
Manav Rathi
f9e25ed14d rescale case 2025-04-29 10:55:51 +05:30
Manav Rathi
acede69f5b Reencode case 2025-04-29 10:44:18 +05:30
Manav Rathi
0c46aa338e br 2025-04-29 10:17:36 +05:30
Manav Rathi
de42700914 Take 1 2025-04-29 09:53:57 +05:30
Manav Rathi
8a2d4a4eee codec 2025-04-29 09:24:25 +05:30
Manav Rathi
5d0ae9edb6 Outline 2025-04-29 09:17:42 +05:30
Laurens Priem
dda7b2a28e [mob][photos] Fixes 'Not person' null response (#5747)
## Description

Fixes 'Not person' null response

## Tests

Tested in debug mode on my pixel phone.
2025-04-28 20:41:37 +05:30
mangesh
7735d938a5 stray backslash
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-28 18:25:19 +05:30
mngshm
adfe701016 dedup bucket cors setup guide 2025-04-28 16:02:52 +05:30
mngshm
76c7d22754 collapse all sections 2025-04-28 16:02:09 +05:30
mngshm
54aab6738e un-yarn 2025-04-28 15:55:45 +05:30
mngshm
825dd79795 move S3 FAQ from /configuring-s3 to /troubleshooting/uploads 2025-04-28 15:47:55 +05:30
mngshm
ef5dc18442 reorganize and unindex old docs 2025-04-28 14:56:53 +05:30
Vishnu Mohandas
4521943fb1 [mob] Setup readable string for Norwegian (#5745) 2025-04-28 13:33:02 +05:30
vishnukvmd
dc82c24674 Reorder 2025-04-28 13:32:48 +05:30
vishnukvmd
6c6d524b15 [mob] Setup readable string for Norwegian 2025-04-28 13:32:17 +05:30
Neeraj Gupta
5341049bdf Merge remote-tracking branch 'origin/main' into ente_hide_banner 2025-04-28 12:34:18 +05:30
Neeraj
3f58bbf9bc [mobile] New translations (#5744)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-app)
2025-04-28 12:34:04 +05:30
Crowdin Bot
880cba335f New Crowdin translations by GitHub Action 2025-04-28 06:51:31 +00:00
Neeraj Gupta
cb321f49bd Remove redundant import 2025-04-28 12:14:34 +05:30
Neeraj Gupta
15b02c59cc Hide ref promo banner for non-ente instance 2025-04-28 11:59:03 +05:30
Manav Rathi
727a47cf34 [desktop] HLS gen - WIP - Part x/x (#5721)
Stream generation works during live uploads (behind a dev feature flag).
2025-04-28 09:38:50 +05:30
Neeraj
718dbae521 [mobile] New translations (#5738)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-app)
2025-04-28 09:22:47 +05:30
Neeraj
2ce4e8e955 [auth] remove hex for LinkedIn icon. (#5727)
Closes #5722 
Fix LinkedIn icon rendering by removing unwanted hex code.

Before:


![image](https://github.com/user-attachments/assets/32bd8b2b-e92b-47fb-918e-c7a8fc0ae735)
2025-04-28 09:22:19 +05:30
Neeraj
df858338bc [mob] streaming hot fixes (#5724)
## Description

- [x] Don't show preview status in home as well as backup status screen
- [x] Only make streamables from local videos under 500mb and under 1
minute.

## Tests

- [x] Test general flow and display of processing text in home and
backup screen
- [x] Test cases for streaming point
2025-04-28 09:20:56 +05:30
Neeraj
43931b852f [auth] New translations (#5739)
New translations from
[Crowdin](https://crowdin.com/project/ente-authenticator-app)
2025-04-28 09:19:52 +05:30
Crowdin Bot
0db4332a02 New Crowdin translations by GitHub Action 2025-04-28 01:17:38 +00:00
Crowdin Bot
c3d121e4ac New Crowdin translations by GitHub Action 2025-04-28 01:05:09 +00:00
Prateek Sunal
b8476769d6 fix(streaming): issue in init check for video 2025-04-27 20:55:20 +05:30
Vishnu Mohandas
aeb3142d23 [docs] Self-hosting (#5728) 2025-04-26 19:45:56 +05:30
vishnukvmd
8bb5b9406d [docs] Update 2025-04-26 19:39:50 +05:30
Alvin Joy
da1e7788f9 remove hex 2025-04-26 18:37:13 +05:30
vishnukvmd
7098e93ae8 [docs] Refactor 2025-04-26 16:44:55 +05:30
Prateek Sunal
1a71513723 fix(file_util): remove async from _getLocalDiskFile function signature 2025-04-26 02:57:36 +05:30
Prateek Sunal
331675091a fix(preview_video_store): modify file check logic to skip files exceeding size and duration limits 2025-04-26 02:57:29 +05:30
Prateek Sunal
106338508d fix(files_db): add conditions for file size and duration 2025-04-26 02:11:46 +05:30
Prateek Sunal
500a9481cb fix(streaming): only upload local files 2025-04-26 00:52:17 +05:30
Prateek Sunal
e4771320b1 chore: update lock file 2025-04-25 23:45:35 +05:30
Prateek Sunal
39e0f34b2d fix: remove preview status from backup and home 2025-04-25 23:45:22 +05:30
Manav Rathi
9ce9fa2dbf Reducing threshold 2025-04-25 19:20:01 +05:30
Manav Rathi
6b8800f151 Implement node side 2025-04-25 18:47:00 +05:30
Manav Rathi
d95864be1c Rename for incoming increased scope 2025-04-25 18:36:17 +05:30
Manav Rathi
b01f6d9482 4 cases 2025-04-25 18:17:41 +05:30
Ashil
5bf3f01de6 Fix auth not building for iOS 18.4 (#5719)
## Description

Fix build failing on iOS 18.4 by [upgrading
sentry](https://github.com/getsentry/sentry-dart/issues/2771#issuecomment-2717968324)
2025-04-25 18:08:49 +05:30
Neeraj
4fcd938575 [mob] Enable gradual rollout for resumable upload (#5718)
## Description

## Tests
2025-04-25 17:46:31 +05:30
ashilkn
500cb9d0f2 Fix auth not building for iOS 18.4 2025-04-25 17:39:25 +05:30
Manav Rathi
34233875bd Split 2025-04-25 17:37:03 +05:30
Manav Rathi
8871902594 Split 2025-04-25 17:12:02 +05:30
Manav Rathi
912d52ea6b Cleanup 2025-04-25 16:04:52 +05:30
Neeraj Gupta
27f635dfaa [mob] Enable gradual rollout for resumable upload 2025-04-25 16:01:05 +05:30
Manav Rathi
7ff6785860 stream 2025-04-25 15:43:47 +05:30
Ashil
d6665b1dbf [mob][Auth] Release v4.3.5 (#5717) 2025-04-25 15:42:42 +05:30
Vishnu Mohandas
1cbc783bc6 [docs] Add Features page for Auth (#5716)
Added a Features page for Ente Auth to the docs, briefly describing all
the available key features. Also fixed a small typo on
`/photos/features/trash.md`
2025-04-25 15:34:37 +05:30
Manav Rathi
e6b446c95f Cont 2025-04-25 15:24:49 +05:30
Sven
480e8682f9 Merge branch 'ente-io:main' into main 2025-04-25 11:26:02 +02:00
Sven
bb997039c8 Add features page for Ente Auth 2025-04-25 11:24:54 +02:00
Manav Rathi
a2debd6746 log 2025-04-25 14:44:28 +05:30
Manav Rathi
f454221634 Upload 2025-04-25 14:44:28 +05:30
Manav Rathi
6614e4468d Web side 2025-04-25 14:44:28 +05:30
Manav Rathi
8c0cbc7343 Still doesn't work - ERR_H2_OR_QUIC_REQUIRED
Committing for posterity. I also realized that the retries will not work once
the stream has been read. So all this needs to be moved to the node side.
2025-04-25 14:44:28 +05:30
Manav Rathi
22f05f73a9 chain 2025-04-25 14:44:28 +05:30
Manav Rathi
d53d5090e0 Tweak 2025-04-25 14:44:28 +05:30
Manav Rathi
64afcc0c70 Dimensions 2025-04-25 14:44:28 +05:30
Manav Rathi
d904aab804 [desktop] Start next release train (#5715) 2025-04-25 14:04:21 +05:30
Manav Rathi
1d8aaa49e7 [desktop] Start next release train 2025-04-25 14:03:17 +05:30
Neeraj
39509813c6 [server] Support for self-recovery on account deletion (#5712)
## Description

## Tests
2025-04-25 13:39:49 +05:30
Manav Rathi
f362943ab6 photosd-v1.7.12 (#5714) 2025-04-25 13:36:13 +05:30
Manav Rathi
976eee005c photosd-v1.7.12 2025-04-25 13:33:48 +05:30
Neeraj Gupta
9b15ab2f2f Remove log 2025-04-25 12:12:26 +05:30
Neeraj Gupta
31f6671626 Gracefully handle bad or expired tokens 2025-04-25 12:11:43 +05:30
Neeraj Gupta
c32e4be8be copy change 2025-04-25 11:57:23 +05:30
Neeraj Gupta
6ae9003585 rename 2025-04-25 11:39:36 +05:30
Neeraj Gupta
851aed6a78 Add link in delete email to auto-recover account 2025-04-25 11:37:25 +05:30
Neeraj Gupta
7732f9eee9 Fix case 2025-04-25 10:03:03 +05:30
Manav Rathi
06099f00c6 [desktop] Video stream generation - WIP x/x (#5711) 2025-04-24 19:38:49 +05:30
Manav Rathi
8e0b0da68f hah! 2025-04-24 19:22:20 +05:30
Manav Rathi
55dbc3a8db Propgagate
The ! (definite assigment assertion) is needed to get tsc to stop emitting an
error about dimensions not being assigned.

Docs for it: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#definite-assignment-assertions
2025-04-24 19:17:17 +05:30
Manav Rathi
f6744d4b47 Full playlist 2025-04-24 18:57:13 +05:30
Manav Rathi
fbf626b578 Fix warning
"Cannot use both -hls_key_info_file and -hls_enc, ignoring -hls_enc"
25b0a8e295/libavformat/hlsenc.c (L1869)
2025-04-24 17:05:14 +05:30
Manav Rathi
9508695bba red 2025-04-24 16:42:06 +05:30
Manav Rathi
645014460b [desktop] Video stream generation - WIP Part x/x (#5710) 2025-04-24 15:27:51 +05:30
Manav Rathi
e32af8e0e5 Alternative dimension
Our currently bundled ffmpeg balks with
"Option allowed_extensions not found."
2025-04-24 15:19:12 +05:30
Manav Rathi
6e2f645905 Read playlist 2025-04-24 14:38:54 +05:30
Manav Rathi
5e091af787 vdim 2025-04-24 14:32:19 +05:30
Ashil
f9dbbb8cc9 [mob][photos] Video editor improvements (#5709)
## Description

- #### Better UX on exporting an edited video
If a video is large enough (even an 8s 4k video), the export process can
take a while. Previously, we were only showing a 'Saving edits...'
message in a dialog, which gave users no indication of how much time it
would take and some even thought the app was stuck. I’ve resolved this
by adding a linear progress indicator to show the progress.
    

https://github.com/user-attachments/assets/b078337f-0e29-4738-a8b6-f8f94474a4c8

- #### Fix video previewing in a flipped state upon opening video editor
(Bug exists only android).
2025-04-24 13:48:14 +05:30
Manav Rathi
1fc72383a3 turn of desat
In my test video (recorded from iPhone, viewing on macOS), this made a
substantial difference (the default desaturation was dulling out the test video
visually).
2025-04-24 13:44:36 +05:30
Manav Rathi
c040ae9dcc tonemap filterchain 1 2025-04-24 13:36:23 +05:30
ashilkn
f70148d652 Update documentation 2025-04-24 13:17:38 +05:30
ashilkn
60f94362d2 Animate linear progress indicator of LinearProgressDialog 2025-04-24 13:14:56 +05:30
ashilkn
a9bf825dde Do video rotation correction only on Android since the bug is absent on iOS 2025-04-24 13:14:42 +05:30
Manav Rathi
004525ddeb Outline
More Refs:
- https://www.canva.dev/blog/engineering/a-journey-through-colour-space-with-ffmpeg/
- https://jimmyhoke.net/wp/?p=412
2025-04-24 10:51:44 +05:30
mangesh
2ff03d7303 [server] don't send OTT if registration is disabled Fixes #5684 (#5695)
fixes #5684
2025-04-24 10:35:54 +05:30
Manav Rathi
fcaf46fcd1 Regex 2025-04-24 09:24:47 +05:30
ashilkn
d8c50ce3fa Update text style of LinearProgressDialog 2025-04-24 08:49:36 +05:30
ashilkn
15ed5e9d7b Show progress dialog when exporting edited video for better UX 2025-04-24 08:41:49 +05:30
Manav Rathi
ef6e4ebbcd pprobe 2025-04-24 08:33:30 +05:30
ashilkn
60b3e0977e Add docs 2025-04-24 07:20:15 +05:30
mngshm
f183c56c20 minor reorganizations of checks 2025-04-24 01:45:11 +05:30
Manav Rathi
01e9d79a22 [desktop] Streaming video generation - WIP Part x/x (#5705) 2025-04-23 19:57:00 +05:30
Manav Rathi
ff22c69ca6 trac recommendations 2025-04-23 19:53:58 +05:30
ashilkn
016b031bf1 Fix flipped version of video being shown in video editor 2025-04-23 17:09:15 +05:30
Manav Rathi
c7a2001405 scale/fps 2025-04-23 15:36:41 +05:30
Manav Rathi
3871a538ab Start sculpting 2025-04-23 15:26:35 +05:30
ashilkn
b52ac3ff5d Log when video editor page is initialized and built 2025-04-23 14:55:07 +05:30
Manav Rathi
be33ee5a1c [web] New translations (#5703)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-04-23 13:51:16 +05:30
Crowdin Bot
8df7c1b9a4 New Crowdin translations by GitHub Action 2025-04-23 08:19:06 +00:00
Manav Rathi
e8997c16a6 [web] Use top level as fallback for leaf files to avoid confusing error (#5702)
Also some visual fixes.
2025-04-23 13:48:20 +05:30
Manav Rathi
141d761ecb Visual fixes 2025-04-23 13:44:34 +05:30
Manav Rathi
fe5feb0394 Use top level as fallback for leaf files to avoid confusing error 2025-04-23 13:26:40 +05:30
mangesh
7ec0c6dbdb [docs] separate all sections from getting-started (revamp part x/x) (#5692) 2025-04-23 09:14:21 +05:30
Ashil
be84e1856d [mob][photos] Update dark mode app icon following iOS design docs to make it look consistent with other iOS app icons (#5701)
## Description

#### Before
<img width="334" alt="Screenshot 2025-04-23 at 7 58 31 AM"
src="https://github.com/user-attachments/assets/482779dc-7a37-4294-8d6f-751df62da873"
/>


#### After
<img width="334" alt="Screenshot 2025-04-23 at 8 03 06 AM"
src="https://github.com/user-attachments/assets/99a158a9-53a7-4475-ac12-603abfaf9d03"
/>
2025-04-23 09:10:16 +05:30
ashilkn
9808ea5d8e Reupload dark mode app icon following apple iOS docs to make it look consisent with other iOS app icons 2025-04-23 08:05:06 +05:30
mngshm
2577b9c93a remove redundant code 2025-04-22 21:55:50 +05:30
Manav Rathi
0981ba5989 [web] Add UX feedback when copying links (#5700) 2025-04-22 20:15:48 +05:30
Manav Rathi
c2959d06b0 elsewhere 2025-04-22 20:09:18 +05:30
Manav Rathi
eed42c9df5 elsewhere 2025-04-22 20:06:50 +05:30
Manav Rathi
ec30ace822 copy feedback 2025-04-22 20:02:05 +05:30
Manav Rathi
7fa9e2a627 [desktop] Handle dock icon for macOS fullscreen (#5698) 2025-04-22 19:40:18 +05:30
Manav Rathi
ac0c96ae29 macOS fs 2025-04-22 19:37:12 +05:30
Manav Rathi
9900c346b5 [web] Use correct translation key (#5697) 2025-04-22 19:27:17 +05:30
Manav Rathi
2108461450 Fix tr key 2025-04-22 19:20:14 +05:30
Manav Rathi
270dd02e20 [desktop] Debounce cluster refresh during uploads (#5696) 2025-04-22 19:17:09 +05:30
mngshm
e6deea1533 separate ott generation purpose checks 2025-04-22 19:10:42 +05:30
Manav Rathi
d303a40cc7 Use promise variant 2025-04-22 18:49:53 +05:30
Manav Rathi
08d435b920 Debounce cluster refresh during uploads 2025-04-22 18:08:40 +05:30
mngshm
efa4c46f6e fixes #5684: don't send OTT if disable registration == true 2025-04-22 16:43:59 +05:30
mangesh
3cd5127488 [server] trivial but better error messages (#5693) 2025-04-22 14:20:44 +05:30
Ashil
e77a8cdf9b [mob][photos] Fix wakelock bugs (#5691)
## Description

#### New `EnteWakelockService` singleton that wraps wakelock_plus APIs
- Persist enable/disable (across sessions) state in `SharedPreferences` 
- Re apply wakelock on app init based on stored state
- Makes sure the wakelock setting across sessions if set is respected
when wakelock is updated for other non-across-session purposes.


### Bugs fixed:
- App not staying awake after disabling auto lock in back up settings
when killed and reopened.
- App not staying awake when video is playing (only on
native_video_player)

## Tests

Tested all cases.
2025-04-22 14:02:42 +05:30
mngshm
77e4506d2a trivial: better error messages 2025-04-22 13:55:19 +05:30
mngshm
c170384607 Separate everything 2025-04-22 13:14:14 +05:30
ashilkn
ce7a564cbd Refactor 2025-04-22 12:56:48 +05:30
ashilkn
0d6f71c193 Update documentation 2025-04-22 12:51:24 +05:30
ashilkn
ab04bd66a5 Fix screen timing out and fading when viewing video played in native video player 2025-04-22 12:31:27 +05:30
ashilkn
9f3c4c8542 Handle edge case where on disposing media_kit player, wakelock state if enabled across app sessions is not respected 2025-04-22 11:59:19 +05:30
ashilkn
879f16a2dd Add wakelock service wrapper for persistent wakelock state across sessions 2025-04-22 11:53:48 +05:30
Manav Rathi
136f8d17cc [web] Tweak nav behaviour (#5690) 2025-04-22 11:24:54 +05:30
Manav Rathi
4539acd239 Tweak nav behaviour 2025-04-22 11:20:55 +05:30
Manav Rathi
4d37e415e7 [server] increase max pg connection 30 -> 45 (#5687)
## Description

## Tests
2025-04-22 10:10:11 +05:30
Neeraj
361283f072 [server] Add retry while putting metadata obj in s3 (#5688)
## Description

## Tests
2025-04-22 10:09:43 +05:30
Neeraj Gupta
3b4f9ecc22 [server] Add retry while putting metadata obj in s3 2025-04-22 09:52:21 +05:30
Neeraj Gupta
d1289bb467 [server] increase max pg connection 30 -> 45 2025-04-22 09:43:53 +05:30
Manav Rathi
b81098f88d [desktop] Routine dependency updates (#5683) 2025-04-21 19:17:08 +05:30
Manav Rathi
432883685d [web] New translations (#5682)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-04-21 19:16:57 +05:30
Manav Rathi
55094b7f2a [desktop] Routine dependency updates 2025-04-21 19:15:16 +05:30
Crowdin Bot
5c9d6610c1 New Crowdin translations by GitHub Action 2025-04-21 13:42:12 +00:00
Manav Rathi
da1ac0696b [web] Tweak translation (#5681)
This jumps around between 1 and 2 lines when there are many files (and
in non-English languages with longer strings). Also the message keeps
moving as the counts change. So I'll omit the message, only retain the
counts, since the
context should make sense from the title.
2025-04-21 19:11:37 +05:30
Manav Rathi
c61667290b tr
this jumps around between 1 and 2 lines when there are many files (and in
non-English languages with longer strings). Also the message keeps moving as the
counts change. So I'll omit the message, only retain the counts, since the
context should make sense from the title
2025-04-21 19:06:08 +05:30
Ashil
61e306e1b3 [mob][photos] Log whether resource intensive features are enabled (#5678) 2025-04-21 17:35:46 +05:30
Manav Rathi
da565172fc [web] The last of the capital keys (#5680) 2025-04-21 17:13:14 +05:30
Manav Rathi
c686c75141 tr 2025-04-21 17:10:07 +05:30
Manav Rathi
d8617cb782 [web] New translations (#5679)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-04-21 17:04:42 +05:30
Crowdin Bot
7a12f6edde New Crowdin translations by GitHub Action 2025-04-21 11:32:23 +00:00
Manav Rathi
f0c489587f [web] Indicate skipped (#5677) 2025-04-21 17:01:40 +05:30
ashilkn
b9a81c3693 Log whether resource intensive features are enabled 2025-04-21 17:01:39 +05:30
Manav Rathi
f143add013 Split 2025-04-21 16:50:52 +05:30
Manav Rathi
7d71a0c9a4 Unprefix 2025-04-21 16:31:53 +05:30
Manav Rathi
fb5bd0bdec prefix ellipsised 2025-04-21 16:31:06 +05:30
Manav Rathi
adbaba8a44 Retain what we can, add new 2025-04-21 16:26:40 +05:30
mangesh
01d0915004 [docs] minor change in index.md (#5671) 2025-04-21 16:20:28 +05:30
Manav Rathi
332e759e6a New 2025-04-21 15:59:38 +05:30
Manav Rathi
a1557e8d27 R 2025-04-21 15:46:05 +05:30
Manav Rathi
8d667333e3 R 2025-04-21 15:39:10 +05:30
Manav Rathi
2843cc36d9 sp 2025-04-21 15:36:58 +05:30
Manav Rathi
1019047eb2 R 2025-04-21 15:35:22 +05:30
Manav Rathi
42a085221c Case 2025-04-21 15:31:14 +05:30
Manav Rathi
e08b228d05 R 2025-04-21 15:28:56 +05:30
Manav Rathi
3eee5a5fdc reorg 2025-04-21 15:27:30 +05:30
Manav Rathi
97c03a4985 [web] Improved thumbnail loading experience (#5675) 2025-04-21 15:04:30 +05:30
Manav Rathi
f3974cdb8a [web] Improved thumbnail loading experience 2025-04-21 14:53:34 +05:30
Ashil
dc402b7bca [mob][photos] Remove setting audio session category (iOS) (#5673)
## Description

Audio session category had to be explicitly set because an older version
of [native_video_player](https://pub.dev/packages/native_video_player)
had an issue.
The version of the package that we currently use includes a [fix for
this](https://github.com/albemala/native_video_player/issues/22#issuecomment-2569092092).

## Tests

Confirmed that video playback on iOS simulator has audio on silent and
ring mode.
2025-04-21 14:39:47 +05:30
Ashil
5082343708 [mob][photos] Fix build failing due to translation error (#5674) 2025-04-21 14:36:25 +05:30
ashilkn
4e34ecd580 fix build failing dur to translation error 2025-04-21 14:25:53 +05:30
ashilkn
fb897d237d Auto generated changes 2025-04-21 14:24:25 +05:30
ashilkn
b6a1a77bf7 Revert "[mob][photos] Fix: audio not playing on iOS when in silent mode"
This reverts commit dc6fde9f77.
2025-04-21 14:09:43 +05:30
Manav Rathi
168ef20e0f [web] Enable new video player for all (#5672)
+ Enable arabic
2025-04-21 14:02:16 +05:30
Manav Rathi
d880255fc8 Enable ar-SA 2025-04-21 13:53:15 +05:30
Manav Rathi
1b1c33977d Enable new player for all 2025-04-21 13:47:45 +05:30
mngshm
07f89bb1d6 rem 2025-04-21 13:43:20 +05:30
Neeraj
47b0d51f22 [auth] Add custom icon for fortrabbit (#5666)
## Description

This MR adds an SVG to be used as custom icon for
[fortrabbit](https://www.fortrabbit.com/).

The icon was taken from the official [fortrabbit logo and corporate
identity repository](https://github.com/fortrabbit/art), and optimized
using [SVGOMG](https://jakearchibald.github.io/svgomg/).
2025-04-21 11:12:08 +05:30
Neeraj
5e489843fa [mobile] New translations (#5669)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-app)
2025-04-21 10:44:56 +05:30
Neeraj
5dea3fd8b0 [docs] self-hosting docs clean up & revamp (part x/x) (#5647) 2025-04-21 10:43:57 +05:30
Neeraj
8dd9dc16ad [auth] New translations (#5670)
New translations from
[Crowdin](https://crowdin.com/project/ente-authenticator-app)
2025-04-21 10:43:36 +05:30
Manav Rathi
d31db6d678 [web] New translations (#5668)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-04-21 09:18:06 +05:30
Crowdin Bot
a928e87747 New Crowdin translations by GitHub Action 2025-04-21 01:17:37 +00:00
Crowdin Bot
064092a3e6 New Crowdin translations by GitHub Action 2025-04-21 01:05:13 +00:00
Crowdin Bot
a76561ebe9 New Crowdin translations by GitHub Action 2025-04-21 00:39:52 +00:00
Ben Peachey
6321f50e6c Add custom icon for fortrabbit. 2025-04-20 17:35:27 +02:00
mngshm
93dd0c4943 reorganize(4): might be bad to let beginners read about S3 straight after getting started 2025-04-18 12:18:12 +05:30
mngshm
83fdda46a3 reorganize (3): separate community contributed guides 2025-04-18 11:53:49 +05:30
Manav Rathi
23943aae89 [desktop] Generate streamable video variant - WIP Part x/x (#5649) 2025-04-17 20:13:33 +05:30
Manav Rathi
f01d0ff274 Update comments 2025-04-17 20:05:16 +05:30
mngshm
d158db9499 Tone (2) and re-organize (x) 2025-04-17 20:04:49 +05:30
mngshm
9186b272b6 Tone up 2025-04-17 19:48:42 +05:30
mngshm
60f1172033 separate bucket-cors troubleshooting guide
sidebar
2025-04-17 19:46:41 +05:30
Manav Rathi
5843aee3d6 Upload 2025-04-17 19:45:36 +05:30
mngshm
f6b186a167 reorganize sidebar & deprecate old community contributed guide 2025-04-17 19:30:48 +05:30
mngshm
aa9096134d "with caddy" and update endpoint.png 2025-04-17 19:29:44 +05:30
Manav Rathi
1370f0523c Preview URL 2025-04-17 19:14:30 +05:30
mngshm
c1051b8a10 Forgot the examples earlier 💀 2025-04-17 18:52:38 +05:30
Manav Rathi
b4d532bb41 PUT video-data 2025-04-17 18:42:18 +05:30
Manav Rathi
4327fbb9e5 Remove output.ts.tmp 2025-04-17 17:56:14 +05:30
mngshm
636d2a8069 merge /system-requirements into /getting-started 2025-04-17 17:55:42 +05:30
Manav Rathi
21e0edcb85 output.ts 2025-04-17 17:49:47 +05:30
Manav Rathi
8b11989e0f Provide the key
[main] [hls @ 0x14e607410] Cannot generate a strong random key
2025-04-17 17:37:23 +05:30
mngshm
5bc6505cb8 getting-started, reverse-proxy, writing museum.yaml 2025-04-17 17:32:07 +05:30
mngshm
a0184013f8 make dead link checker happy 2025-04-17 17:02:34 +05:30
Manav Rathi
d0b5f84854 replace 2025-04-17 16:56:48 +05:30
mngshm
4bb2aea5d2 clean stuff from the merge 2025-04-17 16:54:27 +05:30
Manav Rathi
298faf8e0a Sketch 2025-04-17 16:41:58 +05:30
Neeraj
e816504576 [mob] Refactor & remove unused methods (#5648)
## Description

## Tests
2025-04-17 16:16:45 +05:30
Neeraj Gupta
1506009a55 doc 2025-04-17 16:12:45 +05:30
Neeraj Gupta
8930a0ddbc Simplify 2025-04-17 15:59:09 +05:30
mangesh
8611d5644d Merge branch 'main' into sh-revamp 2025-04-17 15:48:28 +05:30
Neeraj Gupta
5df815da58 Remove unused method 2025-04-17 15:45:02 +05:30
Neeraj Gupta
59e2906bdc Remove unused method 2025-04-17 15:41:26 +05:30
Neeraj Gupta
79e8fffc7a Simplify 2025-04-17 15:40:46 +05:30
Bl4ckspell
bbd81a6385 [auth] fix luma icon (#5640)
## Description
Because the icon (added in #5276) is black, it was not visible when the
app was in darkmode.
I added `mix-blend-mode: difference` to the svg source.
Now in darkmode, the icon turns white:

![Screenshot From 2025-04-16
22-22-25](https://github.com/user-attachments/assets/45e5b156-6645-4e8c-ae67-133ad19231fc)
![Screenshot From 2025-04-16
22-22-32](https://github.com/user-attachments/assets/074e6a15-c4a3-4d36-905f-efef078ec6ac)
2025-04-17 15:21:05 +05:30
Bl4ckspell
1ba31e9442 [auth] fix coinspot icon (#5641)
## Description
some elements of the coinspot icon added in #5186 were displayed as
black.
i fixed the source code using the [Oh My SVG
App](https://flathub.org/apps/re.sonny.OhMySVG)

|  | before | fixed |
|-------|-------|------|
| light | ![Screenshot From 2025-04-16
22-51-12](https://github.com/user-attachments/assets/45a8ebd0-278c-4783-86bb-1680d7ceaa9b)
| ![Screenshot From 2025-04-16
22-50-04](https://github.com/user-attachments/assets/02bafd51-55b9-4885-95d7-3eee3d3d21f0)
|
| dark | ![Screenshot From 2025-04-16
22-51-21](https://github.com/user-attachments/assets/336e50b4-2982-44f2-b465-7d91182a4d7a)
| ![Screenshot From 2025-04-16
22-50-12](https://github.com/user-attachments/assets/ea11c18b-3aca-4041-b9c7-5016d5de69db)
|
2025-04-17 15:20:45 +05:30
Bl4ckspell
7cf8ccdc7e [auth] fix bingx icon (#5637)
## Description
the bingx icon added in #5186 was displayed as black.
i fixed the source using [this
code](https://github.com/Bl4ckspell7/svg-css-to-inline-styling)

|  | old | fixed |
|-------|-------|------|
| light |![Screenshot From 2025-04-16
14-14-13](https://github.com/user-attachments/assets/ce0d1226-c82a-4e1b-a0d0-4a34839e8dce)|![Screenshot
From 2025-04-16
14-19-36](https://github.com/user-attachments/assets/c8955cbd-7917-49dc-9c1f-24764da37765)|
| dark |![Screenshot From 2025-04-16
14-07-42](https://github.com/user-attachments/assets/dfeec407-6a32-40c4-a57f-fbf728406238)|![Screenshot
From 2025-04-16
14-09-55](https://github.com/user-attachments/assets/3742dd50-deb2-474d-920f-f34d707983d6)|
2025-04-17 15:20:10 +05:30
Bl4ckspell
ae6e2b1349 [auth] Fix android monochrome app icon (#5484)
## Description
Removes the shadow of the app icon on the homescreen which is currently
present. Closes #3840. It is especially visible as a "glowing" in dark
mode.


| Mode       | Current Icon | Fix Icon |
|-----------|-------------|----------|
| **Light**
|![light-old](https://github.com/user-attachments/assets/f2bc791c-6ce0-4fd5-a810-1962269c5bf1)|![light-fix](https://github.com/user-attachments/assets/5c3b1280-1f19-40fe-a011-e52a88786cd4)|
| **Dark**
|![dark-old](https://github.com/user-attachments/assets/b079634d-b436-4f9c-b42b-318ce97a3654)|![dark-fix](https://github.com/user-attachments/assets/cebc2b8b-e40a-4280-992f-4a28e742d639)|
2025-04-17 15:19:54 +05:30
Bl4ckspell
a65493192f [auth] specify flutter version (#5636)
## Description
Allows to explicitly set the flutter version you want to use, by
utilizing `fvm`.

`dart pub global activate fvm`

`fvm install 3.24.3`
`fvm use 3.24.3`

`fvm flutter ...`
2025-04-17 15:17:42 +05:30
Bl4ckspell
cf538a713b [auth] add fanatical icon (#5466)
## Description

add icon for fanatical


![fanatical](https://github.com/user-attachments/assets/9d2b95eb-6da3-4a01-8e0e-7e06db577bb7)
2025-04-17 15:17:18 +05:30
Manav Rathi
3440bbd772 Route 2025-04-17 15:13:21 +05:30
Manav Rathi
657a57f46a Res 2025-04-17 15:04:56 +05:30
Manav Rathi
f6db2daaee array 2025-04-17 15:03:22 +05:30
mngshm
2d8ffae74b un-index web-app.md, surface new doc /guides/from-source 2025-04-17 14:11:54 +05:30
Manav Rathi
1efaefbf9c nn fin 2025-04-17 14:05:18 +05:30
Manav Rathi
29f5693078 nn 2025-04-17 14:01:56 +05:30
mngshm
94bd9f4dd6 note unnote 2025-04-17 14:00:46 +05:30
mngshm
ce9c08c607 removing unnecessary pm2 nonsense 2025-04-17 14:00:46 +05:30
ashilkn
a35d16e20d Merge branch 'main' into auth_release_v4.3.4 2025-04-17 13:06:49 +05:30
ashilkn
77a6508a0b Bump up auth build number and version 2025-04-17 13:05:25 +05:30
Manav Rathi
347140c14c generisize 2025-04-17 12:49:33 +05:30
Manav Rathi
97bc768092 Sketch 2025-04-17 12:09:41 +05:30
Manav Rathi
cdb81c621d Sketch 2025-04-17 11:26:11 +05:30
Manav Rathi
bd7fec03d3 Revert "cond type take 1" - It just doesn't seem to work without casts
...and we don't even need in the final goal (this is desktop only).

This reverts commit 0c904d37c8.
2025-04-17 10:58:11 +05:30
Manav Rathi
0c904d37c8 cond type take 1 2025-04-17 10:49:34 +05:30
Manav Rathi
dc9f665029 [web] Omit spurious ffmpeg logs (#5646)
We don't need to do it for the desktop code since there the deletion
function checks if the file exists first.
2025-04-17 10:28:52 +05:30
Manav Rathi
4b0536a5b2 Fix 2025-04-17 10:18:15 +05:30
Manav Rathi
c2efd198a6 Revert "omitlog" - there is already an if exists check
This reverts commit a2a74e2166.
2025-04-17 10:13:18 +05:30
Manav Rathi
a2a74e2166 omitlog
ref: https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback

> in case of any error (including any error resulting in an exit code other than
  0), a rejected promise is returned...
2025-04-17 09:59:33 +05:30
Manav Rathi
b0f8258a90 Omit spurious logs 2025-04-17 09:39:57 +05:30
Manav Rathi
c75937759f [web] New translations (#5645)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-04-17 09:39:35 +05:30
Crowdin Bot
466f31bbb9 New Crowdin translations by GitHub Action 2025-04-17 04:00:53 +00:00
Manav Rathi
09f6922ccf [web] Move video streaming strings to translations (#5644) 2025-04-17 09:30:11 +05:30
Manav Rathi
eacc364498 tr 2025-04-17 09:24:39 +05:30
Manav Rathi
3c3ce516f5 [docs] Add example line to OTT faq (#5643) 2025-04-17 08:13:25 +05:30
Manav Rathi
7fe070b5ae vc 2025-04-17 08:11:36 +05:30
Prateek Sunal
b1fb5d548b Merge branch 'main' into pending-sync-info 2025-04-17 03:43:36 +05:30
Manav Rathi
13bcfe61ed [web] Enable streaming video playback for public albums app (#5633) 2025-04-16 14:20:48 +05:30
Manav Rathi
4d3926c150 Enable for albums app 2025-04-16 14:14:10 +05:30
Manav Rathi
7d92b5923b Clear transient 2025-04-16 14:07:03 +05:30
Manav Rathi
864f0317fa Outline 2025-04-16 13:05:00 +05:30
Manav Rathi
a928676280 Outline 2025-04-16 12:35:08 +05:30
Manav Rathi
2073134e7a [server] Copy only libsodium lib to Docker image (#5632)
Suggested twice:
- https://github.com/ente-io/ente/pull/3952
- https://github.com/ente-io/ente/issues/5631

Fixes: https://github.com/ente-io/ente/issues/5631

**Tested by**

Theory: On a clean alpine container, ran `apk add libsodium` then
visually glanced using
`docker container diff` that the .so is the only relevant file.

Practice: Recreated the local Docker compose using this updated file and
verified that server runs and can upload files etc.
2025-04-16 07:36:16 +05:30
Manav Rathi
5a411d1d4d [server] Copy only libsodium lib to Docker image
Suggested twice:
- https://github.com/ente-io/ente/pull/3952
- https://github.com/ente-io/ente/issues/5631

Fixes: https://github.com/ente-io/ente/issues/5631

Tested:

Theory: On a clean alpine container, ran `apk add libsodium` then visually glanced using
`docker container diff` that the .so is the only relevant file.

Practice: Recreated the local Docker compose using this updated file and
verified that server runs and can upload files etc.
2025-04-16 06:36:06 +05:30
Manav Rathi
5f1d767b9c [meta] Ask for last known version (#5629) 2025-04-15 21:00:42 +05:30
Manav Rathi
1ecff890f0 [meta] Ask for last known version 2025-04-15 20:49:18 +05:30
Manav Rathi
38aae47445 [desktop] Show person name in the file info panel (#5628) 2025-04-15 20:10:45 +05:30
Manav Rathi
e4cd1434df Fix a stale effect 2025-04-15 20:02:05 +05:30
Manav Rathi
f907beab62 [desktop] Show person name in the file info panel 2025-04-15 19:33:46 +05:30
Neeraj
f2e336c35a [mob] Bump version 1.0.4 (#5626)
## Description

## Tests
2025-04-15 16:07:18 +05:30
Neeraj Gupta
a8b2423d77 Bump version 1.0.4 2025-04-15 16:06:48 +05:30
Neeraj
f8f2e6f7c7 [server] Preview public albums (#5601)
## Description

## Tests
[ ] Local testing pending
2025-04-15 15:11:48 +05:30
ashilkn
cd3b9defcd Update build number for Auth app 2025-04-15 14:55:31 +05:30
Manav Rathi
e103d7490e [web] Public album streaming (#5625)
Behind a ff flag, meant for testing
https://github.com/ente-io/ente/pull/5601
2025-04-15 14:24:27 +05:30
ashilkn
aa9e8abf0e Bump up auth version to 4.3.4 2025-04-15 14:08:29 +05:30
Neeraj Gupta
f068d6ef24 Fix panic 2025-04-15 14:02:33 +05:30
Manav Rathi
3ec3f9f2e1 Forward 2025-04-15 13:33:53 +05:30
Manav Rathi
25c472e584 Support for public albums 2025-04-15 13:29:08 +05:30
Neeraj
7b69c86cba [cli] Update documentation for change of export directory (#5623)
In my case to change export directory was necessary to add "--app"
2025-04-15 11:43:26 +05:30
Prateek Sunal
1d197694ef [mob] switch to custom ffmpeg kit (#5586)
## Description

Switch to custom ffmpeg kit.

Future actionables on this:
- Creating minimal ffmpeg configuration and using it
- Replace and use .aar for android plugin, currently it is fine and
using the published maven package

## Tests
2025-04-15 00:01:47 +05:30
horfnt
4c9a37f3c8 Update README.md
In my case to change export directory was necessary to add "--app"
2025-04-14 21:29:01 +03:00
Prateek Sunal
59bc454f5c Merge branch 'main' into switch-ffmpeg-kit 2025-04-14 22:52:17 +05:30
Neeraj
dd9f3f993d [Auth] Fix import from aegis (#5618)
## Description
Fixes https://github.com/ente-io/ente/issues/5438
https://github.com/ente-io/ente/issues/5324
https://github.com/ente-io/ente/issues/5188
https://github.com/ente-io/ente/issues/5064
## Tests
Tested locally
2025-04-14 16:54:59 +05:30
Neeraj
f5b20cf8d0 [auth] Add advanced options to edit period & TOTP (#5520)
**Description**
1. Add custom time period (between 10 to 60 seconds)
2. Select type of OTP from TOTP, STEAM, HOTP

**Desktop** 
<img
src="https://github.com/user-attachments/assets/494ca78c-0cd9-4c85-8ffb-c00a5e909e87"
alt="Desktop" width="300">

**Mobile** 
<img
src="https://github.com/user-attachments/assets/dc9a289e-4db5-481c-b590-2882be09f99a"
alt="Mobile" width="300">
2025-04-14 16:51:01 +05:30
Neeraj Gupta
2f9d664b05 [Auth] Fix import from aegis 2025-04-14 16:50:34 +05:30
Neeraj Gupta
2bfb52168e Update label 2025-04-14 16:41:39 +05:30
Ashil
c4fe18bbc1 [mob][auth] Fix lock screen appearing on reinstall (iOS/macOS) if previously installed instance had lock screen enabled (#5617) 2025-04-14 16:18:51 +05:30
ashilkn
d3a47eedda Fix issue where lock screen appears on installing the Auth app, if it was enabled on a previously installed instance of the app (iOS & macOS only) 2025-04-14 15:34:28 +05:30
laurenspriem
6c412e5803 Fix not person bug 2025-04-14 14:51:01 +05:30
ashilkn
28717ce2f2 Refactor 2025-04-14 14:13:00 +05:30
laurenspriem
8113a9aa97 Simplify memories update lock 2025-04-14 14:02:54 +05:30
Laurens Priem
082d15b41b [mob][photos] Advanced option to disable curated memories (#5614)
## Description

Advanced option to disable curated memories

## Tests

Tested in debug mode on my pixel phone.
2025-04-14 13:40:23 +05:30
Prateek Sunal
a582f40fa5 [mob] fix build (#5604)
## Description

This PR fixes the build on main branch for photos mobile.

## Tests
2025-04-14 13:40:09 +05:30
laurenspriem
c706904263 Extract string 2025-04-14 12:26:09 +05:30
laurenspriem
8a73b19a3e Advanced option to disable curated memories 2025-04-14 12:24:51 +05:30
Daniel Friesen
dd53cd5f47 [auth] Add Postmark logo (#5611)
## Description
Adds a logo for Postmark (https://postmarkapp.com/).

Postmarkapp doesn't have any official branding source files or use SVGs,
so Vector logo is sourced from here:
https://www.vectorlogo.zone/logos/postmarkapp/
![Postmarkapp vector from VectorLogo
Zone](https://www.vectorlogo.zone/logos/postmarkapp/postmarkapp-icon.svg)

I went with this rather than the ones on sites like
https://brandfetch.com/postmarkapp.com because the white stamp border
looks the closest to the logo that Postmark uses in their official
Zapier integration.
https://zapier.com/apps/postmark/integrations

![Postmarkapp Zapier
Logo](https://zapier-images.imgix.net/storage/services/e1cd4dba89396528988daf12ba63d35d.png?auto=format&fit=crop&q=98&w=32&h=32&dpr=3&bg=black)
2025-04-14 10:40:15 +05:30
Alex K
368b0c946a [docs] Update Authy import docs to mention Authy-iOS-MiTM (#5445)
## Description
This pull request adds mention of the Authy-iOS-MiTM method to Ente's
documentation on migrating from Authy. Currently, the only working
method to import Authy tokens into Ente is to use a rooted Android
device, which is not ideal due to most people not having rooted Android
devices. The Authy-iOS-MiTM method (that I made) only requires an iOS
device with Authy and a computer with Python and mitmproxy, making it
significantly more accessible to people looking to migrate their Authy
tokens. By mentioning my method in Ente's Authy import docs, it would
help more people discover it and would hopefully make some people's
lives easier since they wouldn't have to manually re-register 2FA on
every website. Let me know if you have any questions.

## Tests
N/A, this pull request does not modify any code
2025-04-14 10:07:02 +05:30
github-actions[bot]
6ead2ab843 [auth] New translations (#5613)
New translations from
[Crowdin](https://crowdin.com/project/ente-authenticator-app)

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-04-14 10:06:26 +05:30
github-actions[bot]
eb3ec77bb6 [mobile] New translations (#5612)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-app)

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-04-14 10:06:03 +05:30
Vishnu Mohandas
037a699790 [docs] Update export.md (#5605) 2025-04-13 07:19:43 +05:30
Vishnu Mohandas
678e97e937 [docs] Update export.md 2025-04-13 07:18:43 +05:30
Prateek Sunal
6f02a048b6 fix: rename package 2025-04-12 22:23:14 +05:30
Prateek Sunal
e1f0605345 fix: app build 2025-04-12 22:20:09 +05:30
Prateek Sunal
3cab14a1eb chore: update SDK versions and dependencies 2025-04-12 20:15:44 +05:30
github-actions[bot]
1f090642f2 [auth] New translations (#5492)
New translations from
[Crowdin](https://crowdin.com/project/ente-authenticator-app)

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-04-12 15:34:26 +05:30
Neeraj Gupta
51235bf81b Add support for accessing preview url for public collections 2025-04-12 15:25:04 +05:30
Neeraj Gupta
4bd31aeea8 Refactor 2025-04-12 14:55:48 +05:30
Neeraj Gupta
f2736c43c1 Refactor 2025-04-12 14:37:33 +05:30
Prateek Sunal
145ad5d309 [mob] fix: only cache at max 50 files for memory widget (#5594)
## Description

Previously we were caching all the memories without a working limit,
this PR fixes that.

## Tests
2025-04-12 14:13:10 +05:30
Neeraj Gupta
c6b4cba8b4 [server] Auto recovery post deletion 1/x 2025-04-12 13:47:46 +05:30
vaguerant
70daffd23e [auth] Add Mbin custom icon (#5530)
## Description
Add a custom icon for the [Mbin](https://joinmbin.org/) fediverse
software. SVG sourced from the linked page and modified to remove
background. Additional `altNames` for some popular or important Mbin
instances: `kbin` (several instances), `thebrainbin` (popular instance)
and `gehirneimer` (Mbin co-developer bentigorlich's instance).

## Tests
Untested
2025-04-12 13:33:07 +05:30
Neeraj
bd4f1071e5 [mobile] New translations (#5491)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-app)
2025-04-12 13:22:24 +05:30
Neeraj
8abd38c57a [mob] ICU syntax fix (#5518)
- Replaces `zero` with `=0` to avoid syntax errors.
- Replaces `one` with `=1` in the context of a single item for better
compatibility with non-English languages.
- Fixes grammar.
2025-04-12 13:22:13 +05:30
Neeraj
098832ccc9 [mob] Add support for pt_PT (#5598)
## Description

## Tests
2025-04-12 13:17:26 +05:30
Neeraj Gupta
3b3e670c50 [mob] Add support for pt_PT 2025-04-12 13:11:22 +05:30
Crowdin Bot
25b39be91c New Crowdin translations by GitHub Action 2025-04-12 07:37:09 +00:00
zDqrK
f67b47183f [Auth] Added Custom Icons for RedotPay & Cwallet (#5469)
## Description
Add RedotPay SVG Icon & Data Entry 
Add Cwallet SVG Icon & Data Entry 

## Tests
None Yet
2025-04-12 12:56:53 +05:30
Prateek Sunal
18a951ccf3 fix: remove the redundant take 50 2025-04-12 02:16:30 +05:30
Prateek Sunal
ca5a2c8fa2 fix: break if 50 files are present for memory set already 2025-04-12 02:14:51 +05:30
Manav Rathi
cfe58aa248 [web] HLS gen - Part x/x (#5593) 2025-04-11 21:02:38 +05:30
Manav Rathi
4d9a1c6389 Revert "wip ocr"
This reverts commit cf5d64554a.
2025-04-11 20:57:32 +05:30
Manav Rathi
cf5d64554a wip ocr
Noticed the ocr filter in `ffmpeg -filters`. It works on CLI! trying out using wasm version.
Incantation from: https://ffmpeg-user.ffmpeg.narkive.com/wfgWXwHf/how-to-use-ocr-filter

This doesn't work because the ffmpeg wasm we have isn't complied with the ocr
filter. Still committing this experiment to git history for potential future
reference (will revert next).
2025-04-11 20:44:25 +05:30
Manav Rathi
5b9752544a Step 2025-04-11 19:02:40 +05:30
Manav Rathi
1496e9fd5a Add trace command 2025-04-11 17:23:28 +05:30
Manav Rathi
1fb3779310 Handle error 2025-04-11 17:18:28 +05:30
Manav Rathi
2d8d137029 Scaffold 2025-04-11 15:07:50 +05:30
Ashil
343108d470 [mob][photos] Use queue for more efficient fetching of local thumbnails (#5591)
## Description

Use a task queue to manage local thumbnail requests with cancellation,
priority and timeout functionality.
This significantly improves the browsing experience of galleries with a
large number of local thumbnails. Previously, scrolling down deep into a
device folder would cause the thumbnails to take a long time to load.
Now, the loading speed has improved considerably.

A `maxQueueSize` of 200 for `smallLocalThumbnailQueue` should be
appropriate, as the maximum number of mounted `Thumbnailwidget`s is 186
when using a gallery grid size of 6 on a decently sized phone screen
(the screen length is the relevant factor here). With a grid size of 6,
the maximum number of mounted ThumbnailWidgets should be around 186 ± 12
for most phone screens.

Note: Thumbnails for HEIC images on android still take some time to
load. There is improvement, but not enough for seamless UX.

## Tests

Manually tested gallery scroll performance checks and if thumbnails load
as expected.
2025-04-11 13:55:37 +05:30
Manav Rathi
7bfc5cb08d Expand 2025-04-11 13:54:54 +05:30
Manav Rathi
ae0a8028d1 [web] Add support for iOS date format (#5592)
Tested on the sample provided by the customer.
2025-04-11 13:12:48 +05:30
Manav Rathi
7215f12d76 [web] Add support for iOS date format
Tested on the sample file provided by the customer.
2025-04-11 13:04:52 +05:30
ashilkn
29d09bf143 Fix grammar 2025-04-11 12:10:55 +05:30
ashilkn
8afc337b62 Update _maxLocalThumbnailRetries 2025-04-11 12:00:03 +05:30
ashilkn
a1b0eec83b Use more descriptive names. Deferring of thumbnail loads is only used for gallery 2025-04-11 11:51:52 +05:30
ashilkn
f4de138b08 Increase thumbnailDiskLoadDeferDuration from 40ms to 500ms to avoid and edge case where if gallery (device folder is a good example) is scrolled deep enough at a specific pace using the scrollbar, thumbanils fail to render when scrolling is stopped. 2025-04-11 11:49:27 +05:30
ashilkn
1b45dfee0e Avoid retrying of local thumbnail fetch if ThumbnailWidget is not mounted 2025-04-11 11:43:48 +05:30
ashilkn
a57041d0d2 Use priority queue for more efficient fetching of local thumbnails 2025-04-11 11:39:43 +05:30
Manav Rathi
6e57cc9e79 Remove outdated FAQ item in family-plans.md (#5584)
The FAQ item mentions that it is not possible to set a storage quota for
a family member, but this is possible since v1
2025-04-11 11:37:35 +05:30
Prateek Sunal
79a73ffd09 fix(ios): switch to ffmpeg_kit_custom 2025-04-11 00:07:17 +05:30
Sven
9425f80ef5 Remove outdated FAQ item in family-plans.md 2025-04-10 20:12:13 +02:00
Laurens Priem
7de9b747a9 [mob][photos] Only smart memories if local indexing is on (#5582)
## Description

Only smart memories if local indexing is on
2025-04-10 21:26:32 +05:30
Manav Rathi
adb8c2bdd6 [web] Video streaming touchup (#5583)
And start WIP work on playlist generation.
2025-04-10 20:37:12 +05:30
Manav Rathi
069a9fba58 Make it work when reopening the file viewer 2025-04-10 20:34:01 +05:30
Manav Rathi
0268c47c45 Match mobile app's behaviour 2025-04-10 20:27:01 +05:30
Laurens Priem
b7f59a18bd [mob][photos] log avatar faceID issue (#5581)
## Description

Log issue around avatarFaceID
2025-04-10 20:26:04 +05:30
laurenspriem
8e4dd04588 Only smart memories if local indexing 2025-04-10 20:25:32 +05:30
Manav Rathi
05f2b3c43e q 2025-04-10 19:23:07 +05:30
laurenspriem
4580e04bf6 log avatar faceID issue 2025-04-10 19:03:07 +05:30
Manav Rathi
970e631808 d only 2025-04-10 18:33:09 +05:30
Manav Rathi
0a40f2fef4 hook 2025-04-10 18:14:39 +05:30
Manav Rathi
5334388041 [web] Video streaming - Playback alpha (#5579) 2025-04-10 16:19:39 +05:30
Manav Rathi
0737054363 Enable alpha 2025-04-10 16:13:04 +05:30
Manav Rathi
85c40dfe29 close 2 2025-04-10 16:08:48 +05:30
Manav Rathi
719c5584f7 close 2025-04-10 15:57:24 +05:30
Manav Rathi
93747a87ec Hide the auto option when nothing is visible 2025-04-10 15:48:31 +05:30
Manav Rathi
6cf881dd60 intercept 2 2025-04-10 11:26:08 +05:30
Manav Rathi
22539c2a2f intercept 2025-04-10 11:13:11 +05:30
Manav Rathi
6ff909d3b8 Fix swap 2025-04-10 11:03:10 +05:30
Manav Rathi
0b609a9159 Update 2025-04-10 10:46:53 +05:30
Manav Rathi
7998f8ac53 Revert "spinner"
This reverts commit 0d223a759e. Only keeping it
for reference in git history.
2025-04-10 10:45:35 +05:30
Manav Rathi
0d223a759e spinner 2025-04-10 10:40:03 +05:30
Manav Rathi
b27e5938f1 [web] Update ffmpeg dep (#5576)
Assets via:

    mkdir ffmpeg-core-0.12.10
curl -fsSLO
https://unpkg.com/@ffmpeg/core@0.12.10/dist/umd/ffmpeg-core.js
curl -fsSLO
https://unpkg.com/@ffmpeg/core@0.12.10/dist/umd/ffmpeg-core.wasm

Note that the latest core version is (0.12.10) is different from the
(latest, 0.12.15) @ffmpeg/ffmpeg version we're updating to.
2025-04-10 09:45:19 +05:30
Manav Rathi
fcaebe2256 [web] Update ffmpeg dep
Assets via:

    mkdir ffmpeg-core-0.12.10
    curl -fsSLO https://unpkg.com/@ffmpeg/core@0.12.10/dist/umd/ffmpeg-core.js
    curl -fsSLO https://unpkg.com/@ffmpeg/core@0.12.10/dist/umd/ffmpeg-core.wasm

Note that the latest core version is (0.12.10) is different from the (latest,
0.12.15) @ffmpeg/ffmpeg version we're updating to.
2025-04-10 09:31:56 +05:30
Manav Rathi
23d1c054aa [docs] Self hosting updates (#5575)
Updates for https://github.com/ente-io/ente/pull/5574
2025-04-10 08:26:00 +05:30
Manav Rathi
c0669a138a [docs] Self hosting updates
Updates for https://github.com/ente-io/ente/pull/5574
2025-04-10 08:24:33 +05:30
Manav Rathi
150fd6f153 [docs] Document some self hosting questions (#5574)
...that arose recently.
2025-04-10 08:17:34 +05:30
Manav Rathi
e8e407a249 pg 2025-04-10 08:14:59 +05:30
Manav Rathi
4cd4445e65 doc csp 2025-04-10 08:04:43 +05:30
Manav Rathi
357926806b [web] Video streaming WIP - Part x/x (#5571)
Ever so closer to enabling video streaming (playback only) for internal
users
2025-04-09 19:50:42 +05:30
Manav Rathi
223043e75c Include playlist info 2025-04-09 19:39:28 +05:30
Manav Rathi
41a688357c More focused hiding 2025-04-09 19:12:25 +05:30
Manav Rathi
ca83e781dd More robust hiding 2025-04-09 19:01:00 +05:30
Manav Rathi
5535fdead5 Enable int 2025-04-09 18:43:37 +05:30
Manav Rathi
96194bdfe4 [desktop] Write timestamps as string for GT consistency; Read either (#5570)
Fixes: https://github.com/ente-io/ente/issues/5568
2025-04-09 17:06:25 +05:30
Manav Rathi
e31d132855 [desktop] Write timestamps as string for GT consistency; Read either
Fixes: https://github.com/ente-io/ente/issues/5568
2025-04-09 16:56:21 +05:30
Manav Rathi
77aef5db3f [docs] Tweaks for recently merged external PRs (#5566) 2025-04-09 12:08:04 +05:30
Manav Rathi
79415880fc Tweak 2025-04-09 12:06:54 +05:30
Manav Rathi
959a2d65a4 tweak 2025-04-09 12:02:43 +05:30
Manav Rathi
5abc0e3dc1 Update index.md (#5556)
* Added explanation to find hostname
* Added explanation of format for the server endpoint address

## Description

## Tests
2025-04-09 11:50:56 +05:30
Manav Rathi
b43d8e0851 Update index.md (#5557)
* Expanded verification code explanation
* Added link to website for app downloads

## Description

## Tests
2025-04-09 11:42:10 +05:30
Manav Rathi
3b577b1881 [web] Run typos on web and desktop (#5565)
* https://github.com/crate-ci/typos
* Manually verified the changes
* Didn't run it on server, but corrected a grammar mistake I recently
noticed.
2025-04-09 11:37:49 +05:30
Manav Rathi
0a1f984082 grammar 2025-04-09 11:32:32 +05:30
Manav Rathi
798977e395 typos web 2025-04-09 11:27:48 +05:30
Manav Rathi
cca47db499 typos desktop 2025-04-09 11:16:35 +05:30
Manav Rathi
1030f8eda8 [web] Yarn dedup (#5564)
npx yarn-deduplicate yarn.lock

https://github.com/scinos/yarn-deduplicate
2025-04-09 10:56:51 +05:30
Manav Rathi
279cbb3938 type 2025-04-09 10:51:42 +05:30
Manav Rathi
9afa495d7e [web] Yarn dedup
npx yarn-deduplicate yarn.lock

https://github.com/scinos/yarn-deduplicate
2025-04-09 10:32:50 +05:30
Manav Rathi
69874bbcf6 [web] Misc tweaks (#5563) 2025-04-09 10:08:04 +05:30
Manav Rathi
787beb951d Un-triple-eq some unambiguious string comparisons 2025-04-09 10:01:09 +05:30
Manav Rathi
4c820b7bf8 Misc tweaks 2025-04-09 09:50:27 +05:30
Manav Rathi
d25fe9296b [web] Node 20 => 22 (#5562)
Contributors do not necessarily need to update to node 22, I tested that
the dev server works with node 20 also.

That said, if someone wishes to update - here is the dance I needed to
do on macOS. Garnish to taste and OS.
```sh
brew uninstall node@20
brew install node@22
brew link node@22
corepack disable
corepack enable
```
2025-04-09 09:12:41 +05:30
Manav Rathi
51f13191b3 Node 20 => 22 2025-04-09 08:43:52 +05:30
Manav Rathi
9d4d3dc159 [web] Node 20 => 22 2025-04-09 08:23:51 +05:30
Manav Rathi
76e7f694f1 [web] Routine dependency updates (#5561) 2025-04-09 07:59:14 +05:30
Manav Rathi
60b484a2ad Fix type errors by ensuring single react types 2025-04-09 07:51:43 +05:30
Manav Rathi
75385a6e02 Same issue in more places 2025-04-09 07:25:57 +05:30
Manav Rathi
575f1744a2 yarn lint 2025-04-08 19:55:29 +05:30
Manav Rathi
90f05021c5 Fix unmet peers warning for media-chrome 2025-04-08 19:38:06 +05:30
Manav Rathi
c9fc6f9e3e Routine dependency updates 2025-04-08 19:36:24 +05:30
Manav Rathi
1d2de2ab76 [desktop] Dependency updates (#5559) 2025-04-08 18:58:40 +05:30
Manav Rathi
a51dfb2d7f Electron 35 uses node 22
https://www.electronjs.org/blog#stack-changes
2025-04-08 18:54:09 +05:30
Manav Rathi
3c2a821045 New lints 2025-04-08 18:46:30 +05:30
Manav Rathi
fdefd2720c app.dock is now only defined on macOS
https://www.electronjs.org/docs/latest/api/app#appdock-macos-readonly
2025-04-08 18:44:43 +05:30
Manav Rathi
c57b93f0d9 Upgrade to Electron 35 (+ others) 2025-04-08 18:37:23 +05:30
Manav Rathi
1cbb00ec3d Update to chokidar v4
We don't use globs so this shouldn't be a breaking change for us
https://github.com/paulmillr/chokidar?tab=readme-ov-file#upgrading
2025-04-08 18:19:20 +05:30
Manav Rathi
ee3f4451ed [web] Video streaming WIP - Part x/x (#5558)
Playback is ready
2025-04-08 17:05:12 +05:30
Manav Rathi
aabaa89add More robust check 2025-04-08 16:53:04 +05:30
Manav Rathi
7556287716 now it was flickering vertically! 2025-04-08 16:52:27 +05:30
Manav Rathi
31ab4962f9 Handle the video quality change case 2025-04-08 16:31:15 +05:30
Manav Rathi
dfba8478b7 Fix workaround 2025-04-08 16:05:09 +05:30
Manav Rathi
5a6c385132 Keep using ente- for the class/ids (et- makes more sense for temporary vars) 2025-04-08 14:55:30 +05:30
Manav Rathi
c6827cc3f4 Tweak caption for videos 2025-04-08 14:50:54 +05:30
Laurens Priem
7002d2b464 [mob][photos] Caching fix (#5531)
## Description

Fix incorrect cache reading for incorrect utf8 encoding for memories and
magic cache.

## Tests

Tested in debug mode on my pixel phone.
2025-04-08 14:24:41 +05:30
Manav Rathi
c062cc8aae Workaround 2025-04-08 14:10:09 +05:30
cmyplay
448ad06902 Update index.md
* Added explanation to find hostname
* Added explanation of format for the server endpoint address
2025-04-08 20:26:09 +12:00
cmyplay
ae6092d2ab Update index.md
* Expanded verification code explanation
* Added link to website for app downloads
2025-04-08 20:24:27 +12:00
Manav Rathi
658b8e5297 Reflect current status 2025-04-08 12:15:12 +05:30
Manav Rathi
b164fde81b Attempt to fix slide reset 2025-04-08 11:46:57 +05:30
Manav Rathi
8593ae8fbc Fix positioning 2025-04-08 10:59:07 +05:30
Manav Rathi
d3e4771055 Fix hiding 2025-04-08 10:59:07 +05:30
Manav Rathi
41e2a93b20 Handle it for the video quality switch too 2025-04-08 10:59:07 +05:30
Manav Rathi
bfa2251d6d Use mc 2025-04-08 10:59:07 +05:30
Manav Rathi
8363b7b7d3 [desktop] Windows icon - Take 3 (#5555)
Resize to make it fit better with the other icons in the start menu.
2025-04-08 10:58:07 +05:30
Manav Rathi
cd072113bb [desktop] Windows icon - Take 3
Resize to make it fit better with the other icons in the start menu.
2025-04-08 10:56:02 +05:30
Manav Rathi
dbf4d055d4 [desktop] Match windows icon with macOS icon (#5553)
Previously in https://github.com/ente-io/ente/pull/5551 the icon.ico was
generated from icon.png. In this PR, based on user feedback we instead
generate
it from the icon.icns (the same as that used by the macOS app) - this
one has
rounded corners.
2025-04-08 07:49:27 +05:30
Manav Rathi
424fbf1169 [desktop] Match windows icon with macOS icon
Previously in https://github.com/ente-io/ente/pull/5551 the icon.ico was
generated from icon.png. In this PR, based on user feedback we instead generate
it from the icon.icns (the same as that used by the macOS app) - this one has
rounded corners.
2025-04-08 07:46:55 +05:30
Manav Rathi
bf4d15db9c [web] Video streaming WIP - Part x/x (#5552) 2025-04-07 19:54:19 +05:30
Manav Rathi
4de0421f88 LF 2025-04-07 19:51:13 +05:30
Manav Rathi
6273313df9 Unnecessary since there shouldn't be an entry at this point 2025-04-07 19:46:30 +05:30
Manav Rathi
104a9bbb94 Better esc handling 2025-04-07 19:35:07 +05:30
Manav Rathi
866958389c Update the menu state 2025-04-07 19:18:35 +05:30
Manav Rathi
c762d16fa5 Menu 1 2025-04-07 18:59:02 +05:30
Manav Rathi
8ee3fb84b1 toggle 2025-04-07 17:30:26 +05:30
Manav Rathi
901b3df9f5 add change listener 2025-04-07 17:04:40 +05:30
Manav Rathi
b9c9d76e5d qmenu 2025-04-07 15:53:13 +05:30
Manav Rathi
a173ca5cd8 Put behind ff 2025-04-07 15:19:46 +05:30
Manav Rathi
86eb974dc3 Keep media chrome in sync
Ref:
- https://github.com/muxinc/media-chrome/pull/1088
- 1b5f331dbb/src/js/media-mute-button.ts (L119)
2025-04-07 15:16:10 +05:30
Manav Rathi
099771dfe6 Prevent a scroll of the file list in the background 2025-04-07 14:57:23 +05:30
Manav Rathi
1d0ab2cd43 eq 2025-04-07 14:54:04 +05:30
Prateek Sunal
db5a56c6f6 [mob] bump packages & replace some (#5427)
## Description

Bump packages, remove unused (used dependency_validator for detection of
them), change source to upstream for some and update comments for rest
of git deps.

## Tests

Unfortunately it is failing the Passkey deep link, will check.
2025-04-07 14:52:23 +05:30
Manav Rathi
4db1a39de2 Add staleness check 2025-04-07 14:34:38 +05:30
Prateek Sunal
255a170088 Merge branch 'main' into mob-bump-packages 2025-04-07 14:20:05 +05:30
Manav Rathi
56623099b3 Outline 2025-04-07 14:13:55 +05:30
Manav Rathi
a069b1b7e4 Revert "Attach validity"
We already convert to object URLs!
This reverts commit 55345cf60e.
2025-04-07 14:07:47 +05:30
Manav Rathi
55345cf60e Attach validity 2025-04-07 13:53:08 +05:30
Manav Rathi
d91555f8f2 Fix 2025-04-07 13:05:35 +05:30
Manav Rathi
a0049f4e78 Move 2025-04-07 13:03:06 +05:30
Manav Rathi
d4199790bb [destkop] Add windows icon variant (#5551)
Generated from icon.png using https://www.icoconverter.com/

Even though the docs (https://www.electron.build/icons.html) say that
the icon.png should automatically get used, in practice it seems to
generate start menu icons that are blurry.

The recommendation from the maintainer
(https://github.com/electron-userland/electron-builder/issues/7328#issuecomment-1499884818)
is to provide an .ico variant that'll get used for Windows.

I'm not sure if it is necessary to also mention this explicitly in the
build config. From reading the docs
(https://www.electron.build/electron-builder.interface.windowsconfiguration#icon),
'build/icon.ico' should be the default, so trying first by just adding
the file.
2025-04-07 12:40:39 +05:30
Manav Rathi
9a36c24227 [destkop] Add windows icon variant
Generated from icon.png using https://www.icoconverter.com/

Even though the docs (https://www.electron.build/icons.html) say that the
icon.png should automatically get used, in practice it seems to generate start
menu icons that are blurry.

The recommendation from the maintainer
(https://github.com/electron-userland/electron-builder/issues/7328#issuecomment-1499884818)
is to provide an .ico variant that'll get used for Windows.

I'm not sure if it is necessary to also mention this explicitly in the build
config. From reading the docs
(https://www.electron.build/electron-builder.interface.windowsconfiguration#icon),
'build/icon.ico' should be the default, so trying first by just adding the file.
2025-04-07 11:59:40 +05:30
Manav Rathi
9341c63ed0 [web] New translations (#5549)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-04-07 10:00:30 +05:30
Crowdin Bot
ca25756717 New Crowdin translations by GitHub Action 2025-04-07 00:38:15 +00:00
Prateek Sunal
33f29cdb41 Merge remote-tracking branch 'origin/main' into pending-sync-info 2025-04-06 21:04:04 +05:30
Ashil
b81448d366 [mob][photos] Bump up to v1.0.2 (#5538)
## Description

f-droid is at `1.0.1` so have to go from `1.0.0` to  `1.0.2`
2025-04-04 19:35:29 +05:30
ashilkn
d9db651ff7 Bump up photos mobile app to v1.0.2 2025-04-04 19:20:41 +05:30
Ashil
1da0870bc5 [mob][photos] Downgrade flutter_secure_storage to fix lockscreen data persisting even after reinstall on iOS (#5534)
## Description

`LockScreenSettings` and `Configuration` uses two different instances of
`FlutterSecureStorage`.

`lsSecureStorage = FlutterSecureStorage();`

```
configSecureStorage = const FlutterSecureStorage(
  iOptions: IOSOptions(
    accessibility: KeychainAccessibility.first_unlock_this_device,
  ),
);
```

On flutter_secure_storage v9.2.4, data written using `lsSecureStorage`
aren't getting deleted when calling `configSecureStorage.deleteAll()`
which is called on logging out and on initialisation of `Configuration`
because of different accessibility configurations of both instances.

v9.0.0 doesn't have this issue and so downgrading is the best solution. 
Let's wait till the
[issue](https://github.com/juliansteenbakker/flutter_secure_storage/issues/870#issuecomment-2777447937)
is resolved by the package maintainer. If not resolved and we need to
upgrade, write a migration script.

## Tests

#### Tested the following cases:
- [x] Install with v9.0.0.
- [x] Login and create PIN lock.
- [x] Reinstall app to check if PIN exists in secure storage and if lock
screen comes up.
- [x] PIN is non-existent and lock screen doesn't come up.

##### And

- [x] Install with v9.2.4
- [x] Login and create PIN lock.
- [x] Reinstall with v9.0.0 and check if PIN exists in secure storage
and if lock screen comes up.
- [x] PIN is non-existent and lock screen doesn't come up.
2025-04-04 19:09:32 +05:30
Manav Rathi
1e2027b6a9 [web] Ignore self email from family suggestions in share list (#5537) 2025-04-04 18:19:17 +05:30
Manav Rathi
579afbd6b5 Tweak 2025-04-04 18:15:10 +05:30
Manav Rathi
fec0b867fe Exclude family self 2025-04-04 18:10:29 +05:30
Manav Rathi
2977a91d17 types 2025-04-04 18:02:15 +05:30
Manav Rathi
e30cb93502 un 2025-04-04 18:00:57 +05:30
Manav Rathi
1b59ea1377 Move 2025-04-04 18:00:14 +05:30
ashilkn
fc8a0b2f37 Fix version number of comment 2025-04-04 17:46:26 +05:30
Manav Rathi
93ad3d65fd [desktop] Potential live photo workaround for Linux-en (#5536) 2025-04-04 17:44:21 +05:30
Manav Rathi
b261f72864 Add another case 2025-04-04 17:33:49 +05:30
Manav Rathi
55e0a8de6f Potential live photo workaround for Linuxen 2025-04-04 17:29:43 +05:30
Ashil
bd12d1e885 [mob][photos]Bump up to v1.0.1 (#5535) 2025-04-04 17:21:58 +05:30
ashilkn
0aabee9e3b Bump up version to 1.0.1 2025-04-04 17:20:37 +05:30
ashilkn
5d28c0038a Refactor 2025-04-04 17:01:28 +05:30
ashilkn
7a31cc982a Auto generated changes 2025-04-04 16:59:40 +05:30
ashilkn
bad8d9bf2a Downgrade flutter_secure_storage to fix lockscreen data persisting even after reinstall on iOS 2025-04-04 16:59:14 +05:30
Manav Rathi
73d67277b7 [web] File URL generator internal API cleanup (#5533) 2025-04-04 16:00:21 +05:30
Manav Rathi
b5130f1ab6 rework 3 2025-04-04 15:43:45 +05:30
Manav Rathi
d8e3807049 step 2 wip 2025-04-04 15:43:45 +05:30
Manav Rathi
1388e34659 transition 1 2025-04-04 15:43:45 +05:30
Manav Rathi
ee2c836a2a Update 2025-04-04 15:43:45 +05:30
Manav Rathi
6379cdd70b Unused 2025-04-04 15:43:45 +05:30
Manav Rathi
fe9989fd5f Revert "[desktop] Show/hide the window on tray icon double click on Linux/Win" (#5532)
Reverts ente-io/ente#5526. Like macOS, the double click interferes with
the click event that shows the context menu on Linux too.
2025-04-04 13:49:16 +05:30
Manav Rathi
34cdefe028 Revert "[desktop] Show/hide the window on tray icon double click on Linux/Win" 2025-04-04 13:44:55 +05:30
laurenspriem
15ec21f3c8 old dependecy pubspec 2025-04-04 12:31:01 +05:30
laurenspriem
2efc645c31 fix incorrect utf8 cache encoding for magic cache too 2025-04-04 12:30:46 +05:30
laurenspriem
ea7109e577 fix incorrect utf8 cache encoding 2025-04-04 12:30:00 +05:30
laurenspriem
444e1a1490 format 2025-04-04 12:28:50 +05:30
Manav Rathi
969b0c1655 [server] Update service definition for recent env var lookup changes (#5529)
**Tested by**

Modifying the compose.yaml to provide an environment variable:
```diff
      environment:
        ENTE_CREDENTIALS_FILE: /credentials.yaml
+       ENTE_HTTP_USE_TLS: 1
```
then observing that museum is honoring it 
```
...
[GIN-debug] Listening and serving HTTPS on :443
```
2025-04-04 11:13:25 +05:30
Manav Rathi
bdd5036cf8 Update comment 2025-04-04 11:07:19 +05:30
Manav Rathi
6fd2db8d0b Augment not replace 2025-04-04 10:54:22 +05:30
Manav Rathi
7eae2936bd [server] Update service definition for recent env var lookup changes 2025-04-04 10:16:07 +05:30
Manav Rathi
f29b8f933b [desktop] Show/hide the window on tray icon double click on Linux/Win (#5526)
Ref: https://github.com/ente-io/ente/discussions/4521
2025-04-03 19:48:56 +05:30
Manav Rathi
ad27bd3b35 [desktop] Show/hide the window on tray icon double click on Linux/Win
Ref: https://github.com/ente-io/ente/discussions/4521
2025-04-03 19:45:16 +05:30
Manav Rathi
21fd608ed7 [web] Better fallback when editing screenshots without exif (#5524) 2025-04-03 19:08:37 +05:30
Vishnu Mohandas
4229238768 [server] Relax criteria for closing families (#5525)
## Description

Users can create a family, leave it and then join another.

In the `families` table, there will be one entry for each such family
they have been a part of (against their `admin_id`).

This PR removes this constraint for only a single row to be affected, so
users who have historically been associated with more than one family
can have a fresh start.
2025-04-03 19:07:19 +05:30
vishnukvmd
d86f4de8ce Relax criteria for closing families 2025-04-03 18:57:39 +05:30
Manav Rathi
f0b8e3b4af Better fallback 2025-04-03 18:55:55 +05:30
Manav Rathi
aa422889f3 [web] Prevent potential npe 2025-04-03 18:33:04 +05:30
Vishnu Mohandas
0738caaa2b [docs] 5GB > 10GB (#5523) 2025-04-03 17:30:03 +05:30
vishnukvmd
c981af5470 [docs] 5GB > 10GB 2025-04-03 17:29:42 +05:30
Manav Rathi
f5eca5b671 [web] Use browser's native HEIC support when detected (#5521) 2025-04-03 15:52:33 +05:30
Manav Rathi
74036bad60 Apparently 17 had it too
https://caniuse.com/heif
2025-04-03 15:47:18 +05:30
Manav Rathi
95f7735164 Add test 2025-04-03 15:28:53 +05:30
Manav Rathi
740c1093ff Cleanup 2025-04-03 15:10:28 +05:30
Aman Raj Singh Mourya
04bf4527d8 [auth] implemented logic for period & TOTP 2025-04-03 15:04:37 +05:30
Manav Rathi
b9a8f58dec scaffold wip 2
Ref: 8d15007530
2025-04-03 15:04:16 +05:30
Aman Raj Singh Mourya
5c66511a31 [auth] added totp selector widget 2025-04-03 15:03:02 +05:30
Aman Raj Singh Mourya
4c204e2a2a [auth] minor changes 2025-04-03 15:01:58 +05:30
Manav Rathi
291833e1e1 scaffold wip 2025-04-03 14:31:36 +05:30
Manav Rathi
be99d92bf2 [web] Reduce flicker when resizing gallery window (#5519) 2025-04-03 12:28:55 +05:30
Manav Rathi
e94b1966bd Fin 2025-04-03 12:19:04 +05:30
Manav Rathi
bc0399dfeb Prune 2 2025-04-03 12:10:57 +05:30
Manav Rathi
c4822a1caf Prune 1 2025-04-03 11:59:15 +05:30
DanteMS
a390d3ff2e [mob] ICU syntax fix 2025-04-03 14:22:07 +08:00
Manav Rathi
3d8d4bd8bf Update to pick the performance improvement
> Changed width and height values to be based om getBoundingClientRect rather
  than offsetWidth and offsetHeight (which are integers and can cause
  rounding/flickering problems in some cases).
>
> https://github.com/bvaughn/react-virtualized-auto-sizer/releases/tag/1.0.26
2025-04-03 11:33:01 +05:30
Manav Rathi
8555358fa3 [desktop] [macOS] Hide dock icon on Window close (#5517)
Based on customer feedback. The dock icon will hide when the window is
closed by using the "x" without quitting the app.

The menu bar icon remains as it is, and so does the existing preferences
(whose value is also retained if it were set explicitly).
2025-04-03 09:22:21 +05:30
Manav Rathi
9999ffa52c centralize 2025-04-03 09:12:39 +05:30
Manav Rathi
9d60e980f8 [desktop] [macOS] Hide dock icon on Window close
Based on customer feedback. The dock icon will hide when the window is closed by
using the "x" without quitting the app. The menu bar icon remains as it is, and
so does the existing preferences (whose value is also retained if set
explicitly).
2025-04-03 08:48:19 +05:30
mangesh
b680129af5 Update mc command for cors (#5504)
## Description

Took me all night to figure this one out. Hopefull no one has to deep
dive like this.

Ref to why it changed:
https://github.com/minio/minio/tree/master/docs/config#api

## Tests
2025-04-02 19:01:09 +05:30
Manav Rathi
732fa6b3d9 [web] Prepare for eventual yarn => npm migration (#5507)
npm doesn't support the "@" character in package names (it's used for
scopes). We eventually want to move from yarn to npm, so in preparation,
rename
our internal packages accordingly so that they also work with npm
workspaces.

Methodology: No manual code changes, just automatic search replace of

```
"@/accounts => "ente-accounts
"@/utils => "ente-utils
...
"@ente/shared => "ente-shared
```

Then reran prettier.

--

EDIT: Updated the docs too later manually in a separate commit.
2025-04-02 19:00:42 +05:30
Manav Rathi
c3a7952c42 Update the docs too 2025-04-02 18:47:32 +05:30
Manav Rathi
fdb4b0374c Prepare for eventual yarn => npm migration
npm doesn't support the "@" character in package names (it's used for
scopes). We eventually want to move from yarn to npm, so in preparation, rename
our internal packages accordingly so that they also work with npm workspaces.

Methodology: No manual code changes, just automatic search replace of

```
"@/accounts => "ente-accounts
"@/utils => "ente-utils
...
"@ente/shared => "ente-shared
```

Then reran prettier.
2025-04-02 18:37:16 +05:30
Manav Rathi
250bc3edcf [web] Video streaming WIP - Part x/x (#5506) 2025-04-02 17:40:08 +05:30
Manav Rathi
822285fd3d Fin 2025-04-02 17:19:18 +05:30
mangesh
f5ea4b0a05 [server] Replace EnvVarKey "-" with "_" (#5496)
Fixes #5493
2025-04-02 16:47:51 +05:30
mngshm
174d9fb82e doc 2025-04-02 16:13:00 +05:30
mngshm
101e27514b Comment 2025-04-02 16:02:52 +05:30
Manav Rathi
fc480e8ce6 Tried tr
https://www.media-chrome.org/docs/en/internationalization/adding-language-support
2025-04-02 15:55:47 +05:30
Manav Rathi
2cbc4998df Couldn't connect when I tried it
Cast is also not supported by hls-video, can investigate both these together.
2025-04-02 14:53:34 +05:30
Manav Rathi
40812ec7c3 More robust 2025-04-02 14:44:57 +05:30
Manav Rathi
09b4025f11 cap 2025-04-02 14:28:11 +05:30
Manav Rathi
7b169fe903 focus workaround 2025-04-02 13:59:19 +05:30
Manav Rathi
9d222cd007 hk 2025-04-02 13:55:31 +05:30
Manav Rathi
cfe6343d63 Fix partial clipped lines showing through on the caption 2025-04-02 13:55:31 +05:30
Manav Rathi
e15fb04ee0 Caption positioning 2025-04-02 13:55:31 +05:30
Manav Rathi
6bbfcb1d13 abs
ref https://github.com/muxinc/media-chrome/discussions/890
2025-04-02 13:55:31 +05:30
Manav Rathi
b9bb7c074d Pause 2025-04-02 13:55:31 +05:30
Manav Rathi
5a7f83212b Tweak 2025-04-02 13:55:31 +05:30
Manav Rathi
01071676ce [meta] Update workflow permissions (#5505)
Continuation of https://github.com/ente-io/ente/pull/5456
2025-04-02 13:34:06 +05:30
Manav Rathi
aadacda2f6 [meta] Update workflow permissions
Continuation of https://github.com/ente-io/ente/pull/5456
2025-04-02 13:31:44 +05:30
Athul Cyriac Ajay
bc0d832105 Update mc command for cors 2025-04-02 02:33:13 +05:30
Manav Rathi
0a1c1e441e [web] Video streaming WIP - Part x/x (#5502) 2025-04-01 20:00:22 +05:30
Manav Rathi
4e95f4b36f settings icon from MUI icon
https://mui.com/material-ui/material-icons/?query=settings&selected=Settings
2025-04-01 19:41:41 +05:30
Manav Rathi
5a3b72b141 Restore clicks on the next/prev arrows 2025-04-01 19:09:55 +05:30
Manav Rathi
c88e04535c style 2025-04-01 18:47:28 +05:30
Manav Rathi
b12a4dd235 speed 2025-04-01 17:52:40 +05:30
Manav Rathi
f24d6b882d take 2 2025-04-01 17:41:30 +05:30
Manav Rathi
199c2d0c95 take 1 2025-04-01 17:41:30 +05:30
Manav Rathi
7508d9c86b Log message
Saw this when working with media-chrome. In WIP code, I am getting

   [error] Unhandled error: ResizeObserver loop completed with undelivered notifications.

but that string comes as event.message (event.error is null).
2025-04-01 17:41:30 +05:30
Manav Rathi
b586281207 [web] Fix assignment typo in previous PR (#5499)
https://github.com/ente-io/ente/pull/5498
2025-04-01 17:38:20 +05:30
Manav Rathi
8510a88e9e Fix assignment 2025-04-01 17:31:43 +05:30
Manav Rathi
2dc202d984 [web] Reduce unnecessary rerenders during upload (#5498)
setTimeout was showing up prominently in the profiler
2025-04-01 14:40:47 +05:30
Manav Rathi
48aec5df86 Reduce unnecessary rerenders during upload 2025-04-01 14:34:21 +05:30
Manav Rathi
2440c38530 [web] Fix expiry date in link settings (#5495) 2025-04-01 12:16:12 +05:30
Manav Rathi
b1ce3edf28 Graceful deg 2025-04-01 12:13:05 +05:30
Manav Rathi
80ea75e2d2 [web] Fix expiry date in link settings 2025-04-01 12:13:05 +05:30
mngshm
f592d73d87 note in local.yaml 2025-04-01 12:10:24 +05:30
mngshm
28295e2b83 Replace '-' with '_' 2025-04-01 12:04:42 +05:30
Manav Rathi
6be4b29331 [web] New translations (#5490)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-04-01 10:58:19 +05:30
Ashil
ba435ad974 Correct typo in cli (#5483)
Corrected "expirty" typo in ente admin update-subscription --no-limit
False success workflow.

## Description
Fixed typo "expirty" to "expiry" in file limit success flow.


## Tests
2025-03-31 08:26:20 +05:30
Ashil
799f9f2878 Updated subscription FAQ (#5479)
Corrected the free storage from 5 GB to 10 GB.
2025-03-31 08:25:16 +05:30
Laurens Priem
39e1f7bfe7 [mob][photos] Improve tag "me" flow (#5426)
## Description

Simplified the action of assigning "me" by sticky-ing the users email on
top (in case "me" is not assigned).

## Tests

Tested in debug mode on my pixel phone.
2025-03-31 07:53:21 +05:30
Crowdin Bot
5d7ce9f542 New Crowdin translations by GitHub Action 2025-03-31 00:38:58 +00:00
deancommasteven
eefd740a4d Correct typo in cli
Corrected "expirty" typo in ente admin update-subscription --no-limit False success workflow.
2025-03-30 14:20:20 -04:00
Niika
ef6e859e76 Updated subscription FAQ
Corrected the free storage from 5 GB to 10 GB.
2025-03-29 23:34:14 +01:00
Vishnu Mohandas
404e8c3214 [mob] Enable translations for Norwegian (#5472) 2025-03-29 16:38:53 +05:30
vishnukvmd
c47ddab7ba Enable translations for Norwegian 2025-03-29 16:38:28 +05:30
Vishnu Mohandas
74849bd257 [mob] Enable translations for Romanian (#5470) 2025-03-29 15:51:32 +05:30
vishnukvmd
a76a7abc2a Enable translations for Romanian 2025-03-29 15:49:57 +05:30
Neeraj
bd7a16a85c [mob][photos] Remove datepicker dependency (#5463)
## Description

Switched to our own date picker in the last place we were using package
(link expiry page) and removed package.

## Tests

Tested in debug mode on my pixel phone.
2025-03-29 05:04:16 +05:30
Manav Rathi
cd634b98a0 [desktop] Next release train (#5465) 2025-03-28 18:28:25 +05:30
Manav Rathi
7b871195c8 [desktop] Next release train 2025-03-28 18:25:48 +05:30
Vishnu Mohandas
bed0b0f902 [docs] Update links for photos (#5462) 2025-03-28 18:14:50 +05:30
vishnukvmd
cdf46acd8b Fix 2025-03-28 18:14:04 +05:30
vishnukvmd
af7698e29e Fix links 2025-03-28 18:13:14 +05:30
laurenspriem
713972af9b Remove redundant dependency 2025-03-28 18:03:35 +05:30
laurenspriem
1c2b9634db Cleanup file 2025-03-28 18:02:52 +05:30
laurenspriem
bf8173708d use own datepicker 2025-03-28 18:01:57 +05:30
laurenspriem
125eca1847 datepicker sheet method 2025-03-28 18:01:34 +05:30
laurenspriem
112a4844ee Cleanup file 2025-03-28 17:02:15 +05:30
vishnukvmd
eb9e97080f [docs] Update links for photos 2025-03-28 16:49:41 +05:30
Prateek Sunal
633184852e fix: deep link experience 2025-03-28 16:47:39 +05:30
Vishnu Mohandas
46a090535f [server] Up free storage (#5461)
## Description

## Tests
2025-03-28 16:46:29 +05:30
Prateek Sunal
886cb06590 feat: Remove temporary directory after processing video preview 2025-03-28 14:53:04 +05:30
Prateek Sunal
cd2094f75e feat: Add Pending Sync Info Screen and enhance path storage viewer 2025-03-28 14:50:05 +05:30
Laurens Priem
360223bd2f [mob][photos] Image embedding caching perf (#5459)
## Description

Made changes to more efficiently handle image embeddings caching,
keeping them cached only in MLComputer and only for limited times when
the user needs it.

## Tests

Tested in debug mode on my pixel phone.
2025-03-28 14:13:42 +05:30
laurenspriem
d11ff14ecd Remove embeddings cache after inactivity 2025-03-28 13:55:23 +05:30
Manav Rathi
60781ba86b [meta] Allow running CodeQL manually (#5458)
Necessary to get GitHub to resync the status until the next time it runs
2025-03-28 13:50:38 +05:30
Manav Rathi
02d2db3e43 [meta] Allow running CodeQL manually
Necessary to get GitHub to resync the status until the next time it runs
2025-03-28 13:49:53 +05:30
Manav Rathi
4035a06040 [meta] Create custom codeql.yml (#5457)
Here is the original autogenerated template on which this is based:

```yaml
# For most projects, this workflow file will not need changing; you simply need # to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages.
#
name: "CodeQL Advanced"

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  schedule:
    - cron: '22 1 * * 1'

jobs:
  analyze:
    name: Analyze (${{ matrix.language }}) # Runner size impacts CodeQL analysis time. To learn more, please see:
    #   - https://gh.io/recommended-hardware-resources-for-running-codeql
    #   - https://gh.io/supported-runners-and-hardware-resources
    #   - https://gh.io/using-larger-runners (GitHub.com only)
    # Consider using larger runners or machines with greater resources for possible analysis time improvements.
    runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
    permissions:
      # required for all workflows
      security-events: write

      # required to fetch internal or private CodeQL packs
      packages: read

      # only required for workflows in private repositories
      actions: read
      contents: read

    strategy: fail-fast: false matrix: include:
        - language: actions build-mode: none
        - language: c-cpp build-mode: autobuild - language: go build-mode: autobuild - language: java-kotlin build-mode: autobuild - language: javascript-typescript build-mode: none - language: ruby build-mode: none - language: swift build-mode: autobuild # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' # Use `c-cpp` to analyze code written in C, C++ or both # Use 'java-kotlin' to analyze code written in Java, Kotlin or both # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps:
    - name: Checkout repository uses: actions/checkout@v4

    # Add any setup steps before running the `github/codeql-action/init` action.
    # This includes steps like installing compilers or runtimes (`actions/setup-node`
    # or others). This is typically only required for manual builds.
    # - name: Setup runtime (example)
    #   uses: actions/setup-example@v1

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file.

        # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
        # queries: security-extended,security-and-quality

    # If the analyze step fails for one of the languages you are analyzing with
    # "We were unable to automatically build your code", modify the matrix above
    # to set the build mode to "manual" for that language. Then modify this step
    # to build your code.
    # ℹ️ Command-line programs to run using the OS shell.
    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
    - if: matrix.build-mode == 'manual' shell: bash run: | echo 'If you are using a "manual" build mode for one or more of the' \ 'languages you are analyzing, replace this with the commands to build' \ 'your code, for example:' echo '  make bootstrap' echo '  make release' exit 1

    - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}"
```
2025-03-28 13:47:51 +05:30
Manav Rathi
2d16d958e3 [meta] Create custom codeql.yml
Here is the original autogenerated template from which this is based:

----

# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  schedule:
    - cron: '22 1 * * 1'

jobs:
  analyze:
    name: Analyze (${{ matrix.language }})
    # Runner size impacts CodeQL analysis time. To learn more, please see:
    #   - https://gh.io/recommended-hardware-resources-for-running-codeql
    #   - https://gh.io/supported-runners-and-hardware-resources
    #   - https://gh.io/using-larger-runners (GitHub.com only)
    # Consider using larger runners or machines with greater resources for possible analysis time improvements.
    runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
    permissions:
      # required for all workflows
      security-events: write

      # required to fetch internal or private CodeQL packs
      packages: read

      # only required for workflows in private repositories
      actions: read
      contents: read

    strategy:
      fail-fast: false
      matrix:
        include:
        - language: actions
          build-mode: none
        - language: c-cpp
          build-mode: autobuild
        - language: go
          build-mode: autobuild
        - language: java-kotlin
          build-mode: autobuild
        - language: javascript-typescript
          build-mode: none
        - language: ruby
          build-mode: none
        - language: swift
          build-mode: autobuild
        # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
        # Use `c-cpp` to analyze code written in C, C++ or both
        # Use 'java-kotlin' to analyze code written in Java, Kotlin or both
        # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
        # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
        # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
        # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
        # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    # Add any setup steps before running the `github/codeql-action/init` action.
    # This includes steps like installing compilers or runtimes (`actions/setup-node`
    # or others). This is typically only required for manual builds.
    # - name: Setup runtime (example)
    #   uses: actions/setup-example@v1

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v3
      with:
        languages: ${{ matrix.language }}
        build-mode: ${{ matrix.build-mode }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.

        # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
        # queries: security-extended,security-and-quality

    # If the analyze step fails for one of the languages you are analyzing with
    # "We were unable to automatically build your code", modify the matrix above
    # to set the build mode to "manual" for that language. Then modify this step
    # to build your code.
    # ℹ️ Command-line programs to run using the OS shell.
    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
    - if: matrix.build-mode == 'manual'
      shell: bash
      run: |
        echo 'If you are using a "manual" build mode for one or more of the' \
          'languages you are analyzing, replace this with the commands to build' \
          'your code, for example:'
        echo '  make bootstrap'
        echo '  make release'
        exit 1

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v3
      with:
        category: "/language:${{matrix.language}}"
2025-03-28 13:44:49 +05:30
laurenspriem
a682fb4ece cleanup 2025-03-28 13:43:40 +05:30
laurenspriem
bc65e2c256 don't cache embeddings on startup 2025-03-28 13:41:16 +05:30
laurenspriem
3457cc1369 log embeddings retrieval time 2025-03-28 13:40:58 +05:30
laurenspriem
5ffd513826 Speed up embedding db call 2025-03-28 13:39:55 +05:30
Manav Rathi
d1df2962cb [meta] Granular action permissions (#5456) 2025-03-28 13:08:45 +05:30
Manav Rathi
cf7d46fd70 go-rel
ref: https://github.com/wangyoucao577/go-release-action?tab=readme-ov-file#basic-example
2025-03-28 13:02:19 +05:30
Manav Rathi
875a747e24 granular perms / release
"only required permissions for the action specified (which is contents: write)"
- https://github.com/ncipollo/release-action?tab=readme-ov-file#notes
2025-03-28 12:57:41 +05:30
Manav Rathi
0e4fa1ad4c ro 2025-03-28 12:57:41 +05:30
laurenspriem
939d1a5d40 properly clear isolate cache 2025-03-28 12:47:22 +05:30
Manav Rathi
0f62c4fa79 granular perms / docker-push
ref: https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#authenticating-to-package-registries-with-repository-scoped-permissions
2025-03-28 12:32:33 +05:30
Manav Rathi
038f6b33e1 granular perms [crowdin] 2025-03-28 12:22:59 +05:30
laurenspriem
bd0818ec7d Reduce time to isolate disposal 2025-03-28 11:57:21 +05:30
laurenspriem
1267587ae5 Fix using plugins in regular isolates 2025-03-28 11:51:34 +05:30
laurenspriem
168a4936f8 cache clip embeddings inside MLComputer isolate 2025-03-28 11:42:06 +05:30
Manav Rathi
eb11d80d79 [desktop] photosd-v1.7.11 (#5455) 2025-03-28 11:15:31 +05:30
Manav Rathi
dbc1cec05a [desktop] photosd-v1.7.11 2025-03-28 11:12:50 +05:30
Manav Rathi
95c9f5877c [docs] AppImage icon FAQ (#5454) 2025-03-28 11:09:58 +05:30
Manav Rathi
34034a77a2 Fix link 2025-03-28 11:08:55 +05:30
Manav Rathi
1da4770728 [docs] AppImage icon FAQ 2025-03-28 11:06:58 +05:30
Manav Rathi
353b2274d1 [docs] Add linux icon update FAQ (#5453) 2025-03-28 08:47:45 +05:30
Manav Rathi
56f15a33af [docs] Add linux icon update FAQ 2025-03-28 08:46:10 +05:30
Manav Rathi
85e0fef80b [server] Quickstart: don't rely on the -w flag for base64 (#5452)
Tested on macOS, Ubuntu (docker), Alpine (docker)
2025-03-28 08:15:30 +05:30
Manav Rathi
f3eb4c9acf Don't silently fail if docker is not installed 2025-03-28 08:10:03 +05:30
Manav Rathi
70924b7416 Don't rely on the -w flag for base64 2025-03-28 08:06:43 +05:30
Neeraj
21028e4985 [mob] Improve ignored file identifier for android (#5451)
## Description
Handle the case where some files were incorrectly ignored for upload
because device reused deleted file name.

## Tests
2025-03-28 07:28:35 +05:30
Neeraj Gupta
4ba22fd677 Improve ignored file identifier for android 2025-03-28 07:19:55 +05:30
laurenspriem
ac43ecf45b Make MLComputer a regular isolate 2025-03-27 16:07:28 +05:30
laurenspriem
a974a95fb2 Auto dispose face thumbnail generator isolate 2025-03-27 16:06:36 +05:30
laurenspriem
eb7f350102 Separate face thumbnail generator from embeddings 2025-03-27 16:04:13 +05:30
Manav Rathi
b2e4b82d5c [web] Video streaming WIP - Part x/x (#5449) 2025-03-27 14:30:33 +05:30
Neeraj
a88e281800 [mob] Log sync status when uploadIcon is hidden (#5448)
## Description

## Tests
2025-03-27 14:18:12 +05:30
Neeraj
279319bd52 [mob] Fix discovery section reload condition (#5447)
## Description
Previous condition didn't handle the case when the cities were not
loaded when discovery section was getting computed.
## Tests
2025-03-27 14:18:00 +05:30
Neeraj Gupta
6a3c3d5b5b Log sync status when uploadIcon is hidden 2025-03-27 14:17:10 +05:30
Neeraj Gupta
f36cc9ec06 [mob] Fix discovery section reload condition 2025-03-27 14:08:36 +05:30
Manav Rathi
8981668052 Tweaks 2025-03-27 13:29:46 +05:30
Manav Rathi
cba4f538f8 grad 2025-03-27 12:56:26 +05:30
Manav Rathi
8b787c7373 rgba => rgb
"The rgba() functional notation is an alias for rgb(). They are exactly equivalent. It is recommended to use rgb()." - MDN

https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb
2025-03-27 12:50:50 +05:30
Manav Rathi
30c4a72e69 2l 2 2025-03-27 12:37:48 +05:30
Manav Rathi
bfd9a0d760 two line 2025-03-27 10:59:22 +05:30
Manav Rathi
2d2696e4ee two line? 2025-03-27 10:33:45 +05:30
Manav Rathi
4f0bee517e Use type 2025-03-27 10:06:56 +05:30
Manav Rathi
e536e34808 Move 2025-03-27 10:00:04 +05:30
Manav Rathi
8a13c9071c Same as mobile 2025-03-27 08:05:40 +05:30
Manav Rathi
e35fae6c3c Notes
Ref: 476e5abdd0/packages/hls-video-element/hls-video-element.js (L73)
2025-03-27 08:04:29 +05:30
Neeraj
313a7064f8 [mob] Search & filter by uploader's name (#5443)
## Description

## Tests
2025-03-27 00:17:13 +05:30
Neeraj Gupta
a550dcce57 Enable search filter for uploader name 2025-03-26 23:44:32 +05:30
Neeraj Gupta
63b9b926a1 Show seperate result for different uploader 2025-03-26 22:54:39 +05:30
Neeraj Gupta
4500a8f620 Add support to search by uploader name 2025-03-26 22:16:11 +05:30
Manav Rathi
90bf99c20b [web] Video streaming WIP - Part x/x (#5440) 2025-03-26 21:05:22 +05:30
Manav Rathi
838b7e2a88 loading indicator 2025-03-26 18:48:50 +05:30
Laurens Priem
99f882043b [mob][photos] Onnx debug options (#5439)
## Description

Some ONNX logging and cleaner menu for loading separate models. 

## Tests
2025-03-26 17:55:32 +05:30
laurenspriem
dd0c5ed770 Focused menu for loading separate models 2025-03-26 17:19:57 +05:30
Manav Rathi
2f3c00fc99 quot 2025-03-26 15:53:39 +05:30
Manav Rathi
acad6895e8 More controls 2025-03-26 15:53:39 +05:30
laurenspriem
1774a8019f Always log OrtVersion on init 2025-03-26 15:09:08 +05:30
laurenspriem
f5ce53d8ca consistent logging in onnx plugin 2025-03-26 15:04:29 +05:30
Manav Rathi
e5720c1906 More controls 2025-03-26 14:16:17 +05:30
Manav Rathi
9803720603 Via CSS 2025-03-26 12:55:15 +05:30
Manav Rathi
86ba1eed5d Workaround: defer setting mediacontroller attribute until next tick 2025-03-26 12:31:06 +05:30
laurenspriem
9ab55ed1e4 Remove "this is me" button 2025-03-26 12:23:38 +05:30
laurenspriem
bf7e10eab6 Make own email stickied at top 2025-03-26 12:18:44 +05:30
Manav Rathi
8383d7dd56 HLS playlists are provided as data: 2025-03-26 11:56:49 +05:30
Manav Rathi
7174cbac3b [web] Video streaming WIP - Part x/x (#5436) 2025-03-26 10:21:59 +05:30
Manav Rathi
52c7c1b4ed LF 2025-03-26 10:21:46 +05:30
Manav Rathi
2187b3ec6e Trim 2025-03-26 10:06:15 +05:30
Manav Rathi
d1af77dbef also for hls
476e5abdd0/packages/hls-video-element/index.html (L52)
2025-03-26 09:35:00 +05:30
Manav Rathi
33ee599f3c Inline playback of live photos on mobile browsers 2025-03-26 09:30:41 +05:30
Manav Rathi
0247d3f458 first slide 2025-03-26 08:31:01 +05:30
Manav Rathi
38c64ac05f move out and link - wip 2025-03-26 07:34:57 +05:30
Manav Rathi
220a6cbc4b Retain dimensions from playlist 2025-03-26 06:08:23 +05:30
Prateek Sunal
4797e03119 fix(pubspec): suggest package alternative 2025-03-26 04:14:43 +05:30
Prateek Sunal
02d730eaae chore: update dependencies in pubspec.yaml and remove unused packages 2025-03-26 03:56:18 +05:30
Prateek Sunal
070907fc69 Merge branch 'main' into mob-bump-packages 2025-03-25 22:58:08 +05:30
Manav Rathi
01b65eb608 wip 2025-03-25 20:36:15 +05:30
Manav Rathi
3ab8c348b0 Move controls out 2025-03-25 16:31:29 +05:30
Manav Rathi
7af57bd7c8 Start adding controls 2025-03-25 16:31:29 +05:30
Manav Rathi
1ac64b5a31 +media-chrome 2025-03-25 16:31:29 +05:30
Manav Rathi
2431c81c44 Use 2025-03-25 16:31:29 +05:30
Manav Rathi
f0b23a495c hls.js + hls-video-element 2025-03-25 16:31:29 +05:30
Manav Rathi
677ad0dc00 Works in Safari 2025-03-25 16:31:29 +05:30
Manav Rathi
142020e26a Add file extension and mime type 2025-03-25 16:31:29 +05:30
Manav Rathi
195bd114f9 [web] Fix video tabbing (#5434) 2025-03-25 16:30:43 +05:30
Manav Rathi
6b91228273 Fix video tabbing 2025-03-25 16:25:06 +05:30
Prateek Sunal
1166b53383 feat: replace uni_links with app_links in Podfile and update dependencies 2025-03-25 15:02:29 +05:30
Neeraj
041a657877 [mob] Delete old identifier for shared-media files (#5433)
## Description

## Tests
2025-03-25 14:28:48 +05:30
Neeraj Gupta
d0ee33131e [mob] Delete old identifier for shared-media files 2025-03-25 14:21:29 +05:30
Prateek Sunal
a33ace26dd chore: update comments 2025-03-24 19:25:53 +05:30
Prateek Sunal
d8826199e0 chore: update comment 2025-03-24 19:22:08 +05:30
Prateek Sunal
e389a2c4a2 chore: update comments for packages 2025-03-24 19:21:17 +05:30
Prateek Sunal
2283f4a25d feat(deprecate): use app_links instead of uri_links 2025-03-24 19:15:50 +05:30
Prateek Sunal
e55ddefa21 chore(photos-mobile): bump figma_squicircle to latest 2025-03-24 19:08:36 +05:30
laurenspriem
76b9c30332 error log 2025-03-24 16:34:58 +05:30
laurenspriem
ce681d83da Add "this is me" to link email screen 2025-03-24 16:32:21 +05:30
laurenspriem
11bc17e766 Separate util method to check if me is assigned 2025-03-24 16:08:31 +05:30
vishnukvmd
69c71d23c3 Migrate existing free folks 2025-03-24 14:45:38 +05:30
vishnukvmd
214573e0c2 Increase free storage to 10gb 2025-03-24 14:45:28 +05:30
Neeraj Gupta
2e3ac8b485 Return complete claim instead of userID 2025-03-18 14:30:24 +05:30
Neeraj Gupta
47f0c88ed8 Extract method 2025-03-18 14:27:39 +05:30
Neeraj Gupta
162ce32b8e omitEmpty field from claim json 2025-03-18 14:23:54 +05:30
Neeraj Gupta
a1dbdfd6ba Reuse existing claim for recovery 2025-03-18 14:22:15 +05:30
Neeraj Gupta
74072b952d Add JWT model for account recovery 2025-03-18 11:43:45 +05:30
Sven
f27ad4786a Merge branch 'main' of https://github.com/sv3nnie/ente 2025-03-10 12:52:58 +01:00
Sven
cf0ef0f9f4 Decrease height for MEXC 2025-03-10 12:52:55 +01:00
Sven
00c6de0e53 Merge branch 'ente-io:main' into main 2025-03-10 12:41:06 +01:00
Sven
4c7d92530f Add ICONOMI 2025-03-07 23:55:14 +01:00
Sven
cafbdc70e8 Add MEXC icon 2025-03-07 23:32:28 +01:00
764 changed files with 34377 additions and 14941 deletions

View File

@@ -26,6 +26,20 @@ body:
label: Version
description: The version can be seen at the bottom of settings.
placeholder: e.g. v1.2.3
- type: input
attributes:
label: Last working version
description: >
The version where the feature was last known to be working. It is
fine if you don't remember the exact version (mention roughly
then), but if there just isn't a last known working version, then
it is likely that what is being reported is not an issue but a
feature request. The difference between the two categories is not
just semantic - feature requests use GitHub discussions and so can
be [upvoted by the
community](https://github.com/ente-io/ente/discussions/categories/feature-requests)
(issues can't be).
placeholder: e.g. v1.2.3
- type: dropdown
attributes:
label: What product are you using?

View File

@@ -9,6 +9,10 @@ on:
# Or the workflow itself is changed
- ".github/workflows/auth-crowdin.yml"
permissions:
contents: write
pull-requests: write
jobs:
push-sources-to-crowdin:
runs-on: ubuntu-latest

View File

@@ -8,6 +8,10 @@ on:
# Also allow manually running the workflow.
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
synchronize-with-crowdin:
runs-on: ubuntu-latest

View File

@@ -6,6 +6,9 @@ on:
env:
FLUTTER_VERSION: "3.24.3"
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest

View File

@@ -10,6 +10,9 @@ on:
env:
FLUTTER_VERSION: "3.24.3"
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest
@@ -30,7 +33,7 @@ jobs:
exit 1
fi
done
- name: Verify all icons are less than 20KB
run: |
find assets/custom-icons -type f -name "*.svg" | while read -r file; do

View File

@@ -31,9 +31,12 @@ on:
env:
FLUTTER_VERSION: "3.24.3"
permissions:
contents: write
jobs:
build-linux-latest:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
defaults:
run:
@@ -90,7 +93,7 @@ jobs:
- name: Install dependencies for desktop build
run: |
sudo apt-get update -y
sudo apt-get install -y libsecret-1-dev libsodium-dev libfuse2 ninja-build libgtk-3-dev dpkg-dev pkg-config rpm patchelf libsqlite3-dev locate libayatana-appindicator3-dev libffi-dev libtiff6 xz-utils libarchive-tools libcurl4-openssl-dev
sudo apt-get install -y libsecret-1-dev libsodium-dev libfuse2 ninja-build libgtk-3-dev dpkg-dev pkg-config rpm patchelf libsqlite3-dev locate libayatana-appindicator3-dev libffi-dev libtiff5 xz-utils libarchive-tools libcurl4-openssl-dev
sudo updatedb --localpaths='/usr/lib/x86_64-linux-gnu'
- name: Install appimagetool

View File

@@ -12,6 +12,10 @@ on:
tags:
- "cli-v*"
permissions:
contents: write
packages: write
jobs:
draft-release:
runs-on: ubuntu-latest

53
.github/workflows/codeql.yml vendored Normal file
View File

@@ -0,0 +1,53 @@
# The only reason we're making a custom CodeQL configuration is because the
# default setup does not have an option to run daily / weekly instead of per
# push, which is too slow.
#
# In the future, it might become faster. Then just delete this file, and revert
# to the default configuration.
#
# References:
# https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/
name: "CodeQL"
on:
workflow_dispatch: # Allow running manually
schedule:
- cron: "22 1 * * 1"
jobs:
analyze:
name: Analyze (${{ matrix.language }})
runs-on: 'ubuntu-latest'
permissions:
contents: read
# Required for all workflows.
security-events: write
# Required to fetch internal or private CodeQL packs.
packages: read
strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: go
build-mode: autobuild
- language: javascript-typescript
build-mode: none
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"

View File

@@ -3,6 +3,9 @@ name: "Release (copycat-db)"
on:
workflow_dispatch: # Run manually
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest

View File

@@ -7,6 +7,9 @@ on:
- "desktop/**"
- ".github/workflows/desktop-lint.yml"
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest
@@ -20,7 +23,7 @@ jobs:
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: "yarn"
cache-dependency-path: "desktop/yarn.lock"

View File

@@ -10,6 +10,9 @@ on:
# Also allow manually running the workflow
workflow_dispatch:
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
@@ -25,7 +28,7 @@ jobs:
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: "yarn"
cache-dependency-path: "docs/yarn.lock"

View File

@@ -10,6 +10,9 @@ on:
- "docs/**"
- ".github/workflows/docs-verify-build.yml"
permissions:
contents: read
jobs:
verify-build:
runs-on: ubuntu-latest
@@ -25,7 +28,7 @@ jobs:
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: "yarn"
cache-dependency-path: "docs/yarn.lock"

View File

@@ -10,6 +10,9 @@ on:
# Also allow manually running the workflow
workflow_dispatch:
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest
@@ -25,7 +28,7 @@ jobs:
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: "yarn"
cache-dependency-path: "infra/staff/yarn.lock"

View File

@@ -7,6 +7,9 @@ on:
- "infra/staff/**"
- ".github/workflows/infra-deploy-staff.yml"
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
@@ -22,7 +25,7 @@ jobs:
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: "yarn"
cache-dependency-path: "infra/staff/yarn.lock"

View File

@@ -9,6 +9,10 @@ on:
# Or the workflow itself is changed
- ".github/workflows/mobile-crowdin.yml"
permissions:
contents: write
pull-requests: write
jobs:
push-sources-to-crowdin:
runs-on: ubuntu-latest

View File

@@ -8,6 +8,10 @@ on:
# Also allow manually running the workflow.
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
synchronize-with-crowdin:
runs-on: ubuntu-latest

View File

@@ -6,6 +6,9 @@ on:
env:
FLUTTER_VERSION: "3.24.3"
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
@@ -54,7 +57,7 @@ jobs:
packageName: io.ente.photos
releaseFiles: mobile/build/app/outputs/bundle/playstoreRelease/app-playstore-release.aab
track: internal
- name: Notify Discord
uses: sarisia/actions-status-discord@v1
with:

View File

@@ -8,9 +8,11 @@ on:
- ".github/workflows/mobile-lint.yml"
env:
FLUTTER_VERSION: "3.24.3"
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest

View File

@@ -11,6 +11,9 @@ on:
env:
FLUTTER_VERSION: "3.24.3"
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest

View File

@@ -7,6 +7,9 @@ on:
- "server/**"
- ".github/workflows/server-lint.yml"
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest

View File

@@ -7,6 +7,10 @@ on:
# Run manually if needed to publish out of schedule.
workflow_dispatch:
permissions:
contents: write # for pushing the `ghcr/server` branch
packages: write
jobs:
publish:
runs-on: ubuntu-latest

View File

@@ -3,6 +3,9 @@ name: "Release (server)"
on:
workflow_dispatch: # Run manually
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest

View File

@@ -12,6 +12,10 @@ on:
# `gh workflow run web-crowdin-push-both.yml --ref <my-branch>`
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
push-both-to-crowdin:
runs-on: ubuntu-latest

View File

@@ -22,6 +22,15 @@ on:
# Also allow manually running the workflow.
workflow_dispatch:
# "In order to push translations and create pull requests, the Crowdin GitHub
# action requires the `GITHUB_TOKEN` to have write permission on the `contents`
# and `pull-requests`.
#
# - https://github.com/crowdin/github-action?tab=readme-ov-file#permissions
permissions:
contents: write
pull-requests: write
jobs:
synchronize-with-crowdin:
runs-on: ubuntu-latest

View File

@@ -15,6 +15,9 @@ on:
- "payments"
- "photos"
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
@@ -30,7 +33,7 @@ jobs:
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: "yarn"
cache-dependency-path: "web/yarn.lock"

View File

@@ -15,6 +15,9 @@ on:
- "payments"
- "photos"
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
@@ -30,7 +33,7 @@ jobs:
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: "yarn"
cache-dependency-path: "web/yarn.lock"

View File

@@ -11,6 +11,9 @@ on:
# Also allow manually running the workflow
workflow_dispatch:
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
@@ -38,7 +41,7 @@ jobs:
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: "yarn"
cache-dependency-path: "web/yarn.lock"

View File

@@ -19,6 +19,9 @@ on:
# Also allow manually running the workflow
workflow_dispatch:
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
@@ -34,7 +37,7 @@ jobs:
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: "yarn"
cache-dependency-path: "web/yarn.lock"

View File

@@ -7,6 +7,9 @@ on:
- "web/**"
- ".github/workflows/web-lint.yml"
permissions:
contents: read
# Cancel in-progress lint runs when a new commit is pushed.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -25,7 +28,7 @@ jobs:
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: "yarn"
cache-dependency-path: "web/yarn.lock"

View File

@@ -7,6 +7,10 @@ on:
# Run manually if needed to publish out of schedule.
workflow_dispatch:
permissions:
contents: write # for pushing the `ghcr/web` branch
packages: write
jobs:
publish:
runs-on: ubuntu-latest

View File

@@ -35,7 +35,7 @@ Private sharing. Collaborative albums. Family plans. Easy import, easier export.
Background uploads. The list goes on. And of course, all of this, while being
fully end-to-end encrypted across platforms.
Ente Photos is a paid service, but we offer 5GB of free storage.
Ente Photos is a paid service, but we offer 10GB of free storage.
You can also clone this repository and choose to self-host.
<br />

3
auth/.fvmrc Normal file
View File

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

5
auth/.gitignore vendored
View File

@@ -41,4 +41,7 @@ lib/generated_plugin_registrant.dart
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
android/key.properties
dist/
dist/
# FVM Version Cache
.fvm/

View File

@@ -5,6 +5,8 @@ gradle-wrapper.jar
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
/app/.cxx/
/.kotlin/
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@@ -1,6 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
<foreground>
<inset
android:drawable="@drawable/ic_launcher_foreground"
android:inset="0%" />
</foreground>
<monochrome>
<inset
android:drawable="@drawable/ic_launcher_monochrome"
android:inset="0%" />
</monochrome>
</adaptive-icon>

View File

@@ -132,6 +132,10 @@
"Binance US"
]
},
{
"title": "Bitkub",
"slug": "bitkub"
},
{
"title": "Bitfinex"
},
@@ -183,6 +187,9 @@
"title": "Bluesky",
"slug": "blue_sky"
},
{
"title": "bonify"
},
{
"title": "Booking",
"altNames": [
@@ -208,6 +215,13 @@
{
"title": "Bugzilla"
},
{
"title": "Bundesagentur für Arbeit",
"slug": "bundesagentur_fur_arbeit",
"altNames": [
"Agentur für Arbeit"
]
},
{
"title": "ButterflyMX",
"slug": "butterflymx"
@@ -285,6 +299,15 @@
"title": "CSGORoll",
"slug": "csgoroll"
},
{
"title": "Cwallet",
"altNames": [
"cwallet",
"c-wallet",
"c wallet",
"cwallet.com"
]
},
{
"title": "DCS",
"altNames": [
@@ -376,6 +399,13 @@
],
"hex": "858585"
},
{
"title": "Fanatical",
"slug": "fanatical",
"altNames": [
"FANATICAL"
]
},
{
"title": "Fastmail"
},
@@ -405,6 +435,9 @@
"title": "Firefox",
"slug": "mozilla"
},
{
"title": "fortrabbit"
},
{
"title": "ForUsAll"
},
@@ -499,12 +532,19 @@
"slug": "id_me"
},
{
"title": "Infomaniak"
"title": "ImmoScout24",
"slug": "immo_scout_24",
"altNames": [
"ImmobilienScout24"
]
},
{
"title": "Impact.com",
"slug": "impact"
},
{
"title": "Infomaniak"
},
{
"title": "ING"
},
@@ -606,8 +646,7 @@
},
{
"title": "LinkedIn",
"slug": "linkedin",
"hex": "2596be"
"slug": "linkedin"
},
{
"title": "Linux.Do",
@@ -658,6 +697,14 @@
"mathworks"
]
},
{
"title": "Mbin",
"altNames": [
"kbin",
"thebrainbin",
"gehirneimer"
]
},
{
"title": "Mercado Livre",
"slug": "mercado_livre",
@@ -888,6 +935,13 @@
{
"title": "PostNL"
},
{
"title": "Postmark",
"slug": "postmarkapp",
"altNames": [
"postmarkapp"
]
},
{
"title": "PostScan Mail",
"slug": "postscanmail",
@@ -952,6 +1006,15 @@
"slug": "realvnc",
"hex": "488aec"
},
{
"title": "RedotPay",
"altNames": [
"redotpay",
"redot pay",
"redot-pay",
"redotpay.com"
]
},
{
"title": "Registro br",
"slug": "registro_br",

View File

@@ -1 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 150 150"><defs><style>.e{fill:#2a54ff;}.f{fill:url(#d);}.g{fill:none;}</style><linearGradient id="d" x1="17.68" y1="116.45" x2="132.14" y2="32.11" gradientTransform="matrix(1, 0, 0, 1, 0, 0)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2a54ff"/><stop offset=".52" stop-color="#2143cb"/><stop offset="1" stop-color="#2a54ff"/></linearGradient></defs><g id="b"><path id="c" class="g" d="M0,0H150V150H0V0Z"/></g><path class="f" d="M140.2,22.33c-25.18-.09-49.79,10.83-66.63,29.47-6.06,6.27-10.1,13.95-14.96,21.06-11.64,15.93-29.81,25.14-49.5,25.13h0v28.65h0c25.17,.1,49.78-10.86,66.63-29.5,6.03-6.27,10.13-13.94,14.96-21.06,11.64-15.91,29.81-25.12,49.5-25.11V22.33h0Z"/><path class="e" d="M140.2,97.99c-19.68,0-37.86-9.2-49.5-25.11-4.81-7.12-8.92-14.78-14.94-21.06C58.95,33.18,34.3,22.24,9.13,22.35h0v28.65h0c21.8-.11,42.05,11.62,53.01,30.46,3.22,5.62,7.06,10.9,11.45,15.74,16.83,18.63,41.46,29.59,66.63,29.5l-.02-28.7h0Z"/></svg>
<?xml version='1.0' encoding='utf-8'?>
<svg xmlns="http://www.w3.org/2000/svg" id="a" viewBox="0 0 150 150">
<defs>
<linearGradient id="d" x1="17.68" y1="116.45" x2="132.14" y2="32.11"
gradientTransform="matrix(1, 0, 0, 1, 0, 0)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#2a54ff" />
<stop offset=".52" stop-color="#2143cb" />
<stop offset="1" stop-color="#2a54ff" />
</linearGradient>
</defs>
<g id="b">
<path id="c" d="M0,0H150V150H0V0Z" fill="none" />
</g>
<path
d="M140.2,22.33c-25.18-.09-49.79,10.83-66.63,29.47-6.06,6.27-10.1,13.95-14.96,21.06-11.64,15.93-29.81,25.14-49.5,25.13h0v28.65h0c25.17,.1,49.78-10.86,66.63-29.5,6.03-6.27,10.13-13.94,14.96-21.06,11.64-15.91,29.81-25.12,49.5-25.11V22.33h0Z"
fill="url(#d)" />
<path
d="M140.2,97.99c-19.68,0-37.86-9.2-49.5-25.11-4.81-7.12-8.92-14.78-14.94-21.06C58.95,33.18,34.3,22.24,9.13,22.35h0v28.65h0c21.8-.11,42.05,11.62,53.01,30.46,3.22,5.62,7.06,10.9,11.45,15.74,16.83,18.63,41.46,29.59,66.63,29.5l-.02-28.7h0Z"
fill="#2a54ff" />
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 245.73 156" xmlns="http://www.w3.org/2000/svg"><g fill="#4cba64"><path d="m167.87 0a23.32 23.32 0 0 0 0 33l44.89 44.9-45 45-22.89-22.9a23.34 23.34 0 0 0 -33 0l55.86 55.87 78-78z"/><circle cx="167.87" cy="78" r="16"/><path d="m77.87 156a23.34 23.34 0 0 0 0-33l-44.87-44.9 45-45 22.87 22.9a23.34 23.34 0 0 0 33 0l-55.87-55.87-78 78z"/><circle cx="77.87" cy="78" r="16"/></g></svg>

After

Width:  |  Height:  |  Size: 396 B

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="logosandtypes_com" data-name="logosandtypes com" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 150 150">
<defs>
<style>
.cls-1 {
fill: #101010;
}
.cls-2 {
fill: none;
}
.cls-3 {
fill: url(#linear-gradient);
}
</style>
<linearGradient id="linear-gradient" x1="186.97" y1="96.04" x2="45.7" y2="96.04" gradientTransform="translate(0 150.11) scale(1 -1)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#165cc3"/>
<stop offset="1" stop-color="#3ddabb"/>
</linearGradient>
</defs>
<g id="Layer_3" data-name="Layer 3">
<g id="Layer_2" data-name="Layer 2">
<path id="Layer_3-2" data-name="Layer 3-2" class="cls-2" d="M0,0H150V150H0V0Z"/>
</g>
</g>
<path class="cls-1" d="M111.63,75.01c.06,.86,.08,1.72,.08,2.59,0,20.52-16.62,37.16-37.14,37.16-20.52,0-37.16-16.62-37.16-37.14,0-20.52,16.62-37.16,37.14-37.16,0,0,.02,0,.02,0,1.61,0,3.22,.1,4.82,.32l12.7-17.11C62.3,14,30.31,30.3,20.63,60.09c-9.68,29.79,6.62,61.78,36.41,71.47,29.79,9.68,61.78-6.62,71.47-36.41,4.29-13.2,3.59-27.52-1.97-40.24l-14.9,20.11Z"/>
<polygon class="cls-3" points="120.26 4.82 74.49 66.53 62.93 53.99 45.67 69.89 76.4 103.32 149.5 4.82 120.26 4.82"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Created with Inkscape (http://www.inkscape.org/) by Marsupilami -->
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="768" height="768" viewBox="-4.3240767 -4.3240767 152.8084434 152.7840434" id="svg7076">
<defs id="defs7078"/>
<path d="M 0,72.07202 C 0,32.27318 32.2935,0 72.08013,0 c 39.78662,0 72.08017,32.27318 72.08017,72.07202 0,39.80291 -32.29355,72.06387 -72.08017,72.06387 -17.63317,0 -33.75958,-6.32434 -46.30232,-16.82687 11.769,-19.46163 46.13944,-77.28864 46.13944,-77.28864 l 17.0223,28.5022 c 0,0 -8.95912,0.0448 -17.06303,0 -8.14464,-0.0448 -10.46588,1.7063 -14.00878,7.11027 -2.9321,4.4877 -9.85505,16.21193 -10.01793,16.42776 -0.81448,1.29093 -0.3258,2.54114 1.58818,2.54114 l 55.18001,0 28.01759,0 c 1.66968,0 2.64704,-1.16875 1.58822,-2.6226 L 73.34255,2.43932 c -0.81447,-1.37236 -2.11759,-1.25021 -2.85061,0 L 8.4704,105.97411 C 3.09495,95.87068 0,84.32969 0,72.07202" id="path8406" style="fill:#ec1c23;fill-rule:nonzero;stroke:none"/>
</svg>
<!-- version: 20110311, original size: 144.16029 144.13589, border: 3% -->

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,130 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;" xml:space="preserve">
<style type="text/css">
.st0{fill:#C5C8CA;}
.st1{fill:#9DA4A8;}
.st2{fill:#B7BBBD;}
.st3{fill:#CBCFD1;}
.st4{fill:#BBBFC2;}
.st5{fill:#CACDCE;}
.st6{fill:#BFC3C5;}
.st7{fill:#BCC0C2;}
.st8{fill:#BDC1C4;}
.st9{fill:#C7CACC;}
.st10{fill:url(#SVGID_1_);}
.st11{fill:#FFFFFF;}
.st12{fill:#B8BCBF;}
.st13{fill:#C4C7C9;}
.st14{fill:#C1C5C7;}
.st15{fill:url(#SVGID_00000003093454306001190100000011813141018663887528_);}
.st16{fill:url(#SVGID_00000017503418065689336600000007511615486600436881_);}
.st17{fill:url(#SVGID_00000057845154053127761930000017803385842445649033_);}
.st18{fill:url(#SVGID_00000156571711195124538550000006687723982713171592_);}
.st19{fill:#DF3030;}
.st20{fill:url(#SVGID_00000001636660173574603980000008731795684331757470_);}
.st21{fill:#17181C;}
.st22{fill:url(#SVGID_00000180343933242210086490000003762167186865041053_);}
.st23{fill:url(#SVGID_00000015338415700440354440000005681408021599925436_);}
</style>
<g>
<path class="st0" d="M14.4,29.5c0.1,0,0.1,0,0.2,0c0.1,0,0.2,0,0.2,0H14.4z"/>
<path class="st1" d="M15.3,29.5h0.1c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0L15.3,29.5
C15.2,29.5,15.3,29.5,15.3,29.5z"/>
<path class="st2" d="M15.3,29.5L15.3,29.5l-0.2,0C15.2,29.5,15.2,29.5,15.3,29.5z"/>
<path class="st3" d="M15.5,29.5L15.5,29.5L15.5,29.5L15.5,29.5L15.5,29.5z"/>
<path class="st0" d="M14.1,29.5c0.1,0,0.1,0,0.2,0H14.1z"/>
<path class="st4" d="M13.9,29.5C13.9,29.5,14,29.5,13.9,29.5c0.1,0,0.1,0,0.2,0H13.9z"/>
<path class="st5" d="M13.6,29.5C13.6,29.5,13.6,29.5,13.6,29.5c0.1,0,0.1,0,0.1,0H13.6z"/>
<path class="st6" d="M13.7,29.5C13.8,29.5,13.8,29.5,13.7,29.5c0.1,0,0.1,0,0.1,0H13.7z"/>
<path class="st7" d="M13.3,29.4C13.3,29.4,13.3,29.4,13.3,29.4C13.4,29.4,13.4,29.4,13.3,29.4L13.3,29.4z"/>
<path class="st8" d="M13.4,29.5C13.4,29.4,13.5,29.4,13.4,29.5C13.5,29.4,13.5,29.4,13.4,29.5L13.4,29.5z"/>
<path class="st8" d="M13.1,29.4C13.1,29.4,13.1,29.4,13.1,29.4C13.1,29.4,13.1,29.4,13.1,29.4L13.1,29.4z"/>
<path class="st9" d="M13.2,29.4C13.2,29.4,13.2,29.4,13.2,29.4C13.2,29.4,13.2,29.4,13.2,29.4C13.2,29.4,13.2,29.4,13.2,29.4
C13.3,29.4,13.3,29.4,13.2,29.4L13.2,29.4z"/>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="21.8812" y1="-88.078" x2="8.2545" y2="-104.6955" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
<stop offset="0" style="stop-color:#020037"/>
<stop offset="1" style="stop-color:#050F62"/>
</linearGradient>
<path class="st10" d="M15,0.4C11.1,0.4,7.5,2,4.7,4.7C2,7.4,0.5,11.1,0.5,15c0,1.7,0.3,3.4,0.9,5.1c0.3,0,0.5,0,0.8,0
c2.9,0,5.8,0.9,8.2,2.6c2.4,1.7,4.2,4.1,5.1,6.9c3.8-0.1,7.4-1.7,10-4.4c2.6-2.7,4.1-6.4,4.1-10.1c0-3.9-1.5-7.6-4.3-10.3
C22.6,2,18.9,0.4,15,0.4"/>
<path class="st11" d="M20.7,22.5C20.7,22.5,20.7,22.5,20.7,22.5L20.7,22.5c0,0.4,0.1,0.8,0.3,1c0.2,0.2,0.6,0.3,1,0.3c0,0,0,0,0,0
c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0l0,0c-0.4,0-0.7,0.1-1,0.3c-0.2,0.2-0.3,0.6-0.3,1c0,0,0,0,0,0c0,0,0,0,0,0
c0,0,0,0,0,0c0,0,0,0,0,0h0l0,0c0-0.4-0.1-0.7-0.3-1c-0.2-0.2-0.6-0.3-1-0.3c0,0,0,0,0,0l0,0c0,0,0,0,0,0s0,0,0,0c0,0,0,0,0,0
c0,0,0,0,0,0c0.4,0,0.7-0.1,1-0.3S20.7,22.9,20.7,22.5C20.7,22.5,20.7,22.5,20.7,22.5C20.7,22.5,20.7,22.5,20.7,22.5z"/>
<path class="st11" d="M6.9,15.5C6.9,15.5,6.9,15.5,6.9,15.5L6.9,15.5c0,0.4,0.1,0.8,0.3,1c0.2,0.2,0.6,0.3,1,0.3c0,0,0,0,0,0
c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0l0,0c-0.4,0-0.7,0.1-1,0.3c-0.2,0.2-0.3,0.6-0.3,1c0,0,0,0,0,0c0,0,0,0,0,0
c0,0,0,0,0,0c0,0,0,0,0,0h0l0,0c0-0.4-0.1-0.7-0.3-1c-0.2-0.2-0.6-0.3-1-0.3c0,0,0,0,0,0l0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0
c0,0,0,0,0,0c0.4,0,0.7-0.1,1-0.3C6.8,16.2,6.9,15.9,6.9,15.5C6.9,15.5,6.9,15.5,6.9,15.5C6.9,15.5,6.9,15.5,6.9,15.5z"/>
<path class="st11" d="M10.6,4.1L10.6,4.1C10.7,4.1,10.7,4.1,10.6,4.1c0,0.3,0.1,0.5,0.3,0.7c0.2,0.2,0.4,0.3,0.7,0.2h0v0l0,0l0,0
l0,0l0,0c-0.3,0-0.5,0.1-0.7,0.2c-0.2,0.2-0.3,0.4-0.2,0.7l0,0l0,0l0,0l0,0h0v0c0-0.3-0.1-0.5-0.2-0.7C10.2,5.1,10,5,9.7,5.1h0v0v0
h0C10,5,10.2,5,10.4,4.8C10.6,4.6,10.7,4.3,10.6,4.1C10.6,4.1,10.6,4.1,10.6,4.1C10.6,4.1,10.6,4.1,10.6,4.1z"/>
<path class="st12" d="M12.8,29.4C12.8,29.4,12.8,29.4,12.8,29.4C12.8,29.4,12.8,29.4,12.8,29.4C12.8,29.4,12.8,29.4,12.8,29.4
C12.8,29.4,12.8,29.4,12.8,29.4L12.8,29.4z"/>
<path class="st13" d="M13,29.4C13,29.4,13,29.4,13,29.4C13,29.4,13,29.4,13,29.4L13,29.4z"/>
<path class="st14" d="M12.9,29.4C12.9,29.4,12.9,29.4,12.9,29.4C12.9,29.4,12.9,29.4,12.9,29.4L12.9,29.4z"/>
<linearGradient id="SVGID_00000173122186048074043340000017421439166240502921_" gradientUnits="userSpaceOnUse" x1="19.2457" y1="-89.3156" x2="22.9553" y2="-91.7188" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
<stop offset="0" style="stop-color:#E5E5E5"/>
<stop offset="1" style="stop-color:#B7B8C1"/>
</linearGradient>
<path style="fill:url(#SVGID_00000173122186048074043340000017421439166240502921_);" d="M21.8,1.2c-1.4,0.7-3,1.9-4.4,4.2
c-2.5,3.9-3.2,7.4-3.2,7.4L16,14l0.3,0.2l1.9,1.2c0,0,2.9-2,5.4-5.9c1.5-2.3,2-4.3,2-5.8c-0.8-0.1-1.5-0.4-2.2-0.8
C22.8,2.5,22.2,1.9,21.8,1.2z"/>
<linearGradient id="SVGID_00000127763695479642710240000017533313096818365313_" gradientUnits="userSpaceOnUse" x1="21.2378" y1="-99.9826" x2="19.0472" y2="-97.8815" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
<stop offset="0" style="stop-color:#EC4F4F"/>
<stop offset="1" style="stop-color:#A91919"/>
</linearGradient>
<path style="fill:url(#SVGID_00000127763695479642710240000017533313096818365313_);" d="M20.8,16.8c0.9-1.4,0.3-3.2,0-3.8
c-0.7,0.8-1.5,1.5-2.3,2.1c0.1,0.4,0.3,0.8,0.3,1.2c0,0.1,0,0.2-0.1,0.3c-0.4,0.6-0.8,1.3-1.1,2c-0.1,0.1-0.1,0.2-0.1,0.3
c-0.1,0.2-0.1,0.3,0,0.5c0,0.3,0.2,0.5,0.3,0.8c0,0,0.1,0.1,0.1,0.1c0.1,0,0.1,0.1,0.2,0.1s0.1,0,0.2-0.1c0.1-0.1,0.3-0.2,0.4-0.4
C19.5,19,19.8,18.5,20.8,16.8z"/>
<linearGradient id="SVGID_00000060717637781723915790000002744012061535479481_" gradientUnits="userSpaceOnUse" x1="11.3158" y1="-99.2586" x2="14.8122" y2="-101.5237" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
<stop offset="0" style="stop-color:#F2A518"/>
<stop offset="1" style="stop-color:#F4E23E"/>
</linearGradient>
<path style="fill:url(#SVGID_00000060717637781723915790000002744012061535479481_);" d="M15.1,15.7l-1.7-1.1c-2,3.1-3.3,7-2.4,7.5
c0.9,0.6,3.9-2.2,5.9-5.3L15.1,15.7z"/>
<linearGradient id="SVGID_00000070084874335106853820000008402293642909580433_" gradientUnits="userSpaceOnUse" x1="-4386.2534" y1="747.6443" x2="-4497.9517" y2="769.0099" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
<stop offset="0" style="stop-color:#EC4F4F"/>
<stop offset="1" style="stop-color:#A91919"/>
</linearGradient>
<path style="fill:url(#SVGID_00000070084874335106853820000008402293642909580433_);" d="M15.2,9.5c-0.7-0.1-2.5,0.1-3.4,1.5
c-1.1,1.6-1.5,2.1-2,3.2c-0.1,0.2-0.1,0.3-0.2,0.5c0,0.1,0,0.1,0,0.2C9.6,15,9.7,15,9.7,15c0,0,0.1,0,0.2,0.1c0.3,0.1,0.6,0,0.8,0
c0.2,0,0.3-0.1,0.4-0.2c0.1-0.1,0.2-0.2,0.3-0.3c0.5-0.6,0.9-1.2,1.3-1.8c0.1-0.1,0.2-0.2,0.3-0.2c0.4-0.1,0.8-0.1,1.2-0.2l0,0
C14.5,11.4,14.8,10.4,15.2,9.5z"/>
<path class="st19" d="M25,0.6c-0.2-0.1-1.5-0.2-3.2,0.7c0.4,0.7,1,1.2,1.6,1.7c0.7,0.4,1.4,0.7,2.2,0.8C25.7,1.9,25.1,0.7,25,0.6z"
/>
<path class="st19" d="M18.4,15.5L14,12.7c-0.1,0-0.1,0-0.2,0l-0.9,1.4c0,0.1,0,0.1,0,0.2l4.4,2.8c0.1,0,0.1,0,0.2,0l0.9-1.4
C18.4,15.6,18.4,15.6,18.4,15.5z"/>
<linearGradient id="SVGID_00000044894753735506851200000013592864944465274029_" gradientUnits="userSpaceOnUse" x1="14.9436" y1="-95.9217" x2="16.3716" y2="-96.8468" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
<stop offset="0" style="stop-color:#B71E1E"/>
<stop offset="0.44" style="stop-color:#DF3030"/>
<stop offset="1" style="stop-color:#C51D1D"/>
</linearGradient>
<path style="fill:url(#SVGID_00000044894753735506851200000013592864944465274029_);" d="M17.8,11.6c-0.4-0.2-2.1,1.6-3.2,3.3
c-0.8,1.2-1.4,3-1.1,3.2c0.4,0.2,1.7-1,2.5-2.3C17.1,14.2,18.1,11.9,17.8,11.6z"/>
<path class="st21" d="M21.2,8.6c1.3,0,2.3-1,2.3-2.3s-1-2.3-2.3-2.3c-1.3,0-2.3,1-2.3,2.3S20,8.6,21.2,8.6z"/>
<linearGradient id="SVGID_00000090987122570624474440000002432161440392897685_" gradientUnits="userSpaceOnUse" x1="20.068" y1="-87.0655" x2="22.3556" y2="-88.5473" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
<stop offset="0" style="stop-color:#CED1EC"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<path style="fill:url(#SVGID_00000090987122570624474440000002432161440392897685_);" d="M21.2,7.7c0.8,0,1.4-0.6,1.4-1.4
S22,5,21.2,5c-0.8,0-1.4,0.6-1.4,1.4S20.5,7.7,21.2,7.7z"/>
<linearGradient id="SVGID_00000044151119195171880090000016489263670362291109_" gradientUnits="userSpaceOnUse" x1="14.4192" y1="-110.4727" x2="2.0973" y2="-101.7197" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
<stop offset="0" style="stop-color:#B7B7BD"/>
<stop offset="0.68" style="stop-color:#EFEFEF"/>
</linearGradient>
<path style="fill:url(#SVGID_00000044151119195171880090000016489263670362291109_);" d="M2.1,20c-0.3,0-0.5,0-0.8,0
c1,2.8,2.9,5.2,5.3,6.9s5.3,2.6,8.3,2.6c0.1,0,0.3,0,0.4,0c-0.9-2.8-2.7-5.2-5.1-6.9C7.9,20.9,5.1,20,2.1,20z"/>
</g>
</svg>
<svg xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" x="0" y="0" version="1.1"
viewBox="0 0 30 30">
<path d="M14.4 29.5h.4z" fill="#c5c8ca" />
<path fill="#9da4a8" d="M15.3 29.5h.1zc-.1 0 0 0 0 0" />
<path fill="#b7bbbd" d="M15.3 29.5h-.2z" />
<path d="M14.1 29.5h.2z" fill="#c5c8ca" />
<path fill="#bbbfc2" d="M13.9 29.5s.1 0 0 0h.2z" />
<path fill="#cacdce" d="M13.6 29.5h.1z" />
<path fill="#bfc3c5" d="M13.7 29.5q.15 0 0 0h.1z" />
<path fill="#bcc0c2" d="M13.3 29.4q.15 0 0 0" />
<path fill="#bdc1c4" d="M13.4 29.5c0-.1.1-.1 0 0q.15-.15 0 0m-.3-.1" />
<path fill="#c7cacc" d="M13.2 29.4q.15 0 0 0" />
<linearGradient id="SVGID_1_" x1="21.8812" x2="8.2545" y1="-88.078" y2="-104.6955" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#020037" />
<stop offset="1" stop-color="#050f62" />
</linearGradient>
<path fill="url(#SVGID_1_)" d="M15 .4C11.1.4 7.5 2 4.7 4.7 2 7.4.5 11.1.5 15q0 2.55.9 5.1h.8c2.9 0 5.8.9 8.2 2.6s4.2 4.1 5.1 6.9c3.8-.1 7.4-1.7 10-4.4s4.1-6.4 4.1-10.1c0-3.9-1.5-7.6-4.3-10.3C22.6 2 18.9.4 15 .4" />
<path fill="#fff" d="M20.7 22.5c0 .4.1.8.3 1s.6.3 1 .3c-.4 0-.7.1-1 .3-.2.2-.3.6-.3 1 0-.4-.1-.7-.3-1-.2-.2-.6-.3-1-.3.4 0 .7-.1 1-.3s.3-.6.3-1m-13.8-7c0 .4.1.8.3 1s.6.3 1 .3c-.4 0-.7.1-1 .3-.2.2-.3.6-.3 1 0-.4-.1-.7-.3-1-.2-.2-.6-.3-1-.3.4 0 .7-.1 1-.3.2-.3.3-.6.3-1m3.7-11.4q.15 0 0 0c0 .3.1.5.3.7s.4.3.7.2c-.3 0-.5.1-.7.2-.2.2-.3.4-.2.7 0-.3-.1-.5-.2-.7-.3-.1-.5-.2-.8-.1.3-.1.5-.1.7-.3s.3-.5.2-.7" />
<linearGradient id="SVGID_00000173122186048074043340000017421439166240502921_" x1="19.2457" x2="22.9553" y1="-89.3156" y2="-91.7188" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#e5e5e5" />
<stop offset="1" stop-color="#b7b8c1" />
</linearGradient>
<path fill="url(#SVGID_00000173122186048074043340000017421439166240502921_)" d="M21.8 1.2c-1.4.7-3 1.9-4.4 4.2-2.5 3.9-3.2 7.4-3.2 7.4L16 14l.3.2 1.9 1.2s2.9-2 5.4-5.9c1.5-2.3 2-4.3 2-5.8-.8-.1-1.5-.4-2.2-.8-.6-.4-1.2-1-1.6-1.7" />
<linearGradient id="SVGID_00000127763695479642710240000017533313096818365313_" x1="21.2378" x2="19.0472" y1="-99.9826" y2="-97.8815" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ec4f4f" />
<stop offset="1" stop-color="#a91919" />
</linearGradient>
<path fill="url(#SVGID_00000127763695479642710240000017533313096818365313_)" d="M20.8 16.8c.9-1.4.3-3.2 0-3.8-.7.8-1.5 1.5-2.3 2.1.1.4.3.8.3 1.2 0 .1 0 .2-.1.3-.4.6-.8 1.3-1.1 2-.1.1-.1.2-.1.3-.1.2-.1.3 0 .5 0 .3.2.5.3.8l.1.1c.1 0 .1.1.2.1s.1 0 .2-.1.3-.2.4-.4c.8-.9 1.1-1.4 2.1-3.1" />
<linearGradient id="SVGID_00000060717637781723915790000002744012061535479481_" x1="11.3158" x2="14.8122" y1="-99.2586" y2="-101.5237" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f2a518" />
<stop offset="1" stop-color="#f4e23e" />
</linearGradient>
<path fill="url(#SVGID_00000060717637781723915790000002744012061535479481_)" d="m15.1 15.7-1.7-1.1c-2 3.1-3.3 7-2.4 7.5.9.6 3.9-2.2 5.9-5.3z" />
<linearGradient id="SVGID_00000070084874335106853820000008402293642909580433_" x1="-4386.2534" x2="-4497.9517" y1="747.6443" y2="769.0099" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ec4f4f" />
<stop offset="1" stop-color="#a91919" />
</linearGradient>
<path fill="url(#SVGID_00000070084874335106853820000008402293642909580433_)" d="M15.2 9.5c-.7-.1-2.5.1-3.4 1.5-1.1 1.6-1.5 2.1-2 3.2-.1.2-.1.3-.2.5v.2c0 .1.1.1.1.1s.1 0 .2.1c.3.1.6 0 .8 0s.3-.1.4-.2l.3-.3c.5-.6.9-1.2 1.3-1.8.1-.1.2-.2.3-.2.4-.1.8-.1 1.2-.2.3-1 .6-2 1-2.9" />
<path fill="#df3030" d="M25 .6c-.2-.1-1.5-.2-3.2.7.4.7 1 1.2 1.6 1.7.7.4 1.4.7 2.2.8.1-1.9-.5-3.1-.6-3.2m-6.6 14.9L14 12.7h-.2l-.9 1.4v.2l4.4 2.8h.2l.9-1.4z" />
<linearGradient id="SVGID_00000044894753735506851200000013592864944465274029_" x1="14.9436" x2="16.3716" y1="-95.9217" y2="-96.8468" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#b71e1e" />
<stop offset=".44" stop-color="#df3030" />
<stop offset="1" stop-color="#c51d1d" />
</linearGradient>
<path fill="url(#SVGID_00000044894753735506851200000013592864944465274029_)" d="M17.8 11.6c-.4-.2-2.1 1.6-3.2 3.3-.8 1.2-1.4 3-1.1 3.2.4.2 1.7-1 2.5-2.3 1.1-1.6 2.1-3.9 1.8-4.2" />
<path fill="#17181c" d="M21.2 8.6c1.3 0 2.3-1 2.3-2.3S22.5 4 21.2 4s-2.3 1-2.3 2.3 1.1 2.3 2.3 2.3" />
<linearGradient id="SVGID_00000090987122570624474440000002432161440392897685_" x1="20.068" x2="22.3556" y1="-87.0655" y2="-88.5473" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ced1ec" />
<stop offset="1" stop-color="#fff" />
</linearGradient>
<path fill="url(#SVGID_00000090987122570624474440000002432161440392897685_)" d="M21.2 7.7c.8 0 1.4-.6 1.4-1.4S22 5 21.2 5s-1.4.6-1.4 1.4.7 1.3 1.4 1.3" />
<linearGradient id="SVGID_00000044151119195171880090000016489263670362291109_" x1="14.4192" x2="2.0973" y1="-110.4727" y2="-101.7197" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#b7b7bd" />
<stop offset=".68" stop-color="#efefef" />
</linearGradient>
<path fill="url(#SVGID_00000044151119195171880090000016489263670362291109_)" d="M2.1 20h-.8c1 2.8 2.9 5.2 5.3 6.9s5.3 2.6 8.3 2.6h.4c-.9-2.8-2.7-5.2-5.1-6.9C7.9 20.9 5.1 20 2.1 20" />
</svg>

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 399.76401 400"
preserveAspectRatio="xMinYMid"
aria-labelledby="navbar-fanatical-logo"
version="1.1"
id="svg2"
sodipodi:docname="Untitled.svg"
width="399.76401"
height="400"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs2" />
<sodipodi:namedview
id="namedview2"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="0.69295302"
inkscape:cx="205.64165"
inkscape:cy="207.08475"
inkscape:window-width="1920"
inkscape:window-height="938"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<g
fill="none"
id="g2">
<path
fill="#ff9800"
d="m 2.8756,166.0056 h 284.671 a 2.9981,2.9981 0 0 0 2.7221,-1.7424 l 25.8632,-56.0452 c 0.6946,-1.504 0.0391,-3.2867 -1.464,-3.9817 a 2.9968,2.9968 0 0 0 -1.258,-0.2767 L 24.4917,103.9952 C 58.4482,42.0187 124.261,0 199.882,0 c 110.3917,0 199.882,89.543 199.882,200 0,110.457 -89.4903,200 -199.882,200 C 89.4902,400 0,310.457 0,200 0,188.412 0.985,177.054 2.8756,166.0056 Z M 125.9256,328 c 0,2.2091 1.7898,4 3.9977,4 h 5.1722 l 62.8312,-79.0111 h 49.4291 a 2.9981,2.9981 0 0 0 2.722,-1.7422 l 25.835,-55.976 a 3.0015,3.0015 0 0 0 0.2761,-1.2577 c 0,-1.6569 -1.3423,-3 -2.9982,-3 H 125.9257 V 328 Z"
id="path1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"><path d="M115 144c0 6-2 12-7 16s-9 7-16 7-11-3-16-7-6-10-6-16 2-12 6-16 10-7 16-7 12 3 16 7c5 5 7 10 7 16zm71-23-8 38-7 34a63 63 0 0 1-36 42c-5 2-11 3-17 3s-10 0-14-2l-7-4c-2-1-4-3-4-5l-1-6c0-4 1-7 3-9s6-4 10-4l9 2c3 1 4 4 6 6l4 8 3 7c3-3 5-7 7-13l7-22 16-75h-18l2-9h18l1-7c1-6 4-11 7-17s7-10 12-14c4-4 10-8 16-10s11-4 17-4l13 1 8 4 4 6 1 6a15 15 0 0 1-3 8l-4 4-7 1-8-2-6-6-4-8-3-7c-3 3-5 7-7 12l-6 23-2 10h22l-2 9h-22z"/></svg>

After

Width:  |  Height:  |  Size: 491 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,4 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 724 264">
<path
d="M38.53 260.65H.43V27.86h38.1zm86.46 2.77c-42.25 0-66.48-22.96-66.48-63V89.33h38.1v108.28c0 23.61 8.7 32.39 32.12 32.39 30.35 0 42.73-14.54 42.73-50.17v-90.5h38.1v171.33h-36.54v-29.91c-4.99 22.98-27.12 32.67-48.03 32.67zm347.2-2.77H434.4V149.87c0-22.5-7.01-30.87-25.88-30.87-24.28 0-37.11 14.45-37.11 41.79v99.86h-37.79V149.87c0-21.93-7.23-30.87-24.94-30.87-31.59 0-38.05 32.96-38.05 41.79v99.86h-38.1V89.33h36.54v29.96c6.49-21.02 27.02-33.71 47.72-33.71 20.69 0 38.09 7.9 45.64 33.71 10.13-26.76 28.35-33.71 50.15-33.71 37.88 0 59.61 18.88 59.61 51.81v123.26h0zm76.65 2.77c-52.62 0-61.55-33.45-61.55-50.52 0-20.1 8.83-38.21 27.93-45.55 8.41-3.11 16.52-5.43 24.84-7.1 7.33-1.47 18.64-3.03 26.91-4.17l2.73-.38c14.38-2 29.67-9.21 29.67-18.62 0-16-20.51-18.39-32.74-18.39-13.87 0-23.64 3.57-27.53 10.05-3.49 6.46-3.73 7.97-4.62 13.6l-.62 4.43h-38.1l.68-5.61c1.35-11.14 3.41-19.03 6.48-24.83 10.54-20.39 31.77-30.75 63.08-30.75 26.11 0 44.63 8.23 53.26 15.94 5.31 4.6 9.1 9.84 11.89 16.46 5.84 12.36 6.32 20.63 6.32 29.4v86.43c0 8.07.78 14.97 2.31 20.5l1.76 6.35h-38.91l-.7-4.19c-.5-2.96-.67-19.75-.88-26.23-8.99 23.61-28.27 33.18-52.21 33.18zm50.53-93.72c-7.97 6.11-20.47 9.6-38.62 13.23-31.27 5.78-36.54 13.06-36.54 27.22 0 12.5 10.63 20.26 27.75 20.26 33.23 0 47.41-15.48 47.41-51.77v-8.94zm124.2-105.51C688.46 64.19 660 35.73 660 .62c0 35.11-28.46 63.57-63.57 63.57h0c35.11 0 63.57 28.46 63.57 63.57h0c0-35.11 28.46-63.57 63.57-63.57z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 724 264">
<path
d="M38.53 260.65H.43V27.86h38.1zm86.46 2.77c-42.25 0-66.48-22.96-66.48-63V89.33h38.1v108.28c0 23.61 8.7 32.39 32.12 32.39 30.35 0 42.73-14.54 42.73-50.17v-90.5h38.1v171.33h-36.54v-29.91c-4.99 22.98-27.12 32.67-48.03 32.67zm347.2-2.77H434.4V149.87c0-22.5-7.01-30.87-25.88-30.87-24.28 0-37.11 14.45-37.11 41.79v99.86h-37.79V149.87c0-21.93-7.23-30.87-24.94-30.87-31.59 0-38.05 32.96-38.05 41.79v99.86h-38.1V89.33h36.54v29.96c6.49-21.02 27.02-33.71 47.72-33.71 20.69 0 38.09 7.9 45.64 33.71 10.13-26.76 28.35-33.71 50.15-33.71 37.88 0 59.61 18.88 59.61 51.81v123.26h0zm76.65 2.77c-52.62 0-61.55-33.45-61.55-50.52 0-20.1 8.83-38.21 27.93-45.55 8.41-3.11 16.52-5.43 24.84-7.1 7.33-1.47 18.64-3.03 26.91-4.17l2.73-.38c14.38-2 29.67-9.21 29.67-18.62 0-16-20.51-18.39-32.74-18.39-13.87 0-23.64 3.57-27.53 10.05-3.49 6.46-3.73 7.97-4.62 13.6l-.62 4.43h-38.1l.68-5.61c1.35-11.14 3.41-19.03 6.48-24.83 10.54-20.39 31.77-30.75 63.08-30.75 26.11 0 44.63 8.23 53.26 15.94 5.31 4.6 9.1 9.84 11.89 16.46 5.84 12.36 6.32 20.63 6.32 29.4v86.43c0 8.07.78 14.97 2.31 20.5l1.76 6.35h-38.91l-.7-4.19c-.5-2.96-.67-19.75-.88-26.23-8.99 23.61-28.27 33.18-52.21 33.18zm50.53-93.72c-7.97 6.11-20.47 9.6-38.62 13.23-31.27 5.78-36.54 13.06-36.54 27.22 0 12.5 10.63 20.26 27.75 20.26 33.23 0 47.41-15.48 47.41-51.77v-8.94zm124.2-105.51C688.46 64.19 660 35.73 660 .62c0 35.11-28.46 63.57-63.57 63.57h0c35.11 0 63.57 28.46 63.57 63.57h0c0-35.11 28.46-63.57 63.57-63.57z"
fill="#ffffff" style="mix-blend-mode: difference;" />
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="320" height="320" viewBox="0 0 320 320" version="1.1" id="svg1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<defs id="defs1">
<linearGradient xlink:href="#linearGradient8" id="linearGradient9" x1="105.88936" y1="-7.966506" x2="153.52075" y2="74.533493" gradientUnits="userSpaceOnUse"/>
<linearGradient id="linearGradient8">
<stop style="stop-color:#2de2e6;stop-opacity:1;" offset="0" id="stop8"/>
<stop style="stop-color:#3399ff;stop-opacity:1;" offset="1" id="stop11"/>
</linearGradient>
<linearGradient xlink:href="#linearGradient6" id="linearGradient7" x1="97.229103" y1="82.033493" x2="97.229103" y2="107.03349" gradientUnits="userSpaceOnUse"/>
<linearGradient id="linearGradient6">
<stop style="stop-color:#f623ac;stop-opacity:1;" offset="0" id="stop6"/>
<stop style="stop-color:#f706cf;stop-opacity:1;" offset="1" id="stop7"/>
</linearGradient>
</defs>
<rect style="display:inline;opacity:1;fill:#29144a;fill-opacity:0;stroke:none;stroke-width:4.39823;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" id="rect35" width="323.65826" height="325.41187" x="0" y="-2.7059329"/>
<g id="g1" transform="matrix(0.97092512,0,0,0.95099897,34.423647,35.890832)">
<g id="layer1" style="display:inline;fill:none" transform="matrix(2.12871,0,0,2.0000001,-90.126008,15.218211)">
<path style="display:inline;opacity:1;fill:url(#linearGradient9);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" d="M 92.898977,-25.466506 23.616945,94.53349 a 4.9999999,4.9999999 60 0 0 4.330127,7.5 H 166.51114 a 4.9999996,4.9999996 120 0 0 4.33012,-7.499999 L 101.55923,-25.466506 a 5.0000002,5.0000002 180 0 0 -8.660253,0 z" id="path5" transform="translate(5.8501312,19.942587)"/>
<path id="path1" style="display:inline;opacity:1;fill:#241734;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" d="M 103.61607,27.033498 60.315284,102.0335 H 77.635596 L 90.625831,79.533498 103.61607,102.0335 116.60825,79.533498 129.59849,102.0335 h 17.32031 z m 0,15 10.82666,18.74973 a 7.4997612,7.4997612 90 0 1 0,7.50054 l -10.82666,18.74973 -10.824962,-18.74959 a 7.5008819,7.5008819 90 0 1 0,-7.50082 z" transform="translate(-0.5188027,0.07359983)"/>
<path style="display:inline;opacity:1;fill:url(#linearGradient7);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" d="M 27.947072,102.03349 H 166.51114 a 5.0000006,5.0000006 120 0 0 4.33012,-7.5 l -7.21687,-12.499996 h -40.41452 l -12.99038,-22.5 -12.990386,22.5 -12.990381,-22.5 -12.990381,22.5 H 30.833821 L 23.616945,94.53349 a 5,5 60 0 0 4.330127,7.5 z" id="path6" transform="matrix(1.0011548,0,0,1.0030727,5.7535451,19.687436)"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><path id="A" d="M128 117v6a5 5 0 0 0-5 5h-6a5 5 0 1 0-10 0h-6a5 5 0 1 0-10 0h-6a5 5 0 1 0-10 0h-6a5 5 0 1 0-10 0h-6a5 5 0 1 0-10 0h-6a5 5 0 1 0-10 0h-6a5 5 0 1 0-10 0H5a5 5 0 0 0-5-5v-6a5 5 0 1 0 0-10v-6a5 5 0 0 0 0-10v-6a5 5 0 0 0 0-10v-6a5 5 0 0 0 0-10v-6a5 5 0 0 0 0-10v-6a5 5 0 0 0 0-10v-6a5 5 0 0 0 0-10V5a5 5 0 0 0 5-5h6a5 5 0 0 0 10 0h6a5 5 0 0 0 10 0h6a5 5 0 0 0 10 0h6a5 5 0 0 0 10 0h6a5 5 0 0 0 10 0h6a5 5 0 0 0 10 0h6a5 5 0 1 0 10 0h6a5 5 0 0 0 5 5v6a5 5 0 1 0 0 10v6a5 5 0 1 0 0 10v6a5 5 0 1 0 0 10v6a5 5 0 1 0 0 10v6a5 5 0 1 0 0 10v6a5 5 0 1 0 0 10v6a5 5 0 1 0 0 10z"/><rect id="B" width="96" height="96" x="16" y="16" rx="2"/></defs><g transform="matrix(.492308 0 0 .492308 .492308 .492308)" fill="none" fill-rule="evenodd"><use xlink:href="#A" fill="#f0f0f0"/><path d="M128.5 116.5v7h-.5a4.5 4.5 0 0 0-4.5 4.5v.5h-7v-.5a4.5 4.5 0 0 0-9 0v.5h-7v-.5a4.5 4.5 0 0 0-9 0v.5h-7v-.5a4.5 4.5 0 0 0-9 0v.5h-7v-.5a4.5 4.5 0 0 0-9 0v.5h-7v-.5a4.5 4.5 0 0 0-9 0v.5h-7v-.5a4.5 4.5 0 0 0-9 0v.5h-7v-.5a4.5 4.5 0 0 0-9 0v.5h-7v-.5a4.5 4.5 0 0 0-4.5-4.5h-.5v-7H0a4.5 4.5 0 0 0 0-9h-.5v-7H0a4.5 4.5 0 1 0 0-9h-.5v-7H0a4.5 4.5 0 1 0 0-9h-.5v-7H0a4.5 4.5 0 1 0 0-9h-.5v-7H0a4.5 4.5 0 1 0 0-9h-.5v-7H0a4.5 4.5 0 1 0 0-9h-.5v-7H0a4.5 4.5 0 1 0 0-9h-.5v-7H0A4.5 4.5 0 0 0 4.5 0v-.5h7V0a4.5 4.5 0 1 0 9 0v-.5h7V0a4.5 4.5 0 1 0 9 0v-.5h7V0a4.5 4.5 0 1 0 9 0v-.5h7V0a4.5 4.5 0 1 0 9 0v-.5h7V0a4.5 4.5 0 1 0 9 0v-.5h7V0a4.5 4.5 0 1 0 9 0v-.5h7V0a4.5 4.5 0 0 0 9 0v-.5h7V0a4.5 4.5 0 0 0 4.5 4.5h.5v7h-.5a4.5 4.5 0 0 0 0 9h.5v7h-.5a4.5 4.5 0 0 0 0 9h.5v7h-.5a4.5 4.5 0 0 0 0 9h.5v7h-.5a4.5 4.5 0 0 0 0 9h.5v7h-.5a4.5 4.5 0 0 0 0 9h.5v7h-.5a4.5 4.5 0 0 0 0 9h.5v7h-.5a4.5 4.5 0 0 0 0 9z" stroke="#ccc"/><path d="M127.5 117.478a5.5 5.5 0 0 1 0-10.956v-5.044a5.5 5.5 0 0 1 0-10.956v-5.044a5.5 5.5 0 0 1 0-10.956v-5.044a5.5 5.5 0 0 1 0-10.956v-5.044a5.5 5.5 0 0 1 0-10.956v-5.044a5.5 5.5 0 0 1 0-10.956v-5.044a5.5 5.5 0 0 1 0-10.956V5.478A5.502 5.502 0 0 1 122.522.5h-5.044a5.5 5.5 0 0 1-10.956 0h-5.044a5.5 5.5 0 0 1-10.956 0h-5.044a5.5 5.5 0 0 1-10.956 0h-5.044a5.5 5.5 0 0 1-10.956 0h-5.044a5.5 5.5 0 0 1-10.956 0h-5.044a5.5 5.5 0 0 1-10.956 0h-5.044a5.5 5.5 0 0 1-10.956 0H5.478A5.502 5.502 0 0 1 .5 5.478v5.044a5.5 5.5 0 0 1 0 10.956v5.044a5.5 5.5 0 0 1 0 10.956v5.044a5.5 5.5 0 0 1 0 10.956v5.044a5.5 5.5 0 0 1 0 10.956v5.044a5.5 5.5 0 0 1 0 10.956v5.044a5.5 5.5 0 0 1 0 10.956v5.044a5.5 5.5 0 0 1 0 10.956v5.044a5.502 5.502 0 0 1 4.978 4.978h5.044a5.5 5.5 0 0 1 10.956 0h5.044a5.5 5.5 0 0 1 10.956 0h5.044a5.5 5.5 0 0 1 10.956 0h5.044a5.5 5.5 0 0 1 10.956 0h5.044a5.5 5.5 0 0 1 10.956 0h5.044a5.5 5.5 0 0 1 10.956 0h5.044a5.5 5.5 0 0 1 10.956 0h5.044a5.502 5.502 0 0 1 4.978-4.978z" stroke="#fff"/><use xlink:href="#B" fill="#fedd00"/><rect width="95" height="95" x="16.5" y="16.5" rx="2" stroke="#d9b500"/><rect width="97" height="97" x="15.5" y="15.5" rx="2" stroke="#fff"/><path d="M50.3 86.084V42.3H43V35h25.886c16.168 0 19.522 10.664 19.522 18.06 0 5.934-2.408 10.492-4.902 12.986-4.042 4.042-9.546 4.988-17.888 4.988h-6.536v15.05h7.654v7.3H43v-7.3zm8.772-22.102h7.3c10.75 0 13.072-4.988 13.072-11.008 0-6.88-3.87-10.664-10.32-10.664H59.082z" fill="#000"/></g></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 KiB

View File

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

View File

@@ -66,14 +66,14 @@ class Configuration {
String? _volatilePassword;
final _secureStorageOptionsIOS = const IOSOptions(
accessibility: KeychainAccessibility.first_unlock_this_device,
);
Future<void> init() async {
_preferences = await SharedPreferences.getInstance();
sqfliteFfiInit();
_secureStorage = const FlutterSecureStorage();
_secureStorage = const FlutterSecureStorage(
iOptions: IOSOptions(
accessibility: KeychainAccessibility.first_unlock_this_device,
),
);
_tempDirectory = (await DirectoryUtils.getDirectoryForInit()).path;
final tempDirectory = io.Directory(_tempDirectory);
try {
@@ -98,7 +98,6 @@ class Configuration {
Future<void> _initOfflineAccount() async {
_offlineAuthKey = await _secureStorage.read(
key: offlineAuthSecretKey,
iOptions: _secureStorageOptionsIOS,
);
}
@@ -108,22 +107,18 @@ class Configuration {
unawaited(
_secureStorage.delete(
key: key,
iOptions: _secureStorageOptionsIOS,
),
);
}
} else {
_key = await _secureStorage.read(
key: keyKey,
iOptions: _secureStorageOptionsIOS,
);
_secretKey = await _secureStorage.read(
key: secretKeyKey,
iOptions: _secureStorageOptionsIOS,
);
_authSecretKey = await _secureStorage.read(
key: authSecretKeyKey,
iOptions: _secureStorageOptionsIOS,
);
if (_key == null) {
await logout(autoLogout: true);
@@ -136,7 +131,6 @@ class Configuration {
for (String key in onlineSecureKeys) {
await _secureStorage.delete(
key: key,
iOptions: _secureStorageOptionsIOS,
);
}
await LockScreenSettings.instance.removePinAndPassword();
@@ -396,7 +390,6 @@ class Configuration {
await _secureStorage.write(
key: keyKey,
value: key,
iOptions: _secureStorageOptionsIOS,
);
}
@@ -405,7 +398,6 @@ class Configuration {
await _secureStorage.write(
key: secretKeyKey,
value: secretKey,
iOptions: _secureStorageOptionsIOS,
);
}
@@ -414,7 +406,6 @@ class Configuration {
await _secureStorage.write(
key: authSecretKeyKey,
value: authSecretKey,
iOptions: _secureStorageOptionsIOS,
);
}
@@ -463,18 +454,15 @@ class Configuration {
Future<void> optForOfflineMode() async {
if ((await _secureStorage.containsKey(
key: offlineAuthSecretKey,
iOptions: _secureStorageOptionsIOS,
))) {
_offlineAuthKey = await _secureStorage.read(
key: offlineAuthSecretKey,
iOptions: _secureStorageOptionsIOS,
);
} else {
_offlineAuthKey = CryptoUtil.bin2base64(CryptoUtil.generateKey());
await _secureStorage.write(
key: offlineAuthSecretKey,
value: _offlineAuthKey,
iOptions: _secureStorageOptionsIOS,
);
}
await _preferences.setBool(hasOptedForOfflineModeKey, true);

View File

@@ -1,6 +1,6 @@
{
"account": "الحساب",
"unlock": "فتح القفل",
"unlock": "فتح القُفْل",
"recoveryKey": "مفتاح الاسترداد",
"counterAppBarTitle": "العداد",
"@counterAppBarTitle": {
@@ -16,7 +16,7 @@
"secretCanNotBeEmpty": "لا يمكن أن يكون رمز السر فارغ",
"bothIssuerAndAccountCanNotBeEmpty": "لا يمكن أن يكون المُصدر والحساب فارغًا",
"incorrectDetails": "بيانات غير صحيحة",
"pleaseVerifyDetails": "من فضلك تأكد من بياناتك وحاول مرة أخرى",
"pleaseVerifyDetails": "الرجاء التأكد من البيانات وإعادة المحاولة",
"codeIssuerHint": "المصدِّر",
"codeSecretKeyHint": "الرمز السري",
"secret": "سري",
@@ -36,7 +36,7 @@
"codeAccountHint": "الحساب (you@domain.com)",
"codeTagHint": "وسم",
"accountKeyType": "نوع المفتاح",
"sessionExpired": "انتهت صلاحية الجلسة",
"sessionExpired": "انتهت صَلاحِيَة الجِلسة",
"@sessionExpired": {
"description": "Title of the dialog when the users current session is invalid/expired"
},
@@ -48,6 +48,8 @@
"nextTotpTitle": "التالي",
"deleteCodeTitle": "حذف الرمز؟",
"deleteCodeMessage": "هل أنت متأكد من أنك تريد حذف هذه الشيفرة؟ هذا الإجراء لا رجعة فيه.",
"trashCode": "حذف الكود؟",
"trashCodeMessage": "هل أنت متيقِّن أنك تريد حذف الكود الخاص بـ {account}؟",
"trash": "سلة المهملات",
"viewLogsAction": "عرض السجلات",
"sendLogsDescription": "سوف يُرسل هذا السجلات لنا لمساعدتنا على تصحيح مشكلتك. بينما نتخذ الاحتياطات لضمان عدم تسجيل المعلومات الحساسة، نشجعك على رؤية هذه السجلات قبل مشاركتها.",
@@ -63,7 +65,7 @@
},
"copyEmailAction": "نسخ البريد الإلكتروني",
"exportLogsAction": "تصدير السجلات",
"reportABug": "الابلاغ عن خلل تقني",
"reportABug": "ألإبلاغ عن خلل تقني",
"crashAndErrorReporting": "الإبلاغ عن الأعطال والأخطاء",
"reportBug": "الإبلاغ عن خلل",
"emailUsMessage": "الرجاء مراسلتنا على {email}",
@@ -79,22 +81,24 @@
"blog": "المدونة",
"merchandise": "إدارة المنتجات",
"verifyPassword": "التحقق من كلمة المرور",
"pleaseWait": "الرجاء الإنتظار...",
"pleaseWait": "انتظر قليلاً...",
"generatingEncryptionKeysTitle": "توليد مفاتيح التشفير...",
"recreatePassword": "إعادة كتابة كلمة المرور",
"recreatePasswordMessage": "الجهاز الحالي ليس قويًا بما يكفي للتحقق من كلمة المرور الخاصة بك، لذا نحتاج إلى إعادة إنشائها مرة واحدة بطريقة تعمل مع جميع الأجهزة.\n\nالرجاء تسجيل الدخول باستخدام مفتاح الاسترداد وإعادة إنشاء كلمة المرور الخاصة بك (يمكنك استخدام نفس كلمة المرور مرة أخرى إذا كنت ترغب في ذلك).",
"useRecoveryKey": "استخدم مفتاح الاسترداد",
"incorrectPasswordTitle": "كلمة المرور غير صحيحة",
"welcomeBack": "مرحبًا مجددًا!",
"madeWithLoveAtPrefix": "مصنوعة بـ❤️ في ",
"emailAlreadyRegistered": "البريد الإلكتروني مُسَجَّل من قبل.",
"emailNotRegistered": "البريد الإلكتروني غير مُسَجَّل.",
"madeWithLoveAtPrefix": "مصنوعة بـ❤️ في",
"supportDevs": "اشترك في <bold-green>ente</bold-green> لدعمنا",
"supportDiscount": "استخدم رمز القسيمة \"AUTH\" للحصول على 10% خصم من السنة الأولى",
"supportDiscount": "استخدم رمز القسيمة \"AUTH\" للحصول على 10% خَصْم من السنة الأولى",
"changeEmail": "غير البريد الإلكتروني",
"changePassword": "غير كلمة المرور",
"data": "البيانات",
"importCodes": "استورد شيفرات",
"importTypePlainText": "نص بسيط",
"importTypeEnteEncrypted": "تصدير مشفر ente",
"importTypeEnteEncrypted": "تصدير مشفَّر ente",
"passwordForDecryptingExport": "كلمة المرور لفك تشفير التصدير",
"passwordEmptyError": "لا يمكن أن تكون كلمة المرور فارغة",
"importFromApp": "استورد الشيفرات من {appName}",
@@ -111,10 +115,11 @@
"importLabel": "استيراد",
"importInstruction": "الرجاء تحديد ملف يحتوي على قائمة بالرموز الخاصة بك بالشكل التالي",
"importCodeDelimiterInfo": "يمكن فصل الرموز بفاصلة أو سطر جديد",
"selectFile": "اختيار الملف",
"selectFile": "حدد مِلَفّ",
"emailVerificationToggle": "تأكيد عنوان البريد الإلكتروني",
"emailVerificationEnableWarning": "لتجنب إقفال حسابك، تأكد من تخزين نسخة من بريدك الإلكتروني 2FA خارج Ente Auth قبل تمكين التحقق من البريد الإلكتروني.",
"authToChangeEmailVerificationSetting": "الرجاء المصادقة لتغيير التحقق من البريد الإلكتروني",
"authenticateGeneric": "الرجاء المصادقة",
"authToViewYourRecoveryKey": "الرجاء المصادقة لعرض مفتاح الاسترداد الخاص بك",
"authToChangeYourEmail": "الرجاء المصادقة لتغيير بريدك الإلكتروني",
"authToChangeYourPassword": "الرجاء المصادقة لتغيير كلمة المرور الخاصة بك",
@@ -129,7 +134,7 @@
"general": "العامة",
"settings": "الإعدادات",
"copied": "تم النسخ",
"pleaseTryAgain": "حاول مرة اخرى",
"pleaseTryAgain": "يرجى المحاولة مرة أخرى",
"existingUser": "المستخدم موجود",
"newUser": "جديد في Ente",
"delete": "حذف",
@@ -142,6 +147,8 @@
"leaveFamily": "مغادرة خطة العائلة",
"leaveFamilyMessage": "هل أنت متأكد من الخروج من خطة العائلة؟",
"inFamilyPlanMessage": "أنت مندرج ضمن خطة عائلية!",
"hintForMobile": "اضغط مطولاً على الكود لتعديل أو إزالته.",
"hintForDesktop": "انقر بزر الأيمن على الكود لتعديله.",
"scan": "مسح",
"scanACode": "فحص رمز Qr",
"verify": "التحقق",
@@ -151,6 +158,7 @@
"twoFactorAuthTitle": "المصادقة الثنائية",
"passkeyAuthTitle": "التحقق من مفتاح المرور",
"verifyPasskey": "تحقق من مفتاح المرور",
"loginWithTOTP": "",
"recoverAccount": "إسترجاع الحساب",
"enterRecoveryKeyHint": "أدخل رمز الاسترداد",
"recover": "استرداد",
@@ -172,7 +180,7 @@
"yesSendFeedbackAction": "نعم، ارسل الملاحظات",
"noDeleteAccountAction": "لا، حذف الحساب",
"initiateAccountDeleteTitle": "الرجاء المصادقة لبدء حذف الحساب",
"sendEmail": "ارسل بريد الكتروني",
"sendEmail": "إرسال بريد إلكتروني",
"createNewAccount": "إنشاء حساب جديد",
"weakStrength": "ضعيف",
"strongStrength": "قوي",
@@ -184,9 +192,9 @@
"language": "اللغة",
"social": "وسائل التواصل",
"security": "الأمان",
"lockscreen": "شاشة القفل",
"authToChangeLockscreenSetting": "الرجاء المصادقة لتغيير إعدادات شاشة القفل",
"deviceLockEnablePreSteps": "لتمكين قفل التطبيق، فضلا أعد شيفرة مرور للجهاز أو قفل الشاشة في إعدادات نظامك.",
"lockscreen": "شاشة القُفْل",
"authToChangeLockscreenSetting": "الرجاء المصادقة لتغيير إعدادات شاشة القُفْل",
"deviceLockEnablePreSteps": "لتفعيل قُفْل الجهاز، اضبط رمز مرور أو قُفْل الشاشة من الإعدادات",
"viewActiveSessions": "عرض الجلسات النشطة",
"authToViewYourActiveSessions": "الرجاء المصادقة لعرض جلساتك النشطة",
"searchHint": "بحث...",
@@ -199,6 +207,7 @@
"edit": "تعديل",
"share": "مشاركة",
"shareCodes": "شارك الرموز",
"shareCodesDuration": "حدد المدة التي تريد أن تشارك فيها ألاكوا د.",
"restore": "استعادة",
"copiedToClipboard": "تم النسخ إلى الحافظة",
"copiedNextToClipboard": "تم نسخ الرموز التالية إلى الحافظة",
@@ -326,6 +335,7 @@
}
},
"manualSort": "مخصّص",
"editOrder": "تعديل الطلب",
"mostFrequentlyUsed": "مستخدم بكثرة",
"mostRecentlyUsed": "مستخدمة مؤخراً",
"activeSessions": "الجلسات النشطة",
@@ -447,6 +457,9 @@
"customEndpoint": "متصل بـ{endpoint}",
"pinText": "ثبت",
"unpinText": "ألغِ التثبيت",
"pinnedCodeMessage": "ثُبِّت {code}",
"unpinnedCodeMessage": "أُلغِي تثبيت {code}",
"pinned": "ثُبِّت",
"tags": "الأوسمة",
"createNewTag": "أنشيء وسم جديد",
"tag": "وسم",
@@ -459,9 +472,9 @@
"viewRawCodes": "عرض الشيفرات الأصلية",
"rawCodes": "الشيفرات الأصلية",
"rawCodeData": "بيانات الشيفرات الأصلية",
"appLock": "قفل التطبيق",
"appLock": "قُفْل التطبيق",
"noSystemLockFound": "لا يوجد قفل نظام",
"toEnableAppLockPleaseSetupDevicePasscodeOrScreen": "لتمكين قفل التطبيق، فضلا أعد شيفرة مرور الجهاز أو قفل الشاشة في إعدادات نظامك.",
"toEnableAppLockPleaseSetupDevicePasscodeOrScreen": "لتفعيل قُفْل التطبيق، اضبط رمز مرور الجهاز أو قُفْل الشاشة من الإعدادات.",
"autoLock": "قفل تلقائي",
"immediately": "فورًا",
"reEnterPassword": "أعد إدخال كلمة المرور",
@@ -475,14 +488,30 @@
"hideContentDescriptionAndroid": "يخفي محتوى التطبيق في مبدل التطبيقات ويمنع لقطات الشاشة",
"hideContentDescriptioniOS": "يخفي محتوى التطبيق في مبدل التطبيقات",
"autoLockFeatureDescription": "الوقت الذي بعده ينقفل التطبيق بعدما يوضع في الخلفية",
"appLockDescription": "اختر بين شاشة القفل الافتراضية الخاصة بجهازك وشاشة قفل مخصصة برقم تعريف شخصي أو كلمة مرور.",
"appLockDescription": "اختر نوع قُفْل الشاشة: افتراضي أو مخصص.",
"pinLock": "قفل رقم التعريف الشخصي",
"enterPin": "أدخل رقم التعريف الشخصي",
"setNewPin": "عين رقم تعريف شخصي جديد",
"importFailureDescNew": "تعذر إعراب الملف المنتقى.",
"appLockNotEnabled": "قُفْل التطبيق غير مفعل ",
"appLockNotEnabledDescription": "لحماية بياناتك، فعِّل قُفْل التطبيق من إعدادات الأمان ← قُفْل التطبيق",
"authToViewPasskey": "الرجاء المصادقة لعرض مفتاح الاسترداد الخاص بك",
"appLockOfflineModeWarning": "لقد اخترتَ المُتابعة دون نُسخ احتياطية. إذا نَسيتَ قُفْل التطبيق، فلن تتمكن من الوصول إلى بياناتك.",
"duplicateCodes": "رموز مكررة",
"noDuplicates": "✨ لا تكرارات",
"youveNoDuplicateCodesThatCanBeCleared": "لا توجد لديك أي أكواد مكررة يمكن حذفها",
"deduplicateCodes": "أكواد مكررة",
"deselectAll": "ألغِ تحديد الكل",
"selectAll": "حدد الكل",
"deleteDuplicates": "احذف التكرار"
"deleteDuplicates": "احذف التكرار",
"plainHTML": "HTML عَادِي ",
"tellUsWhatYouThink": "شاركنا برأيك",
"dropReviewiOS": "اترك مراجعة على أبل ستور",
"dropReviewAndroid": "اترك مراجعة بلاي ستور",
"supportEnte": "دعم <bold-green>ente</bold-green></bold-green>",
"giveUsAStarOnGithub": "من فضلك أعطِنا نجمة على جيت هاب",
"free5GB": "5GB مجانًا على <bold-green>ente</bold-green> صور",
"loginWithAuthAccount": "سجّل الدخول باستخدام حساب المُصادقة",
"freeStorageOffer": "خَصْم 10٪ على صور <bold-green>ente</bold-green>",
"freeStorageOfferDescription": "استخدم الكود \"AUTH\" وأحصل على 10٪ خَصْم في السنة الأولى"
}

View File

@@ -499,11 +499,13 @@
"duplicateCodes": "Doppelte Codes",
"noDuplicates": "✨ Keine Duplikate",
"youveNoDuplicateCodesThatCanBeCleared": "Du hast keine doppelten Codes, die bereinigt werden können",
"deduplicateCodes": "Codes deduplizieren",
"deselectAll": "Alle abwählen",
"selectAll": "Alles auswählen",
"deleteDuplicates": "Duplikate löschen",
"plainHTML": "Reines HTML",
"tellUsWhatYouThink": "Sagen Sie uns, was Sie denken",
"dropReviewiOS": "Hinterlasse eine Rezension im App Store",
"dropReviewAndroid": "Hinterlasse eine Rezension im Google Play Store",
"supportEnte": "Support <bold-green>ente</bold-green>",
"giveUsAStarOnGithub": "Gib uns einen Stern auf Github",

View File

@@ -506,6 +506,8 @@
"deleteDuplicates": "Eliminar duplicados",
"plainHTML": "HTML plano",
"tellUsWhatYouThink": "Cuéntanos cuál es su opinión",
"dropReviewiOS": "Deja una reseña en la App Store",
"dropReviewAndroid": "Deja una reseña en la Play Store",
"supportEnte": "Apoya a <bold-green>ente</bold-green>",
"giveUsAStarOnGithub": "Danos una estrella en GitHub",
"free5GB": "5 GB gratis en <bold-green>ente</bold-green> Fotos",

View File

@@ -499,12 +499,15 @@
"appLockOfflineModeWarning": "Vous avez choisi de fonctionner sans sauvegardes. Si vous oubliez votre outil Applock, vous serez bloqué dans l'accès à vos données.",
"duplicateCodes": "Codes dupliqués",
"noDuplicates": "✨ Pas de doublons",
"youveNoDuplicateCodesThatCanBeCleared": "Vous n'avez aucun code en doublon pouvant être supprimé",
"deduplicateCodes": "Codes dédupliqués",
"deselectAll": "Tout désélectionner",
"selectAll": "Tout sélectionner",
"deleteDuplicates": "Supprimer les doublons",
"plainHTML": "HTML Pur",
"tellUsWhatYouThink": "Dites-nous ce que vous pensez",
"dropReviewiOS": "Laisser un avis sur l'App Store",
"dropReviewAndroid": "Laisser un avis sur le Play Store",
"supportEnte": "Soutenir <bold-green>Ente</bold-green>",
"giveUsAStarOnGithub": "Donnez-nous une étoile sur Github",
"free5GB": "5 Go gratuits sur <bold-green>Ente</bold-green> Photos",

View File

@@ -79,7 +79,7 @@
"contactSupport": "Lépj kapcsolatba az Ügyfélszolgálattal",
"rateUsOnStore": "Értékelj minket a következőn: {storeName}",
"blog": "Blog",
"merchandise": "Áru",
"merchandise": "Ajándéktárgyak",
"verifyPassword": "Jelszó megerősítése",
"pleaseWait": "Kérem várjon...",
"generatingEncryptionKeysTitle": "Titkosítási kulcs generálása...",
@@ -499,12 +499,15 @@
"appLockOfflineModeWarning": "Úgy döntött, hogy biztonsági mentés nélkül folytatja. Ha elfelejti az alkalmazászárat, akkor nem férhet hozzá adataihoz.",
"duplicateCodes": "Ismétlődő kódok",
"noDuplicates": "✨Nincs ismétlődés",
"youveNoDuplicateCodesThatCanBeCleared": "Nincsenek törölhető ismétlődő kódok",
"deduplicateCodes": "Ismétlődő kódok",
"deselectAll": "Összes kijelölés megszüntetése",
"selectAll": "Összes kijelölése",
"deleteDuplicates": "Ismétlődések törlése",
"plainHTML": "Sima HTML kód",
"tellUsWhatYouThink": "Mondja el mit gondol",
"dropReviewiOS": "Írj véleményt az App Store-ban",
"dropReviewAndroid": "Írj véleményt a Play Store-ban",
"supportEnte": "Támogassa <bold-green>ente <bold-green>",
"giveUsAStarOnGithub": "Adj nekünk egy csillagot a Githubon",
"free5GB": "5GB ingyen <bold-green>ente <bold-green> Photos",

View File

@@ -506,6 +506,8 @@
"deleteDuplicates": "Ištrinti dublikatus",
"plainHTML": "Grynasis HTML",
"tellUsWhatYouThink": "Pasakykite mums, ką manote",
"dropReviewiOS": "Rašyti apžvalgą parduotuvėje „App Store“",
"dropReviewAndroid": "Rašyti apžvalgą parduotuvėje „Play“ parduotuvė“",
"giveUsAStarOnGithub": "Suteikite mums žvaigždutę platformoje „Github“",
"free5GB": "5 GB nemokami programai „<bold-green>ente</bold-green>“ nuotraukos",
"loginWithAuthAccount": "Prisijungti su jūsų „Auth“ paskyra",

View File

@@ -506,6 +506,8 @@
"deleteDuplicates": "Dubbelen verwijderen",
"plainHTML": "Alleen HTML",
"tellUsWhatYouThink": "Vertel ons wat je vindt",
"dropReviewiOS": "Laat een beoordeling achter in de App Store",
"dropReviewAndroid": "Laat een beoordeling achter in de Play Store",
"supportEnte": "Steun <bold-green>ente</bold-green>",
"giveUsAStarOnGithub": "Geef ons een ster op Github",
"free5GB": "5GB gratis op <bold-green>ente</bold-green> Photos",

View File

@@ -0,0 +1 @@
{}

View File

@@ -83,22 +83,22 @@
"verifyPassword": "Подтверждение пароля",
"pleaseWait": "Пожалуйста, подождите...",
"generatingEncryptionKeysTitle": "Генерируем ключи шифрования...",
"recreatePassword": "Воссоздать пароль заново",
"recreatePassword": "Повторное создание пароля",
"recreatePasswordMessage": "Текущее устройство недостаточно мощное для проверки пароля, поэтому нам нужно регенерировать его один раз таким образом, чтобы работать со всеми устройствами. \n\nПожалуйста, войдите, используя ваш ключ восстановления и сгенерируйте ваш пароль (вы можете использовать тот же самый, если пожелаете).",
"useRecoveryKey": "Использовать ключ восстановления",
"incorrectPasswordTitle": "Неправильный пароль",
"welcomeBack": "С возвращением!",
"emailAlreadyRegistered": "Адрес электронной почты уже зарегистрирован.",
"emailNotRegistered": "Адрес электронной почты не зарегистрирован.",
"madeWithLoveAtPrefix": "сделана с ❤️ в ",
"madeWithLoveAtPrefix": "сделано с ❤️ в ",
"supportDevs": "Подпишитесь на <bold-green>ente</bold-green> для поддержки нашего проекта",
"supportDiscount": "Используйте код скидки \"AUTH\", чтобы получить скидку 10% на первый год",
"changeEmail": "Изменить почту",
"supportDiscount": "Используйте кодовое слово \"AUTH\", чтобы получить скидку 10% на первый год",
"changeEmail": "Изменить адрес электронной почты",
"changePassword": "Изменить пароль",
"data": "Данные",
"importCodes": "Импортировать коды",
"importTypePlainText": "Обычный текст",
"importTypeEnteEncrypted": "Ente Зашифрованный экспорт",
"importTypeEnteEncrypted": "Зашифрованный экспорт из Ente",
"passwordForDecryptingExport": "Пароль для расшифровки экспорта",
"passwordEmptyError": "Пароль не может быть пустым",
"importFromApp": "Импорт кодов из {appName}",
@@ -106,27 +106,27 @@
"importSelectJsonFile": "Выбрать JSON-файл",
"importSelectAppExport": "Выбрать файл экспорта {appName}",
"importEnteEncGuide": "Выберите зашифрованный JSON файл, экспортированный из Ente",
"importRaivoGuide": "Используйте опцию «Export OTPs to Zip archive» в настройках Raivo.\n\nРаспакуйте zip-архив и импортируйте JSON-файл.",
"importBitwardenGuide": "Используйте опцию \"Экспортировать хранилище\" в Bitwarden Tools и импортируйте незашифрованный JSON файл.",
"importRaivoGuide": "Используйте опцию «Экспорт OTP-кодов в Zip-архив» в настройках Raivo.\n\nРаспакуйте zip-архив и импортируйте JSON-файл.",
"importBitwardenGuide": "Используйте опцию \"Экспортировать хранилище\" в Bitwarden и импортируйте незашифрованный JSON-файл.",
"importAegisGuide": "Используйте опцию «Экспортировать хранилище» в настройках Aegis.\n\nЕсли ваше хранилище зашифровано, то для его расшифровки потребуется ввести пароль хранилища.",
"import2FasGuide": "Используйте опцию \"Settings->Backup -Export\" в 2FAS.\n\nЕсли ваша резервная копия зашифрована, то для расшифровки резервной копии необходимо ввести пароль",
"importLastpassGuide": "Используйте опцию \"Перенести аккаунты\" в настройках Lastpass Authenticator и нажмите на \"Экспортировать учетные записи в файл\". Импортируйте загружённый JSON файл.",
"import2FasGuide": "Используйте опцию \"Настройки->Резервное копирование -Экспорт\" в 2FAS.\n\nЕсли ваша резервная копия зашифрована, то для расшифровки резервной копии необходимо ввести пароль",
"importLastpassGuide": "Используйте опцию \"Перенести аккаунты\" в настройках Lastpass Authenticator и нажмите на \"Экспортировать учетные записи в файл\". Импортируйте загружённый JSON-файл.",
"exportCodes": "Экспортировать коды",
"importLabel": "Импорт",
"importInstruction": "Пожалуйста, выберите файл, содержащий список ваших кодов в следующем формате",
"importCodeDelimiterInfo": "Коды могут быть разделены запятой или новой строкой",
"selectFile": "Выбрать файл",
"emailVerificationToggle": "Подтверждение электронной почты",
"emailVerificationEnableWarning": "Если вы храните у нас двухфакторную аутентификацию в своей электронной почте, включение проверки электронной почты может привести к тупиковой ситуации. Если у вас заблокирован доступ к одной службе, возможно, вы не сможете войти в другую.",
"emailVerificationToggle": "Подтверждение адреса электронной почты",
"emailVerificationEnableWarning": "Чтобы избежать блокировки вашей учетной записи, обязательно сохраните копию вашего электронного письма 2FA за пределами Ente Auth, прежде чем активировать проверку электронной почты.",
"authToChangeEmailVerificationSetting": "Авторизуйтесь, чтобы изменить подтверждение электронной почты",
"authenticateGeneric": "Пожалуйста, авторизуйтесь",
"authToViewYourRecoveryKey": "Пожалуйста, авторизуйтесь для просмотра вашего ключа восстановления",
"authToChangeYourEmail": "Пожалуйста, авторизуйтесь, чтобы изменить адрес электронной почты",
"authToChangeYourPassword": "Пожалуйста, авторизуйтесь, чтобы изменить пароль",
"authToViewSecrets": "Пожалуйста, авторизуйтесь для просмотра ваших секретов",
"authToInitiateSignIn": "Пожалуйста, авторизуйтесь, чтобы начать вход для резервного копирования.",
"authToInitiateSignIn": "Пожалуйста, авторизуйтесь, чтобы получить доступ к резервному копированию.",
"ok": "Ок",
"cancel": "Отменить",
"cancel": "Отмена",
"yes": "Да",
"no": "Нет",
"email": "Электронная почта",
@@ -136,30 +136,31 @@
"copied": "Скопировано",
"pleaseTryAgain": "Пожалуйста, попробуйте ещё раз",
"existingUser": "Существующий пользователь",
"newUser": "Впервые здесь, в Ente",
"newUser": "Впервые в Ente",
"delete": "Удалить",
"enterYourPasswordHint": "Введите пароль",
"forgotPassword": "Забыл пароль",
"oops": "Ой",
"suggestFeatures": "Предложить идеи",
"faq": "FAQ",
"somethingWentWrongMessage": "Что-то пошло не так. Попробуйте еще раз",
"faq": "ЧаВо",
"somethingWentWrongMessage": "Что-то пошло не так, пожалуйста, попробуйте еще раз",
"leaveFamily": "Покинуть семью",
"leaveFamilyMessage": "Вы уверены, что хотите отказаться от семейного плана?",
"inFamilyPlanMessage": "Вы на семейном плане!",
"hintForMobile": "Длительное нажмите на код для редактирования или удаления.",
"hintForDesktop": "Щелкните правой кнопкой мыши по коду, чтобы изменить или удалить.",
"hintForMobile": "Нажмите на код и удерживайте, чтобы редактировать его или удалить.",
"hintForDesktop": "Щелкните правой кнопкой мыши по коду, чтобы редактировать его или удалить.",
"scan": "Сканировать",
"scanACode": "Сканировать QR-код",
"verify": "Подтвердить",
"verifyEmail": "Подтвердить электронную почту",
"verifyEmail": "Подтвердить адрес электронной почты",
"enterCodeHint": "Введите 6-значный код из\nвашего приложения-аутентификатора",
"lostDeviceTitle": "Потеряно устройство?",
"twoFactorAuthTitle": "Двухфакторная аутентификация",
"passkeyAuthTitle": "Проверка с помощью пароля",
"passkeyAuthTitle": "Проверка с помощью ключа доступа",
"verifyPasskey": "Подтвердить пароль",
"loginWithTOTP": "Войти с помощью TOTP",
"recoverAccount": "Восстановить аккаунт",
"enterRecoveryKeyHint": "Введите свой ключ восстановления",
"enterRecoveryKeyHint": "Введите ключ восстановления",
"recover": "Восстановить",
"contactSupportViaEmailMessage": "Пожалуйста, отправьте электронное письмо на адрес {email} с вашего зарегистрированного адреса электронной почты",
"@contactSupportViaEmailMessage": {
@@ -171,7 +172,7 @@
},
"invalidQRCode": "Неверный QR-код",
"noRecoveryKeyTitle": "Нет ключа восстановления?",
"enterEmailHint": "Введите свою почту",
"enterEmailHint": "Введите адрес электронной почты",
"invalidEmailTitle": "Неверный адрес электронной почты",
"invalidEmailMessage": "Пожалуйста, введите действительный адрес электронной почты.",
"deleteAccount": "Удалить аккаунт",
@@ -182,7 +183,7 @@
"sendEmail": "Отправить электронное письмо",
"createNewAccount": "Создать новый аккаунт",
"weakStrength": "Слабый",
"strongStrength": "Крепкий",
"strongStrength": "Сильный",
"moderateStrength": "Средний",
"confirmPassword": "Подтвердить пароль",
"close": "Закрыть",
@@ -333,6 +334,9 @@
}
}
},
"manualSort": "Ручная",
"editOrder": "Изменить порядок",
"mostFrequentlyUsed": "Частота использования",
"mostRecentlyUsed": "Недавно использованные",
"activeSessions": "Активные сеансы",
"somethingWentWrongPleaseTryAgain": "Что-то пошло не так. Попробуйте еще раз",
@@ -376,7 +380,7 @@
"deleteCodeAuthMessage": "Аутентификация для удаления кода",
"showQRAuthMessage": "Аутентификация для отображения QR-кода",
"confirmAccountDeleteTitle": "Подтвердить удаление аккаунта",
"confirmAccountDeleteMessage": "Эта учетная запись связана с другими приложениями Ente, если вы ими пользуетесь.\n\nЗагруженные вами данные во всех приложениях ente будут запланированы к удалению, а ваша учетная запись будет удалена без возможности восстановления.",
"confirmAccountDeleteMessage": "Эта учетная запись связана с другими приложениями Ente, если вы ими пользуетесь.\n\nЗагруженные вами данные во всех приложениях Ente будут запланированы к удалению, а ваша учетная запись будет удалена без возможности восстановления.",
"androidBiometricHint": "Подтвердите личность",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
@@ -436,7 +440,7 @@
"signOutOtherDevices": "Выйти из других устройств",
"doNotSignOut": "Не выходить",
"hearUsWhereTitle": "Как вы узнали о Ente? (необязательно)",
"hearUsExplanation": "Будет полезно, если вы укажете, где нашли нас, так как мы не отслеживаем установки приложения",
"hearUsExplanation": "Мы не отслеживаем установки приложений. Было бы полезно, если бы вы сказали, где нас нашли!",
"recoveryKeySaved": "Ключ восстановления сохранён в папке Загрузки!",
"waitingForBrowserRequest": "Ожидание запроса браузера...",
"waitingForVerification": "Ожидание подтверждения...",
@@ -453,6 +457,9 @@
"customEndpoint": "Подключено к {endpoint}",
"pinText": "Прикрепить",
"unpinText": "Открепить",
"pinnedCodeMessage": "{code} был закреплен",
"unpinnedCodeMessage": "{code} был откреплен",
"pinned": "Закреплено",
"tags": "Метки",
"createNewTag": "Создать новую метку",
"tag": "Метка",
@@ -462,9 +469,9 @@
"deleteTagMessage": "Вы уверены, что хотите удалить эту метку? Это действие необратимо.",
"somethingWentWrongParsingCode": "Мы не смогли разобрать коды {x}.",
"updateNotAvailable": "Обновление недоступно",
"viewRawCodes": "Просмотр сырых кодов",
"rawCodes": "Сырые коды",
"rawCodeData": "Сырая информация кодов",
"viewRawCodes": "Просмотр необработанных кодов",
"rawCodes": "Необработанные коды",
"rawCodeData": "Необработанные кодовые данные",
"appLock": "Блокировка приложения",
"noSystemLockFound": "Системная блокировка не найдена",
"toEnableAppLockPleaseSetupDevicePasscodeOrScreen": "Чтобы включить блокировку, настройте пароль устройства или блокировку экрана в настройках системы.",
@@ -482,20 +489,28 @@
"hideContentDescriptioniOS": "Скрывает содержимое приложения в переключателе приложений",
"autoLockFeatureDescription": "Время в фоне, после которого приложение блокируется",
"appLockDescription": "Выберите между экраном блокировки вашего устройства и пользовательским экраном блокировки с PIN-кодом или паролем.",
"pinLock": "Pin Замок",
"pinLock": "Pin блокировка",
"enterPin": "Введите PIN",
"setNewPin": "Установите новый PIN",
"importFailureDescNew": "Не удалось обработать выбранный файл.",
"appLockNotEnabled": "Блокировка приложения отключена",
"appLockNotEnabledDescription": "Пожалуйста, включите блокировку приложения в безопасности > Блокировка приложений",
"appLockNotEnabledDescription": "Пожалуйста, включите блокировку приложения в разделе Безопасность > Блокировка приложений",
"authToViewPasskey": "Пожалуйста, авторизуйтесь, чтобы просмотреть пароль",
"appLockOfflineModeWarning": "Вы решили продолжить работу без резервного копирования. Если вы забудете свой пароль, доступ к вашим данным будет заблокирован.",
"duplicateCodes": "Дублировать коды",
"noDuplicates": "✨ Дубликатов нет",
"youveNoDuplicateCodesThatCanBeCleared": "У вас нет повторяющихся кодов, которые можно было бы удалить",
"deduplicateCodes": "Дедупликационные коды",
"deselectAll": "Снять выделение",
"selectAll": "Выбрать все",
"deleteDuplicates": "Удалить повторяющиеся",
"plainHTML": "Обычный HTML",
"tellUsWhatYouThink": "Расскажите нам, что вы думаете",
"free5GB": "5GB бесплатно на <bold-green>ente</bold-green> фото",
"dropReviewiOS": "Оставьте отзыв в App Store",
"dropReviewAndroid": "Оставьте отзыв в Play Store",
"supportEnte": "Поддержка <bold-green>ente</bold-green>",
"giveUsAStarOnGithub": "Поставьте нам звезду на Github",
"free5GB": "5Гб бесплатного пространства на <bold-green>ente</bold-green> Фото",
"loginWithAuthAccount": "Войти с помощью учетной записи Auth",
"freeStorageOffer": "Скидка 10% на <bold-green>ente</bold-green> фото",
"freeStorageOfferDescription": "Используйте код \"AUTH\", чтобы получить скидку 10% в первый год"

View File

@@ -1 +1,3 @@
{}
{
"importScanQrCode": ""
}

View File

@@ -51,7 +51,7 @@
"trashCode": "Xóa mã?",
"trashCodeMessage": "Bạn có chắc chắn muốn xóa mã cho {account} không?",
"trash": "Xóa",
"viewLogsAction": "Xem các bản ghi",
"viewLogsAction": "Xem nhật ký",
"sendLogsDescription": "Thao tác này sẽ gửi nhật ký để giúp chúng tôi gỡ lỗi sự cố của bạn. Mặc dù chúng tôi thực hiện các biện pháp phòng ngừa để đảm bảo rằng thông tin nhạy cảm không được ghi lại, nhưng chúng tôi khuyến khích bạn xem các nhật ký này trước khi chia sẻ chúng.",
"preparingLogsTitle": "Đang chuẩn bị nhật ký...",
"emailLogsTitle": "Nhật ký email",
@@ -506,6 +506,8 @@
"deleteDuplicates": "Xóa trùng lặp",
"plainHTML": "HTML thuần",
"tellUsWhatYouThink": "Hãy cho chúng tôi biết bạn nghĩ gì",
"dropReviewiOS": "Đánh giá ngay trên App Store",
"dropReviewAndroid": "Đánh giá ngay trên Play Store",
"supportEnte": "Hỗ trợ <bold-green>ente</bold-green>",
"giveUsAStarOnGithub": "Cho chúng tôi ngôi sao trên Github",
"free5GB": "Miễn phí 5GB cho <bold-green>ente</bold-green> Hình ảnh",

View File

@@ -504,10 +504,10 @@
"deselectAll": "取消全选",
"selectAll": "全选",
"deleteDuplicates": "删除重复项",
"plainHTML": "Plain HTML",
"plainHTML": " HTML",
"tellUsWhatYouThink": "告诉我们您的想法",
"dropReviewiOS": "在 App Store 上发表评",
"dropReviewAndroid": "在 Play 商店上发表评",
"dropReviewiOS": "在 App Store 上发表评",
"dropReviewAndroid": "在 Play 商店上发表评",
"supportEnte": "支持 <bold-green>ente</bold-green>",
"giveUsAStarOnGithub": "在 Github 上给我们一个星标",
"free5GB": "<bold-green>ente</bold-green> Photos 上 5GB 可用空间",

View File

@@ -504,8 +504,10 @@
"deselectAll": "取消全選",
"selectAll": "全選",
"deleteDuplicates": "刪除重複項",
"plainHTML": "Plain HTML",
"plainHTML": "HTML",
"tellUsWhatYouThink": "告訴我們您的想法",
"dropReviewiOS": "在 App Store 上發表意見",
"dropReviewAndroid": "在 Play 商店上發表評測",
"supportEnte": "支援 <bold-green>ente</bold-green>",
"giveUsAStarOnGithub": "在 Github 上給我們一個星標",
"free5GB": "<bold-green>ente</bold-green> Photos 上 5GB 可用空間",

View File

@@ -114,18 +114,19 @@ class Code {
CodeDisplay? display,
int digits, {
Algorithm algorithm = Algorithm.sha1,
int period = defaultPeriod,
}) {
final String encodedIssuer = Uri.encodeQueryComponent(issuer);
return Code(
account,
issuer,
digits,
defaultPeriod,
period,
secret,
algorithm,
type,
0,
"otpauth://${type.name}/$issuer:$account?algorithm=${algorithm.name.toUpperCase()}&digits=$digits&issuer=$encodedIssuer&period=30&secret=$secret",
"otpauth://${type.name}/$issuer:$account?algorithm=${algorithm.name.toUpperCase()}&digits=$digits&issuer=$encodedIssuer&period=$period&secret=$secret",
display: display ?? CodeDisplay(),
);
}

View File

@@ -3,10 +3,12 @@ import 'package:flutter/material.dart';
class FieldLabel extends StatelessWidget {
final String label;
final double width;
const FieldLabel(
this.label, {
super.key,
this.width = 80,
});
@override
@@ -14,7 +16,7 @@ class FieldLabel extends StatelessWidget {
return Padding(
padding: const EdgeInsets.only(right: 12.0),
child: SizedBox(
width: 80,
width: width,
child: Text(
label,
style: getEnteTextTheme(context).miniBoldMuted,

View File

@@ -18,6 +18,7 @@ import 'package:ente_auth/ui/components/buttons/button_widget.dart';
import 'package:ente_auth/ui/components/custom_icon_widget.dart';
import 'package:ente_auth/ui/components/models/button_result.dart';
import 'package:ente_auth/ui/custom_icon_page.dart';
import 'package:ente_auth/ui/topt_selector_widget.dart';
import 'package:ente_auth/ui/utils/icon_utils.dart';
import 'package:ente_auth/utils/dialog_util.dart';
import 'package:ente_auth/utils/toast_util.dart';
@@ -40,11 +41,13 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
final int _notesLimit = 500;
final int _otherTextLimit = 200;
final int defaultDigits = 6;
final int defaultPeriodInSeconds = 30;
late TextEditingController _issuerController;
late TextEditingController _accountController;
late TextEditingController _secretController;
late TextEditingController _notesController;
late TextEditingController _digitsController;
late TextEditingController _periodController;
late bool _secretKeyObscured;
late List<String> selectedTags = [...?widget.code?.display.tags];
List<String> allTags = [];
@@ -53,6 +56,8 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
String _customIconID = "";
late IconType _iconSrc;
late Algorithm _algorithm;
late Type _type;
final ValueNotifier<bool> showAdvancedOptions = ValueNotifier<bool>(false);
@override
void initState() {
@@ -74,6 +79,11 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
? widget.code!.digits.toString()
: defaultDigits.toString(),
);
_periodController = TextEditingController(
text: widget.code != null
? widget.code!.period.toString()
: defaultPeriodInSeconds.toString(),
);
_secretKeyObscured = widget.code != null;
_loadTags();
@@ -112,6 +122,7 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
: IconType.customIcon;
_algorithm = widget.code == null ? Algorithm.sha1 : widget.code!.algorithm;
_type = widget.code == null ? Type.totp : widget.code!.type;
super.initState();
}
@@ -134,6 +145,7 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
_accountController.dispose();
_notesController.dispose();
_digitsController.dispose();
_periodController.dispose();
super.dispose();
}
@@ -282,76 +294,7 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
),
const SizedBox(height: 12),
widget.code == null
? Theme(
data: Theme.of(context).copyWith(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
),
child: ExpansionTile(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
collapsedShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
collapsedBackgroundColor: Colors.transparent,
tilePadding: EdgeInsets.zero,
title: Text(
"Advanced",
style: getEnteTextTheme(context).small,
),
children: <Widget>[
Row(
children: [
const FieldLabel("Digits"),
Expanded(
child: TextFormField(
keyboardType: TextInputType.number,
// The validator receives the text that the user has entered.
validator: (value) {
if (value == null || value.isEmpty) {
return "Please enter a number";
}
final intValue = int.tryParse(value);
if (intValue == null) {
return "Only integers are allowed";
}
if (intValue < 1 || intValue > 10) {
return "OTP digits must be between 1 and 10";
}
return null;
},
maxLines: 1,
decoration: const InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 12.0,
),
),
style: getEnteTextTheme(context).small,
controller: _digitsController,
),
),
],
),
const SizedBox(height: 22),
Row(
children: [
const FieldLabel("Algorithm"),
AlgorithmSelectorWidget(
currentAlgorithm: _algorithm,
onSelected: (newAlgorithm) async {
setState(() {
_algorithm = newAlgorithm;
});
},
),
],
),
const SizedBox(height: 12),
],
),
)
? advanceOptionWidget()
: const SizedBox.shrink(),
const SizedBox(height: 12),
Wrap(
@@ -419,11 +362,25 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
return;
}
final period =
int.tryParse(_periodController.text.trim());
if (period != null && (period < 10 || period > 60)) {
String message =
"Period must be between 10 and 60 seconds";
_showIncorrectDetailsDialog(
context,
message: message,
);
return;
}
if ((_accountController.text.trim().isEmpty &&
_issuerController.text.trim().isEmpty) ||
_secretController.text.trim().isEmpty ||
_digitsController.text.trim().isEmpty ||
digits == null) {
digits == null ||
_periodController.text.trim().isEmpty ||
period == null) {
String message;
if (_secretController.text.trim().isEmpty) {
message = context.l10n.secretCanNotBeEmpty;
@@ -431,6 +388,10 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
message = "Digits cannot be empty";
} else if (digits == null) {
message = "Digits is not a integer";
} else if (_periodController.text.isEmpty) {
message = "Period cannot be empty";
} else if (period == null) {
message = "Period is not a integer";
} else {
message =
context.l10n.bothIssuerAndAccountCanNotBeEmpty;
@@ -462,6 +423,7 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
final secret = _secretController.text.trim().replaceAll(' ', '');
final notes = _notesController.text.trim();
final digits = int.tryParse(_digitsController.text.trim());
final period = int.tryParse(_periodController.text.trim());
final isStreamCode = issuer.toLowerCase() == "steam" ||
issuer.toLowerCase().contains('steampowered.com');
@@ -498,13 +460,14 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
final Code newCode = widget.code == null
? Code.fromAccountAndSecret(
isStreamCode ? Type.steam : Type.totp,
isStreamCode ? Type.steam : _type,
account,
issuer,
secret,
display,
isStreamCode ? Code.steamDigits : digits!,
algorithm: _algorithm,
period: period!,
)
: widget.code!.copyWith(
account: account,
@@ -513,6 +476,8 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
display: display,
algorithm: _algorithm,
digits: digits!,
type: _type,
period: period,
);
// Verify the validity of the code
@@ -558,4 +523,159 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
_iconSrc = newCustomIcon.type;
});
}
Widget advanceOptionWidget() {
return Padding(
padding: const EdgeInsets.only(top: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
showAdvancedOptions.value = !showAdvancedOptions.value;
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Advanced',
),
ValueListenableBuilder<bool>(
valueListenable: showAdvancedOptions,
builder: (context, isExpanded, child) {
return Icon(
isExpanded
? Icons.keyboard_arrow_up
: Icons.keyboard_arrow_down,
size: 24,
);
},
),
],
),
),
ValueListenableBuilder<bool>(
valueListenable: showAdvancedOptions,
builder: (context, isExpanded, child) {
return AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
transitionBuilder: (child, animation) {
return SizeTransition(
sizeFactor: animation,
child: child,
);
},
child: isExpanded
? SizedBox(
width: 400,
child: Padding(
padding: const EdgeInsets.only(
top: 16,
),
child: GridView.count(
crossAxisCount: 2,
shrinkWrap: true,
childAspectRatio: 2.5,
crossAxisSpacing: 16,
mainAxisSpacing: 14,
physics: const NeverScrollableScrollPhysics(),
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const FieldLabel("Algorithm", width: 60),
AlgorithmSelectorWidget(
currentAlgorithm: _algorithm,
onSelected: (newAlgorithm) async {
setState(() {
_algorithm = newAlgorithm;
});
},
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const FieldLabel("Type", width: 60),
ToptSelectorWidget(
currentTopt: _type,
onSelected: (newTopt) async {
setState(() {
_type = newTopt;
});
},
),
],
),
Row(
children: [
const FieldLabel("Period", width: 60),
Expanded(
child: TextFormField(
keyboardType: TextInputType.number,
// The validator receives the text that the user has entered.
validator: (value) {
if (value == null || value.isEmpty) {
return "Please enter a number";
}
final intValue = int.tryParse(value);
if (intValue == null) {
return "Only integers are allowed";
}
if (intValue < 1 || intValue > 60) {
return "Period must be between 1 and 60";
}
return null;
},
maxLines: 1,
style: getEnteTextTheme(
context,
).small,
controller: _periodController,
),
),
],
),
Row(
children: [
const FieldLabel("Digits", width: 60),
Expanded(
child: TextFormField(
keyboardType: TextInputType.number,
// The validator receives the text that the user has entered.
validator: (value) {
if (value == null || value.isEmpty) {
return "Please enter a number";
}
final intValue = int.tryParse(value);
if (intValue == null) {
return "Only integers are allowed";
}
if (intValue < 1 || intValue > 10) {
return "OTP digits must be between 1 and 10";
}
return null;
},
maxLines: 1,
style: getEnteTextTheme(
context,
).small,
controller: _digitsController,
),
),
],
),
],
),
),
)
: const SizedBox.shrink(),
);
},
),
],
),
);
}
}

View File

@@ -580,7 +580,9 @@ class _HomePageState extends State<HomePage> {
return ClipRect(
child: CodeWidget(
key: ValueKey('${code.hashCode}_${newIndex}_$_codeSortKey'),
key: ValueKey(
'${code.hashCode}_${newIndex}_$_codeSortKey',
),
code,
isCompactMode: isCompactMode,
sortKey: _codeSortKey,
@@ -667,11 +669,13 @@ class _HomePageState extends State<HomePage> {
}
return false;
}
int lastScanTime = DateTime.now().millisecondsSinceEpoch - 1000;
void _handleDeeplink(BuildContext context, String? link) {
bool isAccountConfigured = Configuration.instance.hasConfiguredAccount();
bool isOfflineModeEnabled = Configuration.instance.hasOptedForOfflineMode() &&
Configuration.instance.getOfflineSecretKey() != null;
bool isOfflineModeEnabled =
Configuration.instance.hasOptedForOfflineMode() &&
Configuration.instance.getOfflineSecretKey() != null;
if (!(isAccountConfigured || isOfflineModeEnabled) || link == null) {
return;
}

View File

@@ -94,6 +94,7 @@ Future<int?> _processAegisExportFile(
final isEncrypted = decodedJson['header']['slots'] != null;
Map? aegisDB;
if (isEncrypted) {
await dialog.hide();
String? password;
try {
await showTextInputDialog(
@@ -109,6 +110,7 @@ Future<int?> _processAegisExportFile(
await dialog.hide();
return null;
}
await dialog.show();
final content = decryptAegisVault(decodedJson, password: password!);
aegisDB = jsonDecode(content);
} catch (e, s) {

View File

@@ -159,6 +159,8 @@ class _ItemsWidgetState extends State<ItemsWidget> {
return 'Lietuvių';
case 'nl':
return 'Nederlands';
case 'no':
return 'Norsk';
case 'pl':
return 'Polski';
case 'pt':

View File

@@ -0,0 +1,72 @@
import 'package:ente_auth/models/code.dart';
import 'package:ente_auth/theme/ente_theme.dart';
import 'package:flutter/material.dart';
class ToptSelectorWidget extends StatelessWidget {
final Type currentTopt;
final void Function(Type) onSelected;
const ToptSelectorWidget({
super.key,
required this.currentTopt,
required this.onSelected,
});
@override
Widget build(BuildContext context) {
Text toptOptionText(Type type) {
return Text(
type.name.toUpperCase(),
style: getEnteTextTheme(context).small,
);
}
return GestureDetector(
onTapDown: (TapDownDetails details) async {
final int? selectedValue = await showMenu<int>(
context: context,
position: RelativeRect.fromLTRB(
details.globalPosition.dx,
details.globalPosition.dy,
details.globalPosition.dx,
details.globalPosition.dy + 300,
),
items: List.generate(Type.values.length, (index) {
return PopupMenuItem(
value: index,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
toptOptionText(Type.values[index]),
if (Type.values[index] == currentTopt)
Icon(
Icons.check,
color: Theme.of(context).iconTheme.color,
),
],
),
);
}),
);
if (selectedValue != null) {
onSelected(Type.values[selectedValue]);
}
},
child: Container(
padding: const EdgeInsets.only(bottom: 4),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Theme.of(context).dividerColor),
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
toptOptionText(currentTopt),
const SizedBox(width: 8),
const Icon(Icons.arrow_drop_down),
],
),
),
);
}
}

View File

@@ -1,4 +1,5 @@
import "dart:convert";
import "dart:io";
import "dart:typed_data";
import "package:ente_auth/core/configuration.dart";
@@ -49,6 +50,8 @@ class LockScreenSettings {
/// Function to Check if the migration for lock screen changes has
/// already been done by checking a stored boolean value.
await runLockScreenChangesMigration();
await _clearLsDataInKeychainIfFreshInstall();
}
Future<void> setOfflineModeWarningStatus(bool value) async {
@@ -210,4 +213,17 @@ class LockScreenSettings {
Future<bool> isPasswordSet() async {
return await _secureStorage.containsKey(key: password);
}
// If the app was uninstalled (without logging out if it was used with
// backups), keychain items of the app persist in the keychain. To avoid using
// old keychain items, we delete them on reinstall.
Future<void> _clearLsDataInKeychainIfFreshInstall() async {
if ((Platform.isIOS || Platform.isMacOS) &&
!Configuration.instance.isLoggedIn() &&
!Configuration.instance.hasOptedForOfflineMode()) {
await _secureStorage.delete(key: password);
await _secureStorage.delete(key: pin);
await _secureStorage.delete(key: saltKey);
}
}
}

View File

@@ -34,11 +34,11 @@ PODS:
- FlutterMacOS
- screen_retriever (0.0.1):
- FlutterMacOS
- Sentry/HybridSDK (8.36.0)
- sentry_flutter (8.9.0):
- Sentry/HybridSDK (8.46.0)
- sentry_flutter (8.14.2):
- Flutter
- FlutterMacOS
- Sentry/HybridSDK (= 8.36.0)
- Sentry/HybridSDK (= 8.46.0)
- share_plus (0.0.1):
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
@@ -157,33 +157,33 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos
SPEC CHECKSUMS:
app_links: 10e0a0ab602ffaf34d142cd4862f29d34b303b2a
connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db
cupertino_http: 947a233f40cfea55167a49f2facc18434ea117ba
device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f
file_saver: 44e6fbf666677faf097302460e214e977fdd977b
flutter_inappwebview_macos: bdf207b8f4ebd58e86ae06cd96b147de99a67c9b
flutter_local_authentication: 85674893931e1c9cfa7c9e4f5973cb8c56b018b0
flutter_local_notifications: 3805ca215b2fb7f397d78b66db91f6a747af52e4
flutter_secure_storage_macos: 59459653abe1adb92abbc8ea747d79f8d19866c9
app_links: 9028728e32c83a0831d9db8cf91c526d16cc5468
connectivity_plus: 3f6c9057f4cd64198dc826edfb0542892f825343
cupertino_http: 94ac07f5ff090b8effa6c5e2c47871d48ab7c86c
device_info_plus: b0fafc687fb901e2af612763340f1b0d4352f8e5
file_saver: e35bd97de451dde55ff8c38862ed7ad0f3418d0f
flutter_inappwebview_macos: c2d68649f9f8f1831bfcd98d73fd6256366d9d1d
flutter_local_authentication: 2f9a2682f498abcc12d7e9729b5007a947170fdc
flutter_local_notifications: 453432cd6399a07d072885bc7828fb2307868856
flutter_secure_storage_macos: b2d62a774c23b060f0b99d0173b0b36abb4a8632
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3
objective_c: e5f8194456e8fc943e034d1af00510a1bc29c067
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
objective_c: ec13431e45ba099cb734eb2829a5c1cd37986cba
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38
Sentry: f8374b5415bc38dfb5645941b3ae31230fbeae57
sentry_flutter: 0eb93e5279eb41e2392212afe1ccd2fecb4f8cbe
share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sodium_libs: d39bd76697736cb11ce4a0be73b9b4bc64466d6f
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
package_info_plus: a8a591e70e87ce97ce5d21b2594f69cea9e0312f
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
screen_retriever: 4f97c103641aab8ce183fa5af3b87029df167936
Sentry: da60d980b197a46db0b35ea12cb8f39af48d8854
sentry_flutter: 27892878729f42701297c628eb90e7c6529f3684
share_plus: 11c7b7fa7020465584eca3ff6392c5bc1e399d6e
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sodium_libs: b9459e5bfc1185349f43472e79fc5d8e526b2bda
sqflite: c35dad70033b8862124f8337cc994a809fcd9fa3
sqlite3: 0bb0e6389d824e40296f531b858a2a0b71c0d2fb
sqlite3_flutter_libs: 5ca46c1a04eddfbeeb5b16566164aa7ad1616e7b
tray_manager: 9064e219c56d75c476e46b9a21182087930baf90
url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
sqlite3_flutter_libs: 03311aede9d32fb2d24e32bebb8cd01c3b2e6239
tray_manager: a104b5c81b578d83f3c3d0f40a997c8b10810166
url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673
window_manager: 1d01fa7ac65a6e6f83b965471b1a7fdd3f06166c
PODFILE CHECKSUM: 6ff827273ace187339fc5d3684072a26ad85c298

View File

@@ -5,15 +5,15 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab"
url: "https://pub.dev"
source: hosted
version: "72.0.0"
version: "76.0.0"
_macros:
dependency: transitive
description: dart
source: sdk
version: "0.3.2"
version: "0.3.3"
adaptive_theme:
dependency: "direct main"
description:
@@ -26,10 +26,10 @@ packages:
dependency: transitive
description:
name: analyzer
sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e"
url: "https://pub.dev"
source: hosted
version: "6.7.0"
version: "6.11.0"
ansicolor:
dependency: transitive
description:
@@ -90,10 +90,10 @@ packages:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
url: "https://pub.dev"
source: hosted
version: "2.11.0"
version: "2.12.0"
auto_size_text:
dependency: "direct main"
description:
@@ -130,10 +130,10 @@ packages:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
build:
dependency: transitive
description:
@@ -202,10 +202,10 @@ packages:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "1.4.0"
checked_yaml:
dependency: transitive
description:
@@ -234,10 +234,10 @@ packages:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
url: "https://pub.dev"
source: hosted
version: "1.1.1"
version: "1.1.2"
code_builder:
dependency: transitive
description:
@@ -250,10 +250,10 @@ packages:
dependency: "direct main"
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev"
source: hosted
version: "1.18.0"
version: "1.19.1"
confetti:
dependency: "direct main"
description:
@@ -435,10 +435,10 @@ packages:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
version: "1.3.2"
ffi:
dependency: "direct main"
description:
@@ -675,14 +675,13 @@ packages:
source: hosted
version: "9.2.2"
flutter_secure_storage_linux:
dependency: "direct overridden"
dependency: transitive
description:
path: flutter_secure_storage_linux
ref: develop
resolved-ref: "5a5692b609b3886cdd49b2ed06b9c079ecdff996"
url: "https://github.com/mogol/flutter_secure_storage.git"
source: git
version: "1.2.1"
name: flutter_secure_storage_linux
sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688
url: "https://pub.dev"
source: hosted
version: "1.2.3"
flutter_secure_storage_macos:
dependency: transitive
description:
@@ -945,18 +944,18 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
url: "https://pub.dev"
source: hosted
version: "10.0.5"
version: "10.0.8"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.9"
leak_tracker_testing:
dependency: transitive
description:
@@ -1025,18 +1024,18 @@ packages:
dependency: transitive
description:
name: macros
sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656"
url: "https://pub.dev"
source: hosted
version: "0.1.2-main.4"
version: "0.1.3-main.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
version: "0.12.17"
material_color_utilities:
dependency: transitive
description:
@@ -1057,10 +1056,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
url: "https://pub.dev"
source: hosted
version: "1.15.0"
version: "1.16.0"
mime:
dependency: transitive
description:
@@ -1169,10 +1168,10 @@ packages:
dependency: "direct main"
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
version: "1.9.1"
path_drawing:
dependency: transitive
description:
@@ -1361,18 +1360,18 @@ packages:
dependency: "direct main"
description:
name: sentry
sha256: "033287044a6644a93498969449d57c37907e56f5cedb17b88a3ff20a882261dd"
sha256: "599701ca0693a74da361bc780b0752e1abc98226cf5095f6b069648116c896bb"
url: "https://pub.dev"
source: hosted
version: "8.9.0"
version: "8.14.2"
sentry_flutter:
dependency: "direct main"
description:
name: sentry_flutter
sha256: "3780b5a0bb6afd476857cfbc6c7444d969c29a4d9bd1aa5b6960aa76c65b737a"
sha256: "5ba2cf40646a77d113b37a07bd69f61bb3ec8a73cbabe5537b05a7c89d2656f8"
url: "https://pub.dev"
source: hosted
version: "8.9.0"
version: "8.14.2"
share_plus:
dependency: "direct main"
description:
@@ -1473,7 +1472,7 @@ packages:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
version: "0.0.0"
sodium:
dependency: transitive
description:
@@ -1510,10 +1509,10 @@ packages:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
version: "1.10.1"
sprintf:
dependency: transitive
description:
@@ -1567,10 +1566,10 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
version: "1.12.1"
steam_totp:
dependency: "direct main"
description:
@@ -1591,10 +1590,10 @@ packages:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.4"
stream_transform:
dependency: transitive
description:
@@ -1607,10 +1606,10 @@ packages:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
version: "1.4.1"
styled_text:
dependency: "direct main"
description:
@@ -1631,18 +1630,18 @@ packages:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.2.2"
test_api:
dependency: transitive
description:
name: test_api
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
url: "https://pub.dev"
source: hosted
version: "0.7.2"
version: "0.7.4"
timezone:
dependency: transitive
description:
@@ -1807,10 +1806,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
url: "https://pub.dev"
source: hosted
version: "14.2.5"
version: "14.3.1"
watcher:
dependency: transitive
description:
@@ -1900,5 +1899,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.5.0 <4.0.0"
dart: ">=3.7.0-0 <4.0.0"
flutter: ">=3.24.0"

View File

@@ -1,7 +1,7 @@
name: ente_auth
description: ente two-factor authenticator
version: 4.3.3+433
version: 4.3.6+437
publish_to: none
environment:
@@ -84,8 +84,8 @@ dependencies:
protobuf: ^3.0.0
qr_code_scanner: ^1.0.1
qr_flutter: ^4.1.0
sentry: ^8.7.0
sentry_flutter: ^8.7.0
sentry: ^8.14.2
sentry_flutter: ^8.14.2
share_plus: ^10.0.2
shared_preferences: ^2.0.5
sqflite:
@@ -107,12 +107,6 @@ dependencies:
window_manager: ^0.4.2
xdg_directories: ^1.0.4
dependency_overrides:
flutter_secure_storage_linux:
git:
url: https://github.com/mogol/flutter_secure_storage.git
ref: develop
path: flutter_secure_storage_linux
dev_dependencies:
build_runner: ^2.1.11
flutter_test:
@@ -148,12 +142,17 @@ flutter:
fonts:
- asset: fonts/Montserrat-Bold.ttf
flutter_icons:
# run "dart run flutter_launcher_icons" to generate icons
flutter_launcher_icons:
image_path: "assets/generation-icons/icon-light.png"
android: "launcher_icon"
adaptive_icon_foreground: "assets/generation-icons/icon-light-adaptive-fg.png"
adaptive_icon_background: "assets/generation-icons/icon-light-adaptive-bg.png"
adaptive_icon_monochrome: "assets/generation-icons/icon-monochrome.png"
adaptive_icon_foreground_inset: 0
ios: true
image_path: "assets/generation-icons/icon-light.png"
remove_alpha_ios: true
flutter_native_splash:

View File

@@ -14,6 +14,7 @@
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
#include <local_auth_windows/local_auth_plugin.h>
#include <screen_retriever/screen_retriever_plugin.h>
#include <sentry_flutter/sentry_flutter_plugin.h>
#include <share_plus/share_plus_windows_plugin_c_api.h>
#include <sodium_libs/sodium_libs_plugin_c_api.h>
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
@@ -38,6 +39,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("LocalAuthPlugin"));
ScreenRetrieverPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
SentryFlutterPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SentryFlutterPlugin"));
SharePlusWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
SodiumLibsPluginCApiRegisterWithRegistrar(

View File

@@ -11,6 +11,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
flutter_secure_storage_windows
local_auth_windows
screen_retriever
sentry_flutter
share_plus
sodium_libs
sqlite3_flutter_libs
@@ -21,7 +22,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
list(APPEND FLUTTER_FFI_PLUGIN_LIST
jni
sentry_flutter
)
set(PLUGIN_BUNDLED_LIBRARIES)

View File

@@ -60,7 +60,7 @@ ente account list
#### Change export directory
```shell
ente account update --email email@domain.com --dir ~/photos
ente account update --app auth/photos --email email@domain.com --dir ~/photos
```
### Export

View File

@@ -135,7 +135,7 @@ func (c *ClICtrl) UpdateFreeStorage(ctx context.Context, params model.AdminActio
return err
}
fmt.Printf("Updating storage for user %s to %s (old %s) with new expirty %s (old %s) \n",
fmt.Printf("Updating storage for user %s to %s (old %s) with new expiry %s (old %s) \n",
params.UserEmail,
utils.ByteCountDecimalGIB(storageSize), utils.ByteCountDecimalGIB(userDetails.Subscription.Storage),
date.Format("2006-01-02"),

View File

@@ -22,6 +22,9 @@ on:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
permissions:
contents: write
jobs:
release:
runs-on: ${{ matrix.os }}
@@ -49,7 +52,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
- name: Increase yarn timeout
# `yarn install` times out sometimes on the Windows runner,

View File

@@ -1,10 +1,18 @@
# CHANGELOG
## v1.7.11 (Unreleased)
## v1.7.13 (Unreleased)
- .
## v1.7.12
- Improved video player with streaming support (for already processed videos).
- Support Arabic translations.
## v1.7.11
- Improved file viewer.
- Improved live photo experience.
- .
## v1.7.10

BIN
desktop/build/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View File

@@ -39,6 +39,15 @@ export default ts.config(
"error",
{ allowTernary: true },
],
// Allow force unwrapping potentially optional values.
//
// See: [Note: non-null-assertions have better stack trace]
"@typescript-eslint/no-non-null-assertion": "off",
// Allow `while(true)` etc.
"@typescript-eslint/no-unnecessary-condition": [
"error",
{ allowConstantLoopConditions: true },
],
},
},
);

View File

@@ -1,6 +1,6 @@
{
"name": "ente",
"version": "1.7.11-beta",
"version": "1.7.13-beta",
"private": true,
"description": "Desktop client for Ente Photos",
"repository": "github:ente-io/photos-desktop",
@@ -27,36 +27,36 @@
"dependencies": {
"any-shell-escape": "^0.1.1",
"auto-launch": "^5.0.6",
"chokidar": "^3.6.0",
"chokidar": "^4.0.3",
"clip-bpe-js": "^0.0.6",
"comlink": "^4.4.2",
"compare-versions": "^6.1.1",
"electron-log": "^5.3.2",
"electron-log": "^5.4.0",
"electron-store": "^8.2.0",
"electron-updater": "^6.4.0",
"electron-updater": "^6.6.3",
"ffmpeg-static": "^5.2.0",
"lru-cache": "^11.0.2",
"lru-cache": "^11.1.0",
"next-electron-server": "^1.0.0",
"node-stream-zip": "^1.15.0",
"onnxruntime-node": "^1.20.1"
},
"devDependencies": {
"@eslint/js": "^9.22.0",
"@tsconfig/node20": "^20.1.4",
"@eslint/js": "^9.25.1",
"@tsconfig/node22": "^22.0.1",
"@types/auto-launch": "^5.0.5",
"@types/ffmpeg-static": "^3.0.3",
"ajv": "^8.17.1",
"concurrently": "^9.1.2",
"cross-env": "^7.0.3",
"electron": "^34.3.4",
"electron-builder": "^26.0.0",
"electron": "^36.1.0",
"electron-builder": "^26.0.14",
"eslint": "^9",
"prettier": "3.5.3",
"prettier-plugin-organize-imports": "^4.1.0",
"prettier-plugin-packagejson": "^2.5.10",
"shx": "^0.3.4",
"typescript": "^5.8.2",
"typescript-eslint": "^8.26.1"
"typescript": "^5.8.3",
"typescript-eslint": "^8.31.1"
},
"packageManager": "yarn@1.22.22",
"productName": "ente"

View File

@@ -24,7 +24,7 @@
*
* Note that `vips.js` would've already run once `beforeBuild.js` is run, but on
* our CI we prepare builds for multiple architectures in one go, so we need to
* unconditonally replace the binary with the relevant one for the current
* unconditionally replace the binary with the relevant one for the current
* architecture being built (which might be different from the one we're running
* on). `beforeBuild.js` runs for each architecture being built.
*

View File

@@ -35,6 +35,7 @@ import log, { initLogging } from "./main/log";
import { createApplicationMenu, createTrayContextMenu } from "./main/menu";
import { setupAutoUpdater } from "./main/services/app-update";
import autoLauncher from "./main/services/auto-launcher";
import { shouldHideDockIcon } from "./main/services/store";
import { createWatcher } from "./main/services/watch";
import { userPreferences } from "./main/stores/user-preferences";
import { migrateLegacyWatchStoreIfNeeded } from "./main/stores/watch";
@@ -385,8 +386,8 @@ const createMainWindow = () => {
const wasAutoLaunched = autoLauncher.wasAutoLaunched();
if (wasAutoLaunched) {
// Don't automatically show the app's window if we were auto-launched.
// On macOS, also hide the dock icon on macOS.
if (process.platform == "darwin") app.dock.hide();
// On macOS, also hide the dock icon.
app.dock?.hide();
} else {
// Show our window otherwise, maximizing it if we're not asked to set it
// to a specific size.
@@ -421,14 +422,18 @@ const createMainWindow = () => {
window.on("hide", () => {
// On macOS, when hiding the window also hide the app's icon in the dock
// if the user has selected the Settings > Hide dock icon checkbox.
if (process.platform == "darwin" && userPreferences.get("hideDockIcon"))
app.dock.hide();
// unless the user has unchecked the Settings > Hide dock icon checkbox.
if (shouldHideDockIcon()) {
// macOS emits a window "hide" event when going fullscreen, and if
// we hide the dock icon there then the window disappears. So ignore
// this scenario.
if (!window.isFullScreen()) {
app.dock?.hide();
}
}
});
window.on("show", () => {
if (process.platform == "darwin") void app.dock.show();
});
window.on("show", () => void app.dock?.show());
// Let ipcRenderer know when mainWindow is in the foreground so that it can
// in turn inform the renderer process.
@@ -609,7 +614,7 @@ const handleBackOnStripeCheckout = (window: BrowserWindow) =>
*
* But this is an issue for uploads in the self hosted apps (or when we
* ourselves are trying to test things by with an arbitrary S3 bucket without
* going via a worker). During upload, theer is no redirection, so the request
* going via a worker). During upload, there is no redirection, so the request
* ACAO is "ente://app" but the response ACAO is `null` which don't match,
* causing the request to fail.
*

View File

@@ -13,8 +13,10 @@ import type { BrowserWindow } from "electron";
import { ipcMain } from "electron/main";
import type {
CollectionMapping,
FFmpegCommand,
FolderWatch,
PendingUploads,
UtilityProcessType,
ZipItem,
} from "../types/ipc";
import { logToDisk } from "./log";
@@ -40,12 +42,12 @@ import {
fsRename,
fsRm,
fsRmdir,
fsStatMtime,
fsWriteFile,
fsWriteFileViaBackup,
} from "./services/fs";
import { convertToJPEG, generateImageThumbnail } from "./services/image";
import { logout } from "./services/logout";
import { createMLWorker } from "./services/ml";
import {
lastShownChangelogVersion,
masterKeyB64,
@@ -55,8 +57,8 @@ import {
import {
clearPendingUploads,
listZipItems,
markUploadedFiles,
markUploadedZipItems,
markUploadedFile,
markUploadedZipItem,
pathOrZipItemSize,
pendingUploads,
setPendingUploads,
@@ -68,6 +70,7 @@ import {
watchUpdateIgnoredFiles,
watchUpdateSyncedFiles,
} from "./services/watch";
import { triggerCreateUtilityProcess } from "./services/workers";
/**
* Listen for IPC events sent/invoked by the renderer process, and route them to
@@ -163,6 +166,8 @@ export const attachIPCHandlers = () => {
ipcMain.handle("fsIsDir", (_, dirPath: string) => fsIsDir(dirPath));
ipcMain.handle("fsStatMtime", (_, path: string) => fsStatMtime(path));
ipcMain.handle("fsFindFiles", (_, folderPath: string) =>
fsFindFiles(folderPath),
);
@@ -187,7 +192,7 @@ export const attachIPCHandlers = () => {
"ffmpegExec",
(
_,
command: string[],
command: FFmpegCommand,
dataOrPathOrZipItem: Uint8Array | string | ZipItem,
outputFileExtension: string,
) => ffmpegExec(command, dataOrPathOrZipItem, outputFileExtension),
@@ -210,13 +215,15 @@ export const attachIPCHandlers = () => {
);
ipcMain.handle(
"markUploadedFiles",
(_, paths: PendingUploads["filePaths"]) => markUploadedFiles(paths),
"markUploadedFile",
(_, path: string, associatedPath: string | undefined) =>
markUploadedFile(path, associatedPath),
);
ipcMain.handle(
"markUploadedZipItems",
(_, items: PendingUploads["zipItems"]) => markUploadedZipItems(items),
"markUploadedZipItem",
(_, item: ZipItem, associatedItem: ZipItem | undefined) =>
markUploadedZipItem(item, associatedItem),
);
ipcMain.handle("clearPendingUploads", () => clearPendingUploads());
@@ -227,9 +234,11 @@ export const attachIPCHandlers = () => {
* the main window to do their thing.
*/
export const attachMainWindowIPCHandlers = (mainWindow: BrowserWindow) => {
// - ML
// - Utility processes
ipcMain.on("createMLWorker", () => createMLWorker(mainWindow));
ipcMain.on("triggerCreateUtilityProcess", (_, type: UtilityProcessType) =>
triggerCreateUtilityProcess(type, mainWindow),
);
};
/**

View File

@@ -0,0 +1,59 @@
/**
* A object that behaves similar to the default export of "./log", except this
* can be used from within a utility process.
*
* ---
*
* We cannot directly do
*
* import log from "../log";
*
* because that requires the Electron APIs that are not available to a utility
* process (See: [Note: Using Electron APIs in UtilityProcess]).
*
* But even if that were to work, logging will still be problematic since we'd
* try opening the log file from two different Node.js processes (this one, and
* the main one), and I didn't find any indication in the electron-log
* repository that the log file's integrity would be maintained in such cases.
*
* So instead we provide this proxy log object that uses the
* `process.parentPort` to transport the logs over to the main process, where
* the {@link processUtilityProcessLogMessage} function in the main process is
* expected to handle these (sending them to the actual log).
*/
export default {
error: (s: string, e?: unknown) =>
mainProcess("log.errorString", messageWithError(s, e)),
warn: (s: string, e?: unknown) =>
mainProcess("log.warnString", messageWithError(s, e)),
info: (...ms: unknown[]) => mainProcess("log.info", ms),
/**
* Unlike the real {@link log.debug}, this is (a) eagerly evaluated, and (b)
* accepts only strings.
*/
debugString: (s: string) => mainProcess("log.debugString", s),
};
/**
* Send a message to the main process using a barebones RPC protocol.
*/
const mainProcess = (method: string, param: unknown) =>
process.parentPort.postMessage({ method, p: param });
// Duplicated verbatim from ./log.ts
const messageWithError = (message: string, e?: unknown) => {
if (!e) return message;
let es: string;
if (e instanceof Error) {
// In practice, we expect ourselves to be called with Error objects, so
// this is the happy path so to say.
es = [`${e.name}: ${e.message}`, e.stack].filter((x) => x).join("\n");
} else {
// For the rest rare cases, use the default string serialization of e.
// eslint-disable-next-line @typescript-eslint/no-base-to-string
es = String(e);
}
return `${message}: ${es}`;
};

View File

@@ -83,6 +83,56 @@ const logDebug = (param: () => unknown) => {
}
};
/**
* Handle log messages posted from the utility process in the main process.
*
* See: [Note: Using Electron APIs in UtilityProcess]
*
* @param message The arbitrary message that was received as an argument to the
* "message" event invoked on a {@link UtilityProcess}.
*
* @returns true if the message was recognized and handled, and false otherwise.
*/
export const processUtilityProcessLogMessage = (
logTag: string,
message: unknown,
) => {
const m = message; /* shorter alias */
if (m && typeof m == "object" && "method" in m && "p" in m) {
const p = m.p;
switch (m.method) {
case "log.errorString":
if (typeof p == "string") {
logError(`${logTag} ${p}`);
return true;
}
break;
case "log.warnString":
if (typeof p == "string") {
logWarn(`${logTag} ${p}`);
return true;
}
break;
case "log.info":
if (Array.isArray(p)) {
// Need to cast from any[] to unknown[]
logInfo(logTag, ...(p as unknown[]));
return true;
}
break;
case "log.debugString":
if (typeof p == "string") {
logDebug(() => `${logTag} ${p}`);
return true;
}
break;
default:
break;
}
}
return false;
};
/**
* Ente's logger.
*

View File

@@ -7,7 +7,7 @@ import {
} from "electron";
import { allowWindowClose } from "../main";
import { forceCheckForAppUpdates } from "./services/app-update";
import { userPreferences } from "./stores/user-preferences";
import { setShouldHideDockIcon, shouldHideDockIcon } from "./services/store";
/** Create and return the entries in the app's main menu bar */
export const createApplicationMenu = (mainWindow: BrowserWindow) => {
@@ -15,7 +15,7 @@ export const createApplicationMenu = (mainWindow: BrowserWindow) => {
//
// Whenever the menu is redrawn the current value of these variables is used
// to set the checked state for the various settings checkboxes.
let shouldHideDockIcon = !!userPreferences.get("hideDockIcon");
let hideDockIcon = shouldHideDockIcon();
const macOSOnly = (options: MenuItemConstructorOptions[]) =>
process.platform == "darwin" ? options : [];
@@ -24,9 +24,9 @@ export const createApplicationMenu = (mainWindow: BrowserWindow) => {
const toggleHideDockIcon = () => {
// Persist
userPreferences.set("hideDockIcon", !shouldHideDockIcon);
setShouldHideDockIcon(!hideDockIcon);
// And update the in-memory state
shouldHideDockIcon = !shouldHideDockIcon;
hideDockIcon = !hideDockIcon;
};
const handleHelp = () =>
@@ -48,7 +48,7 @@ export const createApplicationMenu = (mainWindow: BrowserWindow) => {
{
label: "Hide Dock Icon",
type: "checkbox",
checked: shouldHideDockIcon,
checked: hideDockIcon,
click: toggleHideDockIcon,
},
],

View File

@@ -1,11 +1,13 @@
import pathToFfmpeg from "ffmpeg-static";
import { randomBytes } from "node:crypto";
import fs from "node:fs/promises";
import type { ZipItem } from "../../types/ipc";
import { ensure } from "../utils/common";
import path, { basename } from "node:path";
import type { FFmpegCommand, ZipItem } from "../../types/ipc";
import log from "../log";
import { execAsync } from "../utils/electron";
import {
deleteTempFileIgnoringErrors,
makeFileForDataOrPathOrZipItem,
makeFileForDataOrStreamOrPathOrZipItem,
makeTempFilePath,
} from "../utils/temp";
@@ -42,7 +44,7 @@ const outputPathPlaceholder = "OUTPUT";
* But I'm not sure if our code is supposed to be able to use it, and how.
*/
export const ffmpegExec = async (
command: string[],
command: FFmpegCommand,
dataOrPathOrZipItem: Uint8Array | string | ZipItem,
outputFileExtension: string,
): Promise<Uint8Array> => {
@@ -50,14 +52,23 @@ export const ffmpegExec = async (
path: inputFilePath,
isFileTemporary: isInputFileTemporary,
writeToTemporaryFile: writeToTemporaryInputFile,
} = await makeFileForDataOrPathOrZipItem(dataOrPathOrZipItem);
} = await makeFileForDataOrStreamOrPathOrZipItem(dataOrPathOrZipItem);
const outputFilePath = await makeTempFilePath(outputFileExtension);
try {
await writeToTemporaryInputFile();
let resolvedCommand: string[];
if (Array.isArray(command)) {
resolvedCommand = command;
} else {
const isHDR = await isHDRVideo(inputFilePath);
log.debug(() => [basename(inputFilePath), { isHDR }]);
resolvedCommand = isHDR ? command.hdr : command.default;
}
const cmd = substitutePlaceholders(
command,
resolvedCommand,
inputFilePath,
outputFilePath,
);
@@ -99,18 +110,17 @@ const ffmpegBinaryPath = () => {
// This substitution of app.asar by app.asar.unpacked is suggested by the
// ffmpeg-static library author themselves:
// https://github.com/eugeneware/ffmpeg-static/issues/16
return ensure(pathToFfmpeg).replace("app.asar", "app.asar.unpacked");
return pathToFfmpeg!.replace("app.asar", "app.asar.unpacked");
};
/**
* A variant of {@link ffmpegExec} adapted to work with streams so that it can
* handle the MP4 conversion of large video files.
*
* See: [Note: Convert to MP4]
* @param inputFilePath The path to a file on the user's local file system. This
* is the video we want to convert.
* @param inputFilePath The path to a file on the user's local file system where
*
* @param outputFilePath The path to a file on the user's local file system where
* we should write the converted MP4 video.
*/
export const ffmpegConvertToMP4 = async (
@@ -130,3 +140,539 @@ export const ffmpegConvertToMP4 = async (
await execAsync(cmd);
};
export interface FFmpegGenerateHLSPlaylistAndSegmentsResult {
playlistPath: string;
videoPath: string;
dimensions: { width: number; height: number };
videoSize: number;
}
/**
* A bespoke variant of {@link ffmpegExec} for generation of HLS playlists for
* videos.
*
* Overview of the cases:
*
* H.264, <= 10 MB - Skip
* H.264, <= 4000 kb/s bitrate - Don't re-encode video stream
* BT.709, <= 2000 kb/s bitrate - Don't apply the scale+fps filter
* !BT.709 - Apply tonemap (zscale+tonemap+zscale)
*
* Example invocation:
*
* ffmpeg -i in.mov -vf 'scale=-2:720,fps=30,zscale=transfer=linear,tonemap=tonemap=hable:desat=0,zscale=primaries=709:transfer=709:matrix=709,format=yuv420p' -c:v libx264 -c:a aac -f hls -hls_key_info_file out.m3u8.info -hls_list_size 0 -hls_flags single_file out.m3u8
*
* See: [Note: Preview variant of videos]
*
* @param inputFilePath The path to a file on the user's local file system. This
* is the video we want to generate an streamable HLS playlist for.
*
* @param outputPathPrefix The path to unique, unused and temporary prefix on
* the user's local file system. This function will write the generated HLS
* playlist and video segments under this prefix.
*
* @returns The paths to two files on the user's local file system - one
* containing the generated HLS playlist, and the other containing the
* transcoded and encrypted video segments that the HLS playlist refers to.
*
* If the video is such that it doesn't require stream generation, then this
* function returns `undefined`.
*/
export const ffmpegGenerateHLSPlaylistAndSegments = async (
inputFilePath: string,
outputPathPrefix: string,
): Promise<FFmpegGenerateHLSPlaylistAndSegmentsResult | undefined> => {
const { isH264, isBT709, bitrate } =
await detectVideoCharacteristics(inputFilePath);
log.debug(() => [basename(inputFilePath), { isH264, isBT709, bitrate }]);
// If the video is smaller than 10 MB, and already H.264 (the codec we are
// going to use for the conversion), then a streaming variant is not much
// use. Skip such cases.
//
// ---
//
// [Note: HEVC/H.265 issues]
//
// We've observed two issues out in the wild with HEVC videos:
//
// 1. On Linux, HEVC video streams don't play. However, since the audio
// stream plays, the browser tells us that the "video" itself is
// playable, but the user sees a blank screen with only audio.
//
// 2. HEVC + HDR videos taken on an iPhone have a rotation (`Side data:
// displaymatrix` in the ffmpeg output) that Chrome (and thus Electron)
// doesn't take into account, so these play upside down.
//
// Not fully related to this case, but mentioning here as to why both the
// size and codec need to be checked before skipping stream generation.
if (isH264) {
const inputVideoSize = await fs
.stat(inputFilePath)
.then((st) => st.size);
if (inputVideoSize <= 10 * 1024 * 1024 /* 10 MB */) {
return undefined;
}
}
// If the video is already H.264 with a bitrate less than 4000 kbps, then we
// do not need to reencode the video stream (by _far_ the costliest part of
// the HLS stream generation).
const reencodeVideo = !(isH264 && bitrate && bitrate <= 4000 * 1000);
// If the bitrate is not too high, then we don't need to rescale the video
// when generating the video stream. This is not a performance optimization,
// but more for avoiding making the video size smaller unnecessarily.
const rescaleVideo = !(bitrate && bitrate <= 2000 * 1000);
// [Note: Tonemapping HDR to HD]
//
// BT.709 ("HD") is a standard that describes things like how color is
// encoded, the range of values, and their "meaning" - i.e. how to map the
// values in the video to the pixels on the screen.
//
// It is not the only such standard, there are three common examples:
//
// - BT.601 ("Standard-Definition" or SD)
// - BT.709 ("High-Definition" or HD)
// - BT.2020 ("Ultra-High-Definition" or UHD, aka HDR^).
//
// ^ HDR ("High-Dynamic-Range") is an addendum to BT.2020, but for our
// purpose here we can treat it as as alias.
//
// BT.709 is the most common amongst these for older files out stored on
// computers, and they conform mostly to the standard (one notable exception
// is that the BT.709 standard also recommends using the yuv422p pixel
// format, but de facto yuv420p is used because many video players only
// support yuv420p).
//
// Since BT.709 is the most widely supported standard, we use it when
// generating the HLS playlist so to allow playback across the widest
// possible hardware/OS/browser combinations.
//
// If we convert HDR to HD without naively, then the colors look washed out
// compared to the original. To resolve this, we use a ffmpeg filterchain
// that uses the tonemap filter.
//
// However applying this tonemap to videos that are already HD leads to a
// brightness drop. So we conditionally apply this filter chain only if the
// colorspace is not already BT.709.
//
// See also: [Note: Alternative FFmpeg command for HDR videos], although
// that uses a allow-list based check (while here we use deny-list).
//
// Reference:
// - https://trac.ffmpeg.org/wiki/colorspace
const tonemap = !isBT709;
// We want the generated playlist to refer to the chunks as "output.ts".
//
// So we arrange things accordingly: We use the `outputPathPrefix` as our
// working directory, and then ask ffmpeg to generate a playlist with the
// name "output.m3u8".
//
// ffmpeg will automatically place the segments in a file with the same base
// name as the playlist, but with a ".ts" extension. And since we use the
// "single_file" option, all the segments will be placed in a file named
// "output.ts".
await fs.mkdir(outputPathPrefix);
const playlistPath = path.join(outputPathPrefix, "output.m3u8");
const videoPath = path.join(outputPathPrefix, "output.ts");
// Generate a cryptographically secure random key (16 bytes).
const keyBytes = randomBytes(16);
const keyB64 = keyBytes.toString("base64");
// Convert it to a data: URI that will be added to the playlist.
const keyURI = `data:text/plain;base64,${keyB64}`;
// Determine two paths - one where we will write the key itself, and where
// we will write the "key info" that provides ffmpeg the `keyURI` and the
// `keyPath;.
const keyPath = playlistPath + ".key";
const keyInfoPath = playlistPath + ".key-info";
// Generate a "key info":
//
// - the first line specifies the key URI that is written into the playlist.
// - the second line specifies the path to the local file system file from
// where ffmpeg should read the key.
const keyInfo = [keyURI, keyPath].join("\n");
// Overview:
//
// - Video H.264 HD 720p 30fps.
// - Audio AAC 128kbps.
// - Encrypted HLS playlist with a single file containing all the chunks.
//
// Reference:
// - `man ffmpeg-all`
// - https://trac.ffmpeg.org/wiki/Encode/H.264
//
const command = [
ffmpegBinaryPath(),
// Reduce the amount of output lines we have to parse.
["-hide_banner"],
// Input file. We don't need any extra options that apply to the input file.
"-i",
inputFilePath,
// The remaining options apply to the next output file (`playlistPath`).
reencodeVideo
? [
// `-vf` creates a filter graph for the video stream. It is a
// comma separated list of filters chained together, e.g.
// `filter1=key=value:key=value.filter2=key=value`.
"-vf",
[
// Do the rescaling to even number of pixels always if the
// tonemapping is going to be applied subsequently,
// otherwise the tonemapping will fail with "image
// dimensions must be divisible by subsampling factor".
//
// While we add the extra condition here for completeness,
// it won't usually matter since a non-BT.709 video is
// likely using a new codec, and as such would've a high
// enough bitrate to require rescaling anyways.
rescaleVideo || tonemap
? [
// Scales the video to maximum 720p height,
// keeping aspect ratio and the calculated
// dimension divisible by 2 (some of the other
// operations require an even pixel count).
"scale=-2:720",
// Convert the video to a constant 30 fps,
// duplicating or dropping frames as necessary.
"fps=30",
]
: [],
// Convert the colorspace if the video is not in the HD
// color space (bt709). Before conversion, tone map colors
// so that they work the same across the change in the
// dyamic range.
//
// 1. The tonemap filter only works linear light, so we
// first use zscale with transfer=linear to linearize
// the input.
//
// 2. Then we use the tonemap, with the hable option that
// is best for preserving details. desat=0 turns off
// the default desaturation.
//
// 3. Use zscale again to "convert to BT.709" by asking it
// to set the all three of color primaries, transfer
// characteristics and colorspace matrix to 709 (Note:
// the constants specified in the tonemap filter help
// do not include the "bt" prefix)
//
// See: https://ffmpeg.org/ffmpeg-filters.html#tonemap-1
//
// See: [Note: Tonemapping HDR to HD]
tonemap
? [
"zscale=transfer=linear",
"tonemap=tonemap=hable:desat=0",
"zscale=primaries=709:transfer=709:matrix=709",
]
: [],
// Output using the well supported pixel format: 8-bit YUV
// planar color space with 4:2:0 chroma subsampling.
"format=yuv420p",
]
.flat()
.join(","),
]
: [],
reencodeVideo
? // Video codec H.264
//
// - `-c:v libx264` converts the video stream to the H.264 codec.
//
// - We don't supply a bitrate, instead it uses the default CRF
// ("23") as recommended in the ffmpeg trac.
//
// - We don't supply a preset, it'll use the default ("medium").
["-c:v", "libx264"]
: // Keep the video stream unchanged
["-c:v", "copy"],
// Audio codec AAC
//
// - `-c:a aac` converts the audio stream to use the AAC codec
//
// - We don't supply a bitrate, it'll use the AAC default 128k bps.
["-c:a", "aac"],
// Generate a HLS playlist.
["-f", "hls"],
// Tell ffmpeg where to find the key, and the URI for the key to write
// into the generated playlist. Implies "-hls_enc 1".
["-hls_key_info_file", keyInfoPath],
// Generate as many playlist entries as needed (default limit is 5).
["-hls_list_size", "0"],
// Place all the video segments within the same .ts file (with the same
// path as the playlist file but with a ".ts" extension).
["-hls_flags", "single_file"],
// Output path where the playlist should be generated.
playlistPath,
].flat();
let dimensions: ReturnType<typeof detectVideoDimensions>;
let videoSize: number;
try {
// Write the key and the keyInfo to their desired paths.
await Promise.all([
fs.writeFile(keyPath, keyBytes),
fs.writeFile(keyInfoPath, keyInfo, { encoding: "utf8" }),
]);
// Run the ffmpeg command to generate the HLS playlist and segments.
//
// Note: Depending on the size of the input file, this may take long!
const { stderr: conversionStderr } = await execAsync(command);
// Determine the dimensions of the generated video from the stderr
// output produced by ffmpeg during the conversion.
dimensions = detectVideoDimensions(conversionStderr);
// Find the size of the generated video segments by reading the size of
// the generated .ts file.
videoSize = await fs.stat(videoPath).then((st) => st.size);
} catch (e) {
log.error("HLS generation failed", e);
await Promise.all([
deleteTempFileIgnoringErrors(playlistPath),
deleteTempFileIgnoringErrors(videoPath),
]);
throw e;
} finally {
await Promise.all([
deleteTempFileIgnoringErrors(keyInfoPath),
deleteTempFileIgnoringErrors(keyPath),
// ffmpeg writes a /path/output.ts.tmp, clear it out too.
deleteTempFileIgnoringErrors(videoPath + ".tmp"),
]);
}
return { playlistPath, videoPath, dimensions, videoSize };
};
/**
* A regex that matches the first line of the form
*
* Stream #0:0: Video: h264 (High 10) ([27][0][0][0] / 0x001B), yuv420p10le(tv, bt2020nc/bt2020/arib-std-b67), 1920x1080, 30 fps, 30 tbr, 90k tbn
*
* The part after Video: is the first capture group.
*
* Another example:
*
* Stream #0:1[0x2](und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(progressive), 480x270 [SAR 1:1 DAR 16:9], 539 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default)
*/
const videoStreamLineRegex = /Stream #.+: Video:(.+)\n/;
/** {@link videoStreamLineRegex}, but global. */
const videoStreamLinesRegex = /Stream #.+: Video:(.+)\n/g;
/**
* A regex that matches "<digits> kb/s" preceded by a space. See
* {@link videoStreamLineRegex} for the context in which it is used.
*/
const videoBitrateRegex = / ([1-9]\d*) kb\/s/;
/**
* A regex that matches <digits>x<digits> pair preceded by a space. See
* {@link videoStreamLineRegex} for the context in which it is used.
*
* We constrain the digit sequence not to begin with 0 to exclude hexadecimal
* representations of various constants that ffmpeg prints on this line (e.g.
* "avc1 / 0x31637661").
*/
const videoDimensionsRegex = / ([1-9]\d*)x([1-9]\d*)/;
interface VideoCharacteristics {
isH264: boolean;
isBT709: boolean;
bitrate: number | undefined;
}
/**
* Heuristically determine information about the video at the given
* {@link inputFilePath}:
*
* - If is encoded using H.264 codec.
* - If it uses the BT.709 colorspace.
* - Its bitrate.
*
* The defaults are tailored for the cases in which these conditions are used,
* so that even if we get the detection wrong we'll only end up encoding videos
* that could've possibly been skipped as an optimization.
*
* [Note: Parsing CLI output might break on ffmpeg updates]
*
* This function tries to determine the these bits of information about the
* given video by scanning the ffmpeg info output for the video stream line, and
* doing various string matches and regex extractions.
*
* Needless to say, while this works currently, this is liable to break in the
* future. So if something stops working after updating ffmpeg, look here!
*
* Ideally, we'd have done this using `ffprobe`, but we don't have the ffprobe
* binary at hand, so we make do by grepping the log output of ffmpeg.
*
* For reference,
*
* - codec and colorspace are printed by the `avcodec_string` function in the
* ffmpeg source:
* https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/avcodec.c
*
* - bitrate is printed by the `dump_stream_format` function in `dump.c`.
*/
const detectVideoCharacteristics = async (inputFilePath: string) => {
const videoInfo = await pseudoFFProbeVideo(inputFilePath);
const videoStreamLine = videoStreamLineRegex.exec(videoInfo)?.at(1)?.trim();
// Since the checks are heuristic, start with defaults that would cause the
// codec conversion to happen, even if it is unnecessary.
const res: VideoCharacteristics = {
isH264: false,
isBT709: false,
bitrate: undefined,
};
if (!videoStreamLine) return res;
res.isH264 = videoStreamLine.startsWith("h264 ");
res.isBT709 = videoStreamLine.includes("bt709");
// The regex matches "\d kb/s", but there can be other units for the
// bitrate. However, (a) "kb/s" is the most common for videos out in the
// wild, and (b) even if we guess wrong it we'll just do "-v:c x264" instead
// of "-v:c copy", so only unnecessary processing but no change in output.
const brs = videoBitrateRegex.exec(videoStreamLine)?.at(0);
if (brs) {
const br = parseInt(brs, 10);
if (br) res.bitrate = br;
}
return res;
};
/**
* Heuristically detect the dimensions of the given video from the log output of
* the ffmpeg invocation during the HLS playlist generation.
*
* This function tries to determine the width and height of the generated video
* from the output log written by ffmpeg on its stderr during the generation
* process, scanning it for the last video stream line, and trying to match a
* "<digits>x<digits>" regex.
*
* See: [Note: Parsing CLI output might break on ffmpeg updates].
*/
const detectVideoDimensions = (conversionStderr: string) => {
// There is a nicer way to do it - by running `pseudoFFProbeVideo` on the
// generated playlist. However, that playlist includes a data URL that
// specifies the encryption info, and ffmpeg refuses to read that unless we
// specify the "-allowed_extensions ALL" or something to that effect.
//
// Unfortunately, our current ffmpeg binary (5.x) does not support that
// option. So we instead parse the conversion output itself.
//
// This is also nice, since it saves on an extra ffmpeg invocation. But we
// now need to be careful to find the right video stream line, since the
// conversion output includes both the input and output video stream lines.
//
// To match the right (output) video stream line, we use a global regex, and
// use the last match since that'd correspond to the single video stream
// written in the output.
const videoStreamLine = Array.from(
conversionStderr.matchAll(videoStreamLinesRegex),
)
.at(-1) /* Last Stream...: Video: line in the output */
?.at(1); /* First capture group */
if (videoStreamLine) {
const [, ws, hs] = videoDimensionsRegex.exec(videoStreamLine) ?? [];
if (ws && hs) {
const w = parseInt(ws, 10);
const h = parseInt(hs, 10);
if (w && h) {
return { width: w, height: h };
}
}
}
throw new Error(
`Unable to detect video dimensions from stream line [${videoStreamLine ?? ""}]`,
);
};
/**
* Heuristically detect if the file at given path is a HDR video.
*
* This is similar to {@link detectVideoCharacteristics}, and see that
* function's documentation for all the caveats. However, this function uses an
* allow-list instead, and considers any file with color transfer "smpte2084" or
* "arib-std-b67" to be HDR. While this is in some sense a more exact check, it
* comes with different caveats:
*
* - These particular constants are not guaranteed to be correct; these are just
* what I saw on the internet as being used / recommended for detecting HDR.
*
* - Since we don't have ffprobe, we're not checking the color space value
* itself but a substring of the stream line in the ffmpeg stderr output.
*
* In particular, we use this more exact check for places where we have less
* leeway. e.g. when generating thumbnails, if we apply the tonemapping to any
* non-BT.709 file (as the HLS stream generation does), we start getting the
* "code 3074: no path between colorspaces" error during the JPEG conversion
* (this is not a problem in the H.264 conversion).
*
* - See: [Note: Alternative FFmpeg command for HDR videos]
* - See: [Note: Tonemapping HDR to HD]
*
* @param inputFilePath The path to a video file on the user's machine.
*
* @returns `true` if this file is likely a HDR video. Exceptions are treated as
* `false` to make this function safe to invoke without breaking the happy path.
*/
const isHDRVideo = async (inputFilePath: string) => {
try {
const videoInfo = await pseudoFFProbeVideo(inputFilePath);
const vs = videoStreamLineRegex.exec(videoInfo)?.at(1);
if (!vs) return false;
return vs.includes("smpte2084") || vs.includes("arib-std-b67");
} catch (e) {
log.warn(`Could not detect HDR status of ${inputFilePath}`, e);
return false;
}
};
/**
* Return the stderr of ffmpeg in an attempt to gain information about the video
* at the given {@link inputFilePath}.
*
* We don't have the ffprobe binary at hand, which is why we need to use this
* alternative. See: [Note: Parsing CLI output might break on ffmpeg updates]
*
* @returns the stderr of ffmpeg after running it on the input file. The exact
* command we run is:
*
* ffmpeg -i in.mov -an -frames:v 0 -f null - 2>info.txt
*
* And the returned string is the contents of the `info.txt` thus produced.
*/
const pseudoFFProbeVideo = async (inputFilePath: string) => {
const command = [
ffmpegPathPlaceholder,
// Reduce the amount of output lines we have to parse.
["-hide_banner"],
["-i", inputPathPlaceholder],
"-an",
["-frames:v", "0"],
["-f", "null"],
"-",
].flat();
const cmd = substitutePlaceholders(command, inputFilePath, /* NA */ "");
const { stderr } = await execAsync(cmd);
return stderr;
};

View File

@@ -36,6 +36,17 @@ export const fsIsDir = async (dirPath: string) => {
return stat.isDirectory();
};
export const fsStatMtime = (path: string) =>
// [Note: Integral last modified time]
//
// Whenever we need to find the modified time of a file, use the
// `mtime.getTime()` instead of `mtimeMs` of the stat; this way, it is
// guaranteed that the times are integral (we persist these values to remote
// in some cases, and the contract is for them to be integral; mtimeMs is a
// float with sub-millisecond precision), and that all places use the same
// value so that they're comparable.
fs.stat(path).then((st) => st.mtime.getTime());
export const fsFindFiles = async (dirPath: string) => {
const items = await fs.readdir(dirPath, { withFileTypes: true });
let paths: string[] = [];

View File

@@ -6,7 +6,7 @@ import { type ZipItem } from "../../types/ipc";
import { execAsync, isDev } from "../utils/electron";
import {
deleteTempFileIgnoringErrors,
makeFileForDataOrPathOrZipItem,
makeFileForDataOrStreamOrPathOrZipItem,
makeTempFilePath,
} from "../utils/temp";
@@ -69,7 +69,7 @@ export const generateImageThumbnail = async (
path: inputFilePath,
isFileTemporary: isInputFileTemporary,
writeToTemporaryFile: writeToTemporaryInputFile,
} = await makeFileForDataOrPathOrZipItem(dataOrPathOrZipItem);
} = await makeFileForDataOrStreamOrPathOrZipItem(dataOrPathOrZipItem);
const outputFilePath = await makeTempFilePath("jpeg");

View File

@@ -1,6 +1,6 @@
import type { FSWatcher } from "chokidar";
import log from "../log";
import { clearConvertToMP4Results } from "../stream";
import { clearPendingVideoResults } from "../stream";
import { clearStores } from "./store";
import { watchReset } from "./watch";
import { clearOpenZipCache } from "./zip";
@@ -22,9 +22,9 @@ export const logout = (watcher: FSWatcher) => {
ignoreError("FS watch", e);
}
try {
clearConvertToMP4Results();
clearPendingVideoResults();
} catch (e) {
ignoreError("convert-to-mp4", e);
ignoreError("video", e);
}
try {
clearStores();

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