Compare commits

...

560 Commits

Author SHA1 Message Date
laurenspriem
e5795198c8 More crash logging 2025-06-10 15:15:28 +05:30
laurenspriem
eed12c2089 Merge branch 'internal-15_06_2025' into usearch_again 2025-06-09 12:34:55 +05:30
laurenspriem
889aed6024 Bump for internal release 2025-06-09 12:34:29 +05:30
laurenspriem
ac7840cbfd Merge branch 'internal-15_06_2025' into usearch_again 2025-06-09 12:33:03 +05:30
laurenspriem
1f1304ca5b Upgrade usearch to fix Armv8-R issues 2025-06-09 12:31:38 +05:30
Neeraj Gupta
94098d8a07 Bump version 2025-06-06 12:35:30 +05:30
Neeraj Gupta
4b9c5fcb73 Merge branch 'internal-15_06_2025' of https://github.com/ente-io/auth into internal-15_06_2025 2025-06-06 12:33:48 +05:30
Neeraj Gupta
6ed16e5e02 Merge branch 'main' into internal-15_06_2025 2025-06-06 12:33:21 +05:30
Neeraj
e0b62ded5a [mob][photos] Birthday notification + memories decoding improvements (#6177)
## Description

- Schedule birthday notifications for named persons.
- Minor performance improvements to memories cache decoding

## Tests

Tested in debug mode on my pixel 8:

- [X]  Notifications are scheduled at correct time
- [X] Tapping notifications navigates to memory of that person
2025-06-06 12:22:00 +05:30
Neeraj
b17821685f [mob] Minor fixes for resumable download (#6189)
## Description

## Tests
2025-06-06 11:43:57 +05:30
Neeraj
a5016b0984 [auth] Add R10.net icon support (#6185)
Add custom icon support for R10.net auth.

## Changes
- Add `r10.svg` icon file to `auth/assets/custom-icons/icons/`
- Add R10.net entry to `custom-icons.json` with proper configuration
- Include alternative names: "R10", "r10.net" for better user matching
2025-06-06 11:43:34 +05:30
alewi7
b5ad82f5ba Add 5 new icons and rename existing icon (#6104)
## Description

Added 5 new custom SVG icons:

- **cronometer.svg**
- **xai.svg**
- **toshl_finance.svg**
- **aternos.svg**
- **atomic_mail.svg**

Also renamed an existing icon **'mercado_livre.svg'** to
**'mercado_libre.svg'** to match the brand's official name.

## Tests

No formal tests added. Verified manually that all SVGs open correctly in
the browser and display as expected.
2025-06-06 11:40:47 +05:30
Neeraj Gupta
14da860973 Handle incorrect pause 2025-06-06 11:37:07 +05:30
Vishnu Mohandas
2b381e7e2f [docs] Minor update (#6174)
## Description

Commits.
2025-06-06 11:22:11 +05:30
Neeraj
e8a35bf6e6 [photos][mob] Trim whitespace from new album name (#6181)
## Description

Previously, newly created albums could easily end with trailing
whitespace, especially when using auto-completion that automatically
adds the next space character. It's not super bad obviously, but I found
it slightly annoying. I can't think of any good reason for why an album
name should ever start or end with whitespace.

## Tests
2025-06-06 10:37:30 +05:30
Yusuf Danış
c98726e4d0 [auth] Add R10.net icon support 2025-06-05 23:03:27 +03:00
vishnukvmd
4b49bab0bd Prettify 2025-06-05 23:57:51 +05:30
Jacques Lucke
7bdcbcca02 trim new album name 2025-06-05 18:03:36 +02:00
Manav Rathi
e1cb8e06a1 [web] Crypto API cleanup (non functional) - Part 3 (#6180) 2025-06-05 20:27:03 +05:30
Manav Rathi
1a15bcb7e0 lint fix 2025-06-05 20:17:39 +05:30
Manav Rathi
2df06ccf61 Use 2025-06-05 20:04:30 +05:30
Manav Rathi
560533b2d4 accessor 2025-06-05 19:49:58 +05:30
Manav Rathi
60a2febe46 Move 2025-06-05 19:43:33 +05:30
Manav Rathi
ed2a98b341 Rename 2025-06-05 18:55:31 +05:30
Manav Rathi
e8187356af Rename 2025-06-05 18:48:35 +05:30
Manav Rathi
21febab897 Del 2025-06-05 18:39:30 +05:30
Manav Rathi
250aad43bc Switch 2025-06-05 18:36:45 +05:30
Manav Rathi
5e9e8bd76b Switch 2025-06-05 18:30:37 +05:30
Manav Rathi
7b3ea32963 Go the other way for better future composability 2025-06-05 18:03:35 +05:30
Manav Rathi
ac9cee8fa3 Specialize 2025-06-05 18:00:40 +05:30
Manav Rathi
4a3d503992 Dup 2025-06-05 17:55:38 +05:30
Manav Rathi
7bfc63ffc7 [web] Crypto API cleanup (non functional) (#6178) 2025-06-05 17:40:09 +05:30
laurenspriem
b359d97b95 Fix typo 2025-06-05 17:32:58 +05:30
laurenspriem
19a0a8a7ec Merge branch 'main' into birthday_notification 2025-06-05 17:29:39 +05:30
Manav Rathi
51a736dbce Adapt 2025-06-05 17:25:38 +05:30
laurenspriem
36928e4f39 memories decoding optimization 2025-06-05 17:24:33 +05:30
laurenspriem
bfe738c846 Fix duplicate memories decoding 2025-06-05 17:17:25 +05:30
Manav Rathi
d62865f9e5 Inline 2025-06-05 17:10:22 +05:30
Manav Rathi
f7dcaffc32 Move 2025-06-05 17:10:11 +05:30
Manav Rathi
c88a43d2dc Use 2025-06-05 17:10:11 +05:30
Manav Rathi
a5fe20b0e9 Rename 2025-06-05 17:10:11 +05:30
Manav Rathi
3dffebf733 Same place both 2025-06-05 17:10:11 +05:30
Manav Rathi
4be5ac8780 types 2025-06-05 17:10:11 +05:30
Manav Rathi
d858fdef75 More annotation 2025-06-05 17:10:11 +05:30
Manav Rathi
f1d9fc61c5 Annotate 2025-06-05 17:10:11 +05:30
Manav Rathi
931dafd264 Reroute 2025-06-05 17:10:11 +05:30
Manav Rathi
40f3ad592f type 2025-06-05 17:10:11 +05:30
Manav Rathi
723362fc33 Rename 2025-06-05 17:10:11 +05:30
Manav Rathi
94c5cf316b Swap 2025-06-05 17:10:11 +05:30
Manav Rathi
5de4b3c1b0 Swap 2025-06-05 17:10:11 +05:30
Manav Rathi
6eab85b7e1 enc 2025-06-05 17:10:11 +05:30
Manav Rathi
40e7d58c0b utf-8 2025-06-05 17:10:11 +05:30
Manav Rathi
c85aac613e Prune 2025-06-05 17:10:11 +05:30
Manav Rathi
9387320948 Conv 2025-06-05 17:10:11 +05:30
Manav Rathi
9e1b1b0850 Convert 2025-06-05 17:10:11 +05:30
Manav Rathi
b656d4fe1f Addendum
https://github.com/jedisct1/libsodium.js/issues/112#issuecomment-337389964
2025-06-05 17:10:11 +05:30
Manav Rathi
76cca72bec Conv 2025-06-05 17:10:11 +05:30
Manav Rathi
3f6a706e9a Conv 2025-06-05 17:10:11 +05:30
Neeraj Gupta
9245af5080 Fix oom during chunk combination 2025-06-05 16:30:51 +05:30
Vishnu Mohandas
0717d12d65 [docs] Update general.md 2025-06-05 15:30:39 +05:30
vishnukvmd
107e8e665a Minor 2025-06-05 15:09:33 +05:30
vishnukvmd
d9040047ec Add a line to avoid starting articles with line-breaks that precede an H2 2025-06-05 15:09:26 +05:30
laurenspriem
4fb2be51e0 Logging 2025-06-05 14:51:47 +05:30
laurenspriem
a99cdbedc4 Fix out of range issue 2025-06-05 14:35:03 +05:30
Neeraj Gupta
a543b8c0f6 Pass token in query param for direct download 2025-06-05 14:21:38 +05:30
Neeraj Gupta
f5ca4a9d15 Logs for resumable download failure 2025-06-05 14:19:58 +05:30
Manav Rathi
5ab0299751 [web] Crypto API cleanup (non functional) (#6173) 2025-06-05 11:28:52 +05:30
Neeraj
f1097a93f7 [mob] Fix: Handle already linked email err (#6172)
## Description
While linking contact to a person, we were not gracefully handling the
error where email id is already mapped to another person. And when such
person doesn't have any face attached, they don't have any way to unlink
the email from that person entity.
## Tests
2025-06-05 11:26:56 +05:30
Manav Rathi
7bce2e358b Conv 2025-06-05 11:18:23 +05:30
Manav Rathi
75b3d2354f Simplify 2025-06-05 11:14:31 +05:30
Manav Rathi
52ee86af18 Proxy 2025-06-05 11:06:52 +05:30
Manav Rathi
462aae8f34 Fwd 2025-06-05 11:01:40 +05:30
laurenspriem
496691d236 Schedule at midnight 2025-06-05 10:41:26 +05:30
laurenspriem
f1a6af048d Cleanup 2025-06-05 10:38:44 +05:30
laurenspriem
22e32baf34 route to person memory 2025-06-05 10:36:47 +05:30
Manav Rathi
e864ea367a Rename 2025-06-05 10:30:08 +05:30
Neeraj Gupta
45cf130375 Perf: remove redundant async 2025-06-05 10:24:23 +05:30
Manav Rathi
e6fd962c75 Del 2025-06-05 10:23:02 +05:30
Manav Rathi
f5aefb445d Conv 2025-06-05 10:22:18 +05:30
Neeraj Gupta
917ce21b35 Fix: Handle already linked email err 2025-06-05 10:19:07 +05:30
Manav Rathi
0241e41f0d Tweak 2025-06-05 10:13:44 +05:30
Manav Rathi
65982b6f82 Del 2025-06-05 09:58:16 +05:30
Manav Rathi
69756d5733 Conv 2025-06-05 09:56:11 +05:30
laurenspriem
b17ba26268 Extract strings 2025-06-05 09:52:40 +05:30
Manav Rathi
594671d96c Conv 2025-06-05 09:44:22 +05:30
Manav Rathi
fa1719e3ca Conv 2025-06-05 09:43:10 +05:30
laurenspriem
e2fbb26dce Reorganize 2025-06-05 09:41:58 +05:30
Manav Rathi
6ba7841632 Conv 2025-06-05 09:39:57 +05:30
Manav Rathi
37b52b5cb5 Reduce API surface 2025-06-05 09:28:28 +05:30
Manav Rathi
2e98d8b652 Ret 3 2025-06-05 09:17:22 +05:30
Manav Rathi
ea4d6c5cf1 consistent 2025-06-05 09:15:30 +05:30
Manav Rathi
413f5479ef ret 2 2025-06-05 09:14:13 +05:30
laurenspriem
81bfc83e9d birthday notifications setting 2025-06-05 09:12:51 +05:30
Manav Rathi
92b3da1198 return type consistency 1 2025-06-05 08:53:16 +05:30
laurenspriem
cc98ca70d5 Log scheduling 2025-06-05 08:50:37 +05:30
laurenspriem
544078a40c Optional notification message 2025-06-05 08:45:36 +05:30
laurenspriem
229d438181 Remove 2025-06-05 08:39:17 +05:30
laurenspriem
aab1450c3f remove old parameter comment 2025-06-05 08:38:59 +05:30
laurenspriem
07d7635464 Merge branch 'main' into birthday_notification 2025-06-05 08:35:44 +05:30
laurenspriem
82a8e504af Merge branch 'internal-15_06_2025' into usearch_again 2025-06-04 22:14:26 +05:30
Neeraj
88b95da04f [mob] widget customizations (+ new widgets) (#5882) 2025-06-04 20:57:22 +05:30
Manav Rathi
32707e2909 [desktop] macOS folder watch EMFILE workaround (#6170) 2025-06-04 20:18:41 +05:30
Manav Rathi
e28ee8ca66 [desktop] macOS folder watch EMFILE workaround 2025-06-04 20:15:19 +05:30
Manav Rathi
751d107518 [web] One less nit (#6169) 2025-06-04 20:09:50 +05:30
Manav Rathi
439dfcab58 One less nit 2025-06-04 19:36:17 +05:30
Manav Rathi
3f9f0d6d10 [web] General code improvements (#6168) 2025-06-04 19:15:25 +05:30
Manav Rathi
506b915f65 conv 2025-06-04 19:02:55 +05:30
Manav Rathi
65a8923799 Conv 2025-06-04 18:53:14 +05:30
Manav Rathi
e6707d9fcb Move 2025-06-04 18:43:05 +05:30
Manav Rathi
3dbc336687 Doc 2025-06-04 18:36:49 +05:30
Manav Rathi
8441aafe81 Inline 2025-06-04 18:26:53 +05:30
Manav Rathi
5d3f431ee0 Doc 2025-06-04 18:25:28 +05:30
ashilkn
cc1660d9af bump up build number" 2025-06-04 18:24:59 +05:30
ashilkn
52b6fc108b Merge branch 'memory_improvement' into internal-15_06_2025 2025-06-04 18:19:37 +05:30
Manav Rathi
ce591e6267 Conv 2025-06-04 18:11:28 +05:30
Prateek Sunal
132a7862fe fix: clear directory on log out 2025-06-04 17:50:21 +05:30
Prateek Sunal
f4167be4b4 fix: update people changed debouncer to 1500 2025-06-04 17:42:46 +05:30
Prateek Sunal
4e17a861dc fix: separate asset resources 2025-06-04 17:41:22 +05:30
Manav Rathi
86f282bb06 Scope 2025-06-04 17:36:50 +05:30
Manav Rathi
334a996357 Scope 2025-06-04 17:27:46 +05:30
Manav Rathi
9a5bac774e Unused 2025-06-04 17:24:08 +05:30
Manav Rathi
04ae02c130 [meta] Issue template (#6166) 2025-06-04 17:13:41 +05:30
Manav Rathi
31232390e8 [meta] Issue template 2025-06-04 17:07:03 +05:30
AmanRajSinghMourya
4d27341787 Refactor: remove unnecessary calls to _resetAnimation and handle reset in onFinalFileLoad 2025-06-04 16:56:52 +05:30
Prateek Sunal
7d4ea8092a chore: readd thermal 2025-06-04 16:49:46 +05:30
AmanRajSinghMourya
45d8c236fe Update onFinalFileLoad to remove unused parameter 2025-06-04 16:48:08 +05:30
AmanRajSinghMourya
4412b016ce Refactor: rename onFileLoad to onFinalFileLoad for consistency across file handling 2025-06-04 16:44:00 +05:30
AmanRajSinghMourya
3cea8e8a90 Hide seekbar and play/pause button for videos shown in memories & long press to play/pause video 2025-06-04 16:43:34 +05:30
Manav Rathi
e80f91ca92 [web] General refactoring (#6164) 2025-06-04 16:42:28 +05:30
Manav Rathi
523d1961b7 other dep 2025-06-04 16:32:08 +05:30
Manav Rathi
6091a0d446 Lockfile updates 2025-06-04 16:28:33 +05:30
Manav Rathi
12d84d0dbe Avoid exceptions for flow control 2025-06-04 16:27:24 +05:30
Manav Rathi
a244140348 tweak 2025-06-04 16:27:24 +05:30
Manav Rathi
2715bd81b0 vis 2025-06-04 16:27:24 +05:30
Manav Rathi
d65424cef2 Document and move 2025-06-04 16:27:24 +05:30
Manav Rathi
a07d39512b Prune ids 2025-06-04 16:27:24 +05:30
Manav Rathi
223ed36d61 Conv 2025-06-04 16:27:24 +05:30
Neeraj
3e893a7b39 [mob] Use file stream to improve hashing speed (#6163)
## Description

## Tests
For 3.38 GB file on iPhone 11
Old Hashing took 24792 ms
Hashing v2 took 10365 ms

Also tested it on a smaller file

```dart
// Returns the hash for a given file, chunking it in batches of hashChunkSize
Future<Uint8List> cryptoGenericHash(Map<String, dynamic> args) async {
  final int startTime = DateTime.now().millisecondsSinceEpoch;
  final sourceFile = File(args["sourceFilePath"]);
  final sourceFileLength = await sourceFile.length();
  final inputFile = sourceFile.openSync(mode: FileMode.read);
  final state =
      Sodium.cryptoGenerichashInit(null, Sodium.cryptoGenerichashBytesMax);
  var bytesRead = 0;
  bool isDone = false;
  while (!isDone) {
    var chunkSize = hashChunkSize;
    if (bytesRead + chunkSize >= sourceFileLength) {
      chunkSize = sourceFileLength - bytesRead;
      isDone = true;
    }
    final buffer = await inputFile.read(chunkSize);
    bytesRead += chunkSize;
    Sodium.cryptoGenerichashUpdate(state, buffer);
  }
  await inputFile.close();
  final hash =
      Sodium.cryptoGenerichashFinal(state, Sodium.cryptoGenerichashBytesMax);

  final int endTime = DateTime.now().millisecondsSinceEpoch;
  final hash2 = await cryptoGenericHashV2(args);
  final endTime2 = DateTime.now().millisecondsSinceEpoch;
  if (hash.length != hash2.length) {
    throw Exception(
      "Hash length mismatch: ${hash.length} != ${hash2.length}",
    );
  }
  if (!const ListEquality().equals(hash, hash2)) {
    throw Exception("not equal: hash");
  }
  print("Hashing took ${endTime2 - startTime} ms");
  print("Hashing v2 took ${endTime2 - endTime} ms");
  return hash;
}

Future<Uint8List> cryptoGenericHashV2(Map<String, dynamic> args) async {
  final file = File(args["sourceFilePath"]);
  final state =
      Sodium.cryptoGenerichashInit(null, Sodium.cryptoGenerichashBytesMax);
  await for (final chunk in file.openRead()) {
    Sodium.cryptoGenerichashUpdate(state, Uint8List.fromList(chunk));
  }
  return Sodium.cryptoGenerichashFinal(state, Sodium.cryptoGenerichashBytesMax);
}
```
2025-06-04 14:33:47 +05:30
Neeraj
eea70db1fd Avoid redundant copy
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-04 14:31:51 +05:30
Neeraj Gupta
85c14b884b [mob] Use file stream to improve hashing speed 2025-06-04 13:43:01 +05:30
laurenspriem
9a0722ffcc todos for after merge 2025-06-04 13:25:32 +05:30
laurenspriem
49dcb55de7 schedule birthdays notifications 2025-06-04 13:22:47 +05:30
laurenspriem
fa37b11c7f Specify birthdays clearer 2025-06-04 13:20:59 +05:30
Prateek Sunal
884b3716ba fix: add debouncer 2025-06-04 12:52:48 +05:30
Prateek Sunal
6f3ee24ac1 chore: update lock files 2025-06-04 12:46:27 +05:30
Prateek Sunal
292ed5fd6d Merge remote-tracking branch 'origin/main' into widget-superpowered 2025-06-04 12:45:21 +05:30
Prateek Sunal
54d2040f2b fix: remove .fvm 2025-06-04 12:43:35 +05:30
Neeraj
15954ce396 [mob] Remember last scroll offset while adding assets from device (#6159)
## Description
Also increased the items in grid, as there's no scrollbar (pkg does not
support it yet afaik)

## Tests
2025-06-04 12:24:32 +05:30
Laurens Priem
86a9e5ec86 [mob][photos] Compute controller (#6158)
## Description

Refactored MLController (now ComputeController) so that ML and Streaming
both first have to ask for its permission to run.

## Tests
2025-06-04 12:02:57 +05:30
Manav Rathi
52c9a15c2c [web] Migrate to zod v4 (#6162) 2025-06-04 11:58:00 +05:30
Manav Rathi
3c514476c2 Reintroduce with new zod 2025-06-04 11:53:49 +05:30
laurenspriem
31b26a1b26 Reduce logs 2025-06-04 11:52:33 +05:30
Manav Rathi
5e26a895d3 passthrough => looseObject
https://zod.dev/v4/changelog?id=deprecates-strict-and-passthrough
2025-06-04 11:45:12 +05:30
Manav Rathi
4b4d9d0fd8 Migrate
https://zod.dev/v4/changelog
2025-06-04 11:45:12 +05:30
laurenspriem
a4f49b8e84 Try trigger streaming when ML is done 2025-06-04 11:11:21 +05:30
Neeraj
1722277141 [mobile] New translations (#6125)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-app)
2025-06-04 11:02:00 +05:30
Manav Rathi
6a6547a984 Up 2025-06-04 11:01:41 +05:30
Manav Rathi
4c78d1ab78 [web] Convert more cases of deprecated single input form (#6160) 2025-06-04 10:58:03 +05:30
Neeraj
8cd87b964a [photos][mob] Trim whitespace from search query (#6153)
## Description

Previously, when searching for e.g. `test ` would not find an album
called `test`. That's because the trailing whitespace is not ignored. On
mobile this can be especially annoying because sometimes auto-completion
automatically inserts whitespace after a word.

This patch trims whitespace of the search query in two places:
* When searching for an album name when moving photos to an album.
* When using the global search.

## Tests
2025-06-04 10:52:40 +05:30
Manav Rathi
68844eb790 Try to retain similar DOM structure as before 2025-06-04 10:52:18 +05:30
Neeraj Gupta
b24b0d340b Remember last scrollOffset while picking asset from device 2025-06-04 10:50:06 +05:30
Neeraj Gupta
47e8ccd5d8 Update asset_picker pkg 2025-06-04 10:49:41 +05:30
Manav Rathi
e0ae9eb911 vis 2025-06-04 10:48:12 +05:30
laurenspriem
c8d53faa5d Don't queue streaming if controller doesn't allow 2025-06-04 10:44:44 +05:30
laurenspriem
b494dc8cad Allow multiple request calls 2025-06-04 10:44:19 +05:30
Manav Rathi
5d3acca7ed Conv 2025-06-04 10:39:40 +05:30
laurenspriem
d6ea8d4ec3 less loging 2025-06-04 10:30:22 +05:30
Manav Rathi
1850aa1aec ref uploader name 2025-06-04 10:15:11 +05:30
laurenspriem
42239fe30d don't stop on force 2025-06-04 10:14:14 +05:30
Neeraj
35f6dc2361 [mob] Switch to exif_reader (#6154) 2025-06-04 10:01:35 +05:30
Manav Rathi
bbfae3731a Swap 2025-06-04 09:21:35 +05:30
Manav Rathi
d99b3e422b Change default to the more frequently needed value 2025-06-04 09:14:52 +05:30
Manav Rathi
5fe497df3b Swap 2025-06-04 09:06:28 +05:30
Manav Rathi
2e5deda9ae [web] Reset cast dialog view on reopen (#6157) 2025-06-04 08:54:05 +05:30
Manav Rathi
c4fc03d933 Reset cast dialog view on reopen 2025-06-04 08:40:40 +05:30
Prateek Sunal
a1c180485d Merge remote-tracking branch 'origin/main' into widget-superpowered 2025-06-04 01:18:56 +05:30
Prateek Sunal
c865e263e5 fix: remove shrink wrap and use casting for GenericSearchResult 2025-06-04 01:06:09 +05:30
Prateek Sunal
4b72acf3c0 chore: add lock files 2025-06-04 01:05:34 +05:30
Manav Rathi
083eb0516a [web] LP and video playback tweaks (#6156) 2025-06-03 21:15:45 +05:30
Manav Rathi
c5f993571e vid tweaks 2025-06-03 21:11:21 +05:30
Manav Rathi
5b698a926e z 2025-06-03 21:05:52 +05:30
Manav Rathi
760cc4b8e0 Take 2 2025-06-03 21:01:01 +05:30
Manav Rathi
5f722f50e6 Reset 2025-06-03 20:29:23 +05:30
Manav Rathi
ddef5a565f 4 2025-06-03 20:06:28 +05:30
laurenspriem
75042010e8 Integrate computeController requests 2025-06-03 19:43:50 +05:30
Manav Rathi
730746781c 3 2025-06-03 19:43:34 +05:30
laurenspriem
eeadc1d0d3 requesting to computeController methods 2025-06-03 19:43:01 +05:30
Manav Rathi
5b7c112c9a 2 2025-06-03 19:39:41 +05:30
Manav Rathi
c0d57c72bf LP tweaks 2025-06-03 19:33:03 +05:30
Manav Rathi
65abbb4126 [web] General improvements to code dealing with keys (#6155)
(Non functional)
2025-06-03 17:28:26 +05:30
Manav Rathi
113b820451 Same name 2025-06-03 16:54:17 +05:30
Neeraj Gupta
c17a8d4c38 Fix fr arb 2025-06-03 16:23:16 +05:30
Neeraj Gupta
0202cd1447 Switch to exif_reader 2025-06-03 16:23:08 +05:30
Manav Rathi
6ce7921a16 Inline 2025-06-03 16:16:08 +05:30
Manav Rathi
2d7689a6da Consolidate and move 2025-06-03 16:03:51 +05:30
Manav Rathi
f0aac696ca Conv 2025-06-03 15:50:43 +05:30
Manav Rathi
7112e96c75 Swap 2025-06-03 15:46:15 +05:30
Manav Rathi
f4ff63ec0a Swap 2025-06-03 15:41:47 +05:30
Manav Rathi
48dc3a6b69 Redirect 2025-06-03 15:38:23 +05:30
Jacques Lucke
1b62dbbb78 also trim in album search 2025-06-03 12:08:00 +02:00
laurenspriem
d9a4ffd8f7 rename to ComputeController 2025-06-03 15:32:47 +05:30
Jacques Lucke
f749e1ee22 trim search query 2025-06-03 11:59:02 +02:00
Manav Rathi
78669a8550 Match mobile and architecture docs
From libsodium source

crypto_secretbox_keygen(unsigned char k[crypto_secretbox_KEYBYTES])
{
    randombytes_buf(k, crypto_secretbox_KEYBYTES);
}

crypto_kdf_keygen(unsigned char k[crypto_kdf_KEYBYTES])
{
    randombytes_buf(k, crypto_kdf_KEYBYTES);
}
2025-06-03 15:20:20 +05:30
laurenspriem
3d5c53b041 Simplify 2025-06-03 15:04:56 +05:30
laurenspriem
e493702c64 Integrate thermal state in check 2025-06-03 14:59:23 +05:30
Manav Rathi
7cdef46385 Update 2025-06-03 14:44:20 +05:30
Manav Rathi
97314b7dc1 conv 2025-06-03 14:15:15 +05:30
Manav Rathi
9d9ed0f01f Refactor API 2025-06-03 14:09:08 +05:30
Manav Rathi
5df1b12ef5 use new api 2025-06-03 14:02:33 +05:30
Manav Rathi
25cadce651 Vars 2025-06-03 13:56:41 +05:30
Manav Rathi
0e0044693c Remove unnecessary roundtrip 2025-06-03 13:56:41 +05:30
Vishnu Mohandas
32bffcb80b [docs] Update deduplicate.md 2025-06-03 13:50:40 +05:30
AmanRajSinghMourya
2bb839e26c Refactor: remove scaling and make memories widget of same size 2025-06-03 13:49:02 +05:30
Manav Rathi
241577739a doc 2025-06-03 13:21:18 +05:30
Manav Rathi
8c99a3e5af Other way 2025-06-03 13:11:54 +05:30
Manav Rathi
c92141b9dc Use 2025-06-03 13:01:52 +05:30
Manav Rathi
54b5100e89 Use 2025-06-03 13:01:52 +05:30
Manav Rathi
d6060e1194 Extract 2025-06-03 13:01:52 +05:30
AmanRajSinghMourya
63d0f23742 Fix: reset animation when switching to next/previous page before starting the next/previous page animation 2025-06-03 12:44:59 +05:30
Vishnu Mohandas
d895e6a0c3 [server] Fix migration index (#6150) 2025-06-03 12:42:54 +05:30
vishnukvmd
55fd87face [server] Fix migration index 2025-06-03 12:42:25 +05:30
AmanRajSinghMourya
36e7a664ff Make zoom-in/zoom-out animation alternate 2025-06-03 11:37:07 +05:30
Manav Rathi
6e8acbab1a [infra] Forward headers from workers + ditto cast (#6149) 2025-06-03 10:42:51 +05:30
Manav Rathi
9dd8cd3558 up 2025-06-03 10:27:52 +05:30
Manav Rathi
a227e8541d + range for files 2025-06-03 10:12:40 +05:30
Neeraj
f4f6f2906c [photos][mob] Fix: Close input dialog after album creation (#6148)
## Description

There is an annoyingly flashing dialog when creating exiting a newly
created album. The solution is to close the new-album-dialog before
entering the album so that it is not visible anymore when leaving the
album again.

The dialog is closed after the album is created and before routing to
the album. An alternative is to close it directly when tapping on the
Create button, but then the dialog disappears and it might take a while
until the album is opened which feels worse.

Old (note how the dialog is still open when leaving the album):


https://github.com/user-attachments/assets/e57d27af-2339-4ba7-a5d8-be052aede99c

New (note how there is no dialog when leaving the album):


https://github.com/user-attachments/assets/874164a3-9550-4fc3-9144-342b5888dbb7

## Tests

I don't know how to add tests for this.
2025-06-03 09:47:17 +05:30
Prateek Sunal
265bad28b0 fix: people selection logic as well 2025-06-03 09:45:02 +05:30
Prateek Sunal
9ee52b5dee fix: don't depend on FaceFilter for fetching personId 2025-06-03 09:43:06 +05:30
Prateek Sunal
1d7baf9dd6 chore: remove unwanted author copyright 2025-06-03 09:38:38 +05:30
Manav Rathi
a5f266421a Also from cast 2025-06-03 09:35:57 +05:30
Manav Rathi
dbbcd44f5b Fwd headers 2025-06-03 09:26:52 +05:30
Manav Rathi
38798e92a3 [web][desktop] Routine dep updates (#6146)
feat. MUI v7
2025-06-03 09:04:26 +05:30
Manav Rathi
fda4f47cba disabled is not a color
lint errors on ci
2025-06-03 08:52:12 +05:30
Jacques Lucke
d0ddce2803 Avoid flashing dialog when leaving newly created album 2025-06-02 20:16:12 +02:00
Manav Rathi
4bfc495f39 Fix errors on ci
[eslint] /home/runner/work/ente/ente/web/packages/new/photos/components/ImageEditorOverlay.tsx
[eslint]   1313:41  error  This assertion is unnecessary since it does not change the type of the expression  @typescript-eslint/no-unnecessary-type-assertion
[eslint]   1325:39  error  This assertion is unnecessary since it does not change the type of the expression  @typescript-eslint/no-unnecessary-type-assertion
[eslint]   1338:35  error  This assertion is unnecessary since it does not change the type of the expression  @typescript-eslint/no-unnecessary-type-assertion
[eslint]   1350:41  error  This assertion is unnecessary since it does not change the type of the expression  @typescript-eslint/no-unnecessary-type-assertion
2025-06-02 19:58:49 +05:30
Manav Rathi
7cbc80adc6 Stick to non-private imports 2025-06-02 19:49:30 +05:30
Manav Rathi
414265de4a mui update 2025-06-02 19:28:55 +05:30
Manav Rathi
a2c032e77b desktop deps 2025-06-02 19:27:11 +05:30
Manav Rathi
b567dddfc3 routine dep update 2025-06-02 19:26:47 +05:30
AmanRajSinghMourya
e9631c2eb2 Add zoom-in/out effect and background blur effect 2025-06-02 19:07:13 +05:30
Manav Rathi
dea77b5dd0 [web] Fix trash open (#6144) 2025-06-02 19:02:28 +05:30
Manav Rathi
1b8a8a2717 [web] Fix trash open 2025-06-02 18:58:34 +05:30
Neeraj Gupta
8b3b20aa93 Remove unsued type 2025-06-02 18:38:45 +05:30
Keerthana
549cd74537 [docs]: lint and refactor navigation and overview structure (#6132)
## Description
This PR introduces the following changes in the documentation:
- Restructuring of sidebar for intuitive navigation for
overview/introduction. **Note:** The content covered by the section
along with rest of the documentation is still under major revision and
the skeleton of the documentation is being provided for easier access to
end-users.
- Updation of information regarding lack of availability of Bucket CORS
for MinIO community edition that's used by compose clusters by default.
- Linting for documentation for consistency with prettier.
2025-06-02 18:21:13 +05:30
Keerthana
2d6c754c15 [docs][actions] add lint checks for PRs 2025-06-02 18:18:35 +05:30
Keerthana
5fe0e424cd [docs] refactor community and help pages in overview 2025-06-02 18:16:58 +05:30
Neeraj Gupta
408b0bfe2d Merge branch 'internal-15_06_2025' of https://github.com/ente-io/auth into internal-15_06_2025 2025-06-02 17:55:33 +05:30
Neeraj Gupta
655be76428 Bump version 2025-06-02 17:55:06 +05:30
Neeraj Gupta
9fedf8d6b7 Merge branch 'main' into internal-15_06_2025 2025-06-02 17:54:47 +05:30
Neeraj
991bfbb7ef [mob] Enable resumable upload for all (#6141)
## Description

## Tests
2025-06-02 17:48:52 +05:30
Laurens Priem
3292ab2d95 [mob][photos] Face thumbnails refactor (#6128)
## Description

- Refactored PersonFaceWidget into separate FileFaceWidget and
PersonFaceWidget. PersonFaceWidget now only requires a person or cluster
ID, no longer is any file needed
- Face thumbnail choice is now made based on highest face score instead
of recency, meaning less changes in face thumbnails and less re-computes
- More aggressive caching of face thumbnails in memory
- Added option to change person cover from top menu
- Fixed issue with decoding HEIC for face thumbnails on Android

## Tests

Tested in debug mode on my pixel 8.
2025-06-02 16:58:18 +05:30
Neeraj Gupta
8eddf3ff4e Upload videos along with photos 2025-06-02 16:21:15 +05:30
Neeraj Gupta
2dca25778b Enable multipart upload for everyone 2025-06-02 16:18:14 +05:30
Manav Rathi
2316f6323e [web] New translations (#6135)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-06-02 16:05:46 +05:30
Neeraj
d15c11cc26 [server] Defer file data replication for 10min (#6139)
## Description

## Tests
2025-06-02 16:04:48 +05:30
Manav Rathi
f32c712c72 [meta] fr => enhancements (#6137) 2025-06-02 16:04:26 +05:30
Vishnu Mohandas
9060eaa0e5 [server] Update first-upload copy (#6138) 2025-06-02 16:01:02 +05:30
vishnukvmd
3a9d507c35 Update copy 2025-06-02 15:59:33 +05:30
Ashil
ed0c1a1ebc [mob][photos] Fix missing 'Added by' indicator in gallery file element and file info for when opening public links via deeplink (#6136)
## Description

User avatar in gallery file element and 'added by' field in file info
were missing for files in public links opened via deeplink. This PR
fixes this issue.
2025-06-02 15:58:30 +05:30
Manav Rathi
6e1b959a61 [meta] fr => enhancements 2025-06-02 15:57:41 +05:30
ashilkn
95a9baa4e2 Show avatar in gallery file element and 'added by' in file info for public links opened via deeplink 2025-06-02 15:53:05 +05:30
ashilkn
0ccc333dad chore 2025-06-02 15:52:25 +05:30
Crowdin Bot
a5224628b7 New Crowdin translations by GitHub Action 2025-06-02 10:11:04 +00:00
Manav Rathi
4d4d961628 [desktop] Post release toggles (#6134) 2025-06-02 15:40:13 +05:30
Manav Rathi
e22f74d653 bg ml and export 2025-06-02 15:33:31 +05:30
Neeraj Gupta
b4fdf441ec Defer filedata replication for 10min 2025-06-02 15:30:31 +05:30
Vishnu Mohandas
e798ac02c6 [server] Check in with paid customers (#6106)
## Description
Update the `subscriptions` table to store the time at which
subscriptions were upgraded (`upgraded_at`).

Reach out to customers who upgraded 7 days ago to make sure all is well.
<img width="628" alt="Screenshot 2025-05-31 at 1 41 09 PM"
src="https://github.com/user-attachments/assets/7d1e970a-c7fa-4666-8d4f-db13ba7c105d"
/>

Store this information within `notification_history` so they are not
contacted again (in case of admin interventions).

> Note: We will not be back-filling data for existing subscriptions.

## Tests
- [x] Tested locally to make sure only customers who upgraded 7 days ago
were pinged.
2025-06-02 15:25:23 +05:30
Manav Rathi
6c41f575c3 fav cast 2025-06-02 15:22:23 +05:30
Manav Rathi
15e211b3a5 typo 2025-06-02 15:18:33 +05:30
Manav Rathi
9ce3fe7756 post rel 2025-06-02 15:18:17 +05:30
Manav Rathi
215bb43f39 [web] FS limit test (#6133) 2025-06-02 15:17:47 +05:30
Manav Rathi
793ee58e2b fs limit test 2025-06-02 15:14:39 +05:30
ashilkn
7c4e775872 Bump build number 2025-06-02 14:56:04 +05:30
Manav Rathi
a6ae092839 [desktop] Make video upload retries idempotent (#6131) 2025-06-02 14:33:33 +05:30
Keerthana
088afe7f2a [fix]: dead links in overview 2025-06-02 14:32:53 +05:30
Manav Rathi
d212d55dca Make retries idempotent 2025-06-02 14:12:37 +05:30
Manav Rathi
bc88a378b0 Note 2025-06-02 14:00:07 +05:30
Keerthana
b0bb5fc916 [docs]: lint and refactor navigation and structure for overview 2025-06-02 13:58:49 +05:30
Neeraj
b3b3f8445a [auth] New translations (#6126) 2025-06-02 12:28:10 +05:30
laurenspriem
9d87b8f303 Rename to clarify Android 2025-06-02 11:43:21 +05:30
Alexander
15e7d9658c [auth] Add new custom icons in auth (#6114)
New icons added:

- CSSBuy
- uollet
2025-06-02 11:38:33 +05:30
Neeraj
fb262c7dc4 [auth] fix: rename GIRAD icon to GERID (#6107)
Made a typo in the previous PR 😅. This PR changes it to the correct name
(GIRAD -> GERID)
2025-06-02 11:37:58 +05:30
Laurens Priem
3080859593 timeout on this day notification android at eod (#6130)
## Description

Auto dismiss 'On this day' notification at the end of the day. Only on
Android since there's no API for this on iOS.

## Tests

Tested in debug mode on my pixel 8 phone.
2025-06-02 11:25:31 +05:30
laurenspriem
9ea70c70d5 timeout on this day notification android at eod 2025-06-02 11:21:01 +05:30
Manav Rathi
a6291f34f9 [web] New translations (#6124)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-06-02 10:25:04 +05:30
Crowdin Bot
40a8449ea5 New Crowdin translations by GitHub Action 2025-06-02 01:17:53 +00:00
Crowdin Bot
765b0982ed New Crowdin translations by GitHub Action 2025-06-02 01:05:16 +00:00
Crowdin Bot
199f4acccc New Crowdin translations by GitHub Action 2025-06-02 00:41:26 +00:00
laurenspriem
026f9a2bb8 Fix heic decoding issue for face thumbnails 2025-06-01 17:58:55 +05:30
AmanRajSinghMourya
27932679dd Add onFileLoad callback to file_widget for better loading of progress animation 2025-05-31 18:58:48 +05:30
Sven
571995bbd9 fix: rename GIRAD icon to GERID 2025-05-31 12:44:54 +02:00
vishnukvmd
a15084374b Setup cron 2025-05-31 13:45:55 +05:30
vishnukvmd
c0ceb68dc6 Say hello to paid customers 2025-05-31 13:45:51 +05:30
vishnukvmd
0b87152057 Hello email 2025-05-31 13:45:27 +05:30
vishnukvmd
feb6a82755 Mark upgrades 2025-05-31 13:44:55 +05:30
vishnukvmd
85c418c9f6 Update query 2025-05-31 13:44:32 +05:30
vishnukvmd
cc68189004 Update model 2025-05-31 13:44:25 +05:30
vishnukvmd
21c1328428 Add column to store upgraded-at timestamps 2025-05-31 13:42:13 +05:30
vishnukvmd
1375b4df12 Fix typo 2025-05-31 13:06:52 +05:30
Neeraj
7f0eeece9c [auth] Bump auth version 4.4.0 (#6103)
## Description

## Tests
2025-05-31 10:14:13 +05:30
Neeraj Gupta
7fb30ed477 Add release 4.4.0 to appdata.xml 2025-05-31 10:13:23 +05:30
Neeraj Gupta
91ea5763fb Bump auth version: 4.4.0 2025-05-31 10:13:07 +05:30
Neeraj
f29f9f2a94 [auth] Sign windows binary using trust store (#6102)
## Description

## Tests
2025-05-31 10:12:23 +05:30
Neeraj Gupta
5138898d73 Sign auth windows binary using trust store 2025-05-31 10:11:13 +05:30
Neeraj Gupta
171be22113 Fix typo 2025-05-31 10:08:51 +05:30
Neeraj
6a3575feb4 [auth] Add GIRAD icon (#6100)
Add GIRAD custom icon, as requested here:
https://github.com/ente-io/ente/issues/6075
2025-05-31 09:53:35 +05:30
Neeraj Gupta
4e80c82a6f Revert "Avoid building for testing sign"
This reverts commit 0c0acd9592.
2025-05-31 09:36:56 +05:30
Neeraj Gupta
0c0acd9592 Avoid building for testing sign 2025-05-31 09:34:03 +05:30
Neeraj Gupta
26384513f2 Mention absolute path 2025-05-31 08:45:53 +05:30
Neeraj
acd05e0a55 [meta] Workflow to test windows sign (#6101)
## Description

## Tests
2025-05-31 08:12:55 +05:30
Neeraj Gupta
91a48943b7 Rename worflow 2025-05-31 08:10:58 +05:30
Neeraj Gupta
a8111eab04 Add workflow for testing trust signing 2025-05-31 08:09:37 +05:30
Sven
0084a3cf59 Add GIRAD icon and entry to custom icons list 2025-05-30 19:10:18 +02:00
Manav Rathi
82e1fd3b0a [web] Convert more uses of older single input form (#6099)
Only a handful left to go.
2025-05-30 18:36:51 +05:30
Manav Rathi
d57c68188c Update for new API methods 2025-05-30 18:32:46 +05:30
Manav Rathi
65a7a49d07 Swap 2025-05-30 18:25:52 +05:30
Manav Rathi
631c46681d Nicer animation 2025-05-30 18:12:50 +05:30
Manav Rathi
023d8ab8b3 Format 2025-05-30 18:07:50 +05:30
Manav Rathi
a1e3cdd5d2 Remove inconsistent trim in one direction
- No other password inputs are trimmed
- The code was trimming here, but not when verifying it
2025-05-30 18:00:13 +05:30
laurenspriem
2df9041e34 Set cover sheet in people app bar 2025-05-30 17:55:11 +05:30
Manav Rathi
b1051bbd47 Swap 2025-05-30 17:51:45 +05:30
laurenspriem
f869483c68 Change icon and reorder 2025-05-30 17:41:40 +05:30
Manav Rathi
8682e3338b Rename 2025-05-30 17:40:51 +05:30
Manav Rathi
ee96b44b74 Use 2025-05-30 17:38:14 +05:30
Manav Rathi
e992db4846 augment 2025-05-30 17:30:30 +05:30
laurenspriem
0d95f8c5a2 Remove redundant 2025-05-30 17:09:10 +05:30
laurenspriem
4b9f6619b5 Rename 2025-05-30 17:02:59 +05:30
laurenspriem
9e30d08fae Don't remove faceAvatar 2025-05-30 17:01:45 +05:30
laurenspriem
2c50b84e30 Better update in memory cache 2025-05-30 16:55:48 +05:30
Neeraj
686d04339d [auth] Fix: handle incorrect device time during code generation (#6096)
## Description

## Tests
2025-05-30 16:50:56 +05:30
Neeraj Gupta
5d0a86c248 Fix progress bar when local time is incorrect 2025-05-31 16:23:06 +05:30
Manav Rathi
2a375e56c3 [web] Update uses of deprecated collection namer (#6098) 2025-05-30 16:43:02 +05:30
laurenspriem
ba468d32f5 Refactor remove redundant method 2025-05-30 16:40:02 +05:30
Manav Rathi
ce3b6b1c1f Remove unnecessary dep 2025-05-30 16:38:26 +05:30
Manav Rathi
52451cd0af Update 2025-05-30 16:35:19 +05:30
Manav Rathi
03a25c2625 Unused 2025-05-30 16:33:51 +05:30
Manav Rathi
f425dc6eaf Use 2025-05-30 16:33:51 +05:30
Manav Rathi
26d111da42 Tweak 2025-05-30 16:33:51 +05:30
Manav Rathi
7b100e8dae Use 2025-05-30 16:33:51 +05:30
Manav Rathi
b5d059c61b Use 2025-05-30 16:33:51 +05:30
Manav Rathi
70c3c1d541 [web] New translations (#6097)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-05-30 16:33:11 +05:30
Crowdin Bot
01b05d243d New Crowdin translations by GitHub Action 2025-05-30 10:59:57 +00:00
Neeraj Gupta
b560e5b71a Fix: handle incorrect device time during code generation 2025-05-30 16:24:43 +05:30
laurenspriem
3354416543 Query typo 2025-05-30 16:15:03 +05:30
AmanRajSinghMourya
09199180f3 Add isFromMemories parameter to handle gestures 2025-05-30 16:01:27 +05:30
AmanRajSinghMourya
d9f36f1949 Added with progress animation for FullScreenMemory 2025-05-30 16:00:33 +05:30
laurenspriem
cfeca1f564 Integrate new PersonFaceWidget everywhere 2025-05-30 15:52:06 +05:30
Neeraj Gupta
ecfa640c28 Bump version 2025-05-30 15:44:46 +05:30
Neeraj Gupta
1997eb20f3 Merge branch 'main' into internal-15_06_2025 2025-05-30 15:44:30 +05:30
AmanRajSinghMourya
e9b95cce62 Minor changes 2025-05-30 15:41:39 +05:30
Manav Rathi
625b562229 [web] [auth] Automatic handling of browsers with incorrect time (#6093) 2025-05-30 15:16:24 +05:30
Manav Rathi
c8d31b3a7e Mention version 2025-05-30 15:12:48 +05:30
laurenspriem
3f212aa1d1 Refactor face thumbnail caching logic 2025-05-30 14:43:59 +05:30
Neeraj
026669b0d0 [Server] Return epochTime in microSeconds (#6094)
## Description

## Tests
2025-05-30 14:21:55 +05:30
Neeraj Gupta
741aed7565 return utc epochTime in auth diff 2025-05-30 14:19:33 +05:30
Neeraj
6ee58b8e0f [mob] Video stream generation refactor (#6085)
## Description

- Avoid checking stream generation for file is duration or size
information is not available. Size information is almost always present,
and duration was missing for files uploaded via Desktop/Web until
recently. As anyways we are processing local only files, it made sense
to simplify the check and completely avoid processing such files.

**Previously, for such files where duration was missing, if my
understanding is correct, we were always downloading it to getProps
info, even for files larger than 500 MB.**

- Pause video streaming generation if ML is running
- Added delay before queuing files for video streaming immediately after
diff sync.
## Tests
2025-05-30 13:48:08 +05:30
Neeraj Gupta
61df740c01 Limit preview cache for preview with size < 50MB 2025-05-30 13:30:43 +05:30
Neeraj Gupta
3b3b41d55f Remove unused imports 2025-05-30 13:26:55 +05:30
Neeraj
0633582c7e [mob][photos] Update contacts section on PeopleChangedEvent (#6088) 2025-05-30 12:52:17 +05:30
Manav Rathi
1acd1f81f4 Use 2025-05-30 12:49:17 +05:30
Manav Rathi
2b35677227 faq 2025-05-30 12:34:33 +05:30
Manav Rathi
2b390b60c4 Handle browsers with incorrect time 2025-05-30 12:27:17 +05:30
Manav Rathi
a33af20944 [web] MUI - Don't override non-elevated backgrounds (#6092) 2025-05-30 11:10:56 +05:30
Manav Rathi
e8643c662e Alert 2025-05-30 11:04:57 +05:30
Ashil
aea57dd212 [mob][photos] Add uncategorized album in album vertical sheet (#6086)
## Description

- Show Uncategorized album on collection actions (except for collection
actions over hidden items)
- Show Uncategorized album on top

Closes #5833 


![simulator_screenshot_07BA6109-B6FA-45BF-9E75-43205697D0A7](https://github.com/user-attachments/assets/c0dc834b-c676-4cde-9006-1c77216141d0)
2025-05-30 11:04:32 +05:30
Manav Rathi
fe33469a79 Don't override non-elevated backgrounds
In particular, don't apply our shadow to variant "outlined"
2025-05-30 10:46:22 +05:30
Manav Rathi
d660f71f56 Update 2025-05-30 07:49:57 +05:30
Manav Rathi
61eb7c0e99 Swap 2025-05-30 07:49:57 +05:30
ashilkn
e438e35ccd Update contacts section on PeopleChangedEvent 2025-05-29 18:29:08 +05:30
Manav Rathi
d01348414c [desktop] Next release train (#6087) 2025-05-29 16:52:49 +05:30
Manav Rathi
2faa616cab [desktop] Next release train 2025-05-29 16:49:33 +05:30
ashilkn
78bad4e5a5 Show uncategorized album option for all CollectionActionTypes other than for hidden collection actions 2025-05-29 16:42:57 +05:30
ashilkn
466bb40a30 Show uncategorized album as the first option in collection action sheet 2025-05-29 16:34:00 +05:30
Neeraj Gupta
e55dcff9a5 Add delay before queuing files for streaming 2025-05-29 16:22:39 +05:30
Neeraj Gupta
8904916770 Pause streaming if ML is running 2025-05-29 16:22:26 +05:30
Neeraj Gupta
7a7a50901f Rename 2025-05-29 16:17:44 +05:30
Neeraj Gupta
09ff43a1ef Simplify check for checking preview req 2025-05-29 16:07:53 +05:30
Neeraj Gupta
7cf4c7bf74 Avoid duplicate preview creation check 2025-05-29 15:35:40 +05:30
ashilkn
a3341202a7 Remove unused CollectionActionType 2025-05-29 15:33:07 +05:30
Neeraj Gupta
c87b2b7542 Only process files with known duration & size 2025-05-29 15:32:00 +05:30
Neeraj Gupta
594c18db79 Use service locator 2025-05-29 14:56:33 +05:30
Neeraj Gupta
fa0c70d633 Avoid mixing upload with preview generation to save cpu 2025-05-29 09:32:15 +05:30
Neeraj Gupta
909695ffaa Mark previewIDs as not nullable 2025-05-29 09:28:51 +05:30
Neeraj Gupta
b679d0213f Use hashMap to dedupe for uploadID 2025-05-29 09:19:19 +05:30
Neeraj Gupta
995342bbdb Clean up unused event 2025-05-29 09:05:45 +05:30
AmanRajSinghMourya
3ea09df4c0 Add NewProgressIndicator widget for step progress animation for memories 2025-05-28 19:12:37 +05:30
laurenspriem
ebfc1103fe Rename to fileFaceWidget 2025-05-28 17:02:31 +05:30
laurenspriem
db07fb35d2 face widget cropping functionality 2025-05-28 17:01:08 +05:30
laurenspriem
7519ed5e15 Use new face widget in file info 2025-05-28 15:51:31 +05:30
laurenspriem
97a174ff75 Merge branch 'main' into face_thumbnails 2025-05-28 14:42:00 +05:30
laurenspriem
903366a42c Refactor to simplify 2025-05-28 11:22:21 +05:30
ashilkn
87fae3e6d9 Resolve merge conflicts and merge main 2025-05-27 19:16:31 +05:30
ashilkn
0a5005d064 Add scrollbar for album widget settings screen 2025-05-27 19:06:16 +05:30
ashilkn
b54fe20520 chore 2025-05-27 18:46:18 +05:30
ashilkn
204a046e0a Merge branch 'main' into widget-superpowered 2025-05-27 18:44:52 +05:30
laurenspriem
015321fa0d Rename widget 2025-05-27 17:51:15 +05:30
Ashil
051ce42ae6 [mob][photos] Home widget improvements (#6059)
## Description

See commits
2025-05-27 17:32:17 +05:30
laurenspriem
3e1a01c1f3 Move person_face_widget 2025-05-27 17:26:14 +05:30
laurenspriem
351cf50f73 Rename for clarity 2025-05-27 17:19:09 +05:30
ashilkn
4d26de8ffd Add safety check 2025-05-27 17:05:46 +05:30
ashilkn
b44ef9f68a Prevent infinite loops 2025-05-27 16:45:37 +05:30
ashilkn
6c3b2ee25e Randomize memories and files shown in memories widget 2025-05-27 15:58:04 +05:30
ashilkn
5fa951ad4b Refactor people widget settings screen 2025-05-27 14:51:23 +05:30
ashilkn
e9ceb705f6 Sort album widget settings screen's albums, showing selected ones on top. Note that sorting doesn't happen when selection is modified on the screen and only once when it's built 2025-05-27 14:38:08 +05:30
laurenspriem
726425bbb6 Put vector db behind feature flag internal 2025-05-27 14:07:34 +05:30
ashilkn
9dcd9d63b2 Avoid using shrinkWrap 2025-05-27 13:43:49 +05:30
ashilkn
129e9f8f49 Avoid adding empty albums in _getAlbumsWithFiles() 2025-05-27 12:32:39 +05:30
ashilkn
6f02df19c6 Improve UI of widget's empty state 2025-05-27 12:31:59 +05:30
ashilkn
c8efc1a590 Randomize albums and files shown in album widget 2025-05-27 12:02:07 +05:30
ashilkn
8b1a659d68 Avoid sorting on selecting albums in album widget settings 2025-05-27 11:47:39 +05:30
Ashil
fe86d3bb34 [mob][photos] Make widget settings pages less confusing on their empty states (#6046) 2025-05-26 19:37:53 +05:30
ashilkn
53a22a8d58 chore 2025-05-26 19:32:21 +05:30
ashilkn
a5b178d283 Extract strings 2025-05-26 19:30:54 +05:30
ashilkn
9069975bf0 Avoid confusion on empty widget settings pages 2025-05-26 19:22:51 +05:30
Ashil
08b7986d70 [mob][photos] Randomize people and file shown in people widget (#6044) 2025-05-26 18:06:17 +05:30
ashilkn
0e2a0388ff Randomize people and thier files shown in people widget 2025-05-26 17:56:48 +05:30
laurenspriem
eb783f0fff Remove redundant method 2025-05-26 16:44:06 +05:30
laurenspriem
ca8f310868 Fix duplicate notification issue 2025-05-26 16:43:15 +05:30
laurenspriem
4249491730 More logging 2025-05-26 16:16:53 +05:30
laurenspriem
a958380a1d More logging 2025-05-26 15:56:23 +05:30
laurenspriem
b00c406b09 Extract string 2025-05-26 15:52:45 +05:30
laurenspriem
ff9494d438 Setting to disable memories notifications 2025-05-26 15:51:59 +05:30
Ashil
be9fddf1d4 [mob][photos] Avoid reordering selected faces (#6037) 2025-05-26 14:43:15 +05:30
ashilkn
f9b3f6e9eb Avoid reordering selected faces 2025-05-26 14:39:16 +05:30
laurenspriem
dcb73abdec Log time of scheduled notificaiton 2025-05-26 14:33:39 +05:30
ashilkn
a14c6f4d26 Merge branch 'main' into widget-superpowered 2025-05-26 14:24:35 +05:30
laurenspriem
bdd09e12d8 More logs 2025-05-26 10:27:46 +05:30
laurenspriem
407ad41520 Test clearing with payload 2025-05-26 10:09:52 +05:30
Ashil
d8b54f5211 [mob][photos] Add files to multiple collections at once (#6019) 2025-05-23 20:37:17 +05:30
Ashil
bc059c861f Merge branch 'widget-superpowered' into collection_sheet_batch_operation 2025-05-23 20:34:06 +05:30
ashilkn
b52ee5bbfb bump up build number to 1052 2025-05-23 20:33:11 +05:30
ashilkn
93c85a57e4 Do remote sync irrespective of error when adding files to multiple collections 2025-05-23 20:23:08 +05:30
ashilkn
e01826217d Refactor 2025-05-23 20:11:44 +05:30
Aman Raj Singh Mourya
b79b7ff3ef Refactor addToMultipleCollections to improve error handling 2025-05-23 19:40:49 +05:30
Aman Raj Singh Mourya
f44c2d14c7 Enable drag functionality in pick cover photo, person avatar, and center point widget. 2025-05-23 15:31:56 +05:30
Aman Raj Singh Mourya
2903388c94 Refactor CollectionActionSheet and improve UX 2025-05-23 14:48:36 +05:30
Aman Raj Singh Mourya
256243e273 Enable drag functionality in collection action sheet 2025-05-23 12:30:27 +05:30
Aman Raj Singh Mourya
dc9dc5d8f9 Single tap selection to select albums 2025-05-23 12:28:24 +05:30
laurenspriem
18e7bbd1ed Extract strings for i18n for existing notifications 2025-05-23 10:41:27 +05:30
laurenspriem
63850df06a Change copy and extract string 2025-05-23 10:33:58 +05:30
Prateek Sunal
634561347f chore: bump version 2025-05-22 23:52:05 +05:30
Prateek Sunal
575abdb8eb Merge remote-tracking branch 'origin/widget-superpowered' into widget-superpowered 2025-05-22 23:50:22 +05:30
Prateek Sunal
e998502b53 fix: add a status key to check if partial sync was did but a full is required now
(like previously widget was not their so it was fine to sync only 5 images but now since widget is there a full sync is compulsory)
2025-05-22 23:50:07 +05:30
laurenspriem
2ada68e837 Merge remote-tracking branch 'origin/widget-superpowered' into widget-superpowered 2025-05-22 22:41:04 +05:30
laurenspriem
28822a8dc1 Swallow notification scheduling issues 2025-05-22 22:38:24 +05:30
laurenspriem
deaa9a703d Bump for internal release 2025-05-22 22:26:02 +05:30
laurenspriem
4510edf8bd Update notification dependency 2025-05-22 22:24:59 +05:30
laurenspriem
7af59a1ecf Schedule test notifications 2025-05-22 22:24:40 +05:30
Prateek Sunal
d528d97a0f fix: add got all widget logic 2025-05-22 21:00:48 +05:30
Prateek Sunal
682e4a913f fix: ui stuff 2025-05-22 20:52:13 +05:30
Prateek Sunal
ab1a8aa592 fix: don't repeat 2025-05-22 20:21:48 +05:30
Prateek Sunal
c37a0339d2 fix: default state ui 2025-05-22 20:18:41 +05:30
Prateek Sunal
1bda14fb6f fix: redirect with correct context 2025-05-22 19:57:08 +05:30
Prateek Sunal
b2855cfd72 fix: rank selected first 2025-05-22 19:20:16 +05:30
Prateek Sunal
06d260f40a fix: only allow selection 2025-05-22 19:04:21 +05:30
laurenspriem
5a574c69d3 log debug notification options 2025-05-22 16:48:01 +05:30
Neeraj Gupta
cbef1a9145 ios build changes 2025-05-22 15:53:59 +05:30
Aman Raj Singh Mourya
822c33940e Skip single tap action when selection mode is enabled 2025-05-22 15:53:06 +05:30
Aman Raj Singh Mourya
c77b4f176c Refactor AlbumColumnItemWidget to improve selection handling and UI layout 2025-05-22 15:49:49 +05:30
Aman Raj Singh Mourya
afcc7b1e46 Add selection functionality and action buttons to collection action sheet 2025-05-22 15:26:49 +05:30
Aman Raj Singh Mourya
4bbc0d1f46 Implement addToMultipleCollections method for batch adding files to collections 2025-05-22 15:26:07 +05:30
laurenspriem
aa6d6f4e77 Bump for internal release 2025-05-22 15:04:50 +05:30
laurenspriem
ec1b54cbb1 Merge branch 'main' into widget-superpowered 2025-05-22 14:46:00 +05:30
laurenspriem
c068f26604 Aggressive logging of vectorDB migration 2025-05-22 11:32:36 +05:30
laurenspriem
e60c2b1192 GC hints 2025-05-22 11:19:19 +05:30
laurenspriem
beb049f817 Reduce batch size in migration 2025-05-22 10:38:43 +05:30
Prateek Sunal
c996c794fd fix: launch people page before launching the file previewer 2025-05-21 08:47:03 +05:30
Prateek Sunal
87195f3801 chore: fix incorrect widget count 2025-05-21 04:15:57 +05:30
Prateek Sunal
8ce45a4fa8 chore: bump version 2025-05-21 04:06:02 +05:30
Prateek Sunal
520e5d4ae7 fix: update routing 2025-05-21 04:01:37 +05:30
Prateek Sunal
2a8e167e42 fix: don't listen to collection route 2025-05-21 03:51:20 +05:30
Prateek Sunal
2f7bde36bd chore: bump version to 1.0.17 2025-05-21 03:27:49 +05:30
Prateek Sunal
ace375b7f6 fix: get effective selected people code 2025-05-21 03:27:38 +05:30
Prateek Sunal
cde6ebfa39 fix: pass and parse mainKey correctly 2025-05-21 03:12:19 +05:30
Prateek Sunal
a1e56a457f fix: update people default illustration 2025-05-21 03:04:21 +05:30
Prateek Sunal
a4ebf972e1 fix: count home widget for android 2025-05-21 02:56:32 +05:30
Prateek Sunal
7d5bed0493 fix: iOS build 2025-05-21 02:20:43 +05:30
Prateek Sunal
d449bd0f90 chore: update version 2025-05-21 02:16:48 +05:30
Prateek Sunal
5d14ca8439 fix: handle PeopleChangedEvent, add better limit for files, better behavior on save 2025-05-21 02:15:23 +05:30
Prateek Sunal
619f6795e2 fix: don't show un-named person 2025-05-21 01:44:12 +05:30
Prateek Sunal
04cd1d3bb3 fix: update code to look clean 2025-05-21 01:28:14 +05:30
Prateek Sunal
0960f189ce Merge remote-tracking branch 'origin/main' into widget-superpowered 2025-05-21 01:11:56 +05:30
Prateek Sunal
734b836a7a chore: update locals 2025-05-21 01:11:48 +05:30
Prateek Sunal
91447cdc77 fix: widgets code 2025-05-21 01:11:40 +05:30
Prateek Sunal
574eea58fc fix: add robust logic for album home widget service 2025-05-20 07:06:57 +05:30
Prateek Sunal
138310b8f8 fix: update get collection by id function 2025-05-19 19:54:24 +05:30
Prateek Sunal
3d63ded84d fix: blockers, getter function for albums hw service 2025-05-19 19:54:09 +05:30
Prateek Sunal
2ff69f661e Merge branch 'main' into widget-superpowered 2025-05-19 19:20:26 +05:30
Prateek Sunal
10c65f13c8 fix: update get total function for memory home widget 2025-05-19 19:19:30 +05:30
Prateek Sunal
761c976d7e Merge remote-tracking branch 'origin/on_this_day' into widget-superpowered 2025-05-19 19:13:47 +05:30
Prateek Sunal
423a7eec37 fix: show on this day to both ml & non-ml users 2025-05-19 19:10:29 +05:30
Prateek Sunal
c8b23f80e2 feat: add selection and save/get from db for people widget settings 2025-05-19 18:53:41 +05:30
Prateek Sunal
d127199ade feat: complete save and selection logic for memories and albums settings 2025-05-19 17:35:33 +05:30
Prateek Sunal
22bae0292d feat: add new widget services 2025-05-19 14:04:42 +05:30
Prateek Sunal
4c7121fd6c chore: update generated messages 2025-05-19 14:04:19 +05:30
Prateek Sunal
f53745bbb0 Merge remote-tracking branch 'origin/album_UI_revamp' into widget-superpowered 2025-05-19 14:00:13 +05:30
Prateek Sunal
bffd4d83a5 fix: update the deep link 2025-05-16 18:41:21 +05:30
Prateek Sunal
a518bbd608 fix(home-widget): update default image caption & rename totalMemories 2025-05-16 15:07:45 +05:30
Prateek Sunal
9b1eacf736 fix: update the preview images 2025-05-16 14:37:33 +05:30
Prateek Sunal
538a5df32d feat: add preview images for both android & iOS 2025-05-16 14:30:13 +05:30
Prateek Sunal
491de296ca feat: similar UI's for all the widgets 2025-05-15 18:18:42 +05:30
Prateek Sunal
9fa13508b8 feat: add iOS widgets 2025-05-15 16:26:16 +05:30
Prateek Sunal
f22ad9611f feat: populate people as well 2025-05-14 15:14:11 +05:30
Prateek Sunal
9cafa72ae3 fix: add color scheme based icon 2025-05-14 14:01:25 +05:30
Prateek Sunal
0c9d7321eb fix: nominal display limit count & disable show create album 2025-05-14 13:52:13 +05:30
Prateek Sunal
5fc5d0ef48 feat: add initial album grid and save button 2025-05-14 13:48:08 +05:30
Prateek Sunal
84017c7397 Merge remote-tracking branch 'origin/memories_widget_api' into widget-superpowered 2025-05-14 12:13:06 +05:30
Prateek Sunal
e250759999 Merge remote-tracking branch 'origin/album_grid_UI' into widget-superpowered 2025-05-14 11:21:50 +05:30
Aman Raj Singh Mourya
51d55ee92b feat: Add new album row item widget and update collections grid view 2025-05-12 22:06:19 +05:30
Prateek Sunal
91fefa7eb9 feat: memories leading icons 2025-05-12 19:12:46 +05:30
Prateek Sunal
63b9a09a2d feat: init widgets settings and default states
Next: Add Grid, make things dynamic, Add sync logic and native code
2025-05-12 19:07:58 +05:30
laurenspriem
7021c9fe02 Bump for internal release 2025-05-12 17:05:31 +05:30
laurenspriem
c2d5dece9e Merge branch 'main' into usearch_again 2025-05-12 17:04:42 +05:30
laurenspriem
b76d41b84d Specify rust version in readme 2025-05-12 15:48:27 +05:30
laurenspriem
3b9c76649d Update readme to include rust 2025-05-12 15:12:31 +05:30
laurenspriem
62ed8b6975 Log vector db stats when opening connection 2025-05-12 14:46:55 +05:30
laurenspriem
2422dba4d4 vector db more stats logging 2025-05-12 14:23:16 +05:30
laurenspriem
eb1916e3a3 integrate vector db in magic search 2025-05-12 11:39:02 +05:30
laurenspriem
df0d9137a6 Integration clip embeddings in vector db 2025-05-11 13:09:56 +05:30
laurenspriem
fc36b87965 Clip migration method 2025-05-11 13:09:20 +05:30
laurenspriem
63d90ea275 Class for vector db stats 2025-05-09 16:36:39 +05:30
laurenspriem
bb7f8a5eef More testing 2025-05-09 15:59:46 +05:30
laurenspriem
2f5a02ec43 delete table option 2025-05-09 12:57:44 +05:30
laurenspriem
d411d91966 vector db api ensure capacity safety 2025-05-09 12:56:59 +05:30
laurenspriem
54b712953a vector db api let clear include capacity reset 2025-05-09 10:49:03 +05:30
laurenspriem
27ad020adc Testing clip migration to vector DB 2025-05-08 17:40:01 +05:30
laurenspriem
ce112bd4d7 Index stats method 2025-05-08 15:23:23 +05:30
laurenspriem
2ffb73d053 Consistent method parameters 2025-05-08 15:07:50 +05:30
laurenspriem
6478d438b5 vector db api ensure never duplicate keys 2025-05-08 14:30:51 +05:30
laurenspriem
d87069eb4c vectordb api add documentation 2025-05-08 12:31:09 +05:30
laurenspriem
5447350ab1 vector db api add check for key 2025-05-08 12:29:41 +05:30
laurenspriem
ea1a2960bf First implementation of clip vector db 2025-05-08 12:08:55 +05:30
laurenspriem
832f2c451e Add bulk get method to vector db api 2025-05-08 11:47:50 +05:30
laurenspriem
715c7c23a7 Add bulk remove embeddings api 2025-05-08 10:29:25 +05:30
laurenspriem
e9c2e40a43 Update to latest usearch 2025-05-07 13:25:40 +05:30
laurenspriem
603c275c09 Update basic usearch test 2025-05-07 12:01:45 +05:30
laurenspriem
7b9d6df2fd Fix ios build issue 2025-05-07 11:32:53 +05:30
laurenspriem
a4afecef3d Fix ios config 2025-05-07 10:50:39 +05:30
laurenspriem
4d9bfb89ae macos config 2025-05-07 10:36:17 +05:30
laurenspriem
f2a74bd35e Merge branch 'main' into usearch_again 2025-05-06 15:34:59 +05:30
laurenspriem
8c65a21b86 don't generate for web 2025-04-10 13:03:52 +05:30
laurenspriem
a07e8477fb format 2025-04-09 15:34:06 +05:30
laurenspriem
8b489e9ced Give distances in bulk search 2025-04-09 15:31:03 +05:30
laurenspriem
77e2bb1d46 Stop our own vector comparisons in benchmark 2025-04-09 15:21:20 +05:30
laurenspriem
4ce24e080a logging of benchmarking 2025-04-09 14:22:39 +05:30
laurenspriem
4e5ca3dca6 Benchmark face embeddings 2025-04-09 13:43:39 +05:30
laurenspriem
2ed155ab47 ignore trailing commas in generated code 2025-04-09 13:14:26 +05:30
laurenspriem
65e71e3caf Reintroduce reset_index method 2025-04-09 10:49:50 +05:30
laurenspriem
ee5efbcfcc Don't consume index if not needed 2025-04-09 10:43:07 +05:30
laurenspriem
6cf4530f7d Remove reset index 2025-04-09 10:06:46 +05:30
laurenspriem
e6ee09ca30 Back to basic error handling 2025-04-08 17:03:41 +05:30
laurenspriem
6d2f53b86c Update usearch 2025-04-08 14:56:47 +05:30
laurenspriem
6500748c5a Make vector db stateful in rust 2025-04-08 14:48:30 +05:30
laurenspriem
120dbeb4fc Fix null pointer crash 2025-04-05 16:56:14 +05:30
laurenspriem
c42807487b Upgrade Android NDK to r28 latest stable 2025-04-05 16:11:03 +05:30
laurenspriem
e707e24da9 first integration of usearch 2025-04-05 16:10:39 +05:30
laurenspriem
af817ec439 Test rust 2025-04-04 11:49:54 +05:30
laurenspriem
ddb44d8fd7 Integrate flutter_rust_bridge 2025-03-31 15:56:03 +05:30
laurenspriem
778822b12d Upgrade sdk 2025-03-31 15:47:51 +05:30
laurenspriem
9599ec3236 dart format 2025-03-31 15:34:48 +05:30
670 changed files with 23730 additions and 6129 deletions

View File

@@ -1,24 +1,21 @@
name: Report a bug
description: Let us know if something's not working the way you expected.
description: For regressions only (things that were working earlier)
labels: []
body:
- type: markdown
attributes:
value: |
Before opening a new bug report, please ensure
1. you are on the latest version (it might've already been fixed),
2. you've searched for existing issues (please add your observations as a comment there instead of creating a duplicate).
If you are self hosting, please create a community [Q&A](https://github.com/ente-io/ente/discussions/categories/q-a) instead.
Before opening a new issue, **please** ensure
1. You are on the latest version,
2. You've searched for existing issues,
3. It was working earlier (otherwise use [this](https://github.com/ente-io/ente/discussions/categories/enhancements))
4. It is not about self hosting (otherwise use [this](https://github.com/ente-io/ente/discussions/categories/q-a))
- type: textarea
attributes:
label: Description
description: >
Please describe the bug. If possible, also include the steps to
reproduce the behaviour, and the expected behaviour (sometimes
bugs are just expectation mismatches, in which case this would be
a good fit for [feature
requests](https://github.com/ente-io/ente/discussions/categories/feature-requests)).
Describe the bug and steps to reproduce the behaviour, and how it
differs from the previously working behaviour.
validations:
required: true
- type: input
@@ -30,15 +27,12 @@ body:
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).
The version where things were 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 working version, then please file
it as an
[enhancement](https://github.com/ente-io/ente/discussions/categories/enhancements))**
(where the community upvotes can be used to help prioritize).
placeholder: e.g. v1.2.3
- type: dropdown
attributes:

View File

@@ -1,5 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Feature requests and questions
- name: Enhacements, feature requests, feedback and questions
url: https://github.com/ente-io/ente/discussions
about: Please use Discussions for everything apart from the above.

View File

@@ -141,6 +141,7 @@ jobs:
build-windows:
runs-on: windows-latest
environment: "auth-win-build"
defaults:
run:
@@ -174,14 +175,22 @@ jobs:
- name: Retain Windows EXE and DLLs
run: cp -r build/windows/x64/runner/Release ente-${{ github.ref_name }}-windows
- name: Code sign Windows installer and EXE
uses: dlemstra/code-sign-action@v1
- name: Sign files with Trusted Signing
uses: azure/trusted-signing-action@v0
with:
certificate: "${{ secrets.WINDOWS_CERTIFICATE }}"
password: "${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}"
files: |
auth/artifacts/ente-${{ github.ref_name }}-installer.exe
auth/ente-${{ github.ref_name }}-windows/auth.exe
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
endpoint: ${{ secrets.AZURE_ENDPOINT }}
trusted-signing-account-name: ${{ secrets.AZURE_CODE_SIGNING_NAME }}
certificate-profile-name: ${{ secrets.AZURE_CERT_PROFILE_NAME }}
files: |
${{ github.workspace }}/auth/artifacts/ente-${{ github.ref_name }}-installer.exe
${{ github.workspace }}/auth/ente-${{ github.ref_name }}-windows/auth.exe
file-digest: SHA256
timestamp-rfc3161: http://timestamp.acs.microsoft.com
timestamp-digest: SHA256
- name: Zip Windows EXE and DLLs
run: tar.exe -a -c -f artifacts/ente-${{ github.ref_name }}-windows.zip ente-${{ github.ref_name }}-windows

70
.github/workflows/auth-win-sign.yml vendored Normal file
View File

@@ -0,0 +1,70 @@
name: "Windows build & Sign (auth)"
on:
workflow_dispatch: # Allow manually running the action
env:
FLUTTER_VERSION: "3.24.3"
permissions:
contents: write
jobs:
build-windows:
runs-on: windows-latest
environment: "auth-win-build"
defaults:
run:
working-directory: auth
steps:
- name: Checkout code and submodules
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Flutter ${{ env.FLUTTER_VERSION }}
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Create artifacts directory
run: mkdir artifacts
- name: Build Windows installer
run: |
flutter config --enable-windows-desktop
# dart pub global activate flutter_distributor
dart pub global activate --source git https://github.com/ente-io/flutter_distributor_fork --git-ref develop --git-path packages/flutter_distributor
make innoinstall
flutter_distributor package --platform=windows --targets=exe --skip-clean
mv dist/**/*-windows-setup.exe artifacts/ente-${{ github.ref_name }}-installer.exe
- name: Retain Windows EXE and DLLs
run: cp -r build/windows/x64/runner/Release ente-${{ github.ref_name }}-windows
- name: Sign files with Trusted Signing
uses: azure/trusted-signing-action@v0
with:
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
endpoint: ${{ secrets.AZURE_ENDPOINT }}
trusted-signing-account-name: ${{ secrets.AZURE_CODE_SIGNING_NAME }}
certificate-profile-name: ${{ secrets.AZURE_CERT_PROFILE_NAME }}
files: |
${{ github.workspace }}/auth/artifacts/ente-${{ github.ref_name }}-installer.exe
${{ github.workspace }}/auth/ente-${{ github.ref_name }}-windows/auth.exe
file-digest: SHA256
timestamp-rfc3161: http://timestamp.acs.microsoft.com
timestamp-digest: SHA256
- name: Zip Windows EXE and DLLs
run: tar.exe -a -c -f artifacts/ente-${{ github.ref_name }}-windows.zip ente-${{ github.ref_name }}-windows
- name: Generate checksums
run: sha256sum artifacts/ente-* > artifacts/sha256sum-windows

32
.github/workflows/docs-lint.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: "Lint (docs)"
on:
# Run on every pull request (open or push to it) that changes docs/
pull_request:
paths:
- "docs/**"
- ".github/workflows/docs-lint.yml"
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest
defaults:
run:
working-directory: docs
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 22
cache: "yarn"
cache-dependency-path: "web/yarn.lock"
- run: yarn install
- run: yarn pretty:check

View File

@@ -23,7 +23,7 @@ Just hang around, enjoy the vibe. Answer someone's query on our
[Discord](https://discord.gg/z2YVKkycX3), or pile on in the sporadic #off-topic
rants there. Chuckle (or wince!) at our [Twitter](https://twitter.com/enteio)
memes. Suggest a new feature in our [Github
Discussions](https://github.com/ente-io/ente/discussions/new?category=feature-requests),
Discussions](https://github.com/ente-io/ente/discussions/new?category=enhancements),
or upvote the existing ones that you feel we should focus on first. Provide your
opinion on existing threads.
@@ -68,8 +68,8 @@ best to start small. Consider some well-scoped changes, say like adding more
Each of the individual product/platform specific directories in this repository
have instructions on setting up a dev environment.
For anything beyond trivial bug fixes, please use [features requests and
discussions](https://github.com/ente-io/ente/discussions) instead of performing
For anything beyond trivial bug fixes, please use
[discussions](https://github.com/ente-io/ente/discussions) instead of performing
code changes directly.
> [!TIP]

View File

@@ -200,7 +200,9 @@
{
"title": "bonify",
"slug": "bonify",
"altNames": ["bonify.de"]
"altNames": [
"bonify.de"
]
},
{
"title": "Booking",
@@ -304,6 +306,15 @@
{
"title": "CSAM"
},
{
"title": "CSSBuy",
"slug": "cssbuy",
"altNames": [
"CSS Buy",
"CSS-Buy",
"cssbuy.com"
]
},
{
"title": "CSFloat"
},
@@ -471,6 +482,9 @@
"title": "Gate.io",
"slug": "gateio.svg"
},
{
"title": "GERID"
},
{
"title": "GitHub"
},
@@ -725,8 +739,8 @@
]
},
{
"title": "Mercado Livre",
"slug": "mercado_livre",
"title": "Mercado Libre",
"slug": "mercado_libre",
"altNames": [
"Mercado Libre",
"MercadoLibre",
@@ -1006,6 +1020,14 @@
"qiniu"
]
},
{
"title": "R10.net",
"slug": "r10",
"altNames": [
"R10",
"r10.net"
]
},
{
"title": "Raindrop.io",
"slug": "raindrop_io",
@@ -1292,6 +1314,14 @@
"title": "US Mobile",
"slug": "us_mobile"
},
{
"title": "uollet",
"slug": "uollet",
"altNames": [
"UOLLET",
"uollet.com.br"
]
},
{
"title": "Vikunja"
},
@@ -1377,6 +1407,25 @@
},
{
"title": "CoinSpot"
},
{
"title": "Aternos",
"slug": "aternos"
},
{
"title": "Toshl Finance",
"slug": "toshl_finance",
"altNames": [
"Toshl"
]
},
{
"title": "xAI",
"slug": "xai"
},
{
"title": "Cronometer",
"slug": "cronometer"
}
]
}

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" xml:space="preserve"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300mm" height="300mm" viewBox="0 0 16000 16000" preserveAspectRatio="xMidYMid meet">
<g>
<path fill="#2b87d3" d="M0 8000 l0 -8000 8000 0 8000 0 0 8000 0 8000 -8000 0 -8000 0 0 -8000z m13990 0 l0 -5990 -5990 0 -5990 0 0 5990 0 5990 5990 0 5990 0 0 -5990z"/>
<path fill="#2b87d3" d="M2995 12998 c-3 -7 -4 -911 -3 -2008 l3 -1995 1005 0 1005 0 3 997 2 998 998 2 997 3 0 1005 0 1005 -2003 3 c-1597 2 -2004 0 -2007 -10z"/>
<path fill="#2b87d3" d="M8995 12998 c-3 -7 -4 -461 -3 -1008 l3 -995 997 -3 998 -2 2 -998 3 -997 1005 0 1005 0 0 2005 0 2005 -2003 3 c-1597 2 -2004 0 -2007 -10z"/>
<path fill="#2b87d3" d="M5995 9998 c-3 -7 -4 -911 -3 -2008 l3 -1995 2005 0 2005 0 0 2005 0 2005 -2003 3 c-1597 2 -2004 0 -2007 -10z"/>
<path fill="#2b87d3" d="M2995 6998 c-3 -7 -4 -911 -3 -2008 l3 -1995 2005 0 2005 0 0 1005 0 1005 -997 3 -998 2 -2 998 -3 997 -1003 3 c-797 2 -1004 0 -1007 -10z"/>
<path fill="#2b87d3" d="M10997 7003 c-4 -3 -7 -453 -7 -1000 l0 -993 -997 -2 -998 -3 0 -1005 0 -1005 2005 0 2005 0 0 2005 0 2005 -1001 3 c-550 1 -1004 -1 -1007 -5z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="107.51429"
height="102.75398"
viewBox="0 0 107.51429 102.75398"
fill="none"
version="1.1"
id="svg12"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs12" />
<g
id="g12"
transform="translate(34.950067,-215.99315)">
<path
d="m 57.85843,271.77769 c -0.774,-0.1257 -1.5665,0.0595 -2.2048,0.5152 -0.6382,0.4557 -1.0704,1.145 -1.2028,1.9179 -0.1447,0.8786 -0.3109,1.7775 -0.496,2.6697 -1.7799,8.5172 -5.1174,16.6325 -9.8446,23.9376 -5.0162,7.5169 -10.8489,12.0047 -15.6015,12.0047 -2.2725,0.0492 -4.5367,-0.2938 -6.6926,-1.0138 -5.6912,-1.775 -11.7884,-1.7717 -17.4777,0.009 -2.1479,0.7139 -4.4023,1.0536 -6.6652,1.0044 -4.7486,0 -10.58,-4.4851 -15.5963,-11.9979 -4.727,-7.3046 -8.0652,-15.4188 -9.84715,-23.935 -1.97756,-9.485 -1.60717,-17.8346 1.06924,-24.1485 1.09829,-2.7795 2.74951,-5.307 4.85381,-7.4292 2.1042,-2.1223 4.6176,-3.7952 7.3876,-4.9171 2.77,-1.122 5.7387,-1.6698 8.7268,-1.6101 2.988,0.0597 5.9328,0.7255 8.6558,1.9572 l 0.1663,0.0635 c 3.1372,1.3741 6.5201,2.0997 9.9449,2.1331 h 0.127 c 3.4272,-0.0346 6.8117,-0.763 9.9498,-2.1412 l 0.1502,-0.0581 c 2.981,-1.3116 6.2053,-1.979 9.462,-1.9586 1.8593,0.0219 3.7051,0.317 5.4785,0.8759 1.02,0.3144 2.0172,0.6982 2.9846,1.1489 0.7121,0.333 1.5269,0.3705 2.2665,0.1042 0.7397,-0.2662 1.3439,-0.8144 1.6805,-1.5248 0.1645,-0.3511 0.2583,-0.7312 0.2755,-1.1185 0.0172,-0.3873 -0.0421,-0.7742 -0.1749,-1.1385 -0.1328,-0.3643 -0.3362,-0.6987 -0.5986,-0.9841 -0.2625,-0.2854 -0.5788,-0.5161 -0.9307,-0.6789 -1.2159,-0.5667 -2.4693,-1.0495 -3.7512,-1.445 -2.3402,-0.7366 -4.7769,-1.1202 -7.2302,-1.1381 -3.9898,-0.0245 -7.9413,0.7777 -11.6058,2.356 l -0.1514,0.0581 c -1.5551,0.6563 -3.1723,1.1544 -4.8271,1.4869 -0.2018,-1.6639 -0.5606,-3.305 -1.0719,-4.9013 11.4383,-2.0749 11.0342,-15.88816 11.0342,-15.88816 -9.3133,1.40309 -13.3294,4.93919 -14.9623,8.33877 -1.5519,-2.01717 -3.4478,-3.74459 -5.6002,-5.10275 -0.3906,-0.24958 -0.8265,-0.41979 -1.2828,-0.50093 -0.4563,-0.0811 -0.9238,-0.0716 -1.3765,0.0281 -0.4526,0.0997 -0.8812,0.28749 -1.2613,0.55278 -0.38,0.26529 -0.7041,0.60283 -0.9537,0.99335 -0.2496,0.39052 -0.4198,0.82638 -0.5009,1.28269 -0.0812,0.45631 -0.0717,0.92412 0.028,1.37675 0.0997,0.45262 0.2875,0.88118 0.5528,1.2612 0.2653,0.38003 0.6028,0.70409 0.9933,0.95367 1.9269,1.29176 3.5632,2.97116 4.8046,4.93076 1.2415,1.9597 2.0607,4.1567 2.4055,6.4507 -1.2634,-0.3369 -2.5038,-0.7536 -3.7143,-1.2476 l -0.1759,-0.0676 c -3.6617,-1.5742 -7.6092,-2.3745 -11.5949,-2.3506 -9.0309,0 -20.73562,6.0327 -25.63155,17.5723 -3.97541,9.3756 -2.962867,20.2042 -1.41244,27.6387 1.94038,9.2532 5.57254,18.0686 10.71379,26.003 6.3017,9.4378 13.5982,14.6369 20.5461,14.6369 2.8438,0.049 5.6759,-0.375 8.3806,-1.255 4.5889,-1.454 9.515,-1.454 14.1039,0 2.6964,0.878 5.5198,1.3 8.3549,1.251 6.8478,0 14.3376,-5.3384 20.5461,-14.645 5.1404,-7.9344 8.7713,-16.75 10.7098,-26.0031 0.2041,-0.9746 0.3851,-1.9559 0.5406,-2.917 0.062,-0.3835 0.0481,-0.7755 -0.0416,-1.1535 -0.0897,-0.3779 -0.2534,-0.7345 -0.4812,-1.0492 -0.2278,-0.3147 -0.5154,-0.5813 -0.8464,-0.7846 -0.3311,-0.2033 -0.6991,-0.3393 -1.0828,-0.4001"
fill="#ff6733"
id="path11" />
<path
d="m 71.33493,256.39499 v 0.0121 l -8.2649,-5.8475 -0.4271,-0.2298 0.0512,-0.5177 0.2393,-10.0798 h 0.0095 c 0.0046,-0.5208 -0.1263,-1.0339 -0.3802,-1.4887 -0.2538,-0.4548 -0.6219,-0.8357 -1.0675,-1.1053 -0.4471,-0.2723 -0.9569,-0.4242 -1.4801,-0.441 -0.5233,-0.0169 -1.0422,0.102 -1.5059,0.3451 l -8.7538,4.3593 c -1.2619,0.6789 -2.3372,1.6578 -3.1318,2.8502 -0.7946,1.1925 -1.2839,2.5621 -1.4247,3.9881 l -0.7408,7.7913 -6.3059,3.3658 c -2.4638,-3.7027 -5.7171,-6.8136 -9.5264,-9.1092 -3.8093,-2.2956 -8.0799,-3.7189 -12.5047,-4.1675 -4.4249,-0.4486 -8.894,0.0886 -13.0866,1.573 -4.1925,1.4843 -8.0041,3.879 -11.1609,7.0119 -2.7859,2.7623 -4.9974,6.0489 -6.5065,9.6702 -1.509,3.6213 -2.286,7.5057 -2.286,11.4288 0,3.9232 0.777,7.8075 2.286,11.4288 1.5091,3.6214 3.7206,6.908 6.5065,9.6702 4.197,4.1711 9.5317,7.0104 15.3356,8.1623 5.8039,1.1518 11.8188,0.5648 17.2905,-1.6873 5.4718,-2.2522 10.157,-6.0694 13.4684,-10.9731 3.3114,-4.9037 5.1017,-10.6758 5.1465,-16.5928 0.0013,-3.8327 -0.7435,-7.6291 -2.1926,-11.1774 l 6.2181,-3.3117 -0.0109,0.0311 6.7206,4.0741 c 1.2315,0.7427 2.6257,1.1736 4.0615,1.2554 1.4357,0.0817 2.8695,-0.1882 4.1772,-0.7863 l 8.7534,-4.3593 c 0.472,-0.2216 0.877,-0.5622 1.177,-0.9882 0.3,-0.426 0.483,-0.9228 0.532,-1.4413 0.049,-0.5185 -0.038,-1.0409 -0.252,-1.5156 -0.214,-0.4747 -0.548,-0.8853 -0.97,-1.1915 m -34.1485,19.4107 c -0.0347,4.7475 -1.47,9.3791 -4.1262,13.3141 -2.6561,3.9351 -6.4148,6.9984 -10.8048,8.806 -4.39,1.8076 -9.2158,2.2789 -13.8727,1.355 -4.6568,-0.924 -8.9373,-3.2021 -12.3047,-6.5488 -2.2347,-2.2161 -4.0086,-4.8527 -5.2191,-7.7579 -1.2105,-2.9051 -1.8335,-6.0211 -1.8335,-9.1684 0,-3.1472 0.623,-6.2632 1.8335,-9.1684 1.2105,-2.9051 2.9844,-5.5417 5.2191,-7.7578 2.5007,-2.4815 5.514,-4.3861 8.8284,-5.5801 3.3145,-1.194 6.85,-1.6486 10.3587,-1.3319 3.5087,0.3167 6.9057,1.397 9.9528,3.1652 3.0471,1.7682 5.6703,4.1815 7.6862,7.0707 l -8.1614,4.3552 c -1.3138,-1.6306 -2.9557,-2.9671 -4.8188,-3.9229 -1.8632,-0.9559 -3.9062,-1.5098 -5.997,-1.6259 -2.0908,-0.1161 -4.1826,0.2082 -6.1401,0.952 -1.9576,0.7437 -3.7372,1.8903 -5.2234,3.3654 -1.3826,1.3719 -2.4797,3.0038 -3.2285,4.8018 -0.7489,1.798 -1.1343,3.7264 -1.1343,5.674 0,1.9477 0.3854,3.8761 1.1343,5.6741 0.7488,1.7979 1.8459,3.4299 3.2285,4.8018 2.317,2.3457 5.3482,3.8548 8.6165,4.2898 3.2684,0.4351 6.5886,-0.2286 9.4386,-1.8865 2.85,-1.6579 5.0682,-4.2161 6.3055,-7.2723 1.2374,-3.0562 1.4238,-6.437 0.53,-9.6107 l 8.2064,-4.3687 c 1.0104,2.6766 1.5273,5.5142 1.526,8.3752 z m -26.0801,1.2734 c 0.3553,0.6991 0.9725,1.2295 1.7171,1.4759 0.7445,0.2463 1.5564,0.1885 2.2586,-0.1607 l 6.9193,-3.6848 c 0.2696,2.1001 -0.213,4.2278 -1.3623,6.006 -1.1493,1.7782 -2.891,3.0921 -4.9165,3.7087 -2.0255,0.6167 -4.2042,0.4963 -6.1494,-0.3399 -1.9452,-0.8361 -3.5316,-2.334 -4.4779,-4.228 -0.9463,-1.8941 -1.1912,-4.0621 -0.6917,-6.1196 0.4995,-2.0576 1.7111,-3.8718 3.4205,-5.1212 1.7094,-1.2494 3.806,-1.8532 5.9181,-1.7044 2.1121,0.1487 4.1034,1.0405 5.6207,2.5172 l -6.9345,3.6997 c -0.3472,0.1714 -0.6571,0.4099 -0.9118,0.7018 -0.2546,0.2918 -0.449,0.6311 -0.5719,0.9984 -0.1229,0.3673 -0.172,0.7553 -0.1442,1.1416 0.0278,0.3863 0.1317,0.7633 0.3059,1.1093 z m 39.7718,-27.0764 c 0.219,-1.157 0.3879,-2.1708 1.4557,-2.7467 l 4.5109,-2.2438 -0.6085,5.5191 -5.7029,2.8386 z m 8.0467,10.3339 c -0.5151,0.173 -1.0642,0.2192 -1.6009,0.1347 -0.5367,-0.0845 -1.0453,-0.2971 -1.4824,-0.6199 l -2.9222,-1.7424 5.7042,-2.8386 4.8109,2.8224 z"
fill="#ff6733"
id="path12" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -0,0 +1,9 @@
<svg width="145" height="39" viewBox="0 0 145 39" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect width="145" height="39" fill="url(#pattern0_2030_2)"/>
<defs>
<pattern id="pattern0_2030_2" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0_2030_2" transform="scale(0.00689655 0.025641)"/>
</pattern>
<image id="image0_2030_2" width="145" height="39" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJEAAAAnCAMAAAA4lVp5AAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAERUExURQAAAGy8Kmy8Kmy9Kmy8Km28KWy9Km2/Lmy8Kmu8Kmu8Kmy8KWy7KGy9Kmu9KWu8Km27K3C/KGy8Kmy8KW29K2y8Kmy8K3C/MGy9Kmy7LGy8KWu8LGy7Kmy9KnDCKWy8KWy7Km28Kmy7Kmy8Kmu5Km29Km26KGq6Kmu8Kmy9Kmu7Kmy8Kmy8Kmy8Kmy8Kmy8Km69KWy9K2u8KoC/IG28Km27Kmy7Kmy5K2y8Km2+LGi3KGq6Kmu8KWy9Kmq8K2y6Kmy7Kmy8Kn7ERazZh9ruyv///+Py177ioYjJUpHNX+335LXdlHXAN9HqvKPVecjmr5rRbfb78qPVerbeldvuyuTz2O335cjmsK3ZiNHqvb/iok0+o7UAAABBdFJOUwD359fHm1UcxmbMv0B/cN+PIKOgj9CQEMBA8EyA1BlQkrDb4DdgPzCkyE/v7c+2r12QnwjDMeJC9VIgYFiXSGh4PBaO/QAAAAFiS0dERY6zqFcAAAAHdElNRQfpBR8TLQ+T8HIEAAAAAW9yTlQBz6J3mgAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyNS0wNS0zMVQxOTo0NToxNSswMDowMFaVqvwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjUtMDUtMzFUMTk6NDU6MTUrMDA6MDAnyBJAAAAAKHRFWHRkYXRlOnRpbWVzdGFtcAAyMDI1LTA1LTMxVDE5OjQ1OjE1KzAwOjAwcN0znwAAAFplWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAAAAABIAAAAAQAAAEgAAAABH1L3NAAABF9JREFUWMPNV3lf2kAQpbWXUlFKOUJpFSnQ1tqD3tYeGxIgEJRww/f/IN3ZczYE/QlqnT8kzmY3L++9md3EyEpx5+7GvfsPHsauI1ZDJOLR5m1DRMjW1WNaExEh8ce3DREh2xHLJuTgTnw3eeOIyJPFZVMXQb5eROTpwrJpYzyzFiK77jhuw2m2UM5rOm3H6dgq4de7NNM9XcZCluZyFo1EJg/jlxEujOfMleFIAL4jU02R6QUi0Za4n5mrWjSVEOCArsLKiPouioA/zm/o1Fn4LnEPef7CWLVAU5a43gO+VkU0cI0IfEgyhoLhkKX6oCG7Gg3HjCUxdd9YtUgzhoIrIuLvPun5xO4zXSY02YKLKQg6ohdDejEDPMDNFIZ6fO6BsWqJkDRGdBlrYw8BisAT5oHnuzbnbcjHIUN/4YffNaFXAzH7JVo0iUGU6T9l7q5KRVq8WqlUeKaip0EyixHB+q4qsZYQaaafOpsNemJAOHw4mUr/43LbUyAoRTuE5Dkgmt0T2RxXsojrEMZLGJHvojeG54/mAG8OZYe19TVHOF6FjF0VgOIKRwI9XtRfWdckkxrKwXQR97IRzCxdG2WYuKfh+14jRJQBUoF4s3uo6SpKsqg+AibIW0SvkTF8NBNWDoXPe8+ZZoVXZLtuon+7rIBLluZAPr0s6UqrokxyzfDkoSjucMjuo3jipl/gCTkUp4+kUFmiO2VK0pUhsnHl5JUphkeiIAVmNyT+zGiYC4jK5vyytrukKy3pqgqp2BxengdqorsMEfEHHFOg3OTxfunOIxHBi2f5Awt5haOgssrYNOj4ERBI/Zbno+8MRD0SHf507Jo281ivcO0oRJSBEi7puJQljZKW0g8cBT+iM+wbPkLv3AG+Wp1uY6DNQ7eMetMJkL+mUYiItjD3h2QjJXIJTRdvXRaa8kCtODeqvwfVxMpqrhLQGOGvuGlk9q8YpkVv9tK74BjZeoqaxCzDUlKa8YzQAXu1FbDNo6f3UoFoqIlpLEGUQBbWNVRG2ZKmC8YPC1ozGu/VkiNd452A7yi+RglHgJlg0lNv0ItAlML/gGVJyNiYLnki1zLHPqglW+IU5ogDEVDB/Ntudjptsc3ZvDd16uxoN46qNbzxM3hFiaiqRNMkJtlkpRnER7WmcV7j/vHHKMNKbYrvaUUgAh9ITbI1Ip9eIOoIYNYBbGdIMxqfPqtF1WmVKiP0kA0aAPkh3IHRLLCxa2xT266BZAIepA+rUiZNIrN+MWbEl6+67ww4gNFAb1p9npqp7mlPGHHjgbmxyeUKxIwU5mLniCf1oZL1xvCXwbfvaAHf87zwCaDlhZo5vckO3aMQ5YxsSelRzUuIOYyoiG2u4scOWT/kYnmVSedS2B9J9lmZ3othRMu+C45rV4fovLCskD6RmvH4uXUTiBYiWjMRm2tiWgXQRd9yJ782bhbROZqpOP598ufv9kqxAqLMeZr9j7DI5b52rz3gS05udbc5/gHZ/BLSJh/eDgAAAABJRU5ErkJggg=="/>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: https://ezgif.com/png-to-svg -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="195" height="195">
<path d="M0,0 L44,0 L70,2 L94,6 L98,8 L98,39 L95,75 L91,98 L85,114 L76,131 L65,145 L58,153 L55,154 L55,144 L51,131 L42,121 L38,118 L38,98 L34,98 L33,29 L28,27 L26,26 L26,89 L22,89 L22,25 L20,25 L20,89 L13,89 L12,29 L11,30 L11,98 L6,98 L6,118 L-3,125 L-9,135 L-11,143 L-11,154 L-15,152 L-25,141 L-35,126 L-43,110 L-48,95 L-52,69 L-54,44 L-55,8 L-50,6 L-26,2 Z " fill="#046097" transform="translate(75,8)"/>
<path d="M0,0 L44,0 L70,2 L94,6 L98,8 L98,39 L95,75 L91,98 L85,114 L76,131 L65,145 L58,153 L55,154 L55,144 L51,131 L42,121 L38,118 L38,98 L34,98 L33,29 L28,27 L26,26 L26,89 L22,89 L22,25 L20,24 L22,24 L22,1 L0,1 Z " fill="#0495C0" transform="translate(75,8)"/>
<path d="M0,0 L8,0 L13,3 L15,7 L15,15 L6,21 L0,20 L-7,16 L-8,10 L-5,3 Z " fill="#0A669B" transform="translate(93,165)"/>
<path d="M0,0 L6,1 L10,5 L11,7 L11,15 L2,21 L-2,20 L0,20 Z " fill="#0D99C1" transform="translate(97,165)"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.0.1, 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 280.6 100" style="enable-background:new 0 0 280.6 100;" xml:space="preserve">
<style type="text/css">
.st0{enable-background:new ;}
.st1{fill:#FFFFFF;}
.st2{fill:#3F4257;}
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#3F4257;}
.st4{fill-rule:evenodd;clip-rule:evenodd;fill:#EA4335;}
.st5{fill:#EA4335;}
.st6{fill:#FBBC05;}
.st7{fill:#4285F4;}
.st8{fill:#34A853;}
</style>
<g>
<g class="st0">
<path class="st1" d="M114.5,57.9h-6.3L97.9,46.2h-7.2v11.7h-5.4V24.1c5.3,0,10.5,0,15.8,0c7.8,0,12,5.4,12,11
c0,4.8-2.5,9.5-9.2,10.5L114,57L114.5,57.9z M90.7,29.1v12.2H101c4.5,0,6.5-2.8,6.5-6c0-3-2-6.2-6.4-6.2H90.7z"/>
<polygon class="st1" points="124.5,57.9 129.9,57.9 129.9,24.2 118.7,27.7 118.7,32.4 124.5,30.8 "/>
<path class="st1" d="M139.7,38.1c0-19.6,28.4-19.5,28.4,0V44c0,19.5-28.4,19.6-28.4,0V38.1z M145.2,44c0,12.8,17.5,12.8,17.5,0
v-5.9c0-12.6-17.5-12.8-17.5,0V44z"/>
</g>
<g class="st0">
<path class="st1" d="M188.8,24.2l22.8,27.9V24.2h2.6v33.8h-1L190.3,30v27.9h-2.6V24.2H188.8z"/>
<path class="st1" d="M226.3,39.7h19.8v2.4h-19.8v13.3h21.4v2.5h-24V24.2h23.4v2.5h-20.8V39.7z"/>
<path class="st1" d="M263.3,26.5h-12.2v-2.3h27.1v2.3h-12.2v31.4h-2.6V26.5z"/>
</g>
<g id="Group_174_3_" transform="translate(-5071.999 -1624)">
<path class="st1" d="M5106.8,1722c-5.8,0-11.4-1.2-16.4-3.6c-4.9-2.3-9.1-5.7-12-9.8c-5-7.1-6.1-16-3-25l0-0.1
c7.8-22.5,13-25.7,18.7-27.4l0.5-0.1l0,0.2l0.8-0.1c0.5,0,0.9-0.1,1.4-0.1c0.6,0,1.2,0,1.8,0.1l0.8,0.1l0.4,0.1
c1.9,0.3,3.8,0.8,5.7,1.5l0,0l0,0c0.4,0.1,0.9,0.2,1.3,0.2c0,0,0,0,0,0c5.2,0,12.8-10.1,18.8-28.9c-0.3,1.7-1.1,6.5-1.4,8.1
c-1.2,6.5-2.3,12.7-3.2,17.7l-0.1,0.5l0.5,0.2c2.8,1.2,5,3.8,6.5,7.6l0.1,0.3l0.3,0.1c5.2,1.9,9.3,4.6,12.1,8
c2.5,3,4.2,6.5,4.8,10.5c0.9,5.3,0,11.6-2.5,17.6c-2.2,5.2-5.3,9.8-8.5,12.3C5126,1718.6,5116.6,1722,5106.8,1722L5106.8,1722z
M5094.2,1635.7l0.5,2.5l-0.2,16.8L5094.2,1635.7z M5099.2,1654.4c-0.2-8.7,5.1-17.6,12.8-21.7c-0.7,0.9-1.4,1.8-2,2.7
C5103.8,1639,5100.3,1645.3,5099.2,1654.4z"/>
<g>
<path class="st1" d="M5128.3,1663.1c-1.7-4.1-4-6.7-6.9-8c1.5-8.3,3.6-20,5.7-31.1c-0.4,1.7-1.1,3.4-1.7,5
c-1.7,9.3-4.2,20.4-5.5,27.4c3.2,1.5,5.6,4.2,6.9,7.6c27.3,9.9,16.5,38.3,6.9,46.1c-28,22.7-67.7,4-57.3-26.9
c6.8-20.3,12.9-24.2,18.7-26v0c2.6-0.5,6.9,0.4,9.2,0.9c1.4,0.4,2.2,0.5,2.5,0.5c8,0.5,15.6-18.5,18.5-29.8
c-2.1,5.3-11.8,30.7-19.9,28.3c-1.9-0.7-3.8-1.2-5.8-1.6c0.8-8.8,4-15.8,10.7-19.6c1.2-1.8,2.7-3.6,4.2-5.1
c-9.9,3.5-16.8,14.4-16.1,24.6c-1.1-0.1-2.2-0.1-3.3,0l0.2-17.2l-2.1-9.6l0.5,26.8c-6.3,1.9-11.6,5.9-19.1,27.8l0,0
c-7.8,22.6,10.4,39.4,32.1,39.4c9.2,0,19-3.1,27.7-10C5144.6,1704.6,5157.1,1673.7,5128.3,1663.1z"/>
<polygon class="st2" points="5114.7,1630.8 5114.7,1630.8 5114.7,1630.8 "/>
</g>
<g id="Group_1_3_" transform="translate(5072 1624)">
<path id="Path_839_2_" class="st3" d="M33.1,41.9c1.8-4.6,5.7-7.7,10.2-7.7c6.2,0,11.3,6.1,11.3,13.6s-5.1,13.6-11.3,13.6
c-4.5,0-8.4-3.2-10.2-7.8c0.1-0.2,0.2-0.3,0.3-0.5c1.7,4.2,5.2,7.2,9.4,7.2c5.7,0,10.4-5.6,10.4-12.4s-4.6-12.4-10.4-12.4
c-4.1,0-7.7,2.9-9.4,7.1C33.3,42.2,33.2,42.1,33.1,41.9z M25.1,36.4c2.9,0,5.5,1.9,7.1,4.8c-1.2-2.3-3.6-3.7-6.2-3.8
c-4.4,0-7.9,4.6-7.9,10.3S22.5,58,26,58s4.7-1.9,6.1-4.2c-1.6,2.8-3.2,5.1-7,5.1c-3.8,0-8.7-5-8.7-11.2
C16.4,41.5,20.3,36.4,25.1,36.4L25.1,36.4z"/>
<path id="Path_840_2_" class="st3" d="M27.8,45.5c0.9,0,1.6-0.7,1.6-1.5c0-0.9-0.7-1.6-1.5-1.6c-0.9,0-1.6,0.7-1.6,1.5
c0,0,0,0,0,0C26.3,44.8,27,45.4,27.8,45.5z"/>
<path id="Path_842_2_" class="st3" d="M46.9,46.4c0.9,0,1.6-0.6,1.6-1.5c0-0.9-0.6-1.6-1.5-1.6s-1.6,0.6-1.6,1.5c0,0,0,0,0,0.1
C45.4,45.7,46.1,46.4,46.9,46.4z"/>
<path id="Path_843_2_" class="st3" d="M26.1,62.8l0.6,0.1l-2.3,23.4l-0.6-0.1L26.1,62.8z"/>
<path id="Path_844_2_" class="st3" d="M38.6,65.3l0.6,0l1.5,23.5l-0.6,0L38.6,65.3z"/>
<path id="Path_845_2_" class="st3" d="M51.6,64.2l0.5-0.1l3.1,19.7L54.6,84L51.6,64.2z"/>
<g>
<polygon class="st2" points="8.1,57.5 8.1,57.5 8.1,57.5 8.1,57.5 "/>
<path class="st2" d="M8.1,57.5c-4.3,39.6,64.1,47.3,56.7-0.1c0,0,0,0,0,0c0,0,0,0,0,0s0,0,0,0c-0.3,0.2-0.6,0.4-0.9,0.6
c-0.3,0.2-0.6,0.5-1,0.7c-0.9,0.6-2.2,1.2-3.8,1.9C41.4,66.9,17.2,62.2,8.1,57.5 M9.3,58.9c7.6,7,37.3,10.1,53,2.1
c0,0,0.3-0.1,0.5-0.3C67.3,101.9,5.8,94.4,9.3,58.9z"/>
</g>
</g>
</g>
<circle class="st1" cx="177.1" cy="53.6" r="4"/>
<path id="Forma_1_3_" class="st4" d="M153,74.7c-1,0-2.1,0.3-2.9,1c-0.7,0.6-1.3,1.3-1.7,2c-0.4-0.8-1-1.5-1.7-2
c-0.8-0.7-1.8-1-2.9-1c-2.9,0-5.2,2.4-5.2,5.6c0,3.5,2.8,5.8,7,9.4c0.7,0.6,1.5,1.3,2.4,2c0.2,0.2,0.6,0.2,0.8,0
c0.8-0.7,1.6-1.4,2.4-2c4.2-3.6,7-6,7-9.4C158.1,77.1,155.9,74.7,153,74.7z"/>
<g>
<path class="st1" d="M86.6,71.9l5.2,15.7l5.3-15.7h1.5l5.3,15.7l5.2-15.7h2.7l-6.6,19h-2.4l-4.9-14.2L93,90.9h-2.4l-6.6-19H86.6z"
/>
<path class="st1" d="M125.1,88.7c-1.4,1.6-3.7,2.4-5.8,2.4c-4.1,0-7-2.7-7-7c0-4,2.9-6.9,6.9-6.9c4.1,0,7.2,2.5,6.7,7.9h-11.4
c0.2,2.5,2.3,4,4.9,4c1.5,0,3.4-0.6,4.3-1.7L125.1,88.7L125.1,88.7z M123.8,83.2c-0.1-2.6-1.9-4-4.5-4c-2.3,0-4.4,1.4-4.7,4
L123.8,83.2L123.8,83.2z"/>
</g>
<g>
<path class="st5" d="M214.6,84.2c0,4.8-3.7,8.3-8.3,8.3s-8.3-3.5-8.3-8.3c0-4.8,3.7-8.3,8.3-8.3S214.6,79.4,214.6,84.2z M211,84.2
c0-3-2.2-5-4.7-5s-4.7,2-4.7,5c0,3,2.2,5,4.7,5S211,87.2,211,84.2z"/>
<path class="st6" d="M232.6,84.2c0,4.8-3.7,8.3-8.3,8.3s-8.3-3.5-8.3-8.3c0-4.8,3.7-8.3,8.3-8.3S232.6,79.4,232.6,84.2z M229,84.2
c0-3-2.2-5-4.7-5s-4.7,2-4.7,5c0,3,2.2,5,4.7,5S229,87.2,229,84.2z"/>
<path class="st7" d="M249.9,76.4v14.9c0,6.1-3.6,8.7-7.9,8.7c-4,0-6.5-2.7-7.4-4.9l3.2-1.3c0.6,1.4,2,3,4.2,3
c2.7,0,4.4-1.7,4.4-4.9v-1.2h-0.1c-0.8,1-2.4,1.9-4.4,1.9c-4.2,0-8-3.6-8-8.3c0-4.7,3.8-8.3,8-8.3c2,0,3.6,0.9,4.4,1.9h0.1v-1.4
L249.9,76.4L249.9,76.4z M246.7,84.3c0-2.9-2-5.1-4.4-5.1c-2.5,0-4.6,2.1-4.6,5.1c0,2.9,2.1,5,4.6,5
C244.7,89.3,246.7,87.2,246.7,84.3z"/>
<path class="st8" d="M255.6,67.7V92H252V67.7H255.6z"/>
<path class="st5" d="M269.5,87l2.8,1.9c-0.9,1.4-3.1,3.7-6.9,3.7c-4.7,0-8.3-3.7-8.3-8.3c0-4.9,3.6-8.3,7.8-8.3
c4.3,0,6.4,3.4,7.1,5.3l0.4,0.9l-11.1,4.6c0.9,1.7,2.2,2.5,4,2.5C267.3,89.3,268.6,88.4,269.5,87L269.5,87z M260.8,84l7.4-3.1
c-0.4-1-1.6-1.8-3.1-1.8C263.3,79.1,260.7,80.8,260.8,84z"/>
<path class="st7" d="M184.5,82.1v-3.5h11.9c0.1,0.6,0.2,1.3,0.2,2.1c0,2.6-0.7,5.9-3.1,8.3c-2.3,2.4-5.2,3.6-9,3.6
c-7.1,0-13.1-5.8-13.1-12.9c0-7.1,6-12.9,13.1-12.9c3.9,0,6.7,1.5,8.9,3.6l-2.5,2.5c-1.5-1.4-3.6-2.5-6.4-2.5
c-5.2,0-9.3,4.2-9.3,9.4c0,5.2,4.1,9.4,9.3,9.4c3.4,0,5.3-1.4,6.5-2.6c1-1,1.7-2.4,1.9-4.4L184.5,82.1z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,15 @@
<svg width="500" height="404" viewBox="0 0 500 404" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M232.61 401.571C220.894 398.642 214.011 395.42 204.052 388.39C199.219 384.876 154.991 341.672 105.783 292.172C37.244 223.34 15.1299 200.347 11.1757 193.61C-3.03008 169.006 -3.61588 146.16 8.97892 121.263C14.6905 109.987 26.6995 96.806 75.0284 48.4771C115.303 8.20299 118.378 6.00622 139.321 1.46623C151.33 -1.02344 160.41 -0.437633 174.176 3.9559C188.235 8.20299 197.901 15.5256 224.262 41.7403C237.443 54.7745 249.013 65.4654 250.038 65.4654C250.916 65.4654 251.649 66.7835 251.649 68.3945C251.649 70.0054 251.063 71.3235 250.331 71.3235C249.745 71.3235 243.887 76.5957 237.443 83.0396C224.409 95.9273 216.647 109.108 215.329 120.385C214.596 127.561 217.525 144.549 219.576 144.549C220.308 144.549 220.894 145.867 220.894 147.478C220.894 151.725 240.811 171.203 248.72 174.865C252.381 176.475 258.532 178.672 262.34 179.697C268.93 181.455 269.955 181.308 279.914 177.501C285.772 175.157 291.044 172.521 291.63 171.35C292.216 170.325 293.241 169.446 293.973 169.446C294.559 169.446 304.664 159.926 316.527 148.21C336.59 128.586 338.494 126.975 343.62 126.975C348.746 126.975 350.943 128.879 386.091 164.027C406.301 184.237 422.997 201.812 422.997 202.837C422.997 203.715 423.582 204.594 424.315 204.594C424.9 204.594 427.39 208.695 429.733 213.821C433.102 221.29 433.98 225.39 434.42 237.253C435.006 249.555 434.713 251.459 432.662 251.459C431.344 251.459 430.319 252.337 430.319 253.362C430.319 254.388 400.15 285.289 363.391 321.902C303.492 381.507 295.145 389.123 286.065 393.809C267.465 403.328 250.184 405.818 232.61 401.571ZM2.24217 152.311C1.94926 149.968 1.65636 151.579 1.65636 155.533C1.65636 159.634 1.94926 161.391 2.24217 159.634C2.53507 157.73 2.53507 154.508 2.24217 152.311Z" fill="#461EC5"/>
<path d="M430.319 233.152C430.319 231.981 429.733 230.955 429.001 230.955C428.269 230.955 427.976 229.637 428.415 228.026C429.733 222.901 433.248 224.512 433.248 230.223C433.248 233.006 432.662 235.349 431.784 235.349C431.052 235.349 430.319 234.324 430.319 233.152Z" fill="#36198A"/>
<path d="M421.386 210.745C417.138 205.766 416.846 203.13 420.8 203.13C424.022 203.13 424.461 203.715 424.461 208.255C424.461 214.113 424.315 214.26 421.386 210.745Z" fill="#36198A"/>
<path d="M252.527 182.48C247.695 180.869 241.104 177.647 237.736 175.304C228.949 169.299 212.4 150.407 215.768 150.407C216.354 150.407 215.622 149.382 214.45 148.064C213.132 146.892 212.4 145.135 212.839 144.403C213.425 143.671 212.986 143.085 212.107 143.085C211.082 143.085 210.789 141.913 211.375 140.156C211.814 138.545 211.814 137.227 211.082 137.227C210.496 137.227 209.91 131.662 209.91 124.778C209.91 117.895 210.496 112.33 211.228 112.33C211.814 112.33 212.107 111.305 211.521 110.133C211.082 108.962 211.375 107.936 212.253 107.936C213.132 107.936 213.571 106.911 212.986 105.74C212.546 104.568 212.839 103.543 213.718 103.543C214.597 103.543 214.889 102.957 214.45 102.225C214.011 101.493 214.597 100.467 215.915 100.028C217.233 99.5887 217.965 98.1242 217.526 97.099C217.086 95.9274 217.672 94.6094 218.844 94.17C220.015 93.7306 220.748 92.8519 220.601 92.2661C220.162 90.8016 244.18 66.9301 246.084 66.9301C246.816 66.9301 246.962 66.1978 246.377 65.3191C245.791 64.2939 246.377 64.001 248.134 64.5868C250.331 65.3191 256.921 59.4611 278.01 38.665C307.007 9.96053 311.694 6.7386 330.732 1.75926C347.721 -2.78073 370.714 1.90571 385.505 12.7431C392.242 17.7224 440.571 65.3191 440.571 67.0765C440.571 67.6623 441.45 68.541 442.475 68.8339C443.353 69.2733 438.374 69.5662 431.052 69.5662C420.946 69.4197 416.406 70.0055 411.72 72.2023C404.69 75.4242 348.16 129.904 351.821 129.904C353.432 129.904 354.165 131.222 354.165 134.298C354.165 138.252 354.604 138.691 358.558 138.691C362.659 138.691 362.952 139.131 362.952 144.11V149.529L353.579 140.302C344.938 131.808 343.767 131.076 341.423 132.98C339.959 134.151 330 143.817 319.163 154.508C308.325 165.052 298.953 173.839 298.367 173.839C297.781 173.839 296.609 174.718 296.023 175.743C295.438 176.915 290.458 179.551 284.893 181.601C273.177 186.288 264.683 186.581 252.527 182.48ZM288.847 141.913C297.342 134.737 299.538 127.414 295.731 119.067C292.069 110.865 287.529 107.204 278.596 105.007C271.859 103.543 270.395 103.689 265.562 106.033C261.315 108.229 259.557 110.573 256.775 117.309C253.406 125.511 253.406 125.95 255.749 132.394C258.386 139.423 263.951 144.549 271.42 147.039C276.253 148.65 283.429 146.6 288.847 141.913Z" fill="#36198A"/>
<path d="M383.455 170.178L378.476 165.052H383.894C389.167 165.052 389.313 165.199 389.313 170.178C389.313 172.961 389.167 175.304 388.874 175.304C388.581 175.304 386.238 172.961 383.455 170.178Z" fill="#36198A"/>
<path d="M430.026 239.157C429.44 228.612 428.561 225.097 424.021 216.017C419.335 206.498 414.649 201.372 382.136 168.714C361.926 148.65 345.084 130.929 344.498 129.465C343.327 125.95 398.392 71.9093 407.326 67.6622C412.012 65.6119 416.552 64.8796 426.218 64.8796H438.959L459.023 84.5041C480.698 105.886 488.899 116.87 492.854 129.758C494.318 134.298 495.929 138.398 496.661 138.838C497.394 139.423 497.54 141.181 497.101 142.792C496.515 144.403 496.808 146.16 497.686 146.746C499.59 147.918 499.59 161.684 497.54 163.002C496.661 163.441 496.222 165.199 496.661 166.663C497.101 168.128 496.075 171.789 494.611 174.865C493.146 177.794 491.828 181.601 491.828 183.066C491.828 186.434 485.97 197.272 484.213 197.272C483.627 197.272 483.041 198.15 483.041 199.175C483.041 201.372 434.419 251.459 432.223 251.459C431.344 251.459 430.465 246.333 430.026 239.157Z" fill="#2B146D"/>
<path d="M266.586 151.432C260.435 149.089 251.355 141.913 252.38 140.009C252.966 139.277 252.527 138.691 251.648 138.691C250.77 138.691 250.477 138.105 250.916 137.227C251.355 136.494 251.209 135.762 250.33 135.762C249.451 135.762 249.159 134.737 249.598 133.565C250.184 132.394 249.891 131.368 249.159 131.368C248.426 131.368 247.84 128.732 247.987 125.51C247.987 122.289 248.426 119.652 248.866 119.652C250.33 119.652 253.259 112.183 252.38 110.719C251.795 109.987 252.234 109.401 252.966 109.401C253.845 109.401 254.431 108.669 254.138 107.643C253.991 106.765 256.481 104.421 259.703 102.664C267.026 98.417 275.959 96.806 278.742 99.1492C279.913 100.028 281.524 100.467 282.257 100.028C282.989 99.4421 284.014 99.735 284.6 100.614C285.186 101.492 286.064 101.785 286.797 101.346C288.847 100.028 297.341 108.229 300.124 114.527C303.638 122.289 303.638 124.046 299.684 124.046C297.195 124.046 295.73 122.581 293.973 118.334C291.044 111.451 282.257 104.568 276.691 104.714C271.566 104.861 260.582 110.133 259.41 113.062C258.971 114.234 257.36 115.259 255.895 115.259C253.552 115.259 253.113 116.43 253.113 121.849C253.113 125.657 254.138 130.49 255.31 132.687C257.946 137.812 265.415 144.256 270.101 145.428C272.591 146.014 273.616 147.332 273.616 149.821C273.616 153.776 273.323 153.776 266.586 151.432Z" fill="#2B146D"/>
<path d="M275.081 149.821C275.081 147.039 276.106 146.014 279.621 145.281C285.186 144.11 293.973 135.03 295.145 129.611C295.731 126.536 296.756 125.51 299.392 125.51C303.346 125.51 303.493 126.682 301.442 134.444C299.538 141.034 293.827 147.039 286.065 150.554C277.864 154.361 275.081 154.068 275.081 149.821Z" fill="#2B146D"/>
<path d="M265.561 150.114C257.507 146.014 254.578 143.231 251.502 136.494C247.841 128.44 247.987 122.289 252.381 113.794C260.143 98.2705 281.818 94.9022 293.241 107.204C299.978 114.38 301.003 115.845 300.27 117.895C299.978 118.774 300.417 119.652 301.296 119.652C302.174 119.652 302.907 121.996 302.907 124.778C302.907 127.561 302.174 129.904 301.296 129.904C300.417 129.904 299.978 131.222 300.417 132.833C300.856 134.444 300.563 135.762 299.685 135.762C298.952 135.762 298.659 136.348 299.099 137.08C299.538 137.812 298.952 138.838 297.634 139.277C296.316 139.863 295.584 140.595 296.17 141.181C296.609 141.62 295.584 142.792 293.68 143.817C291.923 144.696 290.605 146.16 290.751 147.039C290.898 147.918 288.408 148.943 285.332 149.528C282.11 149.968 279.474 151.139 279.474 151.872C279.474 154.215 271.859 153.19 265.561 150.114Z" fill="#1F0E4E"/>
<rect x="1.21729" y="150.407" width="4.39354" height="10.2516" fill="#461EC5"/>
<path d="M462.539 88.1654C506.161 130.726 511.237 166.488 480.113 203.13L462.539 88.1654Z" fill="#2B146D"/>
<circle cx="275.081" cy="125.51" r="27.8257" fill="#1F0E4E"/>
<path d="M222.359 89.6299C196.86 117.609 199.757 132.937 221.627 159.926L222.359 89.6299Z" fill="#36198A"/>
</svg>

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version="1.1"
id="katman_1"
x="0px"
y="0px"
viewBox="0 0 841.89 595.28"
style="enable-background:new 0 0 841.89 595.28;"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs id="defs4" />
<g
id="g4"
style="fill:currentColor">
<polygon
points="557.09,211.99 565.4,538.36 631.96,538.36 640.28,93.18"
id="polygon1"
style="fill:currentColor" />
<polygon
points="640.28,56.91 538.72,56.91 379.35,284.53 430.13,357.05"
id="polygon2"
style="fill:currentColor" />
<polygon
points="201.61,538.36 303.17,538.36 353.96,465.84 303.17,393.31"
id="polygon3"
style="fill:currentColor" />
<polygon
points="201.61,211.99 430.13,538.36 531.69,538.36 303.17,211.99"
id="polygon4"
style="fill:currentColor" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -11,7 +11,7 @@ const String roadmapURL = "https://roadmap.ente.io";
const String kAccountsUrl = "https://accounts.ente.io";
const String githubFeatureRequestUrl =
"https://github.com/ente-io/ente/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+requests%22+label%3A%22-+auth%22+sort%3Atop";
"https://github.com/ente-io/ente/discussions/categories/enhancements?discussions_q=is%3Aopen%+label%3A%22-+auth%22+sort%3Atop";
const int microSecondsInDay = 86400000000;
const int android11SDKINT = 30;
const int galleryLoadStartTime = -8000000000000000; // Wednesday, March 6, 1748

View File

@@ -73,7 +73,10 @@ class AuthenticatorGateway {
);
}
Future<List<AuthEntity>> getDiff(int sinceTime, {int limit = 500}) async {
Future<(List<AuthEntity>, int?)> getDiff(
int sinceTime, {
int limit = 500,
}) async {
try {
final response = await _enteDio.get(
"/authenticator/entity/diff",
@@ -84,11 +87,12 @@ class AuthenticatorGateway {
);
final List<AuthEntity> authEntities = <AuthEntity>[];
final diff = response.data["diff"] as List;
final int? unixTimeInMicroSeconds = response.data["timestamp"] as int?;
for (var entry in diff) {
final AuthEntity entity = AuthEntity.fromMap(entry);
authEntities.add(entity);
}
return authEntities;
return (authEntities, unixTimeInMicroSeconds);
} catch (e) {
if (e is DioException && e.response?.statusCode == 401) {
throw UnauthorizedError();

View File

@@ -173,6 +173,7 @@
"invalidQRCode": "شيفرة استجابة سريعة غير صالحة",
"noRecoveryKeyTitle": "لا يوجد مفتاح استرجاع؟",
"enterEmailHint": "أدخل عنوان البريد الإلكتروني الخاص بك",
"enterNewEmailHint": "أدخل عنوان بريدك الإلكتروني الجديد",
"invalidEmailTitle": "عنوان البريد الإلكتروني غير صالح",
"invalidEmailMessage": "الرجاء إدخال بريد إلكتروني صالح.",
"deleteAccount": "إزالة الحساب",

View File

@@ -88,6 +88,8 @@
"useRecoveryKey": "Gunakan kunci pemulihan",
"incorrectPasswordTitle": "Kata sandi salah",
"welcomeBack": "Selamat datang kembali!",
"emailAlreadyRegistered": "Email sudah terdaftar.",
"emailNotRegistered": "Email belum terdaftar.",
"madeWithLoveAtPrefix": "dibuat dengan ❤️ di ",
"supportDevs": "Berlangganan <bold-green>ente</bold-green> untuk mendukung kami",
"supportDiscount": "Gunakan kode kupon \"AUTH\" untuk mendapatkan potongan 10% untuk tahun pertama",
@@ -171,6 +173,7 @@
"invalidQRCode": "Kode QR tidak valid",
"noRecoveryKeyTitle": "Tidak punya kunci pemulihan?",
"enterEmailHint": "Masukkan alamat email Anda",
"enterNewEmailHint": "Masukkan alamat email baru anda",
"invalidEmailTitle": "Alamat email tidak valid",
"invalidEmailMessage": "Harap masukkan alamat email yang valid.",
"deleteAccount": "Hapus akun",
@@ -501,5 +504,12 @@
"deselectAll": "Batalkan semua pilihan",
"selectAll": "Pilih semua",
"deleteDuplicates": "Hapus duplikat",
"plainHTML": "HTML Sederhana"
"plainHTML": "HTML Sederhana",
"tellUsWhatYouThink": "Berikan pendapatmu",
"dropReviewAndroid": "Berikan ulasan di Play Store",
"advanced": "Lanjutan",
"algorithm": "Algoritma",
"type": "Tipe",
"period": "Periode",
"digits": "Digit"
}

View File

@@ -0,0 +1,523 @@
{
"account": "Налог",
"unlock": "Откључај",
"recoveryKey": "Резервни Кључ",
"counterAppBarTitle": "Бројач",
"@counterAppBarTitle": {
"description": "Text shown in the AppBar of the Counter Page"
},
"onBoardingBody": "Сигурносно правити копију 2ФА кôдова",
"onBoardingGetStarted": "Почети",
"setupFirstAccount": "Подесити свој први налог",
"importScanQrCode": "Скенирај QR кôд",
"qrCode": "QR кôд",
"importEnterSetupKey": "Унети кључ за подешавање",
"importAccountPageTitle": "Унети детаље налога",
"secretCanNotBeEmpty": "Тајна не може бити празна",
"bothIssuerAndAccountCanNotBeEmpty": "И издавалац и рачун не могу бити празни",
"incorrectDetails": "Погрешни детаљи",
"pleaseVerifyDetails": "Проверите детаље и покушајте поново",
"codeIssuerHint": "Издавач",
"codeSecretKeyHint": "Тајни кључ",
"secret": "Тајна",
"all": "Све",
"notes": "Белешке",
"notesLengthLimit": "Белешке могу имати највише {count} знакова",
"@notesLengthLimit": {
"description": "Text to indicate the maximum number of characters allowed for notes",
"placeholders": {
"count": {
"description": "The maximum number of characters allowed for notes",
"type": "int",
"example": "100"
}
}
},
"codeAccountHint": "Налог (you@domain.com)",
"codeTagHint": "Ознака",
"accountKeyType": "Тип кључа",
"sessionExpired": "Сесија је истекла",
"@sessionExpired": {
"description": "Title of the dialog when the users current session is invalid/expired"
},
"pleaseLoginAgain": "Молимо да се поново пријавите",
"loggingOut": "Одјављивање...",
"timeBasedKeyType": "Временски (TOTP)",
"counterBasedKeyType": "На основу бројања (HOTP)",
"saveAction": "Сачувај",
"nextTotpTitle": "следеће",
"deleteCodeTitle": "Обрисати кôд?",
"deleteCodeMessage": "Сигурно желите да избришете овај кôд? Ова акција је неповратна.",
"trashCode": "Кôд у смеће?",
"trashCodeMessage": "Сигурно желите да поставите кôд у смеће за {account}?",
"trash": "Смеће",
"viewLogsAction": "Прегледај извештаје",
"sendLogsDescription": "Ово ће делите ваше записе како би нам помогли да вам исправимо проблем. Док преузмемо мере предострожности да осигурамо да осетљиве информације нису пријављене, охрабрујемо вас да прегледате ове записе пре него што их делите.",
"preparingLogsTitle": "Спремање извештаја...",
"emailLogsTitle": "Имејловати извештаје",
"emailLogsMessage": "Пошаљите извештаје на {email}",
"@emailLogsMessage": {
"placeholders": {
"email": {
"type": "String"
}
}
},
"copyEmailAction": "Копирати имејл",
"exportLogsAction": "Извези изештаје",
"reportABug": "Пријави грешку",
"crashAndErrorReporting": "Пријављивање дања и грешке",
"reportBug": "Пријaви грешку",
"emailUsMessage": "Пошаљите нам имејл на {email}",
"@emailUsMessage": {
"placeholders": {
"email": {
"type": "String"
}
}
},
"contactSupport": "Контактирати подршку",
"rateUsOnStore": "Оцените нас на {storeName}",
"blog": "Блог",
"merchandise": "Роба",
"verifyPassword": "Верификујте лозинку",
"pleaseWait": "Молимо сачекајте...",
"generatingEncryptionKeysTitle": "Генерисање кључева за шифровање...",
"recreatePassword": "Поново креирати лозинку",
"recreatePasswordMessage": "Тренутни уређај није довољно моћан да потврди вашу лозинку, тако да је морамо да регенеришемо једном на начин који ради са свим уређајима. \n\nПријавите се помоћу кључа за опоравак и обновите своју лозинку (можете поново користити исту ако желите).",
"useRecoveryKey": "Користите кључ за опоравак",
"incorrectPasswordTitle": "Неисправна лозинка",
"welcomeBack": "Добродошли назад!",
"emailAlreadyRegistered": "Имејл је већ регистрован.",
"emailNotRegistered": "Имејл није регистрован.",
"madeWithLoveAtPrefix": "урађено са ❤️ на ",
"supportDevs": "Претплатити се на <bold-green>ente</bold-green> да би нас подржали",
"supportDiscount": "Употребите купон \"AUTH\" да би добили попуст од 10% прве године",
"changeEmail": "Промени имејл",
"changePassword": "Промени лозинку",
"data": "Подаци",
"importCodes": "Увоз кôдова",
"importTypePlainText": "Обичан текст",
"importTypeEnteEncrypted": "Ente шифрован извоз",
"passwordForDecryptingExport": "Лозинка за дешифровање извоза",
"passwordEmptyError": "Лозинка не може да буде празна",
"importFromApp": "Увоз кôдова од {appName}",
"importGoogleAuthGuide": "Извезите своје рачуне од Google Authenticator на QR кôд помоћу опције \"Трансфер налоге\". Затим помоћу другог уређаја скенирајте QR кôд.\n\nСавет: можете користити веб камеру вашег лаптопа да бисте снимили слику QR кôда.",
"importSelectJsonFile": "Одабрати JSON датотеку",
"importSelectAppExport": "Одабрати извозну датотеку {appName}-а",
"importEnteEncGuide": "Одабрати шифровану извозну JSON датотеку од Ente",
"importRaivoGuide": "Употребите \"Export OTPs to Zip archive\" опцију из подешавања Raivo-а.\n\nИздвојите zip датотеку и увезите JSON датотеку.",
"importBitwardenGuide": "Употребите \"Извоз Сефа\" из Bitwarden и увезите нешифровану JSON датотеку.",
"importAegisGuide": "Употребити \"Export the vault\" из Aegis-а.\n\nАко је сеф шифрован, мораћете унети лозинку сефа да би га дешифровали.",
"import2FasGuide": "Употребити \"Settings->Backup -Export\" из 2FAS-а.\n\nАко је ваша копија шифрирана, мораћете да унесете лозинку за дешифрирање копије",
"importLastpassGuide": "Употребити \"Transfer accounts\" из Lastpass Authenticator и стисните \"Export accounts to file\". Унесите преузет JSON.",
"exportCodes": "Извоз кôдова",
"importLabel": "Увоз",
"importInstruction": "Изаберите датотеку која садржи списак ваших кôдова у следећем формату",
"importCodeDelimiterInfo": "Кôдови се могу одвојити зарезом или новом линијом",
"selectFile": "Изаберите датотеку",
"emailVerificationToggle": "Имејл провера",
"emailVerificationEnableWarning": "Да бисте избегли да се закључате са свог рачуна, обавезно чувајте копију 2ФА имејла ван Ente Auth пре него што омогућите имејл верификацију.",
"authToChangeEmailVerificationSetting": "Потврдите аутентичност да промените верификацији имејл",
"authenticateGeneric": "Молимо потврдите аутентичност",
"authToViewYourRecoveryKey": "Аутентификујте се да бисте погледали кључ за опоравак",
"authToChangeYourEmail": "Аутентификујте се да бисте променили имејл",
"authToChangeYourPassword": "Аутентификујте се да бисте променили лозинку",
"authToViewSecrets": "Аутентификујте се да бисте прегледали Ваше тајне",
"authToInitiateSignIn": "Аутентификујте се да бисте почели пријављивање за копију.",
"ok": "У реду",
"cancel": "Откажи",
"yes": "Да",
"no": "Не",
"email": "Имејл",
"support": "Подршка",
"general": "Опште",
"settings": "Подешавања",
"copied": "Копирано",
"pleaseTryAgain": "Пробајте поново",
"existingUser": "Постојећи корисник",
"newUser": "Нов у Ente",
"delete": "Обриши",
"enterYourPasswordHint": "Унесите лозинку",
"forgotPassword": "Заборавио сам лозинку",
"oops": "Упс",
"suggestFeatures": "Предложи карактеристике",
"faq": "Питања",
"somethingWentWrongMessage": "Нешто је пошло наопако, покушајте поново",
"leaveFamily": "Напусти family претплату",
"leaveFamilyMessage": "Јесте ли сигурни да желите да напустите family чланство?",
"inFamilyPlanMessage": "Имате family чланство!",
"hintForMobile": "Дуго притисните кôд за уређивање или уклањање.",
"hintForDesktop": "Десни клик на кôд за уређивање или уклањање.",
"scan": "Скенирај",
"scanACode": "Скенирај кôд",
"verify": "Верификуј",
"verifyEmail": "Потврди имејл",
"enterCodeHint": "Унесите 6-цифрени кôд из\nапликације за аутентификацију",
"lostDeviceTitle": "Узгубили сте уређај?",
"twoFactorAuthTitle": "Дво-факторска аутентификација",
"passkeyAuthTitle": "Верификација сигурносном кључем",
"verifyPasskey": "Проверите сигурносни кључ",
"loginWithTOTP": "Пријава са TOTP",
"recoverAccount": "Опоравак налога",
"enterRecoveryKeyHint": "Унети кључ за опоравак",
"recover": "Опорави",
"contactSupportViaEmailMessage": "Послати имејл на {email} са регистрованог имејла",
"@contactSupportViaEmailMessage": {
"placeholders": {
"email": {
"type": "String"
}
}
},
"invalidQRCode": "Неважећи QR кôд",
"noRecoveryKeyTitle": "Немате кључ за опоравак?",
"enterEmailHint": "Унесите Ваш имејл",
"enterNewEmailHint": "Унесите Ваш нови имејл",
"invalidEmailTitle": "Погрешна имејл адреса",
"invalidEmailMessage": "Унесите важећи имејл.",
"deleteAccount": "Избриши налог",
"deleteAccountQuery": "Жао нам је што одлазите. Да ли се суочавате са неком грешком?",
"yesSendFeedbackAction": "Да, послати повратне информације",
"noDeleteAccountAction": "Не, избрисати налог",
"initiateAccountDeleteTitle": "Молимо вас да се аутентификујете за брисање рачуна",
"sendEmail": "Шаљи имејл",
"createNewAccount": "Креирај нови налог",
"weakStrength": "Слабо",
"strongStrength": "Јако",
"moderateStrength": "Умерено",
"confirmPassword": "Потврдите лозинку",
"close": "Затвори",
"oopsSomethingWentWrong": "Нешто није у реду.",
"selectLanguage": "Изабери језик",
"language": "Језик",
"social": "Друштвене мреже",
"security": "Безбедност",
"lockscreen": "Закључавање екрана",
"authToChangeLockscreenSetting": "Аутентификујте се да бисте променили закључавање екрана",
"deviceLockEnablePreSteps": "Да бисте омогућили закључавање уређаја, молимо вас да подесите шифру уређаја или закључавање екрана у системским подешавањима.",
"viewActiveSessions": "Видети активне сесије",
"authToViewYourActiveSessions": "Аутентификујте се да бисте преглеадали активне сесије",
"searchHint": "Претрага...",
"search": "Претрага",
"sorryUnableToGenCode": "Извините, не могу да генеришем кôд за {issuerName}",
"noResult": "Нема резултата",
"addCode": "Додај кôд",
"scanAQrCode": "Скенирај QR кôд",
"enterDetailsManually": "Ручно унети детеље",
"edit": "Уреди",
"share": "Подели",
"shareCodes": "Дели кôдове",
"shareCodesDuration": "Изаберите трајање за које желите да поделите кôдове.",
"restore": "Врати",
"copiedToClipboard": "Копирано у оставу",
"copiedNextToClipboard": "Копирали следећи кôд у остави",
"error": "Грешка",
"recoveryKeyCopiedToClipboard": "Кључ за опоравак копирано у остави",
"recoveryKeyOnForgotPassword": "Ако заборавите лозинку, једини начин на који можете повратити податке је са овим кључем.",
"recoveryKeySaveDescription": "Не чувамо овај кључ, молимо да сачувате кључ од 24 речи на сигурном месту.",
"doThisLater": "Уради то касније",
"saveKey": "Сачувај кључ",
"save": "Сачувај",
"send": "Пошаљи",
"saveOrSendDescription": "Да ли желите да ово сачувате у складиште (фасцикли за преузимање подразумевано) или да га пошаљете другим апликацијама?",
"saveOnlyDescription": "Да ли желите да ово сачувате у складиште (фасцикли за преузимање подразумевано)?",
"back": "Назад",
"createAccount": "Направи налог",
"passwordStrength": "Снага лозинке: {passwordStrengthValue}",
"@passwordStrength": {
"description": "Text to indicate the password strength",
"placeholders": {
"passwordStrengthValue": {
"description": "The strength of the password as a string",
"type": "String",
"example": "Weak or Moderate or Strong"
}
},
"message": "Password Strength: {passwordStrengthText}"
},
"password": "Лозинка",
"signUpTerms": "Прихватам <u-terms>услове сервиса</u-terms> и <u-policy>политику приватности</u-policy>",
"privacyPolicyTitle": "Политика приватности",
"termsOfServicesTitle": "Услови",
"encryption": "Шифровање",
"setPasswordTitle": "Постави лозинку",
"changePasswordTitle": "Промени лозинку",
"resetPasswordTitle": "Ресетуј лозинку",
"encryptionKeys": "Кључеве шифровања",
"passwordWarning": "Не чувамо ову лозинку, па ако је заборавите, <underline>не можемо дешифрирати ваше податке</underline>",
"enterPasswordToEncrypt": "Унесите лозинку за употребу за шифровање ваших података",
"enterNewPasswordToEncrypt": "Унесите нову лозинку за употребу за шифровање ваших података",
"passwordChangedSuccessfully": "Лозинка је успешно промењена",
"generatingEncryptionKeys": "Генерисање кључева за шифровање...",
"continueLabel": "Настави",
"insecureDevice": "Уређај није сигуран",
"sorryWeCouldNotGenerateSecureKeysOnThisDevicennplease": "Извините, не можемо да генеришемо сигурне кључеве на овом уређају.\n\nМолимо пријавите се са другог уређаја.",
"howItWorks": "Како то функционише",
"ackPasswordLostWarning": "Разумем да ако изгубим лозинку, могу изгубити своје податке пошто су <underline>шифрирани од краја до краја</underline>.",
"loginTerms": "Кликом на пријаву, прихватам <u-terms>услове сервиса</u-terms> и <u-policy>политику приватности</u-policy>",
"logInLabel": "Пријави се",
"logout": "Одјави ме",
"areYouSureYouWantToLogout": "Да ли сте сигурни да се одјавите?",
"yesLogout": "Да, одјави ме",
"exit": "Излаз",
"theme": "Тема",
"lightTheme": "Светла",
"darkTheme": "Tamna",
"systemTheme": "Систем",
"verifyingRecoveryKey": "Провера кључа за опоравак...",
"recoveryKeyVerified": "Кључ за опоравак је проверен",
"recoveryKeySuccessBody": "Сјајно! Ваш кључ за опоравак важи. Хвала за проверу.\n\nИмајте на уму да задржите кључ за опоравак на сигрном.",
"invalidRecoveryKey": "Кључ за опоравак који сте унели није валидан. Молимо вас да будете сигурни да садржи 24 речи и проверите правопис сваког.\n\nАко сте унели старији кôд за опоравак, проверите да ли је дугачак 64 знака и проверите сваки од њих.",
"recreatePasswordTitle": "Поново креирати лозинку",
"recreatePasswordBody": "Тренутни уређај није довољно моћан да потврди вашу лозинку, али можемо регенерирати на начин који ради са свим уређајима.\n\nПријавите се помоћу кључа за опоравак и обновите своју лозинку (можете поново користити исту ако желите).",
"invalidKey": "Неисправан кључ",
"tryAgain": "Покушај поново",
"viewRecoveryKey": "Видети кључ за опоравак",
"confirmRecoveryKey": "Потврдити кључ за опоравак",
"recoveryKeyVerifyReason": "Ваш кључ за опоравак је једини начин да се врате фотографије ако заборавите лозинку. Можете пронаћи свој кључ за опоравак у Подешавања> Рачун.\n\nОвдје унесите кључ за опоравак да бисте проверили да ли сте га исправно сачували.",
"confirmYourRecoveryKey": "Потврдити кључ за опоравак",
"confirm": "Потврди",
"emailYourLogs": "Имејлирајте извештаје",
"pleaseSendTheLogsTo": "Пошаљите извештаје на \n{toEmail}",
"copyEmailAddress": "Копирати имејл адресу",
"exportLogs": "Извези изештаје",
"enterYourRecoveryKey": "Унети кључ за опоравак",
"tempErrorContactSupportIfPersists": "Изгледа да је нешто погрешно. Покушајте поново након неког времена. Ако грешка настави, обратите се нашем тиму за подршку.",
"networkHostLookUpErr": "Није могуће повезивање са Ente-ом, молимо вас да проверите мрежне поставке и контактирајте подршку ако грешка и даље постоји.",
"networkConnectionRefusedErr": "Није могуће повезивање са Ente-ом, покушајте поново мало касније. Ако грешка настави, обратите се подршци.",
"itLooksLikeSomethingWentWrongPleaseRetryAfterSome": "Изгледа да је нешто погрешно. Покушајте поново након неког времена. Ако грешка настави, обратите се нашем тиму за подршку.",
"about": "О програму",
"weAreOpenSource": "Користимо отворени извор!",
"privacy": "Приватност",
"terms": "Услови",
"checkForUpdates": "Провери ажурирања",
"checkStatus": "Провери статус",
"downloadUpdate": "Преузми",
"criticalUpdateAvailable": "Критично ажурирање је доступно",
"updateAvailable": "Доступно ажурирање",
"update": "Ажурирај",
"checking": "Провера...",
"youAreOnTheLatestVersion": "Користите најновију верзију",
"warning": "Упозорење",
"exportWarningDesc": "Извозна датотека садржи осетљиве информације. Молимо вас да је чувате на сигурно.",
"iUnderStand": "Разумем",
"@iUnderStand": {
"description": "Text for the button to confirm the user understands the warning"
},
"authToExportCodes": "Аутентификујте се да бисте извезли кôдове",
"importSuccessTitle": "Jeeee!",
"importSuccessDesc": "Увели сте {count} кôдова!",
"@importSuccessDesc": {
"placeholders": {
"count": {
"description": "The number of codes imported",
"type": "int",
"example": "1"
}
}
},
"sorry": "Жао ми је",
"importFailureDesc": "Нисам могао да анализирам изабрану датотеку.\nПишите на support@ente.io ако вам је потребна помоћ!",
"pendingSyncs": "Упозорење",
"pendingSyncsWarningBody": "Неки од ваших кôдова нису сачувани.\n\nМолимо вас осигурајте да имате резервну копију за ове кôдове пре него што се одјавите.",
"checkInboxAndSpamFolder": "Молимо вас да проверите примљену пошту (и нежељену пошту) да бисте довршили верификацију",
"tapToEnterCode": "Пипните да бисте унели кôд",
"resendEmail": "Поново послати имејл",
"weHaveSendEmailTo": "Послали смо имејл на <green>{email}</green>",
"@weHaveSendEmailTo": {
"description": "Text to indicate that we have sent a mail to the user",
"placeholders": {
"email": {
"description": "The email address of the user",
"type": "String",
"example": "example@ente.io"
}
}
},
"manualSort": "Прилагођено",
"editOrder": "Уреди поредак",
"mostFrequentlyUsed": "Често коришћено",
"mostRecentlyUsed": "Недавно коришћено",
"activeSessions": "Активне сесије",
"somethingWentWrongPleaseTryAgain": "Нешто је пошло наопако. Покушајте поново",
"thisWillLogYouOutOfThisDevice": "Ово ће вас одјавити из овог уређаја!",
"thisWillLogYouOutOfTheFollowingDevice": "Ово ће вас одјавити из овог уређаја:",
"terminateSession": "Прекинути сесију?",
"terminate": "Прекини",
"thisDevice": "Овај уређај",
"toResetVerifyEmail": "Да бисте ресетовали лозинку, прво потврдите свој имејл.",
"thisEmailIsAlreadyInUse": "Овај имејл је већ у употреби",
"verificationFailedPleaseTryAgain": "Неуспешна верификација, покушајте поново",
"yourVerificationCodeHasExpired": "Ваш верификациони кôд је истекао",
"incorrectCode": "Погрешан кôд",
"sorryTheCodeYouveEnteredIsIncorrect": "Унет кôд није добар",
"emailChangedTo": "Имејл промењен на {newEmail}",
"authenticationFailedPleaseTryAgain": "Аутентификација није успела, покушајте поново",
"authenticationSuccessful": "Успешна аутентификација!",
"twofactorAuthenticationSuccessfullyReset": "Двофакторска аутентификација успешно рисетирана",
"incorrectRecoveryKey": "Нетачан кључ за опоравак",
"theRecoveryKeyYouEnteredIsIncorrect": "Унети кључ за опоравак је натачан",
"enterPassword": "Унеси лозинку",
"selectExportFormat": "Изабрати формат извоза",
"exportDialogDesc": "Шифровани извоз ће бити заштићен лозинком по вашем избору.",
"encrypted": "Шифровано",
"plainText": "Обичан текст",
"passwordToEncryptExport": "Лозинка за шифровање извоза",
"export": "Извези",
"useOffline": "Користите без резервних копија",
"signInToBackup": "Пријавите се да бисте сачували кôдове",
"singIn": "Пријавите се",
"sigInBackupReminder": "Извезите кôдове да бисте имали резервну копију од које можете да их вратите.",
"offlineModeWarning": "Одлучили сте да наставите без резервних копија. Молимо примите ручне резервне копије да бисте били сигурни да су ваше кодове на сигурном.",
"showLargeIcons": "Прикажи велике иконе",
"compactMode": "Компактни режим",
"shouldHideCode": "Сакриј кодове",
"doubleTapToViewHiddenCode": "Можете да двапут додирнете унос да бисте видели кôд",
"focusOnSearchBar": "Фокус на претрагу на покретање",
"confirmUpdatingkey": "Јесте ли сигурни да желите да ажурирате тајну кључ?",
"minimizeAppOnCopy": "Умањи апликацију после копије",
"editCodeAuthMessage": "Аутентификуј се за уред кôда",
"deleteCodeAuthMessage": "Аутентификуј се за брсање кôда",
"showQRAuthMessage": "Аутентификуј се за приказ QR кôда",
"confirmAccountDeleteTitle": "Потврда брисања рачуна",
"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."
},
"androidBiometricNotRecognized": "Нисмо препознали. Покушати поново.",
"@androidBiometricNotRecognized": {
"description": "Message to let the user know that authentication was failed. It is used on Android side. Maximum 60 characters."
},
"androidBiometricSuccess": "Успех",
"@androidBiometricSuccess": {
"description": "Message to let the user know that authentication was successful. It is used on Android side. Maximum 60 characters."
},
"androidCancelButton": "Откажи",
"@androidCancelButton": {
"description": "Message showed on a button that the user can click to leave the current dialog. It is used on Android side. Maximum 30 characters."
},
"androidSignInTitle": "Потребна аутентификација",
"@androidSignInTitle": {
"description": "Message showed as a title in a dialog which indicates the user that they need to scan biometric to continue. It is used on Android side. Maximum 60 characters."
},
"androidBiometricRequiredTitle": "Потребна је биометрија",
"@androidBiometricRequiredTitle": {
"description": "Message showed as a title in a dialog which indicates the user has not set up biometric authentication on their device. It is used on Android side. Maximum 60 characters."
},
"androidDeviceCredentialsRequiredTitle": "Потребни су акредитиви уређаја",
"@androidDeviceCredentialsRequiredTitle": {
"description": "Message showed as a title in a dialog which indicates the user has not set up credentials authentication on their device. It is used on Android side. Maximum 60 characters."
},
"androidDeviceCredentialsSetupDescription": "Потребни су акредитиви уређаја",
"@androidDeviceCredentialsSetupDescription": {
"description": "Message advising the user to go to the settings and configure device credentials on their device. It shows in a dialog on Android side."
},
"goToSettings": "Иди на поставке",
"@goToSettings": {
"description": "Message showed on a button that the user can click to go to settings pages from the current dialog. It is used on both Android and iOS side. Maximum 30 characters."
},
"androidGoToSettingsDescription": "Биометријска аутентификација није постављена на вашем уређају. Идите на \"Подешавања> Сигурност\" да бисте додали биометријску аутентификацију.",
"@androidGoToSettingsDescription": {
"description": "Message advising the user to go to the settings and configure biometric on their device. It shows in a dialog on Android side."
},
"iOSLockOut": "Биометријска аутентификација је онемогућена. Закључајте и откључите екран да бисте је омогућили.",
"@iOSLockOut": {
"description": "Message advising the user to re-enable biometrics on their device. It shows in a dialog on iOS side."
},
"iOSGoToSettingsDescription": "Биометријска аутентификација није постављена на вашем уређају. Молимо или омогућите Touch ID или Face ID.",
"@iOSGoToSettingsDescription": {
"description": "Message advising the user to go to the settings and configure Biometrics for their device. It shows in a dialog on iOS side."
},
"iOSOkButton": "У реду",
"@iOSOkButton": {
"description": "Message showed on a button that the user can click to leave the current dialog. It is used on iOS side. Maximum 30 characters."
},
"noInternetConnection": "Нема интернет везе",
"pleaseCheckYourInternetConnectionAndTryAgain": "Провери своју везу са интернетом и покушај поново.",
"signOutFromOtherDevices": "Одјави се из других уређаја",
"signOutOtherBody": "Ако мислиш да неко може знати твоју лозинку, можеш приморати одјављивање све остале уређаје које користе твој налог.",
"signOutOtherDevices": "Одјави друге уређаје",
"doNotSignOut": "Не одјави",
"hearUsWhereTitle": "Како сте чули о Ente? (опционо)",
"hearUsExplanation": "Не пратимо инсталацију апликације. Помогло би да нам кажеш како си нас нашао!",
"recoveryKeySaved": "Кључ за опоравак сачуван у фасцикли за преузимање!",
"waitingForBrowserRequest": "Чека се захтев за претраживач...",
"waitingForVerification": "Чека се верификација...",
"passkey": "Кључ за приступ",
"passKeyPendingVerification": "Верификација је још у току",
"loginSessionExpired": "Сесија је истекла",
"loginSessionExpiredDetails": "Ваша сесија је истекла. Молимо пријавите се поново.",
"developerSettingsWarning": "Сигурно желиш да промениш подешавања за програмере?",
"developerSettings": "Подешавања за програмере",
"serverEndpoint": "Крајња тачка сервера",
"invalidEndpoint": "Погрешна крајња тачка",
"invalidEndpointMessage": "Извини, крајња тачка коју си унео је неважећа. Унеси важећу крајњу тачку и покушај поново.",
"endpointUpdatedMessage": "Крајна тачка успешно ажурирана",
"customEndpoint": "Везано за {endpoint}",
"pinText": "Закачи",
"unpinText": "Откачи",
"pinnedCodeMessage": "{code} је прикачен",
"unpinnedCodeMessage": "{code} је одкачен",
"pinned": "Прикачено",
"tags": "Ознаке",
"createNewTag": "Креирај нову ознаку",
"tag": "Ознака",
"create": "Направи",
"editTag": "Уреди ознаку",
"deleteTagTitle": "Обрисати ознаку?",
"deleteTagMessage": "Сигурно желите да избришете ову ознаку? Ова акција је неповратна.",
"somethingWentWrongParsingCode": "Нисмо били у стању да рашчланимо {x} кôдова.",
"updateNotAvailable": "Ажурирање није доступно",
"viewRawCodes": "Погледајте сирове кôдове",
"rawCodes": "Сирове кôдове",
"rawCodeData": "Податак сировог кôда",
"appLock": "Закључавање апликације",
"noSystemLockFound": "Није пронађено ниједно закључавање система",
"toEnableAppLockPleaseSetupDevicePasscodeOrScreen": "Да бисте омогућили закључавање апликације, молимо вас да подесите шифру уређаја или закључавање екрана у системским подешавањима.",
"autoLock": "Ауто-закључавање",
"immediately": "Одмах",
"reEnterPassword": "Поново унеси лозинку",
"reEnterPin": "Поново унеси ПИН",
"next": "Следеће",
"tooManyIncorrectAttempts": "Превише погрешних покушаја",
"tapToUnlock": "Додирните да бисте откључали",
"setNewPassword": "Постави нову лозинку",
"deviceLock": "Закључавање уређаја",
"hideContent": "Сакриј садржај",
"hideContentDescriptionAndroid": "Сакрива садржај апликације у пребацивање апликација и онемогућује снимке екрана",
"hideContentDescriptioniOS": "Сакрива садржај апликације у пребацивање апликација",
"autoLockFeatureDescription": "Време након којег се апликација блокира након што је постављенеа у позадину",
"appLockDescription": "Изаберите између заданог закључавање екрана вашег уређаја и прилагођени екран за закључавање са ПИН-ом или лозинком.",
"pinLock": "ПИН клокирање",
"enterPin": "Унеси ПИН",
"setNewPin": "Постави нови ПИН",
"importFailureDescNew": "Није могао да анализира изабрану датотеку.",
"appLockNotEnabled": "Блокирање апликације није упаљено",
"appLockNotEnabledDescription": "Молимо упалие блокирање апликације на Безбедност > Блокирај апликацију",
"authToViewPasskey": "Аутентификујте се да бисте прегледали кључ",
"appLockOfflineModeWarning": "Одлучили сте да наставите без резервних копија. Ако заборавите лозинку, нећете моћи да приступите својим подацима.",
"duplicateCodes": "Дупликатни кодови",
"noDuplicates": "✨ Нема дупликата",
"youveNoDuplicateCodesThatCanBeCleared": "Немате дупликатне кодове који се могу очистити",
"deduplicateCodes": "Дедуплицирај кодове",
"deselectAll": "Поништи избор свега",
"selectAll": "Изабери све",
"deleteDuplicates": "Обриши дупликате",
"plainHTML": "HTML",
"tellUsWhatYouThink": "Реци нам шта мислиш",
"dropReviewiOS": "Напиши мишљење на App Store",
"dropReviewAndroid": "Напиши мишљење на Play Store",
"supportEnte": "Подржи <bold-green>ente</bold-green>",
"giveUsAStarOnGithub": "Дај нам звездицу на Github",
"free5GB": "5GB бесплатно на <bold-green>ente</bold-green> Photos",
"loginWithAuthAccount": "Пријави се са твојим Auth налогом",
"freeStorageOffer": "Попуст од 10% на <bold-green>ente</bold-green> photos",
"freeStorageOfferDescription": "Употребите кôд \"AUTH\" да би добили попуст од 10% прве године",
"advanced": "Напредно",
"algorithm": "Алгоритам",
"type": "Тип",
"period": "Период",
"digits": "Цифре"
}

View File

@@ -173,6 +173,7 @@
"invalidQRCode": "Geçersiz QR kodu",
"noRecoveryKeyTitle": "Kurtarma anahtarınız yok mu?",
"enterEmailHint": "E-posta adresinizi girin",
"enterNewEmailHint": "Yeni e-posta adresinizi girin",
"invalidEmailTitle": "Geçersiz e-posta adresi",
"invalidEmailMessage": "Lütfen geçerli bir e-posta adresi girin.",
"deleteAccount": "Hesabı sil",

View File

@@ -13,6 +13,7 @@ import 'package:ente_auth/models/authenticator/auth_entity.dart';
import 'package:ente_auth/models/authenticator/auth_key.dart';
import 'package:ente_auth/models/authenticator/entity_result.dart';
import 'package:ente_auth/models/authenticator/local_auth_entity.dart';
import 'package:ente_auth/services/preference_service.dart';
import 'package:ente_auth/store/authenticator_db.dart';
import 'package:ente_auth/store/offline_authenticator_db.dart';
import 'package:ente_crypto_dart/ente_crypto_dart.dart';
@@ -194,8 +195,13 @@ class AuthenticatorService {
final int lastSyncTime = _prefs.getInt(_lastEntitySyncTime) ?? 0;
_logger.info("Current sync is $lastSyncTime");
const int fetchLimit = 500;
final List<AuthEntity> result =
late final List<AuthEntity> result;
late final int? epochTimeInMicroseconds;
(result, epochTimeInMicroseconds) =
await _gateway.getDiff(lastSyncTime, limit: fetchLimit);
PreferenceService.instance
.computeAndStoreTimeOffset(epochTimeInMicroseconds);
_logger.info("${result.length} entries fetched from remote");
if (result.isEmpty) {
return;

View File

@@ -18,6 +18,7 @@ class PreferenceService {
late final SharedPreferences _prefs;
static const kHasShownCoachMarkKey = "has_shown_coach_mark_v2";
static const kLocalTimeOffsetKey = "local_time_offset";
static const kShouldShowLargeIconsKey = "should_show_large_icons";
static const kShouldHideCodesKey = "should_hide_codes";
static const kShouldAutoFocusOnSearchBar = "should_auto_focus_on_search_bar";
@@ -114,4 +115,24 @@ class PreferenceService {
return installedTimeinMillis;
}
}
// localEpochOffsetInMilliSecond returns the local epoch offset in milliseconds.
// This is used to adjust the time for TOTP calculations when device local time is not in sync with actual time.
int timeOffsetInMilliSeconds() {
return _prefs.getInt(kLocalTimeOffsetKey) ?? 0;
}
void computeAndStoreTimeOffset(
int? epochTimeInMicroseconds,
) {
if (epochTimeInMicroseconds == null) {
_prefs.remove(kLocalTimeOffsetKey);
return;
}
int serverEpochTimeInMilliSecond = epochTimeInMicroseconds ~/ 1000;
int localEpochTimeInMilliSecond = DateTime.now().millisecondsSinceEpoch;
int localEpochOffset =
serverEpochTimeInMilliSecond - localEpochTimeInMilliSecond;
_prefs.setInt(kLocalTimeOffsetKey, localEpochOffset);
}
}

View File

@@ -7,10 +7,12 @@ import 'package:flutter/material.dart';
class CodeTimerProgress extends StatefulWidget {
final int period;
final bool isCompactMode;
final int timeOffsetInMilliseconds;
const CodeTimerProgress({
super.key,
required this.period,
this.isCompactMode = false,
this.timeOffsetInMilliseconds = 0,
});
@override
@@ -20,7 +22,7 @@ class CodeTimerProgress extends StatefulWidget {
class _CodeTimerProgressState extends State<CodeTimerProgress> {
late final Timer _timer;
late final ValueNotifier<double> _progress;
late final int _periodInMicros;
late final int _periodInMilii;
// Reduce update frequency
final int _updateIntervalMs =
@@ -29,29 +31,30 @@ class _CodeTimerProgressState extends State<CodeTimerProgress> {
@override
void initState() {
super.initState();
_periodInMicros = widget.period * 1000000;
_periodInMilii = widget.period * 1000;
_progress = ValueNotifier<double>(0.0);
_updateTimeRemaining(DateTime.now().microsecondsSinceEpoch);
_updateTimeRemaining(DateTime.now().millisecondsSinceEpoch);
_timer = Timer.periodic(Duration(milliseconds: _updateIntervalMs), (timer) {
final now = DateTime.now().microsecondsSinceEpoch;
final now = DateTime.now().millisecondsSinceEpoch;
_updateTimeRemaining(now);
});
}
void _updateTimeRemaining(int currentMicros) {
void _updateTimeRemaining(int currentMilliSeconds) {
// More efficient time calculation using modulo
final elapsed = (currentMicros) % _periodInMicros;
final timeRemaining = _periodInMicros - elapsed;
_progress.value = timeRemaining / _periodInMicros;
final elapsed = (currentMilliSeconds + widget.timeOffsetInMilliseconds) %
_periodInMilii;
final timeRemaining = _periodInMilii - elapsed;
_progress.value = timeRemaining / _periodInMilii;
}
@override
void didUpdateWidget(covariant CodeTimerProgress oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.period != widget.period) {
_periodInMicros = widget.period * 1000000;
_updateTimeRemaining(DateTime.now().microsecondsSinceEpoch);
_periodInMilii = widget.period * 1000;
_updateTimeRemaining(DateTime.now().millisecondsSinceEpoch);
}
}

View File

@@ -152,6 +152,8 @@ class _CodeWidgetState extends State<CodeWidget> {
key: ValueKey('period_${widget.code.period}'),
period: widget.code.period,
isCompactMode: widget.isCompactMode,
timeOffsetInMilliseconds:
PreferenceService.instance.timeOffsetInMilliSeconds(),
),
widget.isCompactMode
? const SizedBox(height: 4)

View File

@@ -1,8 +1,14 @@
import 'package:ente_auth/models/code.dart';
import 'package:ente_auth/services/preference_service.dart';
import 'package:flutter/foundation.dart';
import 'package:otp/otp.dart' as otp;
import 'package:steam_totp/steam_totp.dart';
int millisecondsSinceEpoch() {
return DateTime.now().millisecondsSinceEpoch +
PreferenceService.instance.timeOffsetInMilliSeconds();
}
String getOTP(Code code) {
if (code.type == Type.steam || code.issuer.toLowerCase() == 'steam') {
return _getSteamCode(code);
@@ -12,7 +18,7 @@ String getOTP(Code code) {
}
return otp.OTP.generateTOTPCodeString(
getSanitizedSecret(code.secret),
DateTime.now().millisecondsSinceEpoch,
millisecondsSinceEpoch(),
length: code.digits,
interval: code.period,
algorithm: _getAlgorithm(code),
@@ -34,7 +40,7 @@ String _getSteamCode(Code code, [bool isNext = false]) {
final SteamTOTP steamtotp = SteamTOTP(secret: code.secret);
return steamtotp.generate(
DateTime.now().millisecondsSinceEpoch ~/ 1000 + (isNext ? code.period : 0),
millisecondsSinceEpoch() ~/ 1000 + (isNext ? code.period : 0),
);
}
@@ -44,7 +50,7 @@ String getNextTotp(Code code) {
}
return otp.OTP.generateTOTPCodeString(
getSanitizedSecret(code.secret),
DateTime.now().millisecondsSinceEpoch + code.period * 1000,
millisecondsSinceEpoch() + code.period * 1000,
length: code.digits,
interval: code.period,
algorithm: _getAlgorithm(code),
@@ -56,9 +62,7 @@ String getNextTotp(Code code) {
// It returns the start time and a list of future codes.
(int, List<String>) generateFutureTotpCodes(Code code, int count) {
final int startTime =
((DateTime.now().millisecondsSinceEpoch ~/ 1000) ~/ code.period) *
code.period *
1000;
((millisecondsSinceEpoch() ~/ 1000) ~/ code.period) * code.period * 1000;
final String secret = getSanitizedSecret(code.secret);
final List<String> codes = [];
if (code.type == Type.steam || code.issuer.toLowerCase() == 'steam') {

View File

@@ -18,6 +18,7 @@
</screenshot>
</screenshots>
<releases>
<release version="4.4.0" date="2025-05-31" />
<release version="4.3.8" date="2025-05-20" />
<release version="4.2.4" date="2025-01-11" />
<release version="4.0.3" date="2024-10-08" />

View File

@@ -1,7 +1,7 @@
name: ente_auth
description: ente two-factor authenticator
version: 4.3.8+438
version: 4.4.0+440
publish_to: none
environment:

View File

@@ -1,5 +1,9 @@
# CHANGELOG
## v1.7.14 (Unreleased)
- .
## v1.7.13
- Generate streams for videos (beta)

View File

@@ -1,6 +1,6 @@
{
"name": "ente",
"version": "1.7.13",
"version": "1.7.14-beta",
"private": true,
"description": "Desktop client for Ente Photos",
"repository": "github:ente-io/photos-desktop",
@@ -39,25 +39,25 @@
"next-electron-server": "^1.0.0",
"node-stream-zip": "^1.15.0",
"onnxruntime-node": "^1.20.1",
"zod": "^3.25.23"
"zod": "^3.25.51"
},
"devDependencies": {
"@eslint/js": "^9.27.0",
"@eslint/js": "^9.28.0",
"@tsconfig/node22": "^22.0.2",
"@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": "^36.3.2",
"electron": "^36.4.0",
"electron-builder": "^26.0.14",
"eslint": "^9",
"prettier": "3.5.3",
"prettier-plugin-organize-imports": "^4.1.0",
"prettier-plugin-packagejson": "^2.5.14",
"prettier-plugin-packagejson": "^2.5.15",
"shx": "^0.4.0",
"typescript": "^5.8.3",
"typescript-eslint": "^8.32.1"
"typescript-eslint": "^8.33.1"
},
"packageManager": "yarn@1.22.22",
"productName": "ente"

View File

@@ -12,7 +12,7 @@ import fs_ from "node:fs";
import fs from "node:fs/promises";
import path from "node:path";
import { Readable } from "node:stream";
import { z } from "zod";
import { z } from "zod/v4";
import type { FFmpegCommand } from "../../types/ipc";
import log from "../log-worker";
import { messagePortMainEndpoint } from "../utils/comlink";

View File

@@ -15,7 +15,7 @@ import { existsSync } from "fs";
import fs from "node:fs/promises";
import path from "node:path";
import * as ort from "onnxruntime-node";
import { z } from "zod";
import { z } from "zod/v4";
import log from "../log-worker";
import { messagePortMainEndpoint } from "../utils/comlink";
import { wait } from "../utils/common";

View File

@@ -28,6 +28,13 @@ export const createWatcher = (mainWindow: BrowserWindow) => {
// Ask the watcher to wait for a the file size to stabilize before
// telling us about a new file. By default, it waits for 2 seconds.
awaitWriteFinish: true,
// On macOS we start getting "EMFILE: too many open files" when watching
// large folders. This is a known regression in Chokidar v4:
// https://github.com/paulmillr/chokidar/issues/1385
//
// The recommended workaround for now is to enable usePolling. Since it
// comes at a performance cost, we only do it where needed (macOS).
...(process.platform == "darwin" ? { usePolling: true } : {}),
});
watcher

View File

@@ -184,10 +184,10 @@
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.9.1.tgz#4a97e85e982099d6c7ee8410aacb55adaa576f06"
integrity sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==
"@eslint/js@^9.27.0":
version "9.27.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.27.0.tgz#181a23460877c484f6dd03890f4e3fa2fdeb8ff0"
integrity sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==
"@eslint/js@^9.28.0":
version "9.28.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.28.0.tgz#7822ccc2f8cae7c3cd4f902377d520e9ae03f844"
integrity sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==
"@eslint/object-schema@^2.1.4":
version "2.1.4"
@@ -392,62 +392,78 @@
dependencies:
"@types/node" "*"
"@typescript-eslint/eslint-plugin@8.32.1":
version "8.32.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.1.tgz#9185b3eaa3b083d8318910e12d56c68b3c4f45b4"
integrity sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==
"@typescript-eslint/eslint-plugin@8.33.1":
version "8.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz#532641b416ed2afd5be893cddb2a58e9cd1f7a3e"
integrity sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==
dependencies:
"@eslint-community/regexpp" "^4.10.0"
"@typescript-eslint/scope-manager" "8.32.1"
"@typescript-eslint/type-utils" "8.32.1"
"@typescript-eslint/utils" "8.32.1"
"@typescript-eslint/visitor-keys" "8.32.1"
"@typescript-eslint/scope-manager" "8.33.1"
"@typescript-eslint/type-utils" "8.33.1"
"@typescript-eslint/utils" "8.33.1"
"@typescript-eslint/visitor-keys" "8.33.1"
graphemer "^1.4.0"
ignore "^7.0.0"
natural-compare "^1.4.0"
ts-api-utils "^2.1.0"
"@typescript-eslint/parser@8.32.1":
version "8.32.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.32.1.tgz#18b0e53315e0bc22b2619d398ae49a968370935e"
integrity sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==
"@typescript-eslint/parser@8.33.1":
version "8.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.33.1.tgz#ef9a5ee6aa37a6b4f46cc36d08a14f828238afe2"
integrity sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==
dependencies:
"@typescript-eslint/scope-manager" "8.32.1"
"@typescript-eslint/types" "8.32.1"
"@typescript-eslint/typescript-estree" "8.32.1"
"@typescript-eslint/visitor-keys" "8.32.1"
"@typescript-eslint/scope-manager" "8.33.1"
"@typescript-eslint/types" "8.33.1"
"@typescript-eslint/typescript-estree" "8.33.1"
"@typescript-eslint/visitor-keys" "8.33.1"
debug "^4.3.4"
"@typescript-eslint/scope-manager@8.32.1":
version "8.32.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz#9a6bf5fb2c5380e14fe9d38ccac6e4bbe17e8afc"
integrity sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==
"@typescript-eslint/project-service@8.33.1":
version "8.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.33.1.tgz#c85e7d9a44d6a11fe64e73ac1ed47de55dc2bf9f"
integrity sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==
dependencies:
"@typescript-eslint/types" "8.32.1"
"@typescript-eslint/visitor-keys" "8.32.1"
"@typescript-eslint/tsconfig-utils" "^8.33.1"
"@typescript-eslint/types" "^8.33.1"
debug "^4.3.4"
"@typescript-eslint/type-utils@8.32.1":
version "8.32.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.32.1.tgz#b9292a45f69ecdb7db74d1696e57d1a89514d21e"
integrity sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==
"@typescript-eslint/scope-manager@8.33.1":
version "8.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz#d1e0efb296da5097d054bc9972e69878a2afea73"
integrity sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==
dependencies:
"@typescript-eslint/typescript-estree" "8.32.1"
"@typescript-eslint/utils" "8.32.1"
"@typescript-eslint/types" "8.33.1"
"@typescript-eslint/visitor-keys" "8.33.1"
"@typescript-eslint/tsconfig-utils@8.33.1", "@typescript-eslint/tsconfig-utils@^8.33.1":
version "8.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz#7836afcc097a4657a5ed56670851a450d8b70ab8"
integrity sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==
"@typescript-eslint/type-utils@8.33.1":
version "8.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz#d73ee1a29d8a0abe60d4abbff4f1d040f0de15fa"
integrity sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==
dependencies:
"@typescript-eslint/typescript-estree" "8.33.1"
"@typescript-eslint/utils" "8.33.1"
debug "^4.3.4"
ts-api-utils "^2.1.0"
"@typescript-eslint/types@8.32.1":
version "8.32.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.32.1.tgz#b19fe4ac0dc08317bae0ce9ec1168123576c1d4b"
integrity sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==
"@typescript-eslint/types@8.33.1", "@typescript-eslint/types@^8.33.1":
version "8.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.33.1.tgz#b693111bc2180f8098b68e9958cf63761657a55f"
integrity sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==
"@typescript-eslint/typescript-estree@8.32.1":
version "8.32.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.1.tgz#9023720ca4ecf4f59c275a05b5fed69b1276face"
integrity sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==
"@typescript-eslint/typescript-estree@8.33.1":
version "8.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz#d271beed470bc915b8764e22365d4925c2ea265d"
integrity sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==
dependencies:
"@typescript-eslint/types" "8.32.1"
"@typescript-eslint/visitor-keys" "8.32.1"
"@typescript-eslint/project-service" "8.33.1"
"@typescript-eslint/tsconfig-utils" "8.33.1"
"@typescript-eslint/types" "8.33.1"
"@typescript-eslint/visitor-keys" "8.33.1"
debug "^4.3.4"
fast-glob "^3.3.2"
is-glob "^4.0.3"
@@ -455,22 +471,22 @@
semver "^7.6.0"
ts-api-utils "^2.1.0"
"@typescript-eslint/utils@8.32.1":
version "8.32.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.32.1.tgz#4d6d5d29b9e519e9a85e9a74e9f7bdb58abe9704"
integrity sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==
"@typescript-eslint/utils@8.33.1":
version "8.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.33.1.tgz#ea22f40d3553da090f928cf17907e963643d4b96"
integrity sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==
dependencies:
"@eslint-community/eslint-utils" "^4.7.0"
"@typescript-eslint/scope-manager" "8.32.1"
"@typescript-eslint/types" "8.32.1"
"@typescript-eslint/typescript-estree" "8.32.1"
"@typescript-eslint/scope-manager" "8.33.1"
"@typescript-eslint/types" "8.33.1"
"@typescript-eslint/typescript-estree" "8.33.1"
"@typescript-eslint/visitor-keys@8.32.1":
version "8.32.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.1.tgz#4321395cc55c2eb46036cbbb03e101994d11ddca"
integrity sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==
"@typescript-eslint/visitor-keys@8.33.1":
version "8.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz#6c6e002c24d13211df3df851767f24dfdb4f42bc"
integrity sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==
dependencies:
"@typescript-eslint/types" "8.32.1"
"@typescript-eslint/types" "8.33.1"
eslint-visitor-keys "^4.2.0"
"@xmldom/xmldom@^0.8.8":
@@ -1234,10 +1250,10 @@ electron-updater@^6.6.3:
semver "^7.6.3"
tiny-typed-emitter "^2.1.0"
electron@^36.3.2:
version "36.3.2"
resolved "https://registry.yarnpkg.com/electron/-/electron-36.3.2.tgz#4a60f95e8d3858d01570c03b58dc2fb2f17ee8b6"
integrity sha512-v0/j7n22CL3OYv9BIhq6JJz2+e1HmY9H4bjTk8/WzVT9JwVX/T/21YNdR7xuQ6XDSEo9gP5JnqmjOamE+CUY8Q==
electron@^36.4.0:
version "36.4.0"
resolved "https://registry.yarnpkg.com/electron/-/electron-36.4.0.tgz#9463bf5fa7565ae7be3a274f7f6a46359bcfe74d"
integrity sha512-LLOOZEuW5oqvnjC7HBQhIqjIIJAZCIFjQxltQGLfEC7XFsBoZgQ3u3iFj+Kzw68Xj97u1n57Jdt7P98qLvUibQ==
dependencies:
"@electron/get" "^2.0.0"
"@types/node" "^22.7.7"
@@ -2664,13 +2680,13 @@ prettier-plugin-organize-imports@^4.1.0:
resolved "https://registry.yarnpkg.com/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.1.0.tgz#f3d3764046a8e7ba6491431158b9be6ffd83b90f"
integrity sha512-5aWRdCgv645xaa58X8lOxzZoiHAldAPChljr/MT0crXVOWTZ+Svl4hIWlz+niYSlO6ikE5UXkN1JrRvIP2ut0A==
prettier-plugin-packagejson@^2.5.14:
version "2.5.14"
resolved "https://registry.yarnpkg.com/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.5.14.tgz#8ada09114ff60c7f42c3f8755ffb2f8152f3624f"
integrity sha512-h+3tSpr2nVpp+YOK1MDIYtYhHVXr8/0V59UUbJpIJFaqi3w4fvUokJo6eV8W+vELrUXIZzJ+DKm5G7lYzrMcKQ==
prettier-plugin-packagejson@^2.5.15:
version "2.5.15"
resolved "https://registry.yarnpkg.com/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.5.15.tgz#7ea880d4bb1681b5331ea7044efd3d653776f469"
integrity sha512-2QSx6y4IT6LTwXtCvXAopENW5IP/aujC8fobEM2pDbs0IGkiVjW/ipPuYAHuXigbNe64aGWF7vIetukuzM3CBw==
dependencies:
sort-package-json "3.2.1"
synckit "0.11.6"
synckit "0.11.8"
prettier@3.5.3:
version "3.5.3"
@@ -3108,10 +3124,10 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
synckit@0.11.6:
version "0.11.6"
resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.11.6.tgz#e742a0c27bbc1fbc96f2010770521015cca7ed5c"
integrity sha512-2pR2ubZSV64f/vqm9eLPz/KOvR9Dm+Co/5ChLgeHl0yEDRc6h5hXHoxEQH8Y5Ljycozd3p1k5TTSVdzYGkPvLw==
synckit@0.11.8:
version "0.11.8"
resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.11.8.tgz#b2aaae998a4ef47ded60773ad06e7cb821f55457"
integrity sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==
dependencies:
"@pkgr/core" "^0.2.4"
@@ -3235,14 +3251,14 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
typescript-eslint@^8.32.1:
version "8.32.1"
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.32.1.tgz#1784335c781491be528ff84ab666e2f0f7591fd1"
integrity sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==
typescript-eslint@^8.33.1:
version "8.33.1"
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.33.1.tgz#d2d59c9b24afe1f903a855b02145802e4ae930ff"
integrity sha512-AgRnV4sKkWOiZ0Kjbnf5ytTJXMUZQ0qhSVdQtDNYLPLnjsATEYhaO94GlRQwi4t4gO8FfjM6NnikHeKjUm8D7A==
dependencies:
"@typescript-eslint/eslint-plugin" "8.32.1"
"@typescript-eslint/parser" "8.32.1"
"@typescript-eslint/utils" "8.32.1"
"@typescript-eslint/eslint-plugin" "8.33.1"
"@typescript-eslint/parser" "8.33.1"
"@typescript-eslint/utils" "8.33.1"
typescript@^5.4.3, typescript@^5.8.3:
version "5.8.3"
@@ -3405,7 +3421,7 @@ yocto-queue@^0.1.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
zod@^3.25.23:
version "3.25.23"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.23.tgz#128fb02f3619a8bca6bbbf6b07b457236cf33391"
integrity sha512-Od2bdMosahjSrSgJtakrwjMDb1zM1A3VIHCPGveZt/3/wlrTWBya2lmEh2OYe4OIu8mPTmmr0gnLHIWQXdtWBg==
zod@^3.25.51:
version "3.25.51"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.51.tgz#aa2cf648e54f6f060f139cf77b694819f63c9f3a"
integrity sha512-TQSnBldh+XSGL+opiSIq0575wvDPqu09AqWe1F7JhUMKY+M91/aGlK4MhpVNO7MgYfHcVCB1ffwAUTJzllKJqg==

View File

@@ -9,11 +9,11 @@ export default defineConfig({
cleanUrls: true,
ignoreDeadLinks: "localhostLinks",
vite: {
build: {
rollupOptions: {
external: ['client-museum-s3.png'] // Added to handle static asset import
}
}
build: {
rollupOptions: {
external: ["client-museum-s3.png"], // Added to handle static asset import
},
},
},
themeConfig: {
// We use the default theme (with some CSS color overrides). This

View File

@@ -2,6 +2,27 @@
// appropriate place here.
export const sidebar = [
{
text: "Overview",
items: [
{
text: "Introduction",
link: "/overview/",
},
{
text: "Community",
link: "/overview/community",
},
{
text: "Contributing",
link: "/overview/contribute",
},
{
text: "Help",
link: "/overview/help",
},
],
},
{
text: "Photos",
items: [
@@ -292,7 +313,7 @@ export const sidebar = [
},
{
text: "Bucket CORS",
link: '/self-hosting/troubleshooting/bucket-cors'
link: "/self-hosting/troubleshooting/bucket-cors",
},
{
text: "Uploads",
@@ -311,7 +332,7 @@ export const sidebar = [
{
text: "Community Guides",
collapsed: true,
items :[
items: [
{
text: "Ente via Tailscale",
link: "/self-hosting/guides/Tailscale",
@@ -319,8 +340,8 @@ export const sidebar = [
{
text: "Ente with External S3",
link: "/self-hosting/guides/external-s3",
}
]
},
],
},
{
text: "FAQ",
@@ -347,12 +368,4 @@ export const sidebar = [
},
],
},
{
text: "About",
link: "/about/",
},
{
text: "Contribute",
link: "/about/contribute",
},
];

View File

@@ -1,15 +0,0 @@
---
title: Contribute
description: Details about how to contribute to Ente's docs
---
# Contributing
To contribute to these docs, you can use the "Edit this page" button at the
bottom of each page. This will allow you to directly edit the markdown file that
is used to generate this documentation and open a quick pull request directly
from GitHub's UI.
If you're more comfortable in contributing with your text editor, see the
`docs/` folder of our GitHub repository,
[github.com/ente-io/ente](https://github.com/ente-io/ente).

View File

@@ -41,6 +41,16 @@ Usually, this discrepancy occurs because the time in your browser might be
incorrect. In particular, multiple users have reported that Firefox provides
incorrect time when certain privacy settings are enabled.
> [!TIP]
>
> Newer Ente Auth clients (upcoming 4.4.0+) will automatically try to correct
> for incorrect system time, so you should be seeing correct codes even if your
> system time is out of sync. However, this automatic correction will not work
> if you're using Ente Auth in offline mode.
>
> If you've recently changed your system time and the codes are still incorrect,
> try to refresh / restart the app if needed.
### Can I access my codes on web?
You can access your codes on the web at [auth.ente.io](https://auth.ente.io).

View File

@@ -10,8 +10,9 @@ A guide written by Green, an ente.io lover
> [!WARNING]
>
> Authy has dropped all support for its desktop apps. It is no longer possible
> to export data from Authy using methods 1 and 2. You will need either an iOS device
> and computer (method 4) or a rooted Android phone (method 3) to follow this guide.
> to export data from Authy using methods 1 and 2. You will need either an iOS
> device and computer (method 4) or a rooted Android phone (method 3) to follow
> this guide.
---
@@ -204,11 +205,24 @@ This uses the tool [Aegis Authenticator](https://getaegis.app/) from
## Method 4: Authy-iOS-MiTM
**Who should use this?** Technical iOS users of Authy that cannot export their tokens with methods 1 or 2 (due to those methods being patched) or method 3 (due to that method requiring a rooted Android device).
**Who should use this?** Technical iOS users of Authy that cannot export their
tokens with methods 1 or 2 (due to those methods being patched) or method 3 (due
to that method requiring a rooted Android device).
This method works by intercepting the data the Authy app receives while logging in for the first time, which contains your encrypted authenticator tokens. After the encrypted authenticator tokens are dumped, you can decrypt them using your backup password and convert them to an Ente token file.
This method works by intercepting the data the Authy app receives while logging
in for the first time, which contains your encrypted authenticator tokens. After
the encrypted authenticator tokens are dumped, you can decrypt them using your
backup password and convert them to an Ente token file.
For an up-to-date guide of how to retrieve the encrypted authenticator tokens and decrypt them, please see [Authy-iOS-MiTM](https://github.com/AlexTech01/Authy-iOS-MiTM). To convert the `decrypted_tokens.json` file from that guide into a format Ente Authenticator can recognize, use [this](https://gist.github.com/gboudreau/94bb0c11a6209c82418d01a59d958c93?permalink_comment_id=5317087#gistcomment-5317087) Python script. Once you have the `ente_auth_import.plain` file from that script, transfer it to your device and follow the instructions below to import it into Ente Authenticator.
For an up-to-date guide of how to retrieve the encrypted authenticator tokens
and decrypt them, please see
[Authy-iOS-MiTM](https://github.com/AlexTech01/Authy-iOS-MiTM). To convert the
`decrypted_tokens.json` file from that guide into a format Ente Authenticator
can recognize, use
[this](https://gist.github.com/gboudreau/94bb0c11a6209c82418d01a59d958c93?permalink_comment_id=5317087#gistcomment-5317087)
Python script. Once you have the `ente_auth_import.plain` file from that script,
transfer it to your device and follow the instructions below to import it into
Ente Authenticator.
## Importing to Ente Authenticator (Method 1, method 2.1, method 4)

View File

@@ -10,4 +10,4 @@ Ende-zu-Ende-verschlüsselte Authenticator-App für jedermann. Wir sind froh, da
du hier bist!
**Please note that this German translation is currently just a placeholder.**
Know German? [Help us fill this in!](/about/contribute).
Know German? [Help us fill this in!](/overview/contribute).

View File

@@ -11,5 +11,5 @@ Use the **sidebar** menu to navigate to information about the product (Photos or
Auth) you'd like to know more about. Or use the **search** at the top to try and
jump directly to page that might contain the information you need.
To know more about Ente, see [about](/about/) or visit our website
To know more about Ente, see [overview](/overview/) or visit our website
[ente.io](https://ente.io).

View File

@@ -0,0 +1,21 @@
---
title: Community
description: >
Information regarding Ente's community channels
---
# Community
We are building Ente in the open with our community on
[GitHub](https://github.com/ente-io/ente) and [Discord](https://ente.io/discord)
## Blog
To stay up to date with new product launches, and behind the scenes details of
how we're building Ente, you can read our [blog](https://ente.io/blog) (or
subscribe to it via [RSS](https://ente.io/blog/rss.xml))
## Socials
You can also follow us on [Twitter](https://twitter.com/enteio) or toot to us on
[Mastodon](https://mstdn.social/@ente)

View File

@@ -0,0 +1,29 @@
---
title: Contribute
description: Details about how to contribute to Ente
---
# Contributing
There are many ways to contribute to Ente. By spreading the word, engaging with
our community, helping us with translations or documentation.
You can find our contribution guidelines
[here](https://github.com/ente-io/ente/blob/main/CONTRIBUTING.md).
## Suggesting features
To suggest new features and/or offer your perspective on how we should design
(planned and upcoming features), use our
[GitHub discussions](https://github.com/ente-io/ente/discussions)
## Documentation
To contribute to these docs, you can use the "Edit this page" button at the
bottom of each page. This will allow you to directly edit the markdown file that
is used to generate this documentation and open a quick pull request directly
from GitHub's UI.
If you're more comfortable in contributing with your text editor, see the
`docs/` folder of our GitHub repository,
[github.com/ente-io/ente](https://github.com/ente-io/ente).

View File

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 87 KiB

View File

@@ -0,0 +1,13 @@
---
title: Help
description: Get help from Ente via customer support and community
---
# Help
If you encounter any issues with any of the products that's not answered by our
[docs](/), please reach out to our team by sending an email to
[support@ente.io](mailto:support@ente.io)
For community support, please post your queries on
[Discord](https://discord.gg/z2YVKkycX3)

View File

@@ -1,5 +1,5 @@
---
title: About Ente
title: Introduction
description: >
An overview of Ente: the company, and the people behind it, and the products
that we make.
@@ -7,17 +7,17 @@ description: >
# About
Ente is a end-to-end encrypted platform for privately, reliably, and securely
storing your data on the cloud. On top of this platform, Ente offers two
products:
Ente (pronounced en-_tay_. Like ca<i>fe</i>) is a end-to-end encrypted platform
for privately, reliably, and securely storing your data on the cloud. On top of
this platform, Ente offers two products:
- **Ente Photos** - An alternative to Google Photos and Apple Photos
- **Ente Auth** - A free 2FA alternative to Authy
Both these apps are available for all desktop (Linux, Mac, Windows) and mobile
(Android, iOS and F-Droid) platforms. They also work directly in your web
browser without you needing to install anything.
(Android and iOS) platforms. They also work directly in your web browser without
you needing to install anything.
More products are in the pipeline.
@@ -48,25 +48,3 @@ the name, and also led to the adoption of "Ducky", Ente's mascot:
For the full origin story of Ducky you can check out
[this blog post](https://ente.io/blog/ducky/).
### How do I pronounce Ente?
en-_tay_. Like ca<i>fe</i>.
## Get in touch
If you have a support query that is not answered by these docs, please reach out
to our Customer Support by sending an email to support@ente.io
To stay up to date with new product launches, and behind the scenes details of
how we're building Ente, you can read our [blog](https://ente.io/blog) (or
subscribe to it via [RSS](https://ente.io/blog/rss.xml))
To suggest new features and/or offer your perspective on how we should design
planned and upcoming features, use our
[GitHub discussions](https://github.com/ente-io/ente/discussions)
Or if you'd just like to hang out, join our
[Discord](https://discord.gg/z2YVKkycX3), follow us on
[Twitter](https://twitter.com/enteio) or give us a shout out on
[Mastodon](https://mstdn.social/@ente)

View File

@@ -1,6 +1,7 @@
---
title: Desktop app FAQ
description: An assortment of frequently asked questions about Ente Photos desktop app
description:
An assortment of frequently asked questions about Ente Photos desktop app
---
# Desktop app FAQ
@@ -15,7 +16,8 @@ to manually update the software.
### Upload errors
**How do I identify which files experienced upload issues within the desktop app?**
**How do I identify which files experienced upload issues within the desktop
app?**
Check the sections within the upload progress bar for "Failed Uploads," "Ignored
Uploads," and "Unsuccessful Uploads."
@@ -33,6 +35,5 @@ be specific to your distro (e.g. `xdg-desktop-menu forceupdate`).
> [!NOTE]
>
> If you're using an AppImage and not seeing the icon, you'll need to [enable
> AppImage desktop
> integration](/photos/troubleshooting/desktop-install/#appimage-desktop-integration).
> If you're using an AppImage and not seeing the icon, you'll need to
> [enable AppImage desktop integration](/photos/troubleshooting/desktop-install/#appimage-desktop-integration).

View File

@@ -7,9 +7,10 @@ description: Frequently asked questions about keeping extra backups of your data
## How can I backup my data in a local drive outside Ente?
You can use our CLI tool or our desktop app to set up exports of your data
to your local drive. This way, you can use Ente in your day to day use, with an additional guarantee that a copy of your original photos and videos are
always available on your machine.
You can use our CLI tool or our desktop app to set up exports of your data to
your local drive. This way, you can use Ente in your day to day use, with an
additional guarantee that a copy of your original photos and videos are always
available on your machine.
- You can use [Ente's CLI](https://github.com/ente-io/ente/tree/main/cli#export)
to export your data in a cron job to a location of your choice. The exports

View File

@@ -1,7 +1,6 @@
---
title: Face recognition
description:
Frequently asked questions about Ente's face recognition
description: Frequently asked questions about Ente's face recognition
---
# Face recognition

View File

@@ -26,7 +26,6 @@ unsupported file format and we will do our best to help you out.
Yes, we currently do not support files larger than 4 GB.
## Does Ente support videos?
Ente supports backing up and downloading of videos in their original format and
@@ -101,29 +100,53 @@ clicking on "Your map" under "Locations" on the search screen.
## How to reset my password if I lost it?
On the login page, enter your email and click on Forgot Password. Then, enter your recovery key and create a new password.
On the login page, enter your email and click on Forgot Password. Then, enter
your recovery key and create a new password.
# iOS Album Backup and Organization in Ente
## Can I search for photos using the descriptions Ive added?
### How does Ente handle photos that are part of multiple iOS albums?
When you select multiple albums for backup, Ente prioritizes uploading each photo to the album with the fewest photos. This means a photo will only be uploaded once, even if it exists in multiple albums on your device. If you create new albums on your device after the initial backup, those photos may not appear in the corresponding Ente album if they were already uploaded to a different album.
Yes, descriptions are searchable, making it easier to find specific photos
later. To do this, open the photo, tap the (i) button, and enter your
description.
## How does the deduplication feature work on the desktop app?
### Why dont all photos from a new iOS album appear in the corresponding Ente album?
If you create a new album on your device after the initial backup, the photos in that album may have already been uploaded to another album in Ente. To fix this, go to the "On Device" album in Ente, select all photos, and manually add them to the corresponding album in Ente.
If the app finds exact duplicates, it will show them in the deduplication. When
you delete a duplicate, the app keeps one copy and creates a symlink for the
other duplicate. This helps save storage space.
### What happens if I reorganize my photos in the iOS Photos app after backing up?
Reorganizing photos in the iOS Photos app (e.g., moving photos to new albums) wont automatically reflect in Ente. Youll need to manually add those photos to the corresponding albums in Ente to maintain consistency.
## What happens if I lose access to my email address? Can I use my recovery key to bypass email verification?
### Can I search for photos using the descriptions Ive added?
Yes, descriptions are searchable, making it easier to find specific photos later.
To do this, open the photo, tap the (i) button, and enter your description.
### How does the deduplication feature work on the desktop app?
If the app finds exact duplicates, it will show them in the deduplication. When you delete a duplicate, the app keeps one copy and creates a symlink for the other duplicate. This helps save storage space.
### What happens if I lose access to my email address? Can I use my recovery key to bypass email verification?
No, the recovery key does not bypass email verification. For security reasons, we do not disable or bypass email verification unless the account owner reaches out to us and successfully verifies their identity by providing details about their account.
No, the recovery key does not bypass email verification. For security reasons,
we do not disable or bypass email verification unless the account owner reaches
out to us and successfully verifies their identity by providing details about
their account.
If you lose access to your email, please contact our support team at
support@ente.io
---
# iOS Album Backup and Organization in Ente
## How does Ente handle photos that are part of multiple iOS albums?
When you select multiple albums for backup, Ente prioritizes uploading each
photo to the album with the fewest photos. This means a photo will only be
uploaded once, even if it exists in multiple albums on your device. If you
create new albums on your device after the initial backup, those photos may not
appear in the corresponding Ente album if they were already uploaded to a
different album.
## Why dont all photos from a new iOS album appear in the corresponding Ente album?
If you create a new album on your device after the initial backup, the photos in
that album may have already been uploaded to another album in Ente. To fix this,
go to the "On Device" album in Ente, select all photos, and manually add them to
the corresponding album in Ente.
## What happens if I reorganize my photos in the iOS Photos app after backing up?
Reorganizing photos in the iOS Photos app (e.g., moving photos to new albums)
wont automatically reflect in Ente. Youll need to manually add those photos to
the corresponding albums in Ente to maintain consistency.

View File

@@ -62,6 +62,7 @@ the upload time as the photo's creation time.
## Modifications
Ente supports modifications to the following metadata:
- File name
- Date & time
- Location

View File

@@ -1,7 +1,6 @@
---
title: Video streaming FAQ
description:
Frequently asked questions about Ente's video streaming feature
description: Frequently asked questions about Ente's video streaming feature
---
# Video streaming
@@ -78,6 +77,7 @@ generated stream.
While this feature is in beta, we will not count the storage consumed by your
streams against your storage quota. This may change in the future. If it does,
we will provide an option to opt-in to one of the following:
1. Original videos only
2. Compressed streams only
3. Both

View File

@@ -43,8 +43,8 @@ need to disable this "Optimize battery usage" mode in the system settings for
Ente if you wish for Ente to automatically back up your photos in the
background.
On Android versions 15 and later, if an app is in private space and the private
space is locked, Android doesnt allow the app to run any background processes.
On Android versions 15 and later, if an app is in private space and the private
space is locked, Android doesnt allow the app to run any background processes.
As a result, background sync will not work.
### Desktop

View File

@@ -52,6 +52,11 @@ Ente also provides a tool for manual de-duplication in _Settings → Backup →
Remove duplicates_. This is useful if you have an existing library with
duplicates across different albums, but wish to keep only one copy.
During this operation, Ente will discard duplicates across all albums, retain a
single copy, and add symlinks to this copy within all existing albums. So your
existing album structure remains unchanged, while the space consumed by the
duplicate data is freed up.
## Adding to Ente album creates symlinks
Note that once a file is in Ente, adding it to another Ente album will create a

View File

@@ -24,19 +24,19 @@ In brief,
## Storage Limits
If you're an admin of a family, you will be able to set storage limits for the
If you're an admin of a family, you will be able to set storage limits for the
members in your family plan.
In brief,
In brief,
- For example, once you set a limit of 10GB for a member, their Storage
quota for uploading photos will be limited to 10GB.
- For example, once you set a limit of 10GB for a member, their Storage quota
for uploading photos will be limited to 10GB.
- Once the invited member accepts the Family invite, you will be able to see
an edit icon in the Members List. Click on it to setup a family limit.
- Once the invited member accepts the Family invite, you will be able to see an
edit icon in the Members List. Click on it to setup a family limit.
- If the admin has set a limit for any user, that limit value will be prefilled
in the input box.
in the input box.
- If you want to remove any storage limit from a members account, you
can click on the "Remove Limit" and they can upload photos without any limit.
- If you want to remove any storage limit from a members account, you can click
on the "Remove Limit" and they can upload photos without any limit.

View File

@@ -3,7 +3,7 @@ title: Creating accounts
description: Creating accounts on your deployment
---
# Creating accounts
# Creating accounts
Once Ente is up and running, the Ente Photos web app will be accessible on
`http://localhost:3000`. Open this URL in your browser and proceed with creating
@@ -20,7 +20,7 @@ This code can be found in the server logs, which should already be shown in your
quickstart terminal. Alternatively, you can open the server logs with the
following command from inside the `my-ente` folder:
```sh
```sh
sudo docker compose logs
```

View File

@@ -1,10 +1,14 @@
---
title: "Environment Variables and Ports"
description: "Information about all the Environment Variables needed to run Ente"
description:
"Information about all the Environment Variables needed to run Ente"
---
# Environment variables and ports
A self-hosted Ente instance requires specific endpoints in both Museum (the server) and web apps. This document outlines the essential environment variables and port mappings of the web apps.
A self-hosted Ente instance requires specific endpoints in both Museum (the
server) and web apps. This document outlines the essential environment variables
and port mappings of the web apps.
Here's the list of important variables that a self hoster should know about:
@@ -12,34 +16,33 @@ Here's the list of important variables that a self hoster should know about:
1. `NEXT_PUBLIC_ENTE_ENDPOINT`
The above environment variable is used to configure Museums endpoint. Where Museum is
running and which port it is listening on. This endpoint should be configured for
all the apps to connect to your self hosted endpoint.
The above environment variable is used to configure Museums endpoint. Where
Museum is running and which port it is listening on. This endpoint should be
configured for all the apps to connect to your self hosted endpoint.
All the apps (regardless of platform) by default connect to api.ente.io - which is
our production instance of Museum.
All the apps (regardless of platform) by default connect to api.ente.io - which
is our production instance of Museum.
### Web Apps
> [!IMPORTANT]
> Web apps don't need to be configured with the below endpoints. Web app environment
> variables are being documented here just so that the users know everything in detail.
> Checkout [Configuring your Server](/self-hosting/museum) to configure endpoints for
> [!IMPORTANT] Web apps don't need to be configured with the below endpoints.
> Web app environment variables are being documented here just so that the users
> know everything in detail. Checkout
> [Configuring your Server](/self-hosting/museum) to configure endpoints for
> particular app.
In Ente, all the web apps are separate NextJS applications. Therefore, they are all
configured via environment variables. The photos app (Ente Photos) has information
about and connects to other web apps like albums, cast, etc.
In Ente, all the web apps are separate NextJS applications. Therefore, they are
all configured via environment variables. The photos app (Ente Photos) has
information about and connects to other web apps like albums, cast, etc.
1. `NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT`
This environment variable is used to configure and declare the endpoint for the Albums
web app.
This environment variable is used to configure and declare the endpoint for the
Albums web app.
## Ports
The below format is according to how ports are mapped in Docker.
The below format is according to how ports are mapped in Docker.
Typically,`<host>:<container-port>`
1. `8080:8080`: Museum (Ente's server)

View File

@@ -2,39 +2,63 @@
title: Self Hosting with Tailscale (Community)
description: Guides for self-hosting Ente Photos and/or Ente Auth with Tailscale
---
# Guide
This guide aims to achieve self-hosting Ente photos or Ente-Auth with tailscale (TSDPROXY) without exposing any port OR if someone is behind CGNAT and cannot open any port on the internet but want to run their own selfhosted service for themselves, friends and family only.
This guide aims to achieve self-hosting Ente photos or Ente-Auth with tailscale
(TSDPROXY) without exposing any port OR if someone is behind CGNAT and cannot
open any port on the internet but want to run their own selfhosted service for
themselves, friends and family only.
Before getting start keep the following NOTE in mind.
> [!NOTE]
> If someone is behind double or triple CGNAT; must install tailscale system wide by running `curl -fsSL https://tailscale.com/install.sh | sh` in your linux terminal and `sudo tailscale up` otherwise dns resolver will fail and uploading will not work. This is not necessary for those who are not behing CGNAT.
> This guide also work on docker rootless and normal.
> [!NOTE] If someone is behind double or triple CGNAT; must install tailscale
> system wide by running `curl -fsSL https://tailscale.com/install.sh | sh` in
> your linux terminal and `sudo tailscale up` otherwise dns resolver will fail
> and uploading will not work. This is not necessary for those who are not
> behing CGNAT. This guide also work on docker rootless and normal.
> [!CAUTION]
Remember that current docker update 28.0.0 has some bug and cannot connect to external network. Make sure to install docker-ce 27.5.0, docker-ce-rootless-extras 27.5.0 and docker-ce-cli 27.5.0. Hopefully docker 28.1.0 will resolve this issue in next week. Refrence links are [Moby Github Repo Issues 49511](https://github.com/moby/moby/issues/49511) and [Moby Github Repo Issues 49519](https://github.com/moby/moby/issues/49519)
> [!CAUTION] Remember that current docker update 28.0.0 has some bug and cannot
> connect to external network. Make sure to install docker-ce 27.5.0,
> docker-ce-rootless-extras 27.5.0 and docker-ce-cli 27.5.0. Hopefully docker
> 28.1.0 will resolve this issue in next week. Refrence links are
> [Moby Github Repo Issues 49511](https://github.com/moby/moby/issues/49511) and
> [Moby Github Repo Issues 49519](https://github.com/moby/moby/issues/49519)
> [!IMPORTANT]
> For Docker rootless, the user must have local permissions for all directories required by the Ente-photos self-hosted server. This can be achieved by running `sudo chown -R 1000:1000 /home/ubuntu/docker/ente`. In the Linux terminal, you can check the UID with `id -u` or simply `id`. The first user typically has UID 1000.
> To allow listening and pinging on any port without root privileges, create a file called `/etc/sysctl.d/99-rootless.conf` with the following content:
> [!IMPORTANT] For Docker rootless, the user must have local permissions for all
> directories required by the Ente-photos self-hosted server. This can be
> achieved by running `sudo chown -R 1000:1000 /home/ubuntu/docker/ente`. In the
> Linux terminal, you can check the UID with `id -u` or simply `id`. The first
> user typically has UID 1000. To allow listening and pinging on any port
> without root privileges, create a file called `/etc/sysctl.d/99-rootless.conf`
> with the following content:
>
> ```
> net.ipv4.ip_unprivileged_port_start=0
> net.ipv4.ping_group_range = 0 2147483647
> ```
> than run `sudo sysctl --system`.
> Create `~/.config/systemd/user/docker.service.d/override.conf` with the following content:
>
> than run `sudo sysctl --system`. Create
> `~/.config/systemd/user/docker.service.d/override.conf` with the following
> content:
>
> ```
> [Service]
> Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_NET=slirp4netns"
> Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=slirp4netns"
> ```
> and Restart the docker daemon
> `systemctl --user restart docker`
> Instead of `--volume /var/run/docker.sock:/var/run/docker.sock` in TSDPROXY compose.yaml, use `--volume $XDG_RUNTIME_DIR/docker.sock:/var/run/docker.sock`
>
> and Restart the docker daemon `systemctl --user restart docker` Instead of
> `--volume /var/run/docker.sock:/var/run/docker.sock` in TSDPROXY compose.yaml,
> use `--volume $XDG_RUNTIME_DIR/docker.sock:/var/run/docker.sock`
## GETTING START WITH SETUP
First of all create a directory
`sudo mkdir -p /home/ubuntu/docker/tsdproxy/config` than `cd docker/tsdproxy`
and create compose.yaml file by running `sudo nano compose.yaml`. Populate it
with the following:
## GETTING START WITH SETUP ##
First of all create a directory `sudo mkdir -p /home/ubuntu/docker/tsdproxy/config` than `cd docker/tsdproxy` and create compose.yaml file by running `sudo nano compose.yaml`. Populate it with the following:
```
services:
tsdproxy:
@@ -62,9 +86,18 @@ networks:
proxy:
name: proxy
```
Now login into your tailscale account admin counsle > settings > keys > Generate authkey. Give any description and must select resuable, because the key get purged if not selected after rebooting machine. It is advisable to create **Tags** in **ACLs settings** `tag: tsdproxy` `tag: ente` `tag: minio` as well. This will create a tag nodes with no key expirory. One is safe to reboot restart docker or machine.
> Copy the generated authkey as it is shown only once.
Make tsdproxy.yaml file in `cd docker/tsdproxy/config` by running `sudo nano tsdproxy.yaml` and pupolate it with the following contant:
Now login into your tailscale account admin counsle > settings > keys > Generate
authkey. Give any description and must select resuable, because the key get
purged if not selected after rebooting machine. It is advisable to create
**Tags** in **ACLs settings** `tag: tsdproxy` `tag: ente` `tag: minio` as well.
This will create a tag nodes with no key expirory. One is safe to reboot restart
docker or machine.
> Copy the generated authkey as it is shown only once. Make tsdproxy.yaml file
> in `cd docker/tsdproxy/config` by running `sudo nano tsdproxy.yaml` and
> pupolate it with the following contant:
```
defaultproxyprovider: default
docker:
@@ -87,12 +120,20 @@ log:
json: false
proxyaccesslog: true
```
In the same directory run `sudo nano authkey` and paste the authkey just copied earlier from tailscale admin counsel.
> Here Tailscale (TSDPROXY) setup is complet in all respect. Just run `docker compose up -d`. Check your tailscale amdin counsel and you will see tsdproxy node up and running. Make sure that **HTTPS** is enabled in tailscale DNS settings.
> You can visit the TSDPROXY web GUI by https://tsdproxy.xyz.ts.net. (xyz is change value for everyone)
## ente Part ##
In the same directory run `sudo nano authkey` and paste the authkey just copied
earlier from tailscale admin counsel.
> Here Tailscale (TSDPROXY) setup is complet in all respect. Just run
> `docker compose up -d`. Check your tailscale amdin counsel and you will see
> tsdproxy node up and running. Make sure that **HTTPS** is enabled in tailscale
> DNS settings. You can visit the TSDPROXY web GUI by
> https://tsdproxy.xyz.ts.net. (xyz is change value for everyone)
## ente Part
First make the following necessary files/directories:
```
sudo mkdir -p /home/ubuntu/docker/ente/custom-logs
sudo mkdir -p /home/ubuntu/docker/ente/data
@@ -100,9 +141,14 @@ sudo mkdir -p /home/ubuntu/docker/ente/minio-data
sudo mkdir -p /home/ubuntu/docker/ente/postgres-data
sudo mkdir -p /home/ubuntu/docker/ente/scripts/compose
```
Than give user permission for each of the above directory. `sudo chown -R 1000:1000 /home/ubuntu/docker/ente/custom-logs` etc etc. Make sure not to skip `/home/ubuntu/docker/tsdproxy/config`
`cd docker/ente/script/compose` and run `sudo nano credentials.yaml` than populate it with the following:
Than give user permission for each of the above directory.
`sudo chown -R 1000:1000 /home/ubuntu/docker/ente/custom-logs` etc etc. Make
sure not to skip `/home/ubuntu/docker/tsdproxy/config`
`cd docker/ente/script/compose` and run `sudo nano credentials.yaml` than
populate it with the following:
```
db:
host: postgres
@@ -134,7 +180,9 @@ s3:
bucket: scw-eu-fr-v3
```
In the same directory run `sudo nano minio-provision.sh` and populate it with the following contant:
In the same directory run `sudo nano minio-provision.sh` and populate it with
the following contant:
```
#!/bin/sh
@@ -154,7 +202,9 @@ mc mb -p wasabi-eu-central-2-v3
mc mb -p scw-eu-fr-v3
```
Now `cd docker/ente` and run `sudo nano docker-compose.yaml` and populate it with the following:
Now `cd docker/ente` and run `sudo nano docker-compose.yaml` and populate it
with the following:
```
services:
museum:
@@ -255,32 +305,52 @@ services:
networks:
ente:
name: ente
proxy:
external: true
```
> Thats it. Run `docker compose up -d`. Wait till every container become healthy. Open web browser. Make sure tailscale is installed on the machine. Visit https://ente.xyz.ts.net/ping. It will pong. All good if you see it. First time it will take minute or two to get SSL cert. Downnload Desktop or mobile app. Tap 7 time on the screen, which will prompt developer mode. Add https://ente.xyz.ts.net. Add new user. When asked for OTP. Just go to linux terminal and run `docker logs ente-museum-1`. Search for userauth. Feed the six digit and Done.
> Thats it. Run `docker compose up -d`. Wait till every container become
> healthy. Open web browser. Make sure tailscale is installed on the machine.
> Visit https://ente.xyz.ts.net/ping. It will pong. All good if you see it.
> First time it will take minute or two to get SSL cert. Downnload Desktop or
> mobile app. Tap 7 time on the screen, which will prompt developer mode. Add
> https://ente.xyz.ts.net. Add new user. When asked for OTP. Just go to linux
> terminal and run `docker logs ente-museum-1`. Search for userauth. Feed the
> six digit and Done.
> For getting 100TB (limitless) storage. Just Install ente-cli for windows.
> Extract it and add folder. Name it **export**. Add config.yaml file along and
> populate it with the following:
> For getting 100TB (limitless) storage. Just Install ente-cli for windows. Extract it and add folder. Name it **export**. Add config.yaml file along and populate it with the following:
```
endpoint:
api: "https://ente.xyz.ts.net"
accounts: "http://localhost:3001"
log: false
```
Right-Click in the directory where you have extracted ente-cli. Select `open in terminal`. Run
Right-Click in the directory where you have extracted ente-cli. Select
`open in terminal`. Run
```
.\ente.exe account bob # change bob to yours
```
Hit Enter twice.
For export directory, just write export. As already created **export** folder earlier.
**Write email. The one which is already used befor when creating ente account in ente desktop app.**
Type the same Password used before for the account.Run
Hit Enter twice. For export directory, just write export. As already created
**export** folder earlier. **Write email. The one which is already used befor
when creating ente account in ente desktop app.** Type the same Password used
before for the account.Run
```
.\ente.ext account list
```
This will list all account details. Copy Acount ID.
> Navigate to museum.yaml file. `cd docker/ente`. Run `sudo nano museum.yaml` and add the account ID under Admins. Delete any previous entries.
Restart ente-museum-1 container from linux terminal. Run `docker restart ente-museum-1`. All well, now you will have 100TB storage. Repeat if for any other accounts you want to give unlimited storage access.
> Navigate to museum.yaml file. `cd docker/ente`. Run `sudo nano museum.yaml`
> and add the account ID under Admins. Delete any previous entries. Restart
> ente-museum-1 container from linux terminal. Run
> `docker restart ente-museum-1`. All well, now you will have 100TB storage.
> Repeat if for any other accounts you want to give unlimited storage access.

View File

@@ -14,7 +14,7 @@ explicit whitelist of admins.
> [!NOTE]
>
> The first user is only treated as the admin if the list of admins in the
> The first user is only treated as the admin if the list of admins in the
> configuration is empty.
>
> Also, if at some point you delete the first user, then you will need to define
@@ -54,11 +54,10 @@ command to find the user id of any account.
# Administering your custom server
> [!NOTE]
> For the first user (admin) to perform administrative actions using the CLI, their
> userID must be whitelisted in the `museum.yaml` configuration file under
> `internal.admins`. While the first user is automatically granted admin privileges
> on the server, this additional step is required for CLI operations.
> [!NOTE] For the first user (admin) to perform administrative actions using the
> CLI, their userID must be whitelisted in the `museum.yaml` configuration file
> under `internal.admins`. While the first user is automatically granted admin
> privileges on the server, this additional step is required for CLI operations.
You can use
[Ente's CLI](https://github.com/ente-io/ente/releases?q=tag%3Acli-v0) to

View File

@@ -29,7 +29,7 @@ A file upload flows as follows:
The upshot of this is that _both_ the client and museum should be able to reach
your S3 bucket.
## Configuring S3
## Configuring S3
The URL for the S3 bucket is configured in
[scripts/compose/credentials.yaml](https://github.com/ente-io/ente/blob/main/server/scripts/compose/credentials.yaml#L10).
@@ -38,9 +38,8 @@ You can edit this file directly while testing, though it is more robust to
create a `museum.yaml` (in the same folder as the Docker compose file) and to
setup your custom configuration there.
> [!TIP]
> For more details about these configuration objects, see the documentation for
> the `s3` object in
> [!TIP] For more details about these configuration objects, see the
> documentation for the `s3` object in
> [configurations/local.yaml](https://github.com/ente-io/ente/blob/main/server/configurations/local.yaml).
By default, you only need to configure the endpoint for the first bucket.
@@ -56,13 +55,14 @@ components of the setup to communicate with each other seamlessly.
The same principle applies if you're deploying to your custom domain.
## Replication
## Replication
![Replication](/replication.png)
<p align="center">Community contributed diagram of Ente's replication process</p>
> [!IMPORTANT]
>
>
> As of now, replication works only if all the 3 storage type needs are
> fulfilled (1 hot, 1 cold and 1 glacier storage).
>
@@ -72,10 +72,10 @@ If you're wondering why there are 3 buckets on the MinIO UI - that's because our
production instance uses these to perform
[replication](https://ente.io/reliability/).
If you're also wondering about why the bucket names are specifically what they are,
it's because that is exactly what we are using on our production instance.
We use `b2-eu-cen` as hot, `wasabi-eu-central-2-v3` as cold (also the secondary hot)
and `scw-eu-fr-v3` as glacier storage. As of now, all of this is hardcoded.
If you're also wondering about why the bucket names are specifically what they
are, it's because that is exactly what we are using on our production instance.
We use `b2-eu-cen` as hot, `wasabi-eu-central-2-v3` as cold (also the secondary
hot) and `scw-eu-fr-v3` as glacier storage. As of now, all of this is hardcoded.
Hence, the same hardcoded configuration is applied when you self host Ente.
In a self hosted Ente instance replication is turned off by default. When
@@ -84,16 +84,15 @@ other two are ignored. Only the names here are specifically fixed, but in the
configuration body you can put any other keys. It does not have any relation
with `b2`, `wasabi` or even `scaleway`.
Use the `s3.hot_storage.primary` option if you'd like to set one of the other
Use the `s3.hot_storage.primary` option if you'd like to set one of the other
predefined buckets as the primary bucket.
## SSL Configuration
## SSL Configuration
> [!NOTE]
>
> If you need to configure SSL, you'll need to turn off `s3.are_local_buckets`
> (which disables SSL in the default starter compose template).
>
Disabling `s3.are_local_buckets` also switches to the subdomain style URLs for
the buckets. However, not all S3 providers support these. In particular, MinIO
@@ -121,4 +120,4 @@ s3:
endpoint: http://<YOUR-WIFI-IP>:3200
region: eu-central-2
bucket: b2-eu-cen
```
```

View File

@@ -111,5 +111,5 @@ network, you need to use the public IP or hostname.
> [!TIP]
>
> If you're having trouble uploading from your mobile app, it is likely that
> museum is not able to connect to your S3 storage. See the [Configuring
> S3](/self-hosting/guides/configuring-s3) guide for more details.
> museum is not able to connect to your S3 storage. See the
> [Configuring S3](/self-hosting/guides/configuring-s3) guide for more details.

View File

@@ -3,13 +3,12 @@ title: Ente from Source
description: Getting started self hosting Ente Photos and/or Ente Auth
---
# Ente from Source
> [!WARNING] NOTE
> The below documentation will cover instructions about self-hosting the web app manually. If you
> want to deploy Ente hassle free, use the [one line](https://ente.io/blog/self-hosting-quickstart/)
> command to setup Ente. This guide might be deprecated in the near future.
> [!WARNING] NOTE The below documentation will cover instructions about
> self-hosting the web app manually. If you want to deploy Ente hassle free, use
> the [one line](https://ente.io/blog/self-hosting-quickstart/) command to setup
> Ente. This guide might be deprecated in the near future.
## Installing Docker
@@ -63,8 +62,9 @@ apps and configure them to use your
## Web app with Docker and Compose
The instructoins in previous section were just a temporary way to run the web app locally.
To run the web apps as services, the user has to build a docker image manually.
The instructoins in previous section were just a temporary way to run the web
app locally. To run the web apps as services, the user has to build a docker
image manually.
> [!IMPORTANT]
>
@@ -144,7 +144,7 @@ docker build -t <image-name>:<tag> --no-cache --progress plain .
You can always edit the Dockerfile and remove the steps for apps which you do
not intend to install on your system (like auth or cast) and opt out of those.
Regarding Albums App, take a note that they are not apps with navigable pages,
Regarding Albums App, take a note that they are not apps with navigable pages,
if accessed on the web-browser they will simply redirect to ente.web.io.
## compose.yaml
@@ -175,17 +175,17 @@ docker compose up -d # --build
docker compose logs <container-name>
```
## Configure App Endpoints
## Configure App Endpoints
> [!NOTE]
> Previously, this was dependent on the env variables `NEXT_ENTE_PUBLIC_ACCOUNTS_ENDPOINT`
> and etc. Please check the below documentation to update your setup configurations
> [!NOTE] Previously, this was dependent on the env variables
> `NEXT_ENTE_PUBLIC_ACCOUNTS_ENDPOINT` and etc. Please check the below
> documentation to update your setup configurations
You can configure the web endpoints for the other apps including Accounts, Albums
Family and Cast in your `museum.yaml` configuration file. Checkout
You can configure the web endpoints for the other apps including Accounts,
Albums Family and Cast in your `museum.yaml` configuration file. Checkout
[`local.yaml`](https://github.com/ente-io/ente/blob/543411254b2bb55bd00a0e515dcafa12d12d3b35/server/configurations/local.yaml#L76-L89)
to configure the endpoints. Make sure to setup up your DNS Records accordingly to the
similar URL's you set up in `museum.yaml`.
to configure the endpoints. Make sure to setup up your DNS Records accordingly
to the similar URL's you set up in `museum.yaml`.
Next part is to configure the web server.

View File

@@ -5,22 +5,20 @@ description:
server
---
> [!WARNING] NOTE
> This page covers documentation around self-hosting the web app manually. If you
> want to deploy Ente hassle free, please use the [one line](https://ente.io/blog/self-hosting-quickstart/)
> command to setup Ente. This guide might be deprecated in the near future.
> [!WARNING] NOTE This page covers documentation around self-hosting the web app
> manually. If you want to deploy Ente hassle free, please use the
> [one line](https://ente.io/blog/self-hosting-quickstart/) command to setup
> Ente. This guide might be deprecated in the near future.
# Web app
The getting started instructions mention using `yarn dev` (which is an alias of
`yarn dev:photos`) to serve your web app.
>[!IMPORTANT]
> Please note that Ente's Web App supports the Yarn version 1.22.xx or 1.22.22 specifically.
> Make sure to install the right version or modify your yarn installation to meet the requirements.
> The user might end up into unknown version and dependency related errors if yarn
> is on different version.
> [!IMPORTANT] Please note that Ente's Web App supports the Yarn version 1.22.xx
> or 1.22.22 specifically. Make sure to install the right version or modify your
> yarn installation to meet the requirements. The user might end up into unknown
> version and dependency related errors if yarn is on different version.
```sh
cd ente/web
@@ -146,15 +144,15 @@ docker compose logs <container-name>
## Configure App Endpoints
> [!NOTE]
> Previously, this was dependent on the env variables `NEXT_ENTE_PUBLIC_ACCOUNTS_ENDPOINT`
> and etc. Please check the below documentation to update your setup configurations
> [!NOTE] Previously, this was dependent on the env variables
> `NEXT_ENTE_PUBLIC_ACCOUNTS_ENDPOINT` and etc. Please check the below
> documentation to update your setup configurations
You can configure the web endpoints for the other apps including Accounts, Albums
Family and Cast in your `museum.yaml` configuration file. Checkout
You can configure the web endpoints for the other apps including Accounts,
Albums Family and Cast in your `museum.yaml` configuration file. Checkout
[`local.yaml`](https://github.com/ente-io/ente/blob/543411254b2bb55bd00a0e515dcafa12d12d3b35/server/configurations/local.yaml#L76-L89)
to configure the endpoints. Make sure to setup up your DNS Records accordingly to the
similar URL's you set up in `museum.yaml`.
to configure the endpoints. Make sure to setup up your DNS Records accordingly
to the similar URL's you set up in `museum.yaml`.
Next part is to configure the web server.

View File

@@ -16,10 +16,10 @@ If you used our quickstart script, your `my-ente` directory will include a
PostgreSQL and MinIO.
> [!TIP]
>
>
> Always do `docker compose down` inside your `my-ente` directory. If you've
> made changes to `museum.yaml`, restart the containers with `docker compose up
> -d ` to see your changes in action.
> made changes to `museum.yaml`, restart the containers with
> `docker compose up -d ` to see your changes in action.
## S3 buckets
@@ -33,19 +33,20 @@ Check out [Configuring S3](/self-hosting/guides/configuring-s3.md) to understand
more about configuring S3 buckets.
MinIO uses the port `3200` for API Endpoints and their web app runs over
`:3201`. You can login to MinIO Web Console by opening `localhost:3201` in your browser.
`:3201`. You can login to MinIO Web Console by opening `localhost:3201` in your
browser.
If you face any issues related to uploads then checkout [Troubleshooting bucket
CORS](/self-hosting/troubleshooting/bucket-cors) and [Frequently encountered S3
errors](/self-hosting/guides/configuring-s3#frequently-encountered-errors).
If you face any issues related to uploads then checkout
[Troubleshooting bucket CORS](/self-hosting/troubleshooting/bucket-cors) and
[Frequently encountered S3 errors](/self-hosting/guides/configuring-s3#frequently-encountered-errors).
## Web apps
The web apps for Ente Photos is divided into multiple sub-apps like albums,
cast, auth, etc. These endpoints are configurable in the museum.yaml under the
cast, auth, etc. These endpoints are configurable in `museum.yaml` under the
`apps.*` section.
For example,
For example,
```yaml
apps:
@@ -55,17 +56,16 @@ apps:
family: https://family.myente.xyz
```
>[!IMPORTANT]
>By default, all the values redirect to our publicly hosted production services.
>For example, if `public-albums` is not configured your shared album will
>use the `albums.ente.io` URL.
> [!IMPORTANT] By default, all the values redirect to our publicly hosted
> production services. For example, if `public-albums` is not configured your
> shared album will use the `albums.ente.io` URL.
After you are done with filling the values, restart museum and the app will
start utilizing those endpoints instead of Ente's production instances.
Once you have configured all the necessary endpoints, `cd` into `my-ente` and
stop all the Docker containers with `docker compose down` and restart them with
`docker compose up -d`.
`docker compose up -d`.
Similarly, you can use the default
[`local.yaml`](https://github.com/ente-io/ente/tree/main/server/configurations/local.yaml)

View File

@@ -22,28 +22,25 @@ server on your machine.
Setting up a reverse proxy with Caddy is easy and straightforward.
Firstly, install Caddy on your server.
Firstly, install Caddy on your server.
```sh
sudo apt install caddy
```
```
After the installation is complete, a `Caddyfile` is created on the path
`/etc/caddy/`. This file is used to configure reverse proxies among other
things.
```yaml
```yaml
# Caddyfile - myente.xyz is just an example.
api.myente.xyz {
reverse_proxy http://localhost:8080
}
ente.myente.xyz {
reverse_proxy http://localhost:3000
}
api.myente.xyz { reverse_proxy http://localhost:8080 } ente.myente.xyz {
reverse_proxy http://localhost:3000 }
#...and so on for other endpoints
```
After a hard-reload, the Ente Photos web app should be up on https://ente.myente.xyz.
After a hard-reload, the Ente Photos web app should be up on
https://ente.myente.xyz.
If you are using a different tool for reverse proxy (like nginx), please check
out their documentation.

View File

@@ -37,13 +37,21 @@ aws s3api put-bucket-cors --bucket YOUR_S3_BUCKET --cors-configuration /path/to/
## For Self-hosted Minio Instance
> Important: MinIO does not take JSON CORS file as the input, instead you will
> have to build a CORS.xml file or just convert the above `cors.json` to XML.
::: warning
- MinIO does not support bucket CORS in the community edition which is used by
default. For more information, check
[this discussion](https://github.com/minio/minio/discussions/20841). However,
global CORS configuration is possible.
- MinIO does not take JSON CORS file as the input, instead you will have to
build a CORS.xml file or just convert the above `cors.json` to XML.
:::
A minor requirement here is the tool `mc` for managing buckets via command line
interface. Checkout the `mc set alias` document to configure alias for your
instance and bucket. After this you will be prompted for your AccessKey and
Secret, which is your username and password, go ahead and enter that.
Secret, which is your username and password.
```sh
mc cors set <your-minio>/<your-bucket-name /path/to/cors.xml
@@ -59,4 +67,4 @@ mc admin config set <your-minio>/<your-bucket-name> api cors_allow_origin="*"
You can create also `.csv` file and dump the list of origins you would like to
allow and replace the `*` with `path` to the CSV file.
Now, uploads should be working fine.
Now, uploads should be working fine.

View File

@@ -1,5 +1,5 @@
---
title: Docker errors
title: Docker Errors
description: Fixing docker related errors when trying to self host Ente
---
@@ -34,30 +34,30 @@ perform the same configuration by removing the "post_start" hook, and adding a
new service definition:
```yaml
minio-provision:
minio-provision:
image: minio/mc
depends_on:
- minio
- minio
volumes:
- minio-data:/data
- minio-data:/data
networks:
- internal
- internal
entrypoint: |
sh -c '
#!/bin/sh
sh -c '
#!/bin/sh
while ! mc config host add h0 http://minio:3200 changeme changeme1234
do
echo "waiting for minio..."
sleep 0.5
done
while ! mc config host add h0 http://minio:3200 changeme changeme1234
do
echo "waiting for minio..."
sleep 0.5
done
cd /data
cd /data
mc mb -p b2-eu-cen
mc mb -p wasabi-eu-central-2-v3
mc mb -p scw-eu-fr-v3
'
mc mb -p b2-eu-cen
mc mb -p wasabi-eu-central-2-v3
mc mb -p scw-eu-fr-v3
'
```
## start_interval
@@ -114,7 +114,7 @@ volumes.
If you're sure of what you're doing, the volumes can be deleted by
```
```sh
docker volume ls
```
@@ -124,6 +124,13 @@ to list them, and then delete the ones that begin with `my-ente` using
that'll delete all volumes (Ente or otherwise) on your machine that are not
currently in use by a running docker container.
An alternative way is to delete the volumes along with removal of cluster's
containers using `docker compose` inside `my-ente` directory.
```sh
docker compose down --volumes
```
If you're unsure about removing volumes, another alternative is to rename your
`my-ente` folder. Docker uses the folder name to determine the volume name
prefix, so giving it a different name will cause Docker to create a volume

View File

@@ -5,8 +5,8 @@ description: A quick hotfix for keyring errors while running Ente CLI.
# Ente CLI Secrets
Ente CLI makes use of keyring for storing sensitive information like your
passwords. And running the cli straight out of the box might give you some
Ente CLI makes use of system keyring for storing sensitive information like your
passwords. And running the CLI straight out of the box might give you some
errors related to keyrings in some case.
Follow the below steps to run Ente CLI and also avoid keyrings errors.

View File

@@ -3,14 +3,14 @@ title: General troubleshooting cases
description: Fixing various errors when trying to self host Ente
---
## Functionality not working on self hosted
## Functionality not working on self hosted instance
If some specific functionality (e.g. album listing, video playback) does not
work on your self hosted instance, it is possible that you have set _some_, but
not _all_ needed CSP headers (by default, CSP is not enabled).
To expand on it - by default, currently the generated build does not enable CSP
headers. The generated build includes a _headers file that Cloudflare will use
headers. The generated build includes a \_headers file that Cloudflare will use
to set HTTP response headers, but even these do not enable CSP, it is set to a
report only mode.
@@ -18,7 +18,7 @@ However, your web server might be setting some CSP policy. If so, then you will
need to ensure that all necessary CSP headers are set.
You can see the current
[_headers](https://github.com/ente-io/ente/blob/main/web/apps/photos/public/_headers)
[\_headers](https://github.com/ente-io/ente/blob/main/web/apps/photos/public/_headers)
file contents to use a template for your CSP policy. The
`Content-Security-Policy-Report-Only` value will show you the CSP headers in
"dry run" report-only mode we're setting - you can use that as a template,
@@ -28,8 +28,8 @@ How do you know if this is the problem you're facing? The browser console
_might_ be giving you errors when you try to open the page and perform the
corresponding function.
> Refused to load https://subdomain.example.org/... because it does not appear
> in the script-src directive of the Content Security Policy.
> Refused to load https://subdomain.example.org/... because it does not appear
> in the script-src directive of the Content Security Policy.
This is not guaranteed, each browsers handles CSP errors differently, and some
may silently swallow it.

View File

@@ -10,27 +10,27 @@ context and potential fixes.
Fundamentally in most situations, the problem is because of minor mistakes or
misconfiguration. Please make sure to reverse proxy museum and MinIO API
endpoint to a domain and check your S3 credentials and whole configuration
file for any minor misconfigurations.
endpoint to a domain and check your S3 credentials and whole configuration file
for any minor misconfigurations.
It is also suggested that the user setups bucket CORS on MinIO or any external
S3 service provider they are connecting to. To setup bucket CORS, please [read
this](/self-hosting/troubleshooting/bucket-cors).
It is also suggested that the user setups bucket CORS or global CORS on MinIO or
any external S3 service provider they are connecting to. To setup bucket CORS,
please [read this](/self-hosting/troubleshooting/bucket-cors).
## What is S3 and how is it incorporated in Ente ?
S3 is an cloud storage protocol made by Amazon (specifically AWS). S3 is designed to store
files and data as objects inside Buckets and it is mostly used for Online
Backups and storing different types of files.
S3 is an cloud storage protocol made by Amazon (specifically AWS). S3 is
designed to store files and data as objects inside buckets and it is mostly used
for online backups and storing different types of files.
Ente's Docker setup is shipped with [MinIO](https://min.io/) as its default S3 provider.
MinIO supports the Amazon S3 protocol and leverages your disk storage to
dump all the uploaded files as encrypted object blobs.
Ente's Docker setup is shipped with [MinIO](https://min.io/) as its default S3
provider. MinIO supports the Amazon S3 protocol and leverages your disk storage
to dump all the uploaded files as encrypted object blobs.
## 403 Forbidden
If museum is able to make a network connection to your S3 bucket but
uploads are still failing, it could be a credentials or permissions issue.
If museum is able to make a network connection to your S3 bucket but uploads are
still failing, it could be a credentials or permissions issue.
A telltale sign of this is that in the museum logs you can see `403 Forbidden`
errors about it not able to find the size of a file even though the
@@ -41,14 +41,15 @@ This could be because
1. The bucket CORS rules do not allow museum to access these objects. For
uploading files from the browser, you will need to set `allowedOrigins` to
`*`, and allow the `X-Auth-Token`, `X-Client-Package`, `X-Client-Version`
headers configuration too. [Here is an example of a working
configuration](https://github.com/ente-io/ente/discussions/1764#discussioncomment-9478204).
headers configuration too.
[Here is an example of a working configuration](https://github.com/ente-io/ente/discussions/1764#discussioncomment-9478204).
2. The credentials are not being picked up (you might be setting the correct
credentials, but not in the place where museum reads them from).
## Mismatch in file size
The "Mismatch in file size" error mostly occurs in a situation where the client is re-uploading a file which is already in the bucket with a different
file size. The reason for re-upload could be anything including network issue,
sudden killing of app before the upload is complete and etc.
The "Mismatch in file size" error mostly occurs in a situation where the client
is re-uploading a file which is already in the bucket with a different file
size. The reason for re-upload could be anything including network issue, sudden
killing of app before the upload is complete and etc.

View File

@@ -5,8 +5,8 @@ description: Fixing yarn install errors when trying to self host Ente
# Yarn
If your `yarn install` is failing, make sure you are using Yarn v1 (also known
as "Yarn Classic"):
If `yarn install` is failing, make sure you are using Yarn v1 (also known as
"Yarn Classic"):
- https://classic.yarnpkg.com/lang/en/docs/install

View File

@@ -5,7 +5,8 @@
"dev": "vitepress dev docs",
"build": "vitepress build docs",
"preview": "vitepress preview docs",
"pretty": "prettier --write ."
"pretty": "prettier --write .",
"pretty:check": "prettier -c ."
},
"devDependencies": {
"prettier": "^3.3.4",

View File

@@ -22,7 +22,8 @@ const handleOPTIONS = (request: Request) => {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Max-Age": "86400",
"Access-Control-Allow-Headers": "X-Cast-Access-Token",
"Access-Control-Allow-Headers":
"X-Cast-Access-Token, X-Client-Package, X-Client-Version",
},
});
};
@@ -60,8 +61,15 @@ const handleGET = async (request: Request) => {
const pathname = url.pathname;
const params = new URLSearchParams({ castToken });
const headers = {
"X-Client-Package": request.headers.get("X-Client-Package") ?? "",
"X-Client-Version": request.headers.get("X-Client-Version") ?? "",
"User-Agent": request.headers.get("User-Agent") ?? "",
};
let response = await fetch(
`https://api.ente.io/cast/files${pathname}${fileID}?${params.toString()}`,
{ headers },
);
if (!response.ok) console.log("Upstream error", response.status);

View File

@@ -1,6 +1,6 @@
name = "cast-albums"
main = "src/index.ts"
compatibility_date = "2024-06-14"
compatibility_date = "2025-06-03"
routes = [
{ pattern = "cast-albums.ente.io", custom_domain = true }

View File

@@ -21,7 +21,8 @@ const handleOPTIONS = (request: Request) => {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Allow-Headers": "X-Auth-Token, X-Client-Package, X-Client-Version",
"Access-Control-Allow-Headers":
"X-Auth-Token, X-Client-Package, X-Client-Version, Range",
"Access-Control-Max-Age": "86400",
},
});
@@ -71,13 +72,16 @@ const handleGET = async (request: Request) => {
const params = new URLSearchParams();
if (token) params.set("token", token);
const headers = {
"X-Client-Package": request.headers.get("X-Client-Package") ?? "",
"X-Client-Version": request.headers.get("X-Client-Version") ?? "",
"User-Agent": request.headers.get("User-Agent") ?? "",
"Range": request.headers.get("Range") ?? "",
};
let response = await fetch(
`https://api.ente.io/files/download/${fileID}?${params.toString()}`,
{
headers: {
"User-Agent": request.headers.get("User-Agent") ?? "",
},
},
{ headers },
);
if (!response.ok) console.log("Upstream error", response.status);

View File

@@ -1,6 +1,6 @@
name = "files"
main = "src/index.ts"
compatibility_date = "2024-06-14"
compatibility_date = "2025-06-03"
routes = [
{ pattern = "files.ente.io", custom_domain = true }

View File

@@ -2,9 +2,9 @@
"name": "workers",
"private": true,
"devDependencies": {
"@cloudflare/workers-types": "^4.20250519.0",
"@cloudflare/workers-types": "^4.20250603.0",
"typescript": "^5.8.3",
"wrangler": "^4.15.2",
"wrangler": "^4.18.0",
"prettier": "^3.5.3"
},
"workspaces": [

View File

@@ -70,8 +70,15 @@ const handleGET = async (request: Request) => {
if (accessToken) params.set("accessToken", accessToken);
if (accessTokenJWT) params.set("accessTokenJWT", accessTokenJWT);
const headers = {
"X-Client-Package": request.headers.get("X-Client-Package") ?? "",
"X-Client-Version": request.headers.get("X-Client-Version") ?? "",
"User-Agent": request.headers.get("User-Agent") ?? "",
};
let response = await fetch(
`https://api.ente.io/public-collection/files${pathname}${fileID}?${params.toString()}`,
{ headers },
);
if (!response.ok) console.log("Upstream error", response.status);

View File

@@ -1,6 +1,6 @@
name = "public-albums"
main = "src/index.ts"
compatibility_date = "2024-06-14"
compatibility_date = "2025-06-03"
routes = [
{ pattern = "public-albums.ente.io", custom_domain = true }

View File

@@ -21,7 +21,8 @@ const handleOPTIONS = (request: Request) => {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Allow-Headers": "X-Auth-Token, X-Client-Package, X-Client-Version",
"Access-Control-Allow-Headers":
"X-Auth-Token, X-Client-Package, X-Client-Version",
"Access-Control-Max-Age": "86400",
},
});
@@ -64,8 +65,15 @@ const handleGET = async (request: Request) => {
const params = new URLSearchParams();
if (token) params.set("token", token);
const headers = {
"X-Client-Package": request.headers.get("X-Client-Package") ?? "",
"X-Client-Version": request.headers.get("X-Client-Version") ?? "",
"User-Agent": request.headers.get("User-Agent") ?? "",
};
let response = await fetch(
`https://api.ente.io/files/preview/${fileID}?${params.toString()}`,
{ headers },
);
if (!response.ok) console.log("Upstream error", response.status);

View File

@@ -1,6 +1,6 @@
name = "thumbnails"
main = "src/index.ts"
compatibility_date = "2024-06-14"
compatibility_date = "2025-06-03"
routes = [
{ pattern = "thumbnails.ente.io", custom_domain = true }

View File

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

View File

@@ -53,7 +53,7 @@ analyzer:
sort_child_properties_last: warning
sort_pub_dependencies: warning
library_private_types_in_public_api: warning
constant_identifier_names: warning
constant_identifier_names: ignore
prefer_const_constructors: warning
prefer_const_declarations: warning
prefer_const_constructors_in_immutables: warning

View File

@@ -31,7 +31,7 @@ if (keystorePropertiesFile.exists()) {
android {
namespace = "io.ente.photos"
compileSdk = 35
ndkVersion = flutter.ndkVersion
ndkVersion = "28.0.13004108"
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8

View File

@@ -153,6 +153,20 @@
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/memory_widget" />
</receiver>
<receiver android:name="EnteAlbumsWidgetProvider" android:label="Albums" android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/albums_widget" />
</receiver>
<receiver android:name="EntePeopleWidgetProvider" android:label="People" android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/people_widget" />
</receiver>
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" /> <!-- Needed for scheduling notifications -->
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver"> <!-- Needed for scheduling notifications -->
<intent-filter>

View File

@@ -0,0 +1,195 @@
package io.ente.photos
import android.appwidget.AppWidgetManager
import android.content.Context
import android.content.SharedPreferences
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import android.util.Log
import android.view.View
import android.widget.RemoteViews
import androidx.core.content.ContextCompat
import es.antonborri.home_widget.HomeWidgetLaunchIntent
import es.antonborri.home_widget.HomeWidgetProvider
import java.io.File
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
@Serializable
data class AlbumsFileData(
val title: String?,
val subText: String?,
val generatedId: Int?,
val mainKey: String?
)
class EnteAlbumsWidgetProvider : HomeWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray,
widgetData: SharedPreferences
) {
appWidgetIds.forEach { widgetId ->
val views =
RemoteViews(context.packageName, R.layout.albums_widget_layout)
.apply {
val totalAlbums =
widgetData.getInt("totalAlbums", 0)
var randomNumber = -1
var imagePath: String? = null
if (totalAlbums > 0) {
randomNumber =
(0 until totalAlbums!!).random()
imagePath =
widgetData.getString(
"albums_widget_" +
randomNumber,
null
)
}
var imageExists: Boolean = false
if (imagePath != null) {
val imageFile = File(imagePath)
imageExists = imageFile.exists()
}
if (imageExists) {
val data =
widgetData.getString(
"albums_widget_${randomNumber}_data",
null
)
val decoded: AlbumsFileData? =
data?.let {
Json.decodeFromString<
AlbumsFileData>(it)
}
val title = decoded?.title
val subText = decoded?.subText
val generatedId = decoded?.generatedId
val mainKey = decoded?.mainKey
val deepLinkUri =
Uri.parse(
"albumwidget://message?generatedId=${generatedId}&mainKey=${mainKey}&homeWidget"
)
val pendingIntent =
HomeWidgetLaunchIntent.getActivity(
context,
MainActivity::class.java,
deepLinkUri
)
setOnClickPendingIntent(
R.id.widget_container,
pendingIntent
)
Log.d(
"EnteAlbumsWidgetProvider",
"Image exists: $imagePath"
)
setViewVisibility(
R.id.widget_img,
View.VISIBLE
)
setViewVisibility(
R.id.widget_subtitle,
View.VISIBLE
)
setViewVisibility(
R.id.widget_title,
View.VISIBLE
)
setViewVisibility(
R.id.widget_overlay,
View.VISIBLE
)
setViewVisibility(
R.id.widget_placeholder,
View.GONE
)
setViewVisibility(
R.id.widget_placeholder_text,
View.GONE
)
setViewVisibility(
R.id.widget_placeholder_container,
View.GONE
)
val bitmap: Bitmap =
BitmapFactory.decodeFile(imagePath)
setImageViewBitmap(R.id.widget_img, bitmap)
setTextViewText(R.id.widget_title, title)
setTextViewText(
R.id.widget_subtitle,
subText
)
} else {
// Open App on Widget Click
val pendingIntent =
HomeWidgetLaunchIntent.getActivity(
context,
MainActivity::class.java
)
setOnClickPendingIntent(
R.id.widget_container,
pendingIntent
)
Log.d(
"EnteAlbumsWidgetProvider",
"Image doesn't exists"
)
setViewVisibility(
R.id.widget_img,
View.GONE
)
setViewVisibility(
R.id.widget_subtitle,
View.GONE
)
setViewVisibility(
R.id.widget_title,
View.GONE
)
setViewVisibility(
R.id.widget_overlay,
View.GONE
)
setViewVisibility(
R.id.widget_placeholder,
View.VISIBLE
)
setViewVisibility(
R.id.widget_placeholder_text,
View.VISIBLE
)
setViewVisibility(
R.id.widget_placeholder_container,
View.VISIBLE
)
val drawable =
ContextCompat.getDrawable(
context,
R.drawable.ic_albums_widget
)
val bitmap =
(drawable as BitmapDrawable).bitmap
setImageViewBitmap(
R.id.widget_placeholder,
bitmap
)
}
}
appWidgetManager.updateAppWidget(widgetId, views)
}
}
}

View File

@@ -91,10 +91,6 @@ class EnteMemoryWidgetProvider : HomeWidgetProvider() {
R.id.widget_img,
View.VISIBLE
)
setViewVisibility(
R.id.widget_placeholder_container,
View.VISIBLE
)
setViewVisibility(
R.id.widget_subtitle,
View.VISIBLE
@@ -148,10 +144,6 @@ class EnteMemoryWidgetProvider : HomeWidgetProvider() {
R.id.widget_img,
View.GONE
)
setViewVisibility(
R.id.widget_placeholder_container,
View.GONE
)
setViewVisibility(
R.id.widget_subtitle,
View.GONE
@@ -181,7 +173,7 @@ class EnteMemoryWidgetProvider : HomeWidgetProvider() {
ContextCompat.getDrawable(
context,
R.drawable
.ic_home_widget_default
.ic_memories_widget
)
val bitmap =
(drawable as BitmapDrawable).bitmap

View File

@@ -0,0 +1,195 @@
package io.ente.photos
import android.appwidget.AppWidgetManager
import android.content.Context
import android.content.SharedPreferences
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import android.util.Log
import android.view.View
import android.widget.RemoteViews
import androidx.core.content.ContextCompat
import es.antonborri.home_widget.HomeWidgetLaunchIntent
import es.antonborri.home_widget.HomeWidgetProvider
import java.io.File
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
@Serializable
data class PeopleFileData(
val title: String?,
val subText: String?,
val generatedId: Int?,
val mainKey: String?
)
class EntePeopleWidgetProvider : HomeWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray,
widgetData: SharedPreferences
) {
appWidgetIds.forEach { widgetId ->
val views =
RemoteViews(context.packageName, R.layout.people_widget_layout)
.apply {
val totalPeople =
widgetData.getInt("totalPeople", 0)
var randomNumber = -1
var imagePath: String? = null
if (totalPeople > 0) {
randomNumber =
(0 until totalPeople!!).random()
imagePath =
widgetData.getString(
"people_widget_" +
randomNumber,
null
)
}
var imageExists: Boolean = false
if (imagePath != null) {
val imageFile = File(imagePath)
imageExists = imageFile.exists()
}
if (imageExists) {
val data =
widgetData.getString(
"people_widget_${randomNumber}_data",
null
)
val decoded: PeopleFileData? =
data?.let {
Json.decodeFromString<
PeopleFileData>(it)
}
val title = decoded?.title
val subText = decoded?.subText
val generatedId = decoded?.generatedId
val mainKey = decoded?.mainKey
val deepLinkUri =
Uri.parse(
"peoplewidget://message?generatedId=${generatedId}&mainKey=${mainKey}&homeWidget"
)
val pendingIntent =
HomeWidgetLaunchIntent.getActivity(
context,
MainActivity::class.java,
deepLinkUri
)
setOnClickPendingIntent(
R.id.widget_container,
pendingIntent
)
Log.d(
"EntePeopleWidgetProvider",
"Image exists: $imagePath"
)
setViewVisibility(
R.id.widget_img,
View.VISIBLE
)
setViewVisibility(
R.id.widget_subtitle,
View.VISIBLE
)
setViewVisibility(
R.id.widget_title,
View.VISIBLE
)
setViewVisibility(
R.id.widget_overlay,
View.VISIBLE
)
setViewVisibility(
R.id.widget_placeholder,
View.GONE
)
setViewVisibility(
R.id.widget_placeholder_text,
View.GONE
)
setViewVisibility(
R.id.widget_placeholder_container,
View.GONE
)
val bitmap: Bitmap =
BitmapFactory.decodeFile(imagePath)
setImageViewBitmap(R.id.widget_img, bitmap)
setTextViewText(R.id.widget_title, title)
setTextViewText(
R.id.widget_subtitle,
subText
)
} else {
// Open App on Widget Click
val pendingIntent =
HomeWidgetLaunchIntent.getActivity(
context,
MainActivity::class.java
)
setOnClickPendingIntent(
R.id.widget_container,
pendingIntent
)
Log.d(
"EntePeopleWidgetProvider",
"Image doesn't exists"
)
setViewVisibility(
R.id.widget_img,
View.GONE
)
setViewVisibility(
R.id.widget_subtitle,
View.GONE
)
setViewVisibility(
R.id.widget_title,
View.GONE
)
setViewVisibility(
R.id.widget_overlay,
View.GONE
)
setViewVisibility(
R.id.widget_placeholder,
View.VISIBLE
)
setViewVisibility(
R.id.widget_placeholder_text,
View.VISIBLE
)
setViewVisibility(
R.id.widget_placeholder_container,
View.VISIBLE
)
val drawable =
ContextCompat.getDrawable(
context,
R.drawable.ic_people_widget
)
val bitmap =
(drawable as BitmapDrawable).bitmap
setImageViewBitmap(
R.id.widget_placeholder,
bitmap
)
}
}
appWidgetManager.updateAppWidget(widgetId, views)
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

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