Compare commits
912 Commits
auth-v4.3.
...
streaming-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0982e01d7 | ||
|
|
dd52ee7763 | ||
|
|
387e4ae826 | ||
|
|
098ff4e664 | ||
|
|
00a04f18e4 | ||
|
|
b8304f0ec5 | ||
|
|
979fa5e6da | ||
|
|
91f356ceda | ||
|
|
a019aaf5fc | ||
|
|
a9df48ea5d | ||
|
|
be6ce6d639 | ||
|
|
9d421e79a7 | ||
|
|
d1d8144fd1 | ||
|
|
7302f1d4ab | ||
|
|
39788341db | ||
|
|
6c86fe0d53 | ||
|
|
30ed06cfda | ||
|
|
21788c28cf | ||
|
|
2969b5c9a5 | ||
|
|
aa74948f4a | ||
|
|
1bdbfe0580 | ||
|
|
cacf4212c7 | ||
|
|
8f540f23dc | ||
|
|
17d76e50da | ||
|
|
db26923d68 | ||
|
|
4670be9bba | ||
|
|
f8c2f4b9dd | ||
|
|
396065e80c | ||
|
|
5a755d851a | ||
|
|
286a968f65 | ||
|
|
efff97bc71 | ||
|
|
2a73de848c | ||
|
|
c7c8fd65b6 | ||
|
|
8d7eef99ad | ||
|
|
1605b44c6e | ||
|
|
578a92d4bc | ||
|
|
bf3ed6f478 | ||
|
|
92a9698df5 | ||
|
|
342ac3258a | ||
|
|
e4427d7605 | ||
|
|
6f729c01e1 | ||
|
|
0d7c319903 | ||
|
|
6d552f5190 | ||
|
|
06450a0ce0 | ||
|
|
72d6789739 | ||
|
|
3d2d0cc345 | ||
|
|
884246d2ab | ||
|
|
cf25cc40e4 | ||
|
|
7138510e48 | ||
|
|
15e7e0ae9d | ||
|
|
9dcced260f | ||
|
|
2d5dc734aa | ||
|
|
1d93d44180 | ||
|
|
0aeb9f0c82 | ||
|
|
183bbdd145 | ||
|
|
8d701d4fd5 | ||
|
|
c6f6041d24 | ||
|
|
f49ece10e6 | ||
|
|
d0f206741f | ||
|
|
87ff5c5c0b | ||
|
|
b931dac18b | ||
|
|
2b52616ba5 | ||
|
|
e66ee5bcb1 | ||
|
|
f18bcc71d3 | ||
|
|
43a7cb1223 | ||
|
|
ceb25651f2 | ||
|
|
8a8934eacd | ||
|
|
20fea517ce | ||
|
|
0d32bd55dd | ||
|
|
20bbdb131d | ||
|
|
1980cb035e | ||
|
|
bd00c27dc6 | ||
|
|
e8fa86e2ad | ||
|
|
baa72202b2 | ||
|
|
46658a26f3 | ||
|
|
6653b36764 | ||
|
|
c17d0d0087 | ||
|
|
b823a8d6a1 | ||
|
|
e06b20a566 | ||
|
|
8218bfba04 | ||
|
|
8df5831944 | ||
|
|
6e774d6758 | ||
|
|
981c74d3f1 | ||
|
|
18ee3b19f7 | ||
|
|
aa27191ddc | ||
|
|
0883fe1d05 | ||
|
|
17e59de59c | ||
|
|
bdb30d64f0 | ||
|
|
57881f34c3 | ||
|
|
6ef3c01030 | ||
|
|
d4ddc0f919 | ||
|
|
4736ec7e0a | ||
|
|
0840c66a34 | ||
|
|
eb2f6aec68 | ||
|
|
45074f85d9 | ||
|
|
c46c27d21d | ||
|
|
3ff8d04d7b | ||
|
|
437eb246b0 | ||
|
|
5e383f3844 | ||
|
|
9bce8dc878 | ||
|
|
a447d615e0 | ||
|
|
239e6a3158 | ||
|
|
5a72d62555 | ||
|
|
7aa8f6f00f | ||
|
|
5b168021f4 | ||
|
|
a407b1baad | ||
|
|
3589cc5bbf | ||
|
|
0cef0656f3 | ||
|
|
3b3ba721a2 | ||
|
|
d899be6eac | ||
|
|
17c713d3de | ||
|
|
0e9153f4ab | ||
|
|
5484a95bf4 | ||
|
|
2a1c1a30e9 | ||
|
|
f902b7e75c | ||
|
|
ac9f4e3181 | ||
|
|
b68b1a97b5 | ||
|
|
b8de2bf736 | ||
|
|
d35975b26e | ||
|
|
c2ca87d3af | ||
|
|
a41c359ae4 | ||
|
|
e00cdee92b | ||
|
|
a4ade14794 | ||
|
|
b1ce7b6edb | ||
|
|
a5efee1ae3 | ||
|
|
33b56a2257 | ||
|
|
9abdfd2555 | ||
|
|
81ead3e4ce | ||
|
|
95d218b3a1 | ||
|
|
74db8767a2 | ||
|
|
1200dbb6a9 | ||
|
|
8a90eba39a | ||
|
|
562ead3202 | ||
|
|
2c92411596 | ||
|
|
2fd5c703c9 | ||
|
|
15d58e3446 | ||
|
|
677a473d7d | ||
|
|
fb0128369a | ||
|
|
bc4aa85eb1 | ||
|
|
b1d2de712b | ||
|
|
526b5da40f | ||
|
|
1c6efd4985 | ||
|
|
defd88050d | ||
|
|
9e12f35650 | ||
|
|
a7f31119fe | ||
|
|
40959cae09 | ||
|
|
f32874fb05 | ||
|
|
69f9bf35ac | ||
|
|
8204ac3070 | ||
|
|
115c2c7fb3 | ||
|
|
60b7ed52b8 | ||
|
|
e6f72ea1c3 | ||
|
|
967d8c0f3b | ||
|
|
b729b8f0ea | ||
|
|
e3323890df | ||
|
|
fe4b0ded71 | ||
|
|
566364191d | ||
|
|
c1dccf438b | ||
|
|
71e419ac20 | ||
|
|
de8fb95477 | ||
|
|
84c00d0d31 | ||
|
|
d9ed2b4c10 | ||
|
|
db308fa199 | ||
|
|
244599ba67 | ||
|
|
ee8ce50649 | ||
|
|
5f5632aac5 | ||
|
|
5f736aaa10 | ||
|
|
f003b4f8ac | ||
|
|
b933a89336 | ||
|
|
016a476895 | ||
|
|
94c4e1ff0d | ||
|
|
d7ee9615b7 | ||
|
|
bf89a0ca9e | ||
|
|
9f1b4fc23c | ||
|
|
f3feb4cdda | ||
|
|
0b7b4b72f3 | ||
|
|
0380a30705 | ||
|
|
ff72dae408 | ||
|
|
be7cbc2ba0 | ||
|
|
1b0d481b45 | ||
|
|
4ee6ef408e | ||
|
|
9eb887e511 | ||
|
|
5dd5f7e9c5 | ||
|
|
cd7183a9ad | ||
|
|
17b213e380 | ||
|
|
79712182af | ||
|
|
97362ddbf2 | ||
|
|
7621041ce0 | ||
|
|
d58c2a3d49 | ||
|
|
2d4e532186 | ||
|
|
3484f81546 | ||
|
|
54da181256 | ||
|
|
021b6ec9b4 | ||
|
|
b4e01d5ab5 | ||
|
|
78334d2e22 | ||
|
|
9496baaffc | ||
|
|
1feb43d3d4 | ||
|
|
5d6cc892f3 | ||
|
|
27070bbe4c | ||
|
|
556a0d1814 | ||
|
|
5c1d7a0315 | ||
|
|
5b1130ab24 | ||
|
|
96937041f1 | ||
|
|
6f0deba3ed | ||
|
|
ca31a422fa | ||
|
|
8c68af7772 | ||
|
|
42ac508fe7 | ||
|
|
2e52efb15f | ||
|
|
825a9df9fa | ||
|
|
f30e05389b | ||
|
|
e952aa80a5 | ||
|
|
f3d9595953 | ||
|
|
a57232c34b | ||
|
|
5c16ce3459 | ||
|
|
44c64c06a7 | ||
|
|
3bbfa71824 | ||
|
|
970da9f29c | ||
|
|
97bdc9362a | ||
|
|
4881f08790 | ||
|
|
d322f5e1bc | ||
|
|
b87b68e9d4 | ||
|
|
782688c1f7 | ||
|
|
38a35696a3 | ||
|
|
cea9fa84a1 | ||
|
|
bf4807da5b | ||
|
|
dc3f074588 | ||
|
|
282ecf763b | ||
|
|
218c652ed1 | ||
|
|
5b17711b55 | ||
|
|
b3d8e2e865 | ||
|
|
85bf3eebcb | ||
|
|
ceb3046a02 | ||
|
|
d3ebb3a50c | ||
|
|
4a9bc84375 | ||
|
|
2282db7800 | ||
|
|
5abd8b8f04 | ||
|
|
45f1549079 | ||
|
|
01aa679698 | ||
|
|
8da160b834 | ||
|
|
2947ca2e3c | ||
|
|
54d63c9969 | ||
|
|
77be0a18d4 | ||
|
|
627e170304 | ||
|
|
59e26779b9 | ||
|
|
dda46c0639 | ||
|
|
d0e9972547 | ||
|
|
1358087ee7 | ||
|
|
5a0d2ba922 | ||
|
|
d607d8a851 | ||
|
|
8d7950afea | ||
|
|
10ee5989f2 | ||
|
|
7509abd1a9 | ||
|
|
b0966e0cca | ||
|
|
d99d08e8ae | ||
|
|
0a19b8259a | ||
|
|
caf601b49b | ||
|
|
b453ffef85 | ||
|
|
1bb8facc56 | ||
|
|
3fb4d3f7fb | ||
|
|
1ef396b34d | ||
|
|
85b9516fa7 | ||
|
|
12c472ef01 | ||
|
|
726c6dc8e6 | ||
|
|
bebe0f6d53 | ||
|
|
e5303e8f0a | ||
|
|
b4c5a7c747 | ||
|
|
4cc7bbb84a | ||
|
|
837f372d4e | ||
|
|
b9a5f42d95 | ||
|
|
b2d02c6a26 | ||
|
|
e0cbe47052 | ||
|
|
d0a2502a39 | ||
|
|
f4b7ef19ce | ||
|
|
4d70556986 | ||
|
|
dae55c7684 | ||
|
|
2c0b6f6dbc | ||
|
|
e07a24a192 | ||
|
|
be5a29b6de | ||
|
|
5d0a15e9e5 | ||
|
|
27f51a6da4 | ||
|
|
38ae9e2b19 | ||
|
|
8559dd8364 | ||
|
|
2ee79af5b7 | ||
|
|
405e51f228 | ||
|
|
13ca35c0f5 | ||
|
|
b6b724f64f | ||
|
|
afb139a301 | ||
|
|
f65ab4a5a0 | ||
|
|
9309a68010 | ||
|
|
caf1f715e1 | ||
|
|
d193efbe14 | ||
|
|
2156c3a946 | ||
|
|
c20dcdae76 | ||
|
|
698e96c6d6 | ||
|
|
5522121cf6 | ||
|
|
0a9e706b50 | ||
|
|
6c0622ab51 | ||
|
|
2f205112d9 | ||
|
|
edcd784852 | ||
|
|
d13f6db1dc | ||
|
|
b9fb797a15 | ||
|
|
d595a2ec15 | ||
|
|
3936954ee2 | ||
|
|
602881ee26 | ||
|
|
1b83acb262 | ||
|
|
3ec410f932 | ||
|
|
8af2a75c84 | ||
|
|
a041853657 | ||
|
|
85f5939ce6 | ||
|
|
10079d4cb0 | ||
|
|
d363f37592 | ||
|
|
5566d5881b | ||
|
|
6623c4fa7f | ||
|
|
a1b63b8ea4 | ||
|
|
0ce2ac279c | ||
|
|
8fc5a8ad88 | ||
|
|
d48e34cfba | ||
|
|
ebf5a63c04 | ||
|
|
d707b76f91 | ||
|
|
cc6b3897a7 | ||
|
|
56f58e4dbe | ||
|
|
bcd1609fd1 | ||
|
|
35ce21e207 | ||
|
|
c7dc01326f | ||
|
|
4e22fba056 | ||
|
|
22f65ce656 | ||
|
|
c35825f54e | ||
|
|
a3adec3fee | ||
|
|
7d892c5285 | ||
|
|
18e6bde91f | ||
|
|
8922d7e663 | ||
|
|
3ef7dca18f | ||
|
|
768b2f8e66 | ||
|
|
578547fc75 | ||
|
|
91a9ff5dd5 | ||
|
|
b47a5d6a97 | ||
|
|
6249008151 | ||
|
|
d244ce21f0 | ||
|
|
85b545049e | ||
|
|
362ae7f2f3 | ||
|
|
cdf9474788 | ||
|
|
10e61ee7f7 | ||
|
|
54611ff256 | ||
|
|
2908c27ab4 | ||
|
|
21acd608ff | ||
|
|
6902e0a8f7 | ||
|
|
7b8ca828c9 | ||
|
|
426765a1e4 | ||
|
|
e7d36f98a7 | ||
|
|
dd7f5cef92 | ||
|
|
61d0c090b7 | ||
|
|
40edd3ecfd | ||
|
|
d6a626fe0d | ||
|
|
d7af576b7d | ||
|
|
09c7cde958 | ||
|
|
eb34372a21 | ||
|
|
6fc2dc96a5 | ||
|
|
7a5a708714 | ||
|
|
6d842fd1e2 | ||
|
|
8333367633 | ||
|
|
4ef56c3dc9 | ||
|
|
684c538fe8 | ||
|
|
0f6016db00 | ||
|
|
c6a907e9f6 | ||
|
|
5094006712 | ||
|
|
63c3e48a00 | ||
|
|
5a1b88983f | ||
|
|
27beed354e | ||
|
|
73bbf39256 | ||
|
|
1a3d665655 | ||
|
|
02f3afc4cc | ||
|
|
d492a0e695 | ||
|
|
299363c8c4 | ||
|
|
37774c31d7 | ||
|
|
9fe36985d6 | ||
|
|
eee6705e11 | ||
|
|
719ac8539b | ||
|
|
7f1d8dba94 | ||
|
|
92fe34d43f | ||
|
|
a6a77ffb9c | ||
|
|
a638cb1ece | ||
|
|
cf3cfe7275 | ||
|
|
edc39f3fd8 | ||
|
|
85729c9426 | ||
|
|
1e50f52801 | ||
|
|
46c941fb8c | ||
|
|
f11803fd1f | ||
|
|
e3833044e9 | ||
|
|
edfd86628a | ||
|
|
6e0be18500 | ||
|
|
99e5bc5050 | ||
|
|
2b3177d51c | ||
|
|
88abe4dac1 | ||
|
|
e1633eccb7 | ||
|
|
12e441a27b | ||
|
|
c6497dcb5a | ||
|
|
252ae8169d | ||
|
|
70be419562 | ||
|
|
834fcf933b | ||
|
|
6f7e56e796 | ||
|
|
3478720cb3 | ||
|
|
667a544fc2 | ||
|
|
051ea691af | ||
|
|
b7db8e9e77 | ||
|
|
d2e5b87bf7 | ||
|
|
de5ece27f2 | ||
|
|
55871c1f2e | ||
|
|
71a195a4de | ||
|
|
320a397b1c | ||
|
|
a295eb39f7 | ||
|
|
df7ffefdf8 | ||
|
|
5e7ac4437f | ||
|
|
b855d38864 | ||
|
|
23712e6bd3 | ||
|
|
dff5e9f4a6 | ||
|
|
fe58758523 | ||
|
|
26a407cc81 | ||
|
|
7513a84ad2 | ||
|
|
bf70129fb6 | ||
|
|
8083cdfaa6 | ||
|
|
f14f1ab6bb | ||
|
|
914802f057 | ||
|
|
80e41c9882 | ||
|
|
8d9ec328f4 | ||
|
|
fea6d58bd4 | ||
|
|
963ac63898 | ||
|
|
7b704d9ea7 | ||
|
|
46669c623b | ||
|
|
2da115b6b7 | ||
|
|
e74c6fd582 | ||
|
|
4be86c4c00 | ||
|
|
d21f7c1a93 | ||
|
|
a60048a4d0 | ||
|
|
737977358a | ||
|
|
f03fa338b1 | ||
|
|
e3c09d7af0 | ||
|
|
1fb6b3dc89 | ||
|
|
e68fa04a14 | ||
|
|
daf33bcb3a | ||
|
|
154a46b2ef | ||
|
|
584d993bc0 | ||
|
|
ddc4c9d275 | ||
|
|
61b5e0ae60 | ||
|
|
e0789b0d5a | ||
|
|
8e847f12f2 | ||
|
|
52086eb697 | ||
|
|
383b7542c8 | ||
|
|
7e50de6e61 | ||
|
|
82cb806fab | ||
|
|
3e89692ebc | ||
|
|
847cba9a8b | ||
|
|
5ed9ac0578 | ||
|
|
be790b5bc5 | ||
|
|
092640af7e | ||
|
|
f8b9bcf79f | ||
|
|
510768bbd6 | ||
|
|
c59dd66c0d | ||
|
|
be894d0aaa | ||
|
|
aa07b53bbd | ||
|
|
3caeaef2b7 | ||
|
|
5804feedc4 | ||
|
|
cc098346b8 | ||
|
|
2639b88348 | ||
|
|
dd061e6171 | ||
|
|
f874396694 | ||
|
|
ed8a17ffd8 | ||
|
|
3988c9ad9d | ||
|
|
088c52b0df | ||
|
|
ed231c2260 | ||
|
|
b712ac8bf1 | ||
|
|
39a93ea8ef | ||
|
|
18e1745146 | ||
|
|
c5fabbd50b | ||
|
|
d7806d3441 | ||
|
|
0658a5a59f | ||
|
|
5203b764c5 | ||
|
|
d357d9ecbe | ||
|
|
9bddc98827 | ||
|
|
8fb51174ce | ||
|
|
d80093bfed | ||
|
|
8ba43d913a | ||
|
|
bd095f3062 | ||
|
|
7a5d7a5c49 | ||
|
|
7b214c1dc0 | ||
|
|
1047767d90 | ||
|
|
2c20ace110 | ||
|
|
6b9e4b186e | ||
|
|
c3f8e6a11d | ||
|
|
f93dbf0633 | ||
|
|
54cf5dba01 | ||
|
|
748b737f74 | ||
|
|
071ffefffd | ||
|
|
3863591d26 | ||
|
|
d92838d9f2 | ||
|
|
e54027c5dd | ||
|
|
36c06d5501 | ||
|
|
701b7b8f37 | ||
|
|
220e46109d | ||
|
|
4ace6675ce | ||
|
|
f3c5e769fe | ||
|
|
c094a5afb5 | ||
|
|
d1be5e4922 | ||
|
|
8555fed3d6 | ||
|
|
ccca42f757 | ||
|
|
4de5b9b8bb | ||
|
|
da5d81fe91 | ||
|
|
4ad13a2991 | ||
|
|
c7859131b0 | ||
|
|
211171b78a | ||
|
|
e9fd33890e | ||
|
|
ee43a9c14c | ||
|
|
011bfc1e0b | ||
|
|
94cb146b3c | ||
|
|
c48963244d | ||
|
|
03d7d826cf | ||
|
|
ef5babd40c | ||
|
|
01ebe68f09 | ||
|
|
6d02686331 | ||
|
|
d2ffea6cf9 | ||
|
|
ca841dcced | ||
|
|
9933bd5385 | ||
|
|
90e052fa49 | ||
|
|
ad12458774 | ||
|
|
fa00c06cf8 | ||
|
|
b8f475bf2e | ||
|
|
ffc87312d1 | ||
|
|
48f0f62d7c | ||
|
|
9ac2ebfc08 | ||
|
|
c96102c2b8 | ||
|
|
f69dd18364 | ||
|
|
6d2c317877 | ||
|
|
3454536799 | ||
|
|
1ecd688fb8 | ||
|
|
54971cbaf8 | ||
|
|
a892061446 | ||
|
|
f6d4c632c7 | ||
|
|
919f0e2b57 | ||
|
|
388add5984 | ||
|
|
10cba852d7 | ||
|
|
404d1feef6 | ||
|
|
d6e0b85af9 | ||
|
|
58c164d2c2 | ||
|
|
7830f9b1b1 | ||
|
|
23db087b6a | ||
|
|
43b9ae6539 | ||
|
|
efe3240bf4 | ||
|
|
1446f20d69 | ||
|
|
296579b80b | ||
|
|
aea6961676 | ||
|
|
6c33671da7 | ||
|
|
982e0068ee | ||
|
|
256178240d | ||
|
|
9d931e2d8b | ||
|
|
92234752a2 | ||
|
|
1d908cbed6 | ||
|
|
305f727078 | ||
|
|
9244a1799a | ||
|
|
d76c512d96 | ||
|
|
8fbbb3a18c | ||
|
|
1b0ed23df9 | ||
|
|
9230ddba3f | ||
|
|
5f2a1e9386 | ||
|
|
1396ca57db | ||
|
|
0d40c382ac | ||
|
|
c1b73dc18c | ||
|
|
84888df08b | ||
|
|
b43c0f6cc7 | ||
|
|
fb10d78c34 | ||
|
|
5b1365e7d1 | ||
|
|
85bf7bbc48 | ||
|
|
f1bf091faf | ||
|
|
5a639a9c60 | ||
|
|
f1a345d04d | ||
|
|
2988a3983e | ||
|
|
6fd19b3dca | ||
|
|
58fce85696 | ||
|
|
fbde5625b2 | ||
|
|
269660c487 | ||
|
|
dbae45ee44 | ||
|
|
0b76611e11 | ||
|
|
b77ac99bbb | ||
|
|
7cfad45b65 | ||
|
|
a3384adfb0 | ||
|
|
e1e05d4781 | ||
|
|
b8e2b265c3 | ||
|
|
e3ffe3e1f0 | ||
|
|
3c352e9ca2 | ||
|
|
85d50890a6 | ||
|
|
0a4ad32d9c | ||
|
|
1201cfc42d | ||
|
|
528526ac10 | ||
|
|
2049bf769d | ||
|
|
597190e375 | ||
|
|
47a68742d2 | ||
|
|
e1327a5896 | ||
|
|
7a9110cc9b | ||
|
|
f64e62ba61 | ||
|
|
54681d3bde | ||
|
|
749109fc73 | ||
|
|
58f84b2a73 | ||
|
|
86c9b1ef00 | ||
|
|
e98b0f4e10 | ||
|
|
930224a2e5 | ||
|
|
3de324f342 | ||
|
|
2e0dcc17ef | ||
|
|
10e6f797eb | ||
|
|
e8e7744af3 | ||
|
|
e42024c912 | ||
|
|
18cc16bcc0 | ||
|
|
01c2348b6e | ||
|
|
4fd3a269b0 | ||
|
|
5e41952e62 | ||
|
|
37d38a0e6b | ||
|
|
2a5d67b5ca | ||
|
|
1b320000fb | ||
|
|
faed01ca01 | ||
|
|
ec147d57dd | ||
|
|
5250f7f355 | ||
|
|
df769a97ec | ||
|
|
9f14d60b42 | ||
|
|
b70de5cc67 | ||
|
|
95ae2c30ec | ||
|
|
05d83cf390 | ||
|
|
a72ae560c9 | ||
|
|
6980f56cc3 | ||
|
|
48169e9794 | ||
|
|
14fbec6b94 | ||
|
|
a845642cfe | ||
|
|
4b7397c9bf | ||
|
|
bf19e07512 | ||
|
|
e3540b7681 | ||
|
|
6ee6e7f217 | ||
|
|
cb4fcfdd25 | ||
|
|
330a3b4dea | ||
|
|
bf1613d91d | ||
|
|
0f7445b219 | ||
|
|
47914126e5 | ||
|
|
bc7400c0a2 | ||
|
|
c15a7909e8 | ||
|
|
5243515beb | ||
|
|
48db372251 | ||
|
|
9671f4e3fc | ||
|
|
e093a0de61 | ||
|
|
4e7c97a45f | ||
|
|
4fac219e52 | ||
|
|
65ea4f755f | ||
|
|
189f647ffe | ||
|
|
eed50f753b | ||
|
|
0ba76ebbf0 | ||
|
|
78ae7c8595 | ||
|
|
45eff8edb3 | ||
|
|
0498fa644b | ||
|
|
6192ea8b3a | ||
|
|
34b20573b5 | ||
|
|
f39ac3529f | ||
|
|
0869421d9c | ||
|
|
e2876d3d24 | ||
|
|
e0b9b27537 | ||
|
|
cecb7fd4f4 | ||
|
|
68319ca725 | ||
|
|
92a718ca0f | ||
|
|
e4e01cce9e | ||
|
|
a77fe84ea4 | ||
|
|
8e3608c396 | ||
|
|
3f673d409a | ||
|
|
b24b249352 | ||
|
|
662cb8135e | ||
|
|
e7a53f87ca | ||
|
|
5a8d45fa98 | ||
|
|
3a7914e1bf | ||
|
|
6afce67d51 | ||
|
|
edcd916744 | ||
|
|
9fdc1c1baf | ||
|
|
0b60603559 | ||
|
|
c080d16ae7 | ||
|
|
14a806c4ea | ||
|
|
a60f1ec213 | ||
|
|
ba53da4a69 | ||
|
|
79b9b2f84e | ||
|
|
17b2348fca | ||
|
|
6453c3d243 | ||
|
|
0842edc82d | ||
|
|
ab9e1f4a3d | ||
|
|
533e20ad46 | ||
|
|
6d257f04b5 | ||
|
|
f6ca34c6e9 | ||
|
|
96e8b09555 | ||
|
|
bdd7dccd74 | ||
|
|
1e55d61279 | ||
|
|
70877b9103 | ||
|
|
888a604633 | ||
|
|
37172c8291 | ||
|
|
beb09defca | ||
|
|
e23f7fd63e | ||
|
|
93f4e9f2c0 | ||
|
|
495c950386 | ||
|
|
8d29e837cd | ||
|
|
226830acaa | ||
|
|
96a18d9f2b | ||
|
|
548955a803 | ||
|
|
f7896d5a82 | ||
|
|
18ca154578 | ||
|
|
d625816eb3 | ||
|
|
094e08c387 | ||
|
|
f7c8a563a9 | ||
|
|
00c43b10ea | ||
|
|
bcaafe7e33 | ||
|
|
a754fe740f | ||
|
|
26020c2e99 | ||
|
|
9e4c3d826a | ||
|
|
da582a2436 | ||
|
|
208e4cbbab | ||
|
|
fbcba9903e | ||
|
|
d37af17445 | ||
|
|
d8b995c3d6 | ||
|
|
58d5374910 | ||
|
|
90db26c07b | ||
|
|
48de9850e5 | ||
|
|
c4d6323a36 | ||
|
|
bc6ede54f9 | ||
|
|
0c92ed96a6 | ||
|
|
20c6f15a0f | ||
|
|
8407816d14 | ||
|
|
369999e0aa | ||
|
|
9295908dc5 | ||
|
|
b2a21084da | ||
|
|
95a27397d3 | ||
|
|
d9c1a21b0c | ||
|
|
821965308e | ||
|
|
22bec8eee7 | ||
|
|
e77998fd71 | ||
|
|
b6ae571b0b | ||
|
|
b3d8072a38 | ||
|
|
892f130580 | ||
|
|
b25e5a9443 | ||
|
|
55994e472a | ||
|
|
9c23c03f23 | ||
|
|
7dda0ecf81 | ||
|
|
09bfca7aa4 | ||
|
|
7c3fe5d57c | ||
|
|
08c4842f20 | ||
|
|
aea5f78765 | ||
|
|
2bd36b0795 | ||
|
|
13860afbc2 | ||
|
|
a7a21e66a7 | ||
|
|
f0e4678307 | ||
|
|
782ef5eeb0 | ||
|
|
7fc7d365ad | ||
|
|
f98be148dc | ||
|
|
09c29362af | ||
|
|
bed645044b | ||
|
|
07618b8041 | ||
|
|
7e0dc22abe | ||
|
|
d37675cc57 | ||
|
|
c5aaed4361 | ||
|
|
1ac0903561 | ||
|
|
adffe6362a | ||
|
|
2cade6f271 | ||
|
|
ac08d5b37d | ||
|
|
9d1cc2a014 | ||
|
|
167807c758 | ||
|
|
ebd4b89f34 | ||
|
|
6217c3a8f5 | ||
|
|
4d307ded5e | ||
|
|
6e7ced0ecc | ||
|
|
2dad8f6db0 | ||
|
|
9b729fb170 | ||
|
|
7598351211 | ||
|
|
657949d109 | ||
|
|
1d118b07f9 | ||
|
|
a0bb50fc37 | ||
|
|
29e77245d7 | ||
|
|
a0a001e8e7 | ||
|
|
d6c58bc9ca | ||
|
|
65ed594574 | ||
|
|
f3952fad49 | ||
|
|
09b88e5bab | ||
|
|
bfdd111dc1 | ||
|
|
a2166308d2 | ||
|
|
29f4bbb0de | ||
|
|
f235da8a05 | ||
|
|
cae38e22e3 | ||
|
|
c4702cdc22 | ||
|
|
05fc91576a | ||
|
|
c64af87e33 | ||
|
|
14f13d9dde | ||
|
|
6d7210cc69 | ||
|
|
1ff4f7d0bb | ||
|
|
ba0ac8ab08 | ||
|
|
8de32ca12d | ||
|
|
bd13a2373a | ||
|
|
ab5f0e7de4 | ||
|
|
cd190f21d1 | ||
|
|
544a124318 | ||
|
|
284fc41c65 | ||
|
|
6134baea55 | ||
|
|
5cabc406af | ||
|
|
86704252e0 | ||
|
|
481d3e3700 | ||
|
|
dcd920cbb4 | ||
|
|
efa6d0289d | ||
|
|
f4d7bbae34 | ||
|
|
c4f5265ff3 | ||
|
|
7e1038a0f6 | ||
|
|
3a7e0c23ac | ||
|
|
cd93cf1be6 | ||
|
|
0a3e1087ef | ||
|
|
2345265e19 | ||
|
|
6468fe9637 | ||
|
|
8e653912cd | ||
|
|
80f64b2f8c | ||
|
|
b022d0292f | ||
|
|
d12aad2817 | ||
|
|
55281b7e32 | ||
|
|
a155855b45 | ||
|
|
81206c0e36 | ||
|
|
d0738f0988 | ||
|
|
4d65e3b233 | ||
|
|
a6f2eae418 | ||
|
|
84e16057b6 | ||
|
|
b91ee793bf | ||
|
|
0059f1817b | ||
|
|
dc401f6f72 | ||
|
|
69025f7ebf | ||
|
|
6176ec6cb9 | ||
|
|
6bdc1f5d65 | ||
|
|
f5ee666a52 | ||
|
|
fc89b9bfc1 | ||
|
|
2071cbc61b | ||
|
|
e06bfd0724 | ||
|
|
e50ab7ca84 | ||
|
|
a575e5f3c8 | ||
|
|
69661b0d30 | ||
|
|
69ddb6fb2c | ||
|
|
6aa3733111 | ||
|
|
9e3d412e99 | ||
|
|
858de20726 | ||
|
|
453f23ffba | ||
|
|
17c2bd24e4 | ||
|
|
771d12bd9b | ||
|
|
edb5e901e4 | ||
|
|
3cf050c2e8 | ||
|
|
3d89d852a0 | ||
|
|
815848450c | ||
|
|
15446d3d98 | ||
|
|
0de1b344ad | ||
|
|
882850e3d5 | ||
|
|
cb9083677f | ||
|
|
c302f1ba2a | ||
|
|
167ed91a01 | ||
|
|
b595272713 | ||
|
|
6e258490fe | ||
|
|
ca118c397b | ||
|
|
04f860c97a | ||
|
|
021cde5b7e | ||
|
|
ca08f39a4e | ||
|
|
05ee252be8 | ||
|
|
6c7a409c35 | ||
|
|
acc367d522 | ||
|
|
1de19e7a3e | ||
|
|
1f122c79f7 | ||
|
|
7a99377dc9 | ||
|
|
50f4cb8e13 | ||
|
|
ff01477021 | ||
|
|
6c4c0a4ed9 | ||
|
|
eba6429e99 | ||
|
|
a197851fe9 | ||
|
|
d359d750c4 | ||
|
|
1115bf7b56 | ||
|
|
5dba461481 | ||
|
|
f9df92212a | ||
|
|
da38726f40 | ||
|
|
f7b89b7126 | ||
|
|
f19f1b0c68 | ||
|
|
1a3716f649 | ||
|
|
ffeb9da0d6 | ||
|
|
3d96e4bd94 | ||
|
|
bf19aa61d7 | ||
|
|
9aa49a7067 | ||
|
|
a299dbcd6b | ||
|
|
3a50c45dde | ||
|
|
d84edcf85c | ||
|
|
7193a61a11 | ||
|
|
03bfd854df | ||
|
|
d8490322d9 | ||
|
|
13da082cda | ||
|
|
f7fc50f2e6 | ||
|
|
fe91f3ee9b | ||
|
|
7bc688d18b | ||
|
|
426cd70c31 | ||
|
|
1fa3d87369 | ||
|
|
8152159583 | ||
|
|
68ac9cbe26 | ||
|
|
01b7a01dc5 | ||
|
|
bbfa447e42 | ||
|
|
c83bd41dae | ||
|
|
223b22ef46 | ||
|
|
982b4a4244 | ||
|
|
3a09d50972 | ||
|
|
9898baddbb | ||
|
|
520d4e4f26 | ||
|
|
ba04e20aeb | ||
|
|
672c209140 | ||
|
|
f15c9ec4d2 | ||
|
|
5c760f8384 | ||
|
|
f1b7deb706 | ||
|
|
b7e60297a0 | ||
|
|
4456797e90 | ||
|
|
0e5942446d | ||
|
|
6918987ffe | ||
|
|
9130e86460 | ||
|
|
b2d2f0d76d |
9
.github/workflows/auth-internal-release.yml
vendored
@@ -54,3 +54,12 @@ jobs:
|
||||
packageName: io.ente.auth
|
||||
releaseFiles: auth/build/app/outputs/bundle/playstoreRelease/app-playstore-release.aab
|
||||
track: internal
|
||||
|
||||
- name: Notify Discord
|
||||
uses: sarisia/actions-status-discord@v1
|
||||
with:
|
||||
webhook: ${{ secrets.DISCORD_INTERNAL_RELEASE_WEBHOOK }}
|
||||
nodetail: true
|
||||
title: "🏆 Internal release available for Auth"
|
||||
description: "[Download](https://play.google.com/store/apps/details?id=io.ente.auth)"
|
||||
color: 0x800080
|
||||
|
||||
11
.github/workflows/mobile-internal-release.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
|
||||
- name: Build PlayStore AAB
|
||||
run: |
|
||||
flutter build appbundle --release --flavor playstore
|
||||
flutter build appbundle --dart-define=cronetHttpNoPlay=true --release --flavor playstore
|
||||
env:
|
||||
SIGNING_KEY_PATH: "/home/runner/work/_temp/keystore/ente_photos_key.jks"
|
||||
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS_PHOTOS }}
|
||||
@@ -54,3 +54,12 @@ jobs:
|
||||
packageName: io.ente.photos
|
||||
releaseFiles: mobile/build/app/outputs/bundle/playstoreRelease/app-playstore-release.aab
|
||||
track: internal
|
||||
|
||||
- name: Notify Discord
|
||||
uses: sarisia/actions-status-discord@v1
|
||||
with:
|
||||
webhook: ${{ secrets.DISCORD_INTERNAL_RELEASE_WEBHOOK }}
|
||||
nodetail: true
|
||||
title: "🏆 Internal release available for Photos"
|
||||
description: "[Download](https://play.google.com/store/apps/details?id=io.ente.photos)"
|
||||
color: 0x00ff00
|
||||
|
||||
2
.github/workflows/mobile-release.yml
vendored
@@ -45,7 +45,7 @@ jobs:
|
||||
|
||||
- name: Build independent APK
|
||||
run: |
|
||||
flutter build apk --release --flavor independent
|
||||
flutter build apk --dart-define=cronetHttpNoPlay=true --release --flavor independent
|
||||
mv build/app/outputs/flutter-apk/app-independent-release.apk build/app/outputs/flutter-apk/ente-${{ github.ref_name }}.apk
|
||||
env:
|
||||
SIGNING_KEY_PATH: "/home/runner/work/_temp/keystore/ente_photos_key.jks"
|
||||
|
||||
25
.github/workflows/server-publish.yml
vendored
@@ -1,27 +1,24 @@
|
||||
name: "Publish ghcr (server)"
|
||||
|
||||
on:
|
||||
# Run manually, providing it the commit.
|
||||
#
|
||||
# To obtain the commit from the currently deployed museum, do:
|
||||
# curl -s https://api.ente.io/ping | jq -r '.id'
|
||||
#
|
||||
# See server/docs/publish.md for more details.
|
||||
# Run automatically on 15th of every month, at 05:00 UTC.
|
||||
schedule:
|
||||
- cron: '0 5 15 * *'
|
||||
# Run manually if needed to publish out of schedule.
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
commit:
|
||||
description: "Commit to publish the image from"
|
||||
type: string
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Determine commit from prod museum
|
||||
run: |
|
||||
echo "museum_commit=$(curl -s https://api.ente.io/ping | jq -r .id)" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.commit }}
|
||||
ref: ${{ env.museum_commit }}
|
||||
|
||||
- name: Build and push
|
||||
uses: mr-smithers-excellent/docker-build-push@v6
|
||||
@@ -34,8 +31,8 @@ jobs:
|
||||
enableBuildKit: true
|
||||
multiPlatform: true
|
||||
platform: linux/amd64,linux/arm64
|
||||
buildArgs: GIT_COMMIT=${{ inputs.commit }}
|
||||
tags: ${{ inputs.commit }}, latest
|
||||
buildArgs: GIT_COMMIT=${{ env.museum_commit }}
|
||||
tags: ${{ env.museum_commit }}, latest
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
"title": "airtm",
|
||||
"hex": "000000"
|
||||
},
|
||||
{
|
||||
"title": "AJ Bell",
|
||||
"slug": "aj_bell",
|
||||
"hex": "c41230"
|
||||
},
|
||||
{
|
||||
"title": "aliyun",
|
||||
"altNames": [
|
||||
@@ -30,9 +35,18 @@
|
||||
{
|
||||
"title": "Amazon"
|
||||
},
|
||||
{
|
||||
"title": "Ankama",
|
||||
"slug": "ankama"
|
||||
},
|
||||
{
|
||||
"title": "Anycoin Direct",
|
||||
"slug": "anycoindirect"
|
||||
},
|
||||
{
|
||||
"title": "Aruba",
|
||||
"slug": "aruba",
|
||||
"hex": "ef8a33"
|
||||
},
|
||||
{
|
||||
"title": "AscendEX"
|
||||
@@ -347,6 +361,14 @@
|
||||
{
|
||||
"title": "Estateguru"
|
||||
},
|
||||
{
|
||||
"title": "EVEOnline",
|
||||
"slug": "eve_online",
|
||||
"altNames": [
|
||||
"EVE Online"
|
||||
],
|
||||
"hex": "858585"
|
||||
},
|
||||
{
|
||||
"title": "Fastmail"
|
||||
},
|
||||
@@ -492,6 +514,12 @@
|
||||
{
|
||||
"title": "Kagi"
|
||||
},
|
||||
{
|
||||
"title": "Keygen",
|
||||
"altNames": [
|
||||
"keygen.sh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Kick"
|
||||
},
|
||||
@@ -749,6 +777,11 @@
|
||||
"altNames": [
|
||||
"欧易"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "OnShape",
|
||||
"slug": "onshape",
|
||||
"hex": "7abb5e"
|
||||
},
|
||||
{
|
||||
"title": "Parqet",
|
||||
@@ -846,6 +879,11 @@
|
||||
{
|
||||
"title": "RealMe",
|
||||
"slug": "realme"
|
||||
},
|
||||
{
|
||||
"title": "RealVNC",
|
||||
"slug": "realvnc",
|
||||
"hex": "488aec"
|
||||
},
|
||||
{
|
||||
"title": "Registro br",
|
||||
@@ -890,6 +928,10 @@
|
||||
{
|
||||
"title": "Samsung"
|
||||
},
|
||||
{
|
||||
"title": "Seafile",
|
||||
"slug": "seafile"
|
||||
},
|
||||
{
|
||||
"title": "Sendgrid"
|
||||
},
|
||||
@@ -1105,13 +1147,6 @@
|
||||
"title": "WARGAMING.NET",
|
||||
"slug": "wargamingnet"
|
||||
},
|
||||
{
|
||||
"title": "World Cube Association",
|
||||
"altNames": [
|
||||
"WCA",
|
||||
"worldcubeassociation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Wealthfront"
|
||||
},
|
||||
@@ -1140,6 +1175,14 @@
|
||||
"Work OS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "World Cube Association",
|
||||
"slug": "wca",
|
||||
"altNames": [
|
||||
"WCA",
|
||||
"worldcubeassociation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "WYZE"
|
||||
},
|
||||
|
||||
7
auth/assets/custom-icons/icons/aj_bell.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1507 1556" width="1507" height="1556">
|
||||
<title>logo_grey-svg</title>
|
||||
<style>
|
||||
.s0 { fill: #c41230 }
|
||||
</style>
|
||||
<path id="Layer" class="s0" d="m759.6 651c10.6 63.6 7.5 126.3-6.8 185.3-0.6-3.5-0.8-7-1.5-10.6-51.7-311.8-346.3-522.7-657.7-470.8-32.4 5.3-63.6 13.5-93.6 23.9 62.4-54.7 140.3-93.4 228.3-108.1 251.6-41.9 489.5 128.4 531.3 380.3zm84.2 340c-48.7 59.8-107.3 106.4-171.5 140 2.8-3.3 5.7-6.4 8.4-9.7 238.7-292.4 195.6-723.2-96.4-962.3-30.4-24.8-62.2-46.4-95.3-65.2 98.4 12.9 194.5 52.4 276.9 119.9 236 193.2 270.9 541.2 77.9 777.3zm409.3-532.7c66.8 402.8-204.2 783.4-605.6 852.1 313.4-230.6 489-625.2 420.9-1035.7-16.2-97.3-45.1-189.3-84.7-274.7 138.4 110.2 238.1 269.9 269.4 458.3zm241.5 84.5c78.6 473.9-241.4 921.9-714.8 1000.6-195.5 32.6-386.6-3.2-549.2-89.5 98.5 11.2 200.2 9.2 302.8-7.9 537.8-89.4 917.1-559.8 908.4-1089.5 23.9 58.8 41.9 121 52.8 186.3z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 943 B |
5
auth/assets/custom-icons/icons/ankama.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 720" width="720" height="720">
|
||||
<title>ankama</title>
|
||||
<path class="s0" d="m572.3 253.3c-0.3-1.4-0.5-3-1.1-4.4-15.1-46-59.7-76.2-107.9-71.5-31.2 3-55.6 18.9-73.4 44.7-3.8 5.7-7.1 12-10.1 18.4-9.4 19.5-19.5 38.7-24.7 59.7-0.5 1.6-1.1 3.5-1.9 4.9-2.5 4.6-5.5 6.3-10.1 4.1-11.7-5.7-23.8-5.2-36.1-4.4-20.3 1.1-37.9-5.7-52.9-19.5-36.1-33.1-35.3-91 1.9-123 26.8-23.3 43.3-52.1 49.3-86.8 3-16.5 3.3-33.4 0-49.9-0.5-2.7-0.8-5.5-1.4-8.7 7.4-1.4 14.3 0 20.8 2.2 42.8 12.4 69.3 40.6 81.6 82.7 0.5 2.2 1.1 4.4 1.6 6.8 0.8 3 2.7 4.9 5.7 5.5 3.3 0.5 6.3-0.5 7.9-3.5 3-6.3 5.7-12.7 8.2-19.2 3.3-9.7 3.8-10.5 14.3-10.6 58.3-0.8 111.7 15.4 159.4 49 60.5 42.9 98.4 101.4 115.7 173.4 0.8 3.5 0.8 7.6 0.5 11.6-4.6 68-26.8 129.6-68.8 183.5-49 63.1-112.4 104.4-190.7 121.4-72.6 15.8-141.7 4.9-207.1-30.1-1.4-0.8-2.7-1.6-3.8-2.5-0.3 0-0.5-0.8-1.6-2.2 8.7 3 17 5.5 24.7 8.6 13.9 5.7 28.5 8.7 43.6 8.6 14.3 0 28.2 0.8 42.5 0 63.9-3.8 119.5-27.4 166.2-70.7 23.6-21.9 32.8-50.7 30.7-82.4-1.9-32.3-16.5-58.6-42.2-78.3-18.9-14.6-32-33.1-38-56.4-4.1-15.8-4.6-32-0.8-48.2 5.7-24.7 27.7-41.7 52.3-40.6 17 0.8 29.6 9 39.5 22.5 1.4 1.9 2.7 4.1 4.1 6.3 0.5 0 0.8-0.5 1.4-0.8l0.8 0.3v-0.5zm-263.5-55.1c-14.7 0-26.3 12.4-26.3 27.7 0 15.3 11.6 27.4 26.6 27.4 15 0 26-12.4 26-27.1 0-14.7-12-27.9-26.3-27.9v-0.2z"/>
|
||||
<path class="s0" d="m168.2 314.5c7.4 1.6 14.7 3.3 22.5 4.9 10.9 2.2 14.3 6.8 12 18.1-1.6 8.2-3 16.2-4.9 24.1-0.8 3.5 0 5.7 2.5 8.2 22.8 23.6 50.1 38.4 83.8 43.6-2.2-1.4-3-2.2-4.1-2.7-19.5-10.1-27.7-25.2-25.2-46.6 1.1-9.8 0-19.2-6-27.4-3.8-5.5-9-9.7-13.9-14.3-1.6-1.6-3.8-2.5-6-4.1 5.2-3.3 10.5-3.3 15.4-3 7.4 0.3 14.7 1.4 22.2 3 11.6 2.5 21.7 8.2 30.4 16.2 6.5 6 12.4 12.4 18.7 18.4 13.9 13.6 25.2 12.8 37.2-2.7 7.6-9.8 12.4-21.4 15.8-33.1 3.8-12.7 8.2-24.9 15.4-36.1 7.4-11.6 16.5-21.7 27.4-30.1 9.7-7.4 19.7-6.8 30.7-3.3v9.7c-1.1 27.1 5.2 52.6 19.5 75.9 1.1 1.9 2.2 4.1 3.5 6 4.1 6.3 3.3 12-0.5 18.1-5.5 8.7-13.5 13.2-23.8 13.5h-6.3c-12.7 0-23.3 8.2-26.8 20.6-3 10.9 1.9 23.3 11.7 29.6 10.9 6.8 24.1 5.7 33.4-3 10.1-9.8 16.5-21.7 18.9-35.7 0.3-1.9 0.8-4.1 1.1-6 17.3-0.3 39.8 16.6 48.2 37.2 10.1 24.1 6.3 46.6-10.1 68.8-0.8-5.2-1.4-9.4-2.2-12.8-2.2-9.7-8.6-15.7-18.1-17.7-6.8-1.6-9.8 0-13.6 5.7-1.9 3-3.5 6.3-5.2 9.7-2.5 4.9-4.6 9.8-7.1 14.6-13.6 27.1-34.9 45.8-63.2 55.6-27.1 9.7-55.2 13.2-83.5 10.1-16.5-1.6-29.3-10.5-39.8-23.6 1.9-1.4 3.3-2.7 4.9-3.8 7.4-5.5 12.8-12.7 16.6-20.8 1.1-2.2 1.6-4.9 1.9-7.4 0.5-5.2-2.7-9.4-7.6-9.8-4.6-0.5-8.7 2.5-10.1 7.6-0.8 3.3-1.1 6.5-2.5 9.7-3.8 7.1-9.7 12.8-16.5 17-7.4 4.4-14.6 3.8-20-1.4-5.5-5.5-6-11.7-1.9-19.7 0.3-0.5 0.5-1.4 1.4-3-2.5 1.1-4.1 1.4-5.5 2.2-17.7 10.6-25.8 31.5-19.2 51.5 18.7 56.7-6 119.5-54 151-3.3 2.2-7.1 4.1-11.6 6.8 0-3-0.5-5.2-0.5-7.4-2.5-57.8-30.1-98.9-82.4-122.8-32.8-14.7-53.7-39.5-62.1-74-12.4-50.1 13.9-102.2 61.2-122.8 1.9-0.8 4.1-1.4 7.6-2.7-15.1 28.8-18.7 57.2-9.4 86.8 5.5 17.3 14.7 32 29 45.5 0.3-12.4-0.8-23.6 7.6-33.4 2.7 6.3 5.5 12 8.2 17.7 4.9 10.9 12.7 19.5 23.3 24.9 12 6.3 24.1 6.8 36.5 1.1 8.6-3.8 15.8-9.4 22.2-16.2 8.6-9 8.6-24.9 0.3-35.7-5.5-7.1-8.6-14.7-7.4-23.6 1.9-15.4 15.1-26.8 32-28.2 4.6-0.3 9.4 0 13.6 0.5 4.1 0.8 8.2 2.5 12.7 3.3-3.5-3.8-7.9-6.5-12.7-8.2-8.2-2.7-16.6-3.3-25.2-1.6-14.7 3.3-24.9 16.2-26.3 33.4-0.5 6.3 0 12.8 1.1 19.2 3 16.5-0.8 30.4-13.2 42.8-1.9-1.6-3.8-2.7-5.7-4.4-43.9-37.6-69.6-84.6-75.6-142.2-10.1-95.9 42.5-184.9 130.9-223 28.5-12.4 46-33.8 53.4-63.9 0.3-1.4 0.8-2.7 1.9-3.8 1.9 10.1 1.4 20.3-1.1 30.1-6 24.1-19.5 42.8-41.4 55.3-21.4 12.4-38.4 29-51.5 50.1-2.5 4.1-2.7 7.1 0 10.9 2.7 3.5 5.2 7.6 7.6 11.6 4.4 7.4 3 13.9-4.1 18.9-6.3 4.4-13.2 8.2-19.5 12.7-1.6 1.1-3.5 3.3-3.8 5.2-1.6 18.7-0.5 36.9 5.5 55.3l1.4-0.3-0.2-0.2zm192.8 132c14.3 0 25.8-11.3 25.5-25.2 0-13.6-12-25.8-25.5-25.8-13.5 0-25.2 11.3-25.5 25.5 0 14.3 11.3 25.5 25.2 25.5z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
4
auth/assets/custom-icons/icons/aruba.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="#FF8300" fill-rule="evenodd" d="M12.1099561,17.3015551 C9.03598293,17.3015551 6.50849391,14.8423766 6.50849391,11.836714 C6.50849391,8.83105139 9.03598293,6.37187289 12.1099561,6.37187289 C15.1839292,6.37187289 17.7114182,8.83105139 17.7114182,11.836714 C17.7114182,14.8423766 15.1839292,17.3015551 12.1099561,17.3015551 L12.1099561,17.3015551 Z M12.1099561,2 C6.50849391,2 2,6.4401834 2,11.836714 C2,17.3015551 6.50849391,21.673428 12.1099561,21.673428 C14.4325135,21.673428 16.5501395,20.9220123 18.2579023,19.6241126 C19.28256,21.3318754 22.2199121,21.673428 22.2199121,21.673428 L22.2199121,11.836714 C22.2199121,6.4401834 17.7114182,2 12.1099561,2 L12.1099561,2 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 901 B |
3
auth/assets/custom-icons/icons/eve_online.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="198.4" height="198.4" xml:space="preserve">
|
||||
<path transform="translate(0, 60)" d="M 0,0 0,13.88 10.97,13.88 10.97,10.31 60.69,10.31 60.69,0 0,0 z M 65.84,0 99.22,58.09 132.6,0 120.7,0 C 120.7,0 100.5,34.91 99.22,37.16 97.92,34.91 77.75,0 77.75,0 L 65.84,0 z M 137.8,0 137.8,13.88 148.7,13.88 148.7,10.31 198.4,10.31 198.4,0 137.8,0 z M 0,19.12 0,29.47 60.69,29.47 60.69,19.12 0,19.12 z M 137.8,19.12 137.8,29.47 198.4,29.47 198.4,19.12 137.8,19.12 z M 0,34.66 0,48.59 60.69,48.59 60.69,38.25 10.97,38.25 10.97,34.66 0,34.66 z M 137.8,34.66 137.8,48.59 198.4,48.59 198.4,38.25 148.7,38.25 148.7,34.66 137.8,34.66 z M 42.19,69.72 C 41.32,69.72 40.71,69.89 40.41,70.19 40.1,70.49 39.97,71.03 39.97,71.84 L 39.97,76.56 C 39.97,77.38 40.1,77.93 40.41,78.22 40.71,78.52 41.32,78.66 42.19,78.66 L 48.72,78.66 C 49.59,78.66 50.19,78.52 50.5,78.22 50.8,77.93 50.97,77.38 50.97,76.56 L 50.97,71.84 C 50.97,71.03 50.8,70.49 50.5,70.19 50.19,69.89 49.59,69.72 48.72,69.72 L 42.19,69.72 z M 64.37,69.72 64.37,78.66 66.25,78.66 66.25,73.84 C 66.25,73.66 66.23,73.43 66.22,73.19 66.2,72.94 66.18,72.69 66.16,72.41 66.26,72.53 66.38,72.67 66.5,72.78 66.62,72.89 66.75,73.01 66.91,73.16 L 73.47,78.66 74.88,78.66 74.88,69.72 73.03,69.72 73.03,74.41 C 73.03,74.52 73.05,74.7 73.06,74.91 73.07,75.11 73.09,75.47 73.12,75.97 72.99,75.81 72.82,75.66 72.66,75.5 72.49,75.35 72.31,75.18 72.09,75 L 65.81,69.72 64.37,69.72 z M 88.53,69.72 88.53,78.66 97.31,78.66 97.31,77 90.59,77 90.59,69.72 88.53,69.72 z M 109.4,69.72 109.4,78.66 111.5,78.66 111.5,69.72 109.4,69.72 z M 125.1,69.72 125.1,78.66 127,78.66 127,73.84 C 127,73.66 127,73.43 126.9,73.19 126.9,72.94 126.9,72.69 126.9,72.41 127,72.53 127.1,72.67 127.2,72.78 127.3,72.89 127.5,73.01 127.6,73.16 L 134.2,78.66 135.6,78.66 135.6,69.72 133.8,69.72 133.8,74.41 C 133.8,74.52 133.8,74.7 133.8,74.91 133.8,75.11 133.8,75.47 133.8,75.97 133.7,75.81 133.6,75.66 133.4,75.5 133.2,75.35 133,75.18 132.8,75 L 126.5,69.72 125.1,69.72 z M 149.3,69.72 149.3,78.66 158.5,78.66 158.5,77 151.3,77 151.3,74.78 155.4,74.78 155.4,73.25 151.3,73.25 151.3,71.25 158.4,71.25 158.4,69.72 149.3,69.72 z M 42.03,71.31 48.87,71.31 48.87,77 42.03,77 42.03,71.31 z" /></svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
19
auth/assets/custom-icons/icons/keygen.svg
Normal file
@@ -0,0 +1,19 @@
|
||||
<svg width="100%" height="100%" viewBox="0 0 113 113" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-1298.97,-1016.72)">
|
||||
<g transform="matrix(0.5,0,0,0.5,736.463,641.721)">
|
||||
<g transform="matrix(0.834925,0,0,0.834925,161.667,288.323)">
|
||||
<circle cx="1198.72" cy="777.527" r="44.914" style="fill:#000811;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.5,0,0,0.5,736.463,641.721)">
|
||||
<g transform="matrix(0.834925,0,0,0.834925,311.66,138.323)">
|
||||
<circle cx="1198.72" cy="777.527" r="44.914" style="fill:#000811;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.5,0,0,0.5,736.463,641.721)">
|
||||
<g transform="matrix(1,0,0,1,281.792,137.715)">
|
||||
<path d="M955.708,762.285C935.011,762.285 918.208,745.482 918.208,724.785C918.208,704.088 935.011,687.285 955.708,687.285C976.405,687.285 993.208,704.088 993.208,724.785C993.208,745.482 1010.01,762.285 1030.71,762.285C1051.4,762.285 1068.21,779.088 1068.21,799.785C1068.21,820.482 1051.4,837.285 1030.71,837.285C1010.01,837.285 993.208,820.482 993.208,799.785C993.208,779.088 976.405,762.285 955.708,762.285Z" style="fill:#000811;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
1
auth/assets/custom-icons/icons/onshape.svg
Normal file
|
After Width: | Height: | Size: 33 KiB |
1
auth/assets/custom-icons/icons/realvnc.svg
Normal file
|
After Width: | Height: | Size: 18 KiB |
13
auth/assets/custom-icons/icons/seafile.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 120" width="180" height="120">
|
||||
<title>seafile</title>
|
||||
<defs>
|
||||
<linearGradient id="g1" x2="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0,114.369,-177.525,0,89.989,2.834)">
|
||||
<stop offset="0" stop-color="#fad956"/>
|
||||
<stop offset="1" stop-color="#ffa10f"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<style>
|
||||
.s0 { fill: url(#g1) }
|
||||
</style>
|
||||
<path class="s0" d="m1.2 52.8c0-3 2.4-5.4 5.4-5.4 1.4 0 2.7 0.6 3.6 1.5q0-0.7 0-1.4c0-9.9 8-17.9 17.9-17.9 2.5 0 4.9 0.5 7.1 1.5q0-0.8 0-1.5c0-14.8 12-26.8 26.8-26.8 14.7 0 26.6 11.9 26.8 26.6-4.8 4.2-8.7 9.6-11.2 15.7-4.8-3-10.4-4.8-16.5-4.8-12.4 0-23.2 7.1-28.3 17.8h-19.1-7.1c-3 0-5.4-2.4-5.4-5.3zm141.2-16c-6.6-6.7-15.8-10.8-25.9-10.8-18.5 0-33.8 13.7-36.3 31.5-4.5-6.1-11.8-10-20-10-13.8 0-25 11.2-25 25 0 4 0.9 7.8 2.6 11.2-8.7 1.7-15.1 8.5-15.1 16.5 0 9.4 8.8 17 19.7 17 4.7 0 9.1-1.5 12.6-4l40.2-39.5c4.4-4.1 10.3-6.6 16.8-6.6 13.6 0 24.7 10.9 25.1 24.4q0 0-0.1-0.1c0.2 4-1.8 8.1-5.7 10.3-5.3 3.1-12 1.4-15-3.7-2.9-5.1-1-11.7 4.4-14.8q1.9-1.1 3.9-1.4-1.8-0.4-3.6-0.4c-9.9 0-17.9 8-17.9 17.9 0 9.9 8 17.9 17.9 17.9q0.6 0 1.3-0.1l0.5-0.1h35.1v0.2c10.7-0.5 20.9-10.4 20.9-22.5 0-12.3-10.6-22.4-22.9-22.4q-0.1 0-0.1 0c-2 3.6-4.4 5.7-7.1 7.9 2.8-5.2 4.5-11.2 4.5-17.6-0.1-10.1-4.2-19.2-10.8-25.8z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -48,6 +48,7 @@
|
||||
"nextTotpTitle": "التالي",
|
||||
"deleteCodeTitle": "حذف الرمز؟",
|
||||
"deleteCodeMessage": "هل أنت متأكد من أنك تريد حذف هذه الشيفرة؟ هذا الإجراء لا رجعة فيه.",
|
||||
"trash": "سلة المهملات",
|
||||
"viewLogsAction": "عرض السجلات",
|
||||
"sendLogsDescription": "سوف يُرسل هذا السجلات لنا لمساعدتنا على تصحيح مشكلتك. بينما نتخذ الاحتياطات لضمان عدم تسجيل المعلومات الحساسة، نشجعك على رؤية هذه السجلات قبل مشاركتها.",
|
||||
"preparingLogsTitle": "جارٍ إعداد السجلات...",
|
||||
@@ -197,6 +198,8 @@
|
||||
"enterDetailsManually": "أدخل التفاصيل يدوياً",
|
||||
"edit": "تعديل",
|
||||
"share": "مشاركة",
|
||||
"shareCodes": "شارك الرموز",
|
||||
"restore": "استعادة",
|
||||
"copiedToClipboard": "تم النسخ إلى الحافظة",
|
||||
"copiedNextToClipboard": "تم نسخ الرموز التالية إلى الحافظة",
|
||||
"error": "خطأ",
|
||||
@@ -248,6 +251,10 @@
|
||||
"areYouSureYouWantToLogout": "هل أنت متأكد من أنك تريد تسجيل الخروج؟",
|
||||
"yesLogout": "نعم، تسجيل الخروج",
|
||||
"exit": "خروج",
|
||||
"theme": "السمة",
|
||||
"lightTheme": "فاتح",
|
||||
"darkTheme": "داكن",
|
||||
"systemTheme": "النظام",
|
||||
"verifyingRecoveryKey": "التحقق من مفتاح الاسترداد...",
|
||||
"recoveryKeyVerified": "تم التحقق من مفتاح الاسترداد",
|
||||
"recoveryKeySuccessBody": "رائع! مفتاح الاسترداد الخاص بك صالح. شكرا لك على التحقق.\n\nيرجى تذكر الاحتفاظ بنسخة احتياطية من مفتاح الاسترداد بشكل آمن.",
|
||||
@@ -318,6 +325,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"manualSort": "مخصّص",
|
||||
"mostFrequentlyUsed": "مستخدم بكثرة",
|
||||
"mostRecentlyUsed": "مستخدمة مؤخراً",
|
||||
"activeSessions": "الجلسات النشطة",
|
||||
"somethingWentWrongPleaseTryAgain": "حدث خطأ ما، يرجى المحاولة مرة أخرى",
|
||||
"thisWillLogYouOutOfThisDevice": "سيؤدي هذا إلى تسجيل خروجك من هذا الجهاز!",
|
||||
@@ -350,6 +360,7 @@
|
||||
"sigInBackupReminder": "يرجى تصدير الرموز الخاصة بك للتأكد من أن لديك نسخة احتياطية يمكنك استعادتها منها.",
|
||||
"offlineModeWarning": "لقد اخترت المضي قدما بدون نسخ احتياطية. يرجى أخذ نسخ احتياطية يدوية للتأكد من سلامة الرموز الخاصة بك.",
|
||||
"showLargeIcons": "إظهار أيقونات كبيرة",
|
||||
"compactMode": "الوضع المضغوط",
|
||||
"shouldHideCode": "إخفاء الرموز",
|
||||
"doubleTapToViewHiddenCode": "يمكنك النقر مرتين على أي عنصر لعرض الرمز",
|
||||
"focusOnSearchBar": "التركيز على البحث عند بدء التطبيق",
|
||||
@@ -468,5 +479,11 @@
|
||||
"pinLock": "قفل رقم التعريف الشخصي",
|
||||
"enterPin": "أدخل رقم التعريف الشخصي",
|
||||
"setNewPin": "عين رقم تعريف شخصي جديد",
|
||||
"importFailureDescNew": "تعذر إعراب الملف المنتقى."
|
||||
"importFailureDescNew": "تعذر إعراب الملف المنتقى.",
|
||||
"duplicateCodes": "رموز مكررة",
|
||||
"noDuplicates": "✨ لا تكرارات",
|
||||
"youveNoDuplicateCodesThatCanBeCleared": "ليس لديك رموز مكررة يمكن مسحها",
|
||||
"deselectAll": "ألغِ تحديد الكل",
|
||||
"selectAll": "حدد الكل",
|
||||
"deleteDuplicates": "احذف التكرار"
|
||||
}
|
||||
@@ -88,6 +88,8 @@
|
||||
"useRecoveryKey": "Usa la clau de recuperació",
|
||||
"incorrectPasswordTitle": "Contrasenya incorrecta",
|
||||
"welcomeBack": "Benvingut de nou!",
|
||||
"emailAlreadyRegistered": "El correu electrònic ja està registrat.",
|
||||
"emailNotRegistered": "El correu electrònic no està registrat.",
|
||||
"madeWithLoveAtPrefix": "fet amb ❤️ a ",
|
||||
"supportDevs": "Subscriu-te a <bold-green>ente</bold-green> per donar-nos suport",
|
||||
"supportDiscount": "Usa el codi de descompte \"AUTH\" per obtenir un 10% de descompte el primer any",
|
||||
@@ -502,5 +504,13 @@
|
||||
"deselectAll": "Desselecciona-ho tot",
|
||||
"selectAll": "Seleccionar-ho tot",
|
||||
"deleteDuplicates": "Elimina duplicats",
|
||||
"plainHTML": "HTML pla"
|
||||
"plainHTML": "HTML pla",
|
||||
"tellUsWhatYouThink": "Digueu-nos què us sembla",
|
||||
"dropReview": "Deixa una ressenya a l'App/Play Store",
|
||||
"supportEnte": "Donar suport a <bold-green>ente</bold-green>",
|
||||
"giveUsAStarOnGithub": "Dona'ns una estrella a Github",
|
||||
"free5GB": "5 GB gratuïts a <bold-green>ente</bold-green> Photos",
|
||||
"loginWithAuthAccount": "Inicieu sessió amb el vostre compte Auth",
|
||||
"freeStorageOffer": "10% de descompte a <bold-green>ente</bold-green> photos",
|
||||
"freeStorageOfferDescription": "Utilitzeu el codi \"AUTH\" per obtenir un 10% de descompte el primer any"
|
||||
}
|
||||
@@ -88,6 +88,8 @@
|
||||
"useRecoveryKey": "Wiederherstellungsschlüssel verwenden",
|
||||
"incorrectPasswordTitle": "Falsches Passwort",
|
||||
"welcomeBack": "Willkommen zurück!",
|
||||
"emailAlreadyRegistered": "E-Mail ist bereits registriert.",
|
||||
"emailNotRegistered": "E-Mail-Adresse nicht registriert.",
|
||||
"madeWithLoveAtPrefix": "gemacht mit ❤️ bei ",
|
||||
"supportDevs": "Bei <bold-green>ente</bold-green> registrieren, um das Projekt zu unterstützen",
|
||||
"supportDiscount": "Benutzen Sie den Rabattcode \"AUTH\" für 10 % Rabatt im ersten Jahr",
|
||||
@@ -255,6 +257,8 @@
|
||||
"areYouSureYouWantToLogout": "Sind sie sicher, dass sie sich ausloggen möchten?",
|
||||
"yesLogout": "Ja ausloggen",
|
||||
"exit": "Schließen",
|
||||
"theme": "Theme",
|
||||
"systemTheme": "System",
|
||||
"verifyingRecoveryKey": "Verifiziere Wiederherstellungsschlüssel...",
|
||||
"recoveryKeyVerified": "Wiederherstellungsschlüssel verifiziert",
|
||||
"recoveryKeySuccessBody": "Großartig! Ihr Wiederherstellungsschlüssel ist gültig. Vielen Dank für die Verifizierung.\n\nBitte denken sie daran, dass sie ihren Wiederherstellungsschlüssel sicher aufbewahren.",
|
||||
@@ -325,6 +329,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"manualSort": "Benutzerdefiniert",
|
||||
"activeSessions": "Aktive Sitzungen",
|
||||
"somethingWentWrongPleaseTryAgain": "Ein Fehler ist aufgetreten, bitte versuche es erneut",
|
||||
"thisWillLogYouOutOfThisDevice": "Dadurch wirst du von diesem Gerät abgemeldet!",
|
||||
@@ -478,5 +483,9 @@
|
||||
"setNewPin": "Neue PIN festlegen",
|
||||
"importFailureDescNew": "Die ausgewählte Datei konnte nicht verarbeitet werden.",
|
||||
"appLockNotEnabled": "App-Sperre nicht aktiviert",
|
||||
"appLockNotEnabledDescription": "Bitte aktivieren Sie die App-Sperre über Security > App-Sperre"
|
||||
"appLockNotEnabledDescription": "Bitte aktivieren Sie die App-Sperre über Security > App-Sperre",
|
||||
"duplicateCodes": "Doppelte Codes",
|
||||
"noDuplicates": "✨ Keine Duplikate",
|
||||
"deselectAll": "Alle abwählen",
|
||||
"selectAll": "Alles auswählen"
|
||||
}
|
||||
@@ -504,5 +504,12 @@
|
||||
"deselectAll": "Deseleccionar todo",
|
||||
"selectAll": "Seleccionar todo",
|
||||
"deleteDuplicates": "Eliminar duplicados",
|
||||
"plainHTML": "HTML plano"
|
||||
"plainHTML": "HTML plano",
|
||||
"tellUsWhatYouThink": "Cuéntanos cuál es su opinión",
|
||||
"dropReview": "Danos una reseña en la App/Play Store",
|
||||
"supportEnte": "Apoya a <bold-green>ente</bold-green>",
|
||||
"giveUsAStarOnGithub": "Danos una estrella en GitHub",
|
||||
"free5GB": "5 GB gratis en <bold-green>ente</bold-green> Fotos",
|
||||
"freeStorageOffer": "10% de descuento en <bold-green>ente</bold-green> fotos",
|
||||
"freeStorageOfferDescription": "Usa el cupón \"AUTH\" para obtener un 10% de descuento en el primer año"
|
||||
}
|
||||
@@ -504,5 +504,13 @@
|
||||
"deselectAll": "Tout désélectionner",
|
||||
"selectAll": "Tout sélectionner",
|
||||
"deleteDuplicates": "Supprimer les doublons",
|
||||
"plainHTML": "HTML Pur"
|
||||
"plainHTML": "HTML Pur",
|
||||
"tellUsWhatYouThink": "Dites-nous ce que vous pensez",
|
||||
"dropReview": "Déposez un avis sur l'App/Play Store",
|
||||
"supportEnte": "Soutenir <bold-green>Ente</bold-green>",
|
||||
"giveUsAStarOnGithub": "Donnez-nous une étoile sur Github",
|
||||
"free5GB": "5 Go gratuits sur <bold-green>Ente</bold-green> Photos",
|
||||
"loginWithAuthAccount": "Connectez-vous avec votre compte Auth",
|
||||
"freeStorageOffer": "10% de réduction sur <bold-green>Ente</bold-green> Photos",
|
||||
"freeStorageOfferDescription": "Utilisez le code coupon \"AUTH\" pour obtenir 10% de réduction la première année"
|
||||
}
|
||||
@@ -8,13 +8,13 @@
|
||||
},
|
||||
"onBoardingGetStarted": "प्रारंभ करें",
|
||||
"setupFirstAccount": "अपना पहला अकाउंट सेटअप करें",
|
||||
"importScanQrCode": "QR कोड स्कैन करें",
|
||||
"importScanQrCode": "एक QR कोड स्कैन करें",
|
||||
"qrCode": "QR कोड",
|
||||
"importEnterSetupKey": "",
|
||||
"importAccountPageTitle": "अकाउंट विवरण डालें",
|
||||
"incorrectDetails": "ग़लत विवरण",
|
||||
"pleaseVerifyDetails": "कृपया विवरण सत्यापित करें और पुनः प्रयास करें",
|
||||
"codeIssuerHint": "जारीकर्ता",
|
||||
"codeIssuerHint": "ज़ारीकर्ता",
|
||||
"codeSecretKeyHint": "सीक्रेट कुंजी",
|
||||
"secret": "सीक्रेट",
|
||||
"all": "सभी",
|
||||
@@ -39,6 +39,10 @@
|
||||
"pleaseLoginAgain": "कृपया फिर से लॉगिन करें",
|
||||
"loggingOut": "लॉग आउट हो रहा है...",
|
||||
"saveAction": "सेव करें",
|
||||
"deleteCodeMessage": "क्या आप वाकई इस कोड को हटाना चाहते हैं? इस क्रिया को वापस नहीं किया जा सकता",
|
||||
"trashCode": "?",
|
||||
"trashCodeMessage": "क्या आप वाकई {account} के लिए कोड नष्ट करना चाहते हैं?",
|
||||
"trash": "नष्ट करें",
|
||||
"viewLogsAction": "लॉग देखें",
|
||||
"preparingLogsTitle": "लॉग तैयार किये जा रहे हैं...",
|
||||
"emailLogsTitle": "लॉग ईमेल करें",
|
||||
@@ -50,6 +54,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"copyEmailAction": "ईमेल कॉपी करें",
|
||||
"exportLogsAction": "लॉग एक्सपोर्ट करें",
|
||||
"reportABug": "बग रिपोर्ट करें",
|
||||
"reportBug": "बग रिपोर्ट करें",
|
||||
@@ -79,5 +84,24 @@
|
||||
"cancel": "रद्द करें",
|
||||
"yes": "हाँ",
|
||||
"no": "नहीं",
|
||||
"settings": "सेटिंग"
|
||||
"settings": "सेटिंग",
|
||||
"pleaseTryAgain": "कृपया पुन: प्रयास करें",
|
||||
"newUser": "एंटे में नए उपयोगकर्ता",
|
||||
"delete": "हटाएं",
|
||||
"enterYourPasswordHint": "अपना पासवर्ड दर्ज करें",
|
||||
"forgotPassword": "पासवर्ड भूल गए",
|
||||
"oops": "ओह",
|
||||
"suggestFeatures": "विशेषताएं सुझाएं",
|
||||
"faq": "अक्सर किये गए सवाल",
|
||||
"somethingWentWrongMessage": "कुछ गड़बड़ हुई है, कृपया दोबारा प्रयास करें",
|
||||
"leaveFamily": "परिवार छोड़ें",
|
||||
"leaveFamilyMessage": "क्या आप सच में परिवार प्लान छोड़ना चाहते हैं?",
|
||||
"inFamilyPlanMessage": "आप परिवार प्लान पर हैं!",
|
||||
"hintForMobile": "कोड को संपादित करने या हटाने के लिए उसे लंबी देर तक दबाए।",
|
||||
"hintForDesktop": "कोड को संपादित करने या हटाने के लिए उस पर राइट क्लिक करें।",
|
||||
"scan": "स्कैन करें",
|
||||
"scanACode": "कोड स्कैन करें",
|
||||
"verify": "सत्यापित करें",
|
||||
"verifyEmail": "ईमेल सत्यापित करें",
|
||||
"twoFactorAuthTitle": "दो-चरणीय प्रमाणीकरण |"
|
||||
}
|
||||
@@ -504,5 +504,13 @@
|
||||
"deselectAll": "Összes kijelölés megszüntetése",
|
||||
"selectAll": "Összes kijelölése",
|
||||
"deleteDuplicates": "Ismétlődések törlése",
|
||||
"plainHTML": "Sima HTML kód"
|
||||
"plainHTML": "Sima HTML kód",
|
||||
"tellUsWhatYouThink": "Mondja el mit gondol",
|
||||
"dropReview": "Írjon véleményt az App/Play Store-ban",
|
||||
"supportEnte": "Támogassa <bold-green>ente <bold-green>",
|
||||
"giveUsAStarOnGithub": "Adj nekünk egy csillagot a Githubon",
|
||||
"free5GB": "5GB ingyen <bold-green>ente <bold-green> Photos",
|
||||
"loginWithAuthAccount": "Jelentkezzen be Auth fiókjával",
|
||||
"freeStorageOffer": "10% kedvezmény on <bold-green>ente<bold-green> photos",
|
||||
"freeStorageOfferDescription": "Használja az \"AUTH\" kódot, hogy 10% kedvezményt kapjon az első évben"
|
||||
}
|
||||
@@ -88,6 +88,8 @@
|
||||
"useRecoveryKey": "回復キーを使用",
|
||||
"incorrectPasswordTitle": "パスワードが正しくありません",
|
||||
"welcomeBack": "おかえりなさい!",
|
||||
"emailAlreadyRegistered": "メールアドレスはすでに登録されています。",
|
||||
"emailNotRegistered": "メールアドレスはまだ登録されていません。",
|
||||
"madeWithLoveAtPrefix": "made with ❤️ at ",
|
||||
"supportDevs": "プロジェクト支援のために <bold-green>ente</bold-green> に登録",
|
||||
"supportDiscount": "クーポンコード \"AUTH\" の使用で初年度が 10% オフに",
|
||||
@@ -258,6 +260,10 @@
|
||||
"areYouSureYouWantToLogout": "本当にログアウトしてよろしいですか?",
|
||||
"yesLogout": "はい、ログアウトします",
|
||||
"exit": "やめる",
|
||||
"theme": "テーマ",
|
||||
"lightTheme": "ライト",
|
||||
"darkTheme": "ダーク",
|
||||
"systemTheme": "システム",
|
||||
"verifyingRecoveryKey": "回復キーを確認中...",
|
||||
"recoveryKeyVerified": "回復キーが確認されました",
|
||||
"recoveryKeySuccessBody": "素晴らしい!回復キーは有効です。ご確認いただきありがとうございます。\n\n回復キーを安全にバックアップしておいてください。",
|
||||
@@ -490,5 +496,21 @@
|
||||
"appLockNotEnabled": "アプリロックが有効になっていません",
|
||||
"appLockNotEnabledDescription": "セキュリティ > アプリロック からアプリロックを有効化してください",
|
||||
"authToViewPasskey": "パスキーを見るには認証してください",
|
||||
"appLockOfflineModeWarning": "バックアップなしで進むことを選択しました。アプリロックを忘れると、データにアクセスできなくなります。"
|
||||
"appLockOfflineModeWarning": "バックアップなしで進むことを選択しました。アプリロックを忘れると、データにアクセスできなくなります。",
|
||||
"duplicateCodes": "重複コード",
|
||||
"noDuplicates": "✨ 重複なし",
|
||||
"youveNoDuplicateCodesThatCanBeCleared": "削除できる重複コードはありません",
|
||||
"deduplicateCodes": "重複コード",
|
||||
"deselectAll": "すべての選択を解除",
|
||||
"selectAll": "すべて選択",
|
||||
"deleteDuplicates": "重複を削除",
|
||||
"plainHTML": "Plain HTML",
|
||||
"tellUsWhatYouThink": "ご意見をお聞かせください",
|
||||
"dropReview": "App/Playストアにレビューを投稿する",
|
||||
"supportEnte": "<bold-green>ente</bold-green>をサポートする",
|
||||
"giveUsAStarOnGithub": "Githubで星をつける",
|
||||
"free5GB": "<bold-green>ente</bold-green>フォトで5GB無料",
|
||||
"loginWithAuthAccount": "認証アカウントでログイン",
|
||||
"freeStorageOffer": "<bold-green>ente</bold-green>の写真が10%オフ",
|
||||
"freeStorageOfferDescription": "クーポンコード \"AUTH\" の使用で初年度が10%オフになります"
|
||||
}
|
||||
@@ -504,5 +504,6 @@
|
||||
"deselectAll": "Naikinti visų pasirinkimą",
|
||||
"selectAll": "Pasirinkti viską",
|
||||
"deleteDuplicates": "Ištrinti dublikatus",
|
||||
"plainHTML": "Grynasis HTML"
|
||||
"plainHTML": "Grynasis HTML",
|
||||
"freeStorageOfferDescription": "Naudokite kodą „AUTH“, kad gautumėte 10 % nuolaida pirmiesiems metams. "
|
||||
}
|
||||
@@ -1 +1,28 @@
|
||||
{}
|
||||
{
|
||||
"blog": "ബ്ലോഗ്",
|
||||
"verifyPassword": "പാസ്വേഡ് സ്ഥിരീകരിക്കുക",
|
||||
"recreatePassword": "പാസ്വേഡ് പുനഃസൃഷ്ടിക്കുക",
|
||||
"incorrectPasswordTitle": "തെറ്റായ പാസ്വേഡ്",
|
||||
"welcomeBack": "വീണ്ടും സ്വാഗതം!",
|
||||
"emailAlreadyRegistered": "ഇമെയിൽ ഇതിനകം രജിസ്റ്റർ ചെയ്തിട്ടുണ്ട്.",
|
||||
"emailNotRegistered": "ഇമെയിൽ രജിസ്റ്റർ ചെയ്തിട്ടില്ല.",
|
||||
"changeEmail": "ഇമെയിൽ മാറ്റുക",
|
||||
"changePassword": "പാസ്സ്വേർഡ് മാറ്റുക",
|
||||
"ok": "ശരി",
|
||||
"cancel": "റദ്ദാക്കുക",
|
||||
"yes": "അതെ",
|
||||
"no": "അല്ല",
|
||||
"email": "ഇമെയിൽ",
|
||||
"somethingWentWrongMessage": "എന്തോ കുഴപ്പമുണ്ടായി, ദയവായി വീണ്ടും ശ്രമിക്കുക",
|
||||
"inFamilyPlanMessage": "നിങ്ങൾ ഒരു ഫാമിലി പ്ലാനിലാണ്!",
|
||||
"scan": "സ്കാൻ ചെയ്യുക",
|
||||
"scanACode": "കോഡ് സ്കാൻ ചെയ്യുക",
|
||||
"verify": "പരിശോധിക്കുക",
|
||||
"verifyEmail": "ഇമെയിൽ സ്ഥിരീകരിക്കുക",
|
||||
"enterCodeHint": "നിങ്ങളുടെ ഓതന്റിക്കേറ്റർ ആപ്പിൽ നിന്നുള്ള 6 അക്ക കോഡ് നൽകുക",
|
||||
"twoFactorAuthTitle": "ടു-ഫാക്ടർ ആധികാരികത",
|
||||
"createNewAccount": "പുതിയ അക്കൗണ്ട് സൃഷ്ടിക്കുക",
|
||||
"confirmPassword": "പാസ്വേഡ് സ്ഥിരീകരിക്കുക",
|
||||
"language": "ഭാഷ",
|
||||
"security": "സുരക്ഷ"
|
||||
}
|
||||
@@ -504,5 +504,13 @@
|
||||
"deselectAll": "Alles deselecteren",
|
||||
"selectAll": "Alles selecteren",
|
||||
"deleteDuplicates": "Dubbelen verwijderen",
|
||||
"plainHTML": "Alleen HTML"
|
||||
"plainHTML": "Alleen HTML",
|
||||
"tellUsWhatYouThink": "Vertel ons wat je vindt",
|
||||
"dropReview": "Laat een beoordeling achter in de App/Play Store",
|
||||
"supportEnte": "Steun <bold-green>ente</bold-green>",
|
||||
"giveUsAStarOnGithub": "Geef ons een ster op Github",
|
||||
"free5GB": "5GB gratis op <bold-green>ente</bold-green> Photos",
|
||||
"loginWithAuthAccount": "Log in met je Auth account",
|
||||
"freeStorageOffer": "10% korting op <bold-green>ente</bold-green> photos",
|
||||
"freeStorageOfferDescription": "Gebruik de code \"AUTH\" voor 10% korting op je eerste jaar"
|
||||
}
|
||||
@@ -504,5 +504,13 @@
|
||||
"deselectAll": "Odznacz wszystko",
|
||||
"selectAll": "Zaznacz wszystko",
|
||||
"deleteDuplicates": "Usuń duplikaty",
|
||||
"plainHTML": "Zwykły HTML"
|
||||
"plainHTML": "Zwykły HTML",
|
||||
"tellUsWhatYouThink": "Wyraź swoją opinię",
|
||||
"dropReview": "Napisz recenzję w App Store/Play Store",
|
||||
"supportEnte": "Wesprzyj <bold-green>ente</bold-green>",
|
||||
"giveUsAStarOnGithub": "Daj nam gwiazdkę na Githubie",
|
||||
"free5GB": "5 GB za darmo na zdjęcia <bold-green>ente</bold-green>",
|
||||
"loginWithAuthAccount": "Zaloguj się przy użyciu konta Auth",
|
||||
"freeStorageOffer": "10% zniżki na zdjęcia <bold-green>ente</bold-green>",
|
||||
"freeStorageOfferDescription": "Użyj kodu „AUTH”, aby uzyskać 10% zniżki na pierwszy rok"
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"@counterAppBarTitle": {
|
||||
"description": "Text shown in the AppBar of the Counter Page"
|
||||
},
|
||||
"onBoardingBody": "Copie com segurança seus códigos 2FA",
|
||||
"onBoardingBody": "Salve com segurança seus códigos 2FA",
|
||||
"onBoardingGetStarted": "Introdução",
|
||||
"setupFirstAccount": "Configure sua primeira conta",
|
||||
"importScanQrCode": "Escanear QR code",
|
||||
@@ -19,7 +19,7 @@
|
||||
"pleaseVerifyDetails": "Verifique os detalhes e tente novamente",
|
||||
"codeIssuerHint": "Emissor",
|
||||
"codeSecretKeyHint": "Chave secreta",
|
||||
"secret": "Segredo",
|
||||
"secret": "Chave secreta",
|
||||
"all": "Todos",
|
||||
"notes": "Notas",
|
||||
"notesLengthLimit": "Notas tem um limite de até {count} caracteres",
|
||||
@@ -504,5 +504,13 @@
|
||||
"deselectAll": "Deselecionar tudo",
|
||||
"selectAll": "Selecionar tudo",
|
||||
"deleteDuplicates": "Excluir duplicados",
|
||||
"plainHTML": "HTML simples"
|
||||
"plainHTML": "HTML simples",
|
||||
"tellUsWhatYouThink": "Diga-nos o que pensa",
|
||||
"dropReview": "Deixe uma avaliação na App/Play Store",
|
||||
"supportEnte": "Apoie o <bold-green>ente.io</bold-green>",
|
||||
"giveUsAStarOnGithub": "Dê-nos uma estrela no Github",
|
||||
"free5GB": "5GB grátis no <bold-green>ente</bold-green> Photos",
|
||||
"loginWithAuthAccount": "Registrar-se com sua conta Auth",
|
||||
"freeStorageOffer": "10% de desconto no <bold-green>ente</bold-green> photos",
|
||||
"freeStorageOfferDescription": "Use o cupom \"AUTH\" para obter 10% de desconto no primeiro ano"
|
||||
}
|
||||
@@ -88,6 +88,8 @@
|
||||
"useRecoveryKey": "Kurtarma anahtarını kullan",
|
||||
"incorrectPasswordTitle": "Yanlış şifre",
|
||||
"welcomeBack": "Tekrar hoş geldiniz!",
|
||||
"emailAlreadyRegistered": "E-posta zaten kayıtlı.",
|
||||
"emailNotRegistered": "E-posta kayıtlı değil.",
|
||||
"madeWithLoveAtPrefix": "❤️ ile şurada yapılmıştır ",
|
||||
"supportDevs": "Bu projeyi desteklemek için <bold-green>ente</bold-green> kanalına abone olun",
|
||||
"supportDiscount": "İlk yılda %10 indirim için \"AUTH\" kupon kodunu kullanın",
|
||||
@@ -333,6 +335,7 @@
|
||||
}
|
||||
},
|
||||
"manualSort": "Özel",
|
||||
"editOrder": "Sıralamayı düzenle",
|
||||
"mostFrequentlyUsed": "Sık kullanılan",
|
||||
"mostRecentlyUsed": "Son kullanılan",
|
||||
"activeSessions": "Aktif oturumlar",
|
||||
@@ -501,5 +504,6 @@
|
||||
"deselectAll": "Tümünün seçimini kaldır",
|
||||
"selectAll": "Tümünü seç",
|
||||
"deleteDuplicates": "Yinelenenleri sil",
|
||||
"plainHTML": "Sade HTML"
|
||||
"plainHTML": "Sade HTML",
|
||||
"supportEnte": "<bold-Green>Ente</bold-Green>'yi destekle"
|
||||
}
|
||||
@@ -504,5 +504,13 @@
|
||||
"deselectAll": "取消全选",
|
||||
"selectAll": "全选",
|
||||
"deleteDuplicates": "删除重复项",
|
||||
"plainHTML": "Plain HTML"
|
||||
"plainHTML": "Plain HTML",
|
||||
"tellUsWhatYouThink": "告诉我们您的想法",
|
||||
"dropReview": "在 App Store/Play 商店上发表评测",
|
||||
"supportEnte": "支持 <bold-green>ente</bold-green>",
|
||||
"giveUsAStarOnGithub": "在 Github 上给我们一个星标",
|
||||
"free5GB": "<bold-green>ente</bold-green> Photos 上 5GB 可用空间",
|
||||
"loginWithAuthAccount": "使用您的认证账户登录",
|
||||
"freeStorageOffer": "购买 <bold-green>ente</bold-green> Photos 可享受 10% 优惠",
|
||||
"freeStorageOfferDescription": "使用优惠码“AUTH”可享受首年 10% 折扣"
|
||||
}
|
||||
@@ -877,6 +877,7 @@ class UserService {
|
||||
"twoFactorType": twoFactorTypeToString(type),
|
||||
},
|
||||
);
|
||||
await dialog.hide();
|
||||
if (response.statusCode == 200) {
|
||||
// ignore: unawaited_futures
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
@@ -974,6 +975,7 @@ class UserService {
|
||||
"twoFactorType": twoFactorTypeToString(type),
|
||||
},
|
||||
);
|
||||
await dialog.hide();
|
||||
if (response.statusCode == 200) {
|
||||
showShortToast(
|
||||
context,
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
class WindowListenerService {
|
||||
static const double minWindowHeight = 320.0;
|
||||
static const double minWindowHeight = 600.0;
|
||||
static const double minWindowWidth = 800.0;
|
||||
static const double maxWindowHeight = 8192.0;
|
||||
static const double maxWindowWidth = 8192.0;
|
||||
|
||||
@@ -33,8 +33,7 @@ class _LockScreenState extends State<LockScreen> with WidgetsBindingObserver {
|
||||
int remainingTimeInSeconds = 0;
|
||||
final _lockscreenSetting = LockScreenSettings.instance;
|
||||
late Brightness _platformBrightness;
|
||||
final bool hasOptedForOfflineMode =
|
||||
Configuration.instance.hasOptedForOfflineMode();
|
||||
final bool isLoggedIn = Configuration.instance.isLoggedIn();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -56,15 +55,15 @@ class _LockScreenState extends State<LockScreen> with WidgetsBindingObserver {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
leading: hasOptedForOfflineMode
|
||||
? const SizedBox.shrink()
|
||||
: IconButton(
|
||||
leading: isLoggedIn
|
||||
? IconButton(
|
||||
icon: const Icon(Icons.logout_outlined),
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
onPressed: () {
|
||||
_onLogoutTapped(context);
|
||||
},
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
body: GestureDetector(
|
||||
onTap: () {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/models/account/two_factor.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
import 'package:ente_auth/theme/ente_theme.dart';
|
||||
import 'package:ente_auth/utils/email_util.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@@ -97,7 +98,8 @@ class _TwoFactorRecoveryPageState extends State<TwoFactorRecoveryPage> {
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
fontSize: 12,
|
||||
color: Colors.white.withOpacity(0.9),
|
||||
color:
|
||||
getEnteColorScheme(context).textBase.withOpacity(0.9),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
48
cli/main.go
@@ -15,7 +15,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var AppVersion = "0.2.2"
|
||||
var AppVersion = "0.2.3"
|
||||
|
||||
func main() {
|
||||
cliConfigDir, err := GetCLIConfigDir()
|
||||
@@ -50,18 +50,21 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
// Define a set of commands that do not require KeyHolder initialisation.
|
||||
skipKeyHolderCommands := map[string]struct{}{"version": {}, "docs": {}, "help": {}}
|
||||
// Define a set of commands that do not require KeyHolder or cli initialisation.
|
||||
skipInitCommands := map[string]struct{}{"version": {}, "docs": {}, "help": {}}
|
||||
|
||||
var keyHolder *secrets.KeyHolder
|
||||
|
||||
// Only initialise KeyHolder if the command isn't in the skip list.
|
||||
shouldInit := len(os.Args) > 1
|
||||
if len(os.Args) > 1 {
|
||||
if _, skip := skipKeyHolderCommands[os.Args[1]]; !skip {
|
||||
keyHolder = secrets.NewKeyHolder(secrets.GetOrCreateClISecret())
|
||||
if _, skip := skipInitCommands[os.Args[1]]; skip {
|
||||
shouldInit = false
|
||||
}
|
||||
}
|
||||
|
||||
if shouldInit {
|
||||
keyHolder = secrets.NewKeyHolder(secrets.GetOrCreateClISecret())
|
||||
}
|
||||
ctrl := pkg.ClICtrl{
|
||||
Client: api.NewClient(api.Params{
|
||||
Debug: viper.GetBool("log.http"),
|
||||
@@ -71,16 +74,10 @@ func main() {
|
||||
KeyHolder: keyHolder,
|
||||
}
|
||||
|
||||
err = ctrl.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if len(os.Args) == 1 {
|
||||
// If no arguments are passed, show help
|
||||
os.Args = append(os.Args, "help")
|
||||
}
|
||||
defer func() {
|
||||
if err := db.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
if len(os.Args) == 2 && os.Args[1] == "docs" {
|
||||
log.Println("Generating docs")
|
||||
err = cmd.GenerateDocs()
|
||||
@@ -89,9 +86,16 @@ func main() {
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(os.Args) == 1 {
|
||||
// If no arguments are passed, show help
|
||||
os.Args = append(os.Args, "help")
|
||||
if shouldInit {
|
||||
err = ctrl.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer func() {
|
||||
if err := db.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
if os.Args[1] == "version" && viper.GetString("endpoint.api") != constants.EnteApiUrl {
|
||||
log.Printf("Custom endpoint: %s\n", viper.GetString("endpoint.api"))
|
||||
@@ -120,10 +124,10 @@ func initConfig(cliConfigDir string) {
|
||||
func GetCLIConfigDir() (string, error) {
|
||||
var configDir = os.Getenv("ENTE_CLI_CONFIG_DIR")
|
||||
|
||||
if configDir == "" {
|
||||
// for backward compatibility, check for ENTE_CLI_CONFIG_PATH
|
||||
configDir = os.Getenv("ENTE_CLI_CONFIG_PATH")
|
||||
}
|
||||
if configDir == "" {
|
||||
// for backward compatibility, check for ENTE_CLI_CONFIG_PATH
|
||||
configDir = os.Getenv("ENTE_CLI_CONFIG_PATH")
|
||||
}
|
||||
|
||||
if configDir != "" {
|
||||
// remove trailing slash (for all OS)
|
||||
|
||||
6
desktop/.gitignore
vendored
@@ -21,5 +21,9 @@ out
|
||||
# electron-builder
|
||||
dist/
|
||||
|
||||
# We download it on demand, if needed for the particular OS/arch.
|
||||
# Legacy, people who checked out main for a brief while in Jan 2025 may have
|
||||
# this. Can be removed in the future.
|
||||
build/magick*
|
||||
|
||||
# We download it on demand, if needed for the particular OS/arch.
|
||||
build/vips*
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v1.7.9 (Unreleased)
|
||||
## v1.7.10 (Unreleased)
|
||||
|
||||
- .
|
||||
|
||||
## v1.7.9
|
||||
|
||||
- Light mode.
|
||||
- Faster and more stable thumbnail generation.
|
||||
- Support `.supplemental-metadata` JSON files in Google Takeout.
|
||||
|
||||
## v1.7.8
|
||||
|
||||
- Parse description from image metadata.
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
</branding>
|
||||
|
||||
<releases>
|
||||
<release version="1.7.8" date="2025-01-13">
|
||||
<url type="details">https://github.com/ente-io/photos-desktop/releases/tag/v1.7.8</url>
|
||||
<release version="1.7" date="2025-01-13">
|
||||
<url type="details">https://github.com/ente-io/photos-desktop/releases</url>
|
||||
</release>
|
||||
</releases>
|
||||
</component>
|
||||
|
||||
@@ -108,13 +108,13 @@ For video conversions and metadata extraction, we use ffmpeg. To bundle a
|
||||
[ffmpeg-static](https://github.com/eugeneware/ffmpeg-static).
|
||||
|
||||
> There is a significant (~20x) speed difference between using the compiled
|
||||
> ffmpeg binary and using the wasm one (that our renderer process already has).
|
||||
> FFmpeg binary and using the Wasm one (that our renderer process already has).
|
||||
> Which is why we bundle it to speed up operations on the desktop app.
|
||||
|
||||
On Linux and Windows, we use ImageMagick for thumbnail generation and JPEG
|
||||
conversion of unpreviewable images. A static OS/architecture specific binary of
|
||||
this is bundled in our extra resources (`build`) folder by `scripts/magick.sh`
|
||||
and/or `scripts/beforeBuild.js`. See "[Note: ImageMagick]" for more details.
|
||||
On Linux and Windows, we use `vips` for thumbnail generation and JPEG conversion
|
||||
of unpreviewable images. A static OS/architecture specific binary of this is
|
||||
bundled in our extra resources (`build`) folder by `scripts/vips.sh` and/or
|
||||
`scripts/beforeBuild.js`. See "[Note: vips]" for more details.
|
||||
|
||||
On macOS, we use the `sips` CLI tool for these tasks, but that is already
|
||||
available on the host machine, and is not bundled with our app.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ente",
|
||||
"version": "1.7.9-beta",
|
||||
"version": "1.7.10-beta",
|
||||
"private": true,
|
||||
"description": "Desktop client for Ente Photos",
|
||||
"repository": "github:ente-io/photos-desktop",
|
||||
@@ -19,7 +19,7 @@
|
||||
"postinstall": "electron-builder install-app-deps",
|
||||
"lint": "yarn prettier --check --log-level warn . && yarn eslint && yarn tsc",
|
||||
"lint-fix": "yarn prettier --write --log-level warn . && yarn eslint && yarn tsc",
|
||||
"prepare": "node scripts/magick.js"
|
||||
"prepare": "node scripts/vips.js"
|
||||
},
|
||||
"resolutions": {
|
||||
"jackspeak": "2.1.1"
|
||||
@@ -31,9 +31,9 @@
|
||||
"clip-bpe-js": "^0.0.6",
|
||||
"comlink": "^4.4.2",
|
||||
"compare-versions": "^6.1.1",
|
||||
"electron-log": "^5.2.4",
|
||||
"electron-log": "^5.3.0",
|
||||
"electron-store": "^8.2.0",
|
||||
"electron-updater": "^6.4.0-alpha.3",
|
||||
"electron-updater": "^6.4.0",
|
||||
"ffmpeg-static": "^5.2.0",
|
||||
"lru-cache": "^11.0.2",
|
||||
"next-electron-server": "^1.0.0",
|
||||
@@ -41,7 +41,7 @@
|
||||
"onnxruntime-node": "^1.20.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.18.0",
|
||||
"@eslint/js": "^9.19.0",
|
||||
"@tsconfig/node20": "^20.1.4",
|
||||
"@types/auto-launch": "^5.0.5",
|
||||
"@types/eslint__js": "^8.42.3",
|
||||
@@ -49,15 +49,15 @@
|
||||
"ajv": "^8.17.1",
|
||||
"concurrently": "^9.1.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"electron": "^34.0.0",
|
||||
"electron-builder": "^26.0.0-alpha.10",
|
||||
"electron": "^34.1.1",
|
||||
"electron-builder": "^26.0.0",
|
||||
"eslint": "^9",
|
||||
"prettier": "3.4.2",
|
||||
"prettier-plugin-organize-imports": "^4.1.0",
|
||||
"prettier-plugin-packagejson": "^2.5.8",
|
||||
"shx": "^0.3.4",
|
||||
"typescript": "^5.7.2",
|
||||
"typescript-eslint": "^8.21.0"
|
||||
"typescript-eslint": "^8.23.0"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"productName": "ente"
|
||||
|
||||
@@ -3,8 +3,8 @@ const fsp = require("fs/promises");
|
||||
/**
|
||||
* This hook is invoked during the initial build (e.g. when triggered by "yarn
|
||||
* build"), and importantly, on each rebuild for a different architecture during
|
||||
* the build. We use it to ensure that the magick binary is for the current
|
||||
* architecture being built. See "[Note: ImageMagick]" for more details.
|
||||
* the build. We use it to ensure that the vips binary is for the current
|
||||
* architecture being built. See "[Note: vips]" for more details.
|
||||
*
|
||||
* The documentation for this hook is at:
|
||||
* https://www.electron.build/app-builder-lib.interface.configuration#beforebuild
|
||||
@@ -22,8 +22,10 @@ const fsp = require("fs/promises");
|
||||
* },
|
||||
* arch: 'arm64'
|
||||
*
|
||||
* Note that we must not return falsey from this function, because
|
||||
* > Resolving to false will skip dependencies install or rebuild.
|
||||
* Note that we must not return falsey from this function, because:
|
||||
*
|
||||
* > Resolving to false will skip dependencies install or rebuild.
|
||||
*
|
||||
*/
|
||||
module.exports = async (context) => {
|
||||
const { appDir, platform, arch } = context;
|
||||
@@ -35,14 +37,14 @@ module.exports = async (context) => {
|
||||
// https://github.com/electron-userland/electron-builder/blob/master/packages/builder-util/src/arch.ts#L9
|
||||
// https://nodejs.org/api/process.html#processarch
|
||||
if (arch == process.arch) {
|
||||
// `magick.js` would've already downloaded the file, nothing to do.
|
||||
// `vips.js` would've already downloaded the file, nothing to do.
|
||||
return true;
|
||||
}
|
||||
|
||||
const download = async (downloadName, outputName) => {
|
||||
const out = `${appDir}/build/${outputName}`;
|
||||
console.log(`Downloading ${downloadName}`);
|
||||
const downloadPath = `https://github.com/ente-io/ImageMagick/releases/download/2025-01-21/${downloadName}`;
|
||||
const downloadPath = `https://github.com/ente-io/libvips-packaging/releases/download/v8.16.0/${downloadName}`;
|
||||
return fetch(downloadPath)
|
||||
.then((res) => res.blob())
|
||||
.then((blob) => fsp.writeFile(out, blob.stream()))
|
||||
@@ -51,13 +53,13 @@ module.exports = async (context) => {
|
||||
|
||||
switch (`${platform.nodeName}-${arch}`) {
|
||||
case "linux-x64":
|
||||
await download("magick-x86_64", "magick");
|
||||
await download("vips-x64", "vips");
|
||||
case "linux-arm64":
|
||||
await download("magick-aarch64", "magick");
|
||||
await download("vips-arm64", "vips");
|
||||
case "win32-x64":
|
||||
await download("magick-x64.exe", "magick.exe");
|
||||
await download("vips-x86_64.exe", "vips.exe");
|
||||
case "linux-arm64":
|
||||
await download("magick-arm64.exe", "magick.exe");
|
||||
await download("vips-aarch64.exe", "vips.exe");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/**
|
||||
* [Note: ImageMagick]
|
||||
*
|
||||
* We need static builds for Linux and Windows for both x64 and ARM. For this,
|
||||
* we need a custom workflow because (as of writing):
|
||||
*
|
||||
* 1. Upstream doesn't publish ARM64 binaries for Linux
|
||||
*
|
||||
* 2. The Windows portable releases are not part of the artifacts attached to
|
||||
* the upstream GitHub release.
|
||||
*
|
||||
* Our custom workflow is an adaption of the upstream release.yml - its goal is
|
||||
* to have 4 standalone binaries - Linux x64, Linux ARM, Win x64, Win ARM -
|
||||
* attached to a GitHub release from which we can pull them when building the
|
||||
* desktop app.
|
||||
*
|
||||
* This is our custom workflow, which runs on a fork of upstream:
|
||||
* https://github.com/ente-io/ImageMagick/commit/df895cce13d6a3f874a716c05ff2babeb33351b9
|
||||
* (For reference, we also include a copy of it in this repo - `magick.yml`).
|
||||
*
|
||||
* The binaries it creates are available at
|
||||
* https://github.com/ente-io/ImageMagick/releases/tag/2025-01-21.
|
||||
*
|
||||
* To integrate this ImageMagick binary, we need to modify two places:
|
||||
*
|
||||
* 1. This script, `magick.js`, runs during "yarn install" (it is set as the
|
||||
* "prepare" step in our `package.json`). It downloads the relevant binary
|
||||
* for the current OS/arch combination and places it in the `build` folder,
|
||||
* allowing it to be used during development.
|
||||
*
|
||||
* 2. The sibling script, `beforeBuild.js`, runs during "yarn build" (it is set
|
||||
* as the beforeBuild script in `electrons-builder.yml`). It downloads the
|
||||
* relevant binary for the OS/arch combination being built.
|
||||
*
|
||||
* Note that `magick.js` would've already run once `beforeBuild.js` is run, but
|
||||
* on our CI we prepare builds for multiple architectures in one go, so we need
|
||||
* to unconditonally replace the binary with the relevant one for the current
|
||||
* architecture being built (which might be different from the one we're running
|
||||
* on). `beforeBuild.js` runs for each architecture being built.
|
||||
*
|
||||
* On macOS, we don't need ImageMagick since there we use the native `sips`.
|
||||
*/
|
||||
|
||||
const fs = require("fs");
|
||||
const fsp = require("fs/promises");
|
||||
|
||||
const main = () => {
|
||||
switch (`${process.platform}-${process.arch}`) {
|
||||
case "linux-x64":
|
||||
return downloadIfNeeded("magick-x86_64", "magick");
|
||||
case "linux-arm64":
|
||||
return downloadIfNeeded("magick-aarch64", "magick");
|
||||
case "win32-x64":
|
||||
return downloadIfNeeded("magick-x64.exe", "magick.exe");
|
||||
case "linux-arm64":
|
||||
return downloadIfNeeded("magick-arm64.exe", "magick.exe");
|
||||
}
|
||||
};
|
||||
|
||||
const downloadIfNeeded = (downloadName, outputName) => {
|
||||
const out = `build/${outputName}`;
|
||||
|
||||
try {
|
||||
// Making the file executable is the last step, so if the file exists at
|
||||
// this path and is executable, we assume it is the correct one.
|
||||
fs.accessSync(out, fs.constants.X_OK);
|
||||
return;
|
||||
} catch {}
|
||||
|
||||
console.log(`Downloading ${downloadName}`);
|
||||
const downloadPath = `https://github.com/ente-io/ImageMagick/releases/download/2025-01-21/${downloadName}`;
|
||||
return fetch(downloadPath)
|
||||
.then((res) => res.blob())
|
||||
.then((blob) => fsp.writeFile(out, blob.stream()))
|
||||
.then(() => fsp.chmod(out, "744"));
|
||||
};
|
||||
|
||||
main();
|
||||
@@ -1,127 +0,0 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push: # Push a tag to build and create a draft release
|
||||
tags:
|
||||
- "*"
|
||||
|
||||
name: binaries-for-ente
|
||||
jobs:
|
||||
create_magick_binary:
|
||||
name: Create magick binary (Linux)
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-24.04, ubuntu-24.04-arm]
|
||||
compiler: [gcc]
|
||||
include:
|
||||
- os: ubuntu-24.04
|
||||
arch: x86_64
|
||||
- os: ubuntu-24.04-arm
|
||||
arch: aarch64
|
||||
- compiler: gcc
|
||||
cxx_compiler: g++
|
||||
packages: gcc g++
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
set -e
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
sudo apt update -y
|
||||
sudo apt install -y autoconf curl fuse git kmod libbz2-dev libdjvulibre-dev libfontconfig-dev libfreetype6-dev libfribidi-dev libharfbuzz-dev liblcms-dev libopenexr-dev libopenjp2-7-dev libturbojpeg0-dev liblqr-dev libraqm-dev libtiff-dev libwebp-dev libx11-dev libxml2-dev liblzma-dev make software-properties-common wget ${{ matrix.packages }}
|
||||
sudo add-apt-repository ppa:git-core/ppa -y
|
||||
sudo apt install -y git
|
||||
sudo add-apt-repository ppa:strukturag/libheif -y
|
||||
sudo add-apt-repository ppa:strukturag/libde265 -y
|
||||
sudo apt install libheif-dev -y
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Avoid fatal: detected dubious ownership in repository at '/__w/ImageMagick/ImageMagick'
|
||||
# Possible workaround: https://github.com/actions/runner/issues/2033#issuecomment-1598547465
|
||||
- name: Flag current workspace as safe for git
|
||||
run: git config --global --add safe.directory ${GITHUB_WORKSPACE}
|
||||
|
||||
- name: Download AppImage
|
||||
run: |
|
||||
set -e
|
||||
sudo apt install -y file
|
||||
mkdir -p out/app-image
|
||||
cd out/app-image
|
||||
wget -c https://github.com/$(wget -q https://github.com/probonopd/go-appimage/releases/expanded_assets/continuous -O - | grep "appimagetool-.*-${{ matrix.arch }}.AppImage" | head -n 1 | cut -d '"' -f 2)
|
||||
chmod +x appimagetool-*.AppImage
|
||||
|
||||
- name: Build ImageMagick
|
||||
env:
|
||||
CFLAGS:
|
||||
-Wno-deprecated-declarations -Wdeclaration-after-statement
|
||||
-Wno-error=unused-variable
|
||||
CC: ${{ matrix.compiler }}
|
||||
CXX: ${{ matrix.cxx_compiler }}
|
||||
run: |
|
||||
set -e
|
||||
./configure --with-quantum-depth=16 --without-magick-plus-plus --without-perl --without-x --disable-docs --prefix=/usr
|
||||
make
|
||||
make install DESTDIR=$(readlink -f out/appdir)
|
||||
|
||||
- name: Create ImageMagick AppImage
|
||||
run: |
|
||||
set -e
|
||||
mkdir -p out/appdir/usr/share/applications/
|
||||
cp app-image/imagemagick.desktop out/appdir/usr/share/applications/
|
||||
mkdir -p out/appdir/usr/share/icons/hicolor/256x256/apps/
|
||||
cp app-image/icon.png out/appdir/usr/share/icons/hicolor/256x256/apps/imagemagick.png
|
||||
unset QTDIR
|
||||
unset QT_PLUGIN_PATH
|
||||
unset LD_LIBRARY_PATH
|
||||
export VERSION=7
|
||||
cd out
|
||||
./app-image/appimagetool-*.AppImage --appimage-extract-and-run -s deploy appdir/usr/share/applications/*.desktop
|
||||
chmod +x appdir/usr/lib/ld-linux-aarch64.so.1 || true
|
||||
./app-image/appimagetool-*.AppImage --appimage-extract-and-run appdir
|
||||
mkdir artifacts
|
||||
cp ImageMagick*.AppImage artifacts/magick-${{ matrix.arch }}
|
||||
|
||||
- name: Upload ImageMagick AppImage
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: magick-${{ matrix.arch }}
|
||||
path: out/artifacts
|
||||
|
||||
- name: Create a draft GitHub release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
artifacts: "out/artifacts/*"
|
||||
draft: true
|
||||
allowUpdates: true
|
||||
updateOnlyUnreleased: true
|
||||
|
||||
download_and_keep_windows_binaries:
|
||||
name: Download magick binary (Windows)
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Download
|
||||
run: |
|
||||
mkdir -p out/artifacts
|
||||
curl -LO https://imagemagick.org/archive/binaries/ImageMagick-7.1.1-43-portable-Q16-x64.zip
|
||||
unzip ImageMagick-7.1.1-43-portable-Q16-x64.zip
|
||||
cp ImageMagick-7.1.1-43-portable-Q16-x64/magick.exe out/artifacts/magick-x64.exe
|
||||
curl -LO https://imagemagick.org/archive/binaries/ImageMagick-7.1.1-43-portable-Q16-arm64.zip
|
||||
unzip ImageMagick-7.1.1-43-portable-Q16-arm64.zip
|
||||
cp ImageMagick-7.1.1-43-portable-Q16-arm64/magick.exe out/artifacts/magick-arm64.exe
|
||||
|
||||
- name: Upload ImageMagick exes
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: magick-${{ matrix.arch }}
|
||||
path: out/artifacts
|
||||
|
||||
- name: Create a draft GitHub release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
artifacts: "out/artifacts/*"
|
||||
draft: true
|
||||
allowUpdates: true
|
||||
updateOnlyUnreleased: true
|
||||
68
desktop/scripts/vips.js
Executable file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* [Note: vips]
|
||||
*
|
||||
* For use within our Electron app we need static builds for Linux and Windows
|
||||
* for both x64 and ARM. For this, we need a custom workflow because (as of
|
||||
* writing) upstream doesn't publish these.
|
||||
*
|
||||
* This is our custom workflow, which runs on a fork of upstream:
|
||||
* https://github.com/ente-io/libvips-packaging/commit/a298aff3e1f25f713508d31d0c3a55a4f828fdd3
|
||||
*
|
||||
* The binaries it creates are available at
|
||||
* https://github.com/ente-io/libvips-packaging/releases/tag/v8.16.0
|
||||
*
|
||||
* To integrate this binary, we need to modify two places:
|
||||
*
|
||||
* 1. This script, `vips.js`, runs during "yarn install" (it is set as the
|
||||
* "prepare" step in our `package.json`). It downloads the relevant binary
|
||||
* for the current OS/arch combination and places it in the `build` folder,
|
||||
* allowing it to be used during development.
|
||||
*
|
||||
* 2. The sibling script, `beforeBuild.js`, runs during "yarn build" (it is set
|
||||
* as the beforeBuild script in `electrons-builder.yml`). It downloads the
|
||||
* relevant binary for the OS/arch combination being built.
|
||||
*
|
||||
* Note that `vips.js` would've already run once `beforeBuild.js` is run, but on
|
||||
* our CI we prepare builds for multiple architectures in one go, so we need to
|
||||
* unconditonally replace the binary with the relevant one for the current
|
||||
* architecture being built (which might be different from the one we're running
|
||||
* on). `beforeBuild.js` runs for each architecture being built.
|
||||
*
|
||||
* On macOS, we don't need `vips` since there we use the native `sips`.
|
||||
*/
|
||||
|
||||
const fs = require("fs");
|
||||
const fsp = require("fs/promises");
|
||||
|
||||
const main = () => {
|
||||
switch (`${process.platform}-${process.arch}`) {
|
||||
case "linux-x64":
|
||||
return downloadIfNeeded("vips-x64", "vips");
|
||||
case "linux-arm64":
|
||||
return downloadIfNeeded("vips-arm64", "vips");
|
||||
case "win32-x64":
|
||||
return downloadIfNeeded("vips-x86_64.exe", "vips.exe");
|
||||
case "linux-arm64":
|
||||
return downloadIfNeeded("vips-aarch64.exe", "vips.exe");
|
||||
}
|
||||
};
|
||||
|
||||
const downloadIfNeeded = (downloadName, outputName) => {
|
||||
const out = `build/${outputName}`;
|
||||
|
||||
try {
|
||||
// Making the file executable is the last step, so if the file exists at
|
||||
// this path and is executable, we assume it is the correct one.
|
||||
fs.accessSync(out, fs.constants.X_OK);
|
||||
return;
|
||||
} catch {}
|
||||
|
||||
console.log(`Downloading ${downloadName}`);
|
||||
const downloadPath = `https://github.com/ente-io/libvips-packaging/releases/download/v8.16.0/${downloadName}`;
|
||||
return fetch(downloadPath)
|
||||
.then((res) => res.blob())
|
||||
.then((blob) => fsp.writeFile(out, blob.stream()))
|
||||
.then(() => fsp.chmod(out, "744"));
|
||||
};
|
||||
|
||||
main();
|
||||
2
desktop/scripts/vips/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
1.heic
|
||||
1.jpeg
|
||||
@@ -1,18 +0,0 @@
|
||||
FROM ubuntu:24.04
|
||||
|
||||
# https://github.com/libvips/libvips/blob/master/.github/workflows/ci.yml
|
||||
RUN apt-get update -y && apt-get install -y \
|
||||
meson pkg-config \
|
||||
libarchive-dev libcfitsio-dev libcgif-dev \
|
||||
libexif-dev libexpat1-dev libffi-dev \
|
||||
libfftw3-dev libheif-dev libheif-plugin-aomenc \
|
||||
libheif-plugin-x265 libhwy-dev libimagequant-dev \
|
||||
libjpeg-dev libjxl-dev liblcms2-dev \
|
||||
libmatio-dev libnifti-dev libopenexr-dev \
|
||||
libopenjp2-7-dev libopenslide-dev libpango1.0-dev \
|
||||
libpng-dev libpoppler-glib-dev librsvg2-dev \
|
||||
libtiff5-dev libwebp-dev
|
||||
|
||||
RUN apt-get install -y git && git clone --depth 1 https://github.com/libvips/libvips
|
||||
|
||||
WORKDIR /libvips
|
||||
@@ -1,74 +0,0 @@
|
||||
FROM debian:bullseye
|
||||
|
||||
# Don't care about layer size.
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc \
|
||||
gcc-10 \
|
||||
make \
|
||||
pkg-config
|
||||
|
||||
# Don't care about layer size.
|
||||
RUN apt-get install -y --no-install-recommends \
|
||||
python3-minimal \
|
||||
python3-pip \
|
||||
python3-setuptools \
|
||||
patchelf
|
||||
|
||||
RUN python3 -m pip \
|
||||
--disable-pip-version-check \
|
||||
--no-cache-dir \
|
||||
install \
|
||||
'staticx==0.12.0'
|
||||
|
||||
# Don't care about layer caching, because I'm only using docker for building.
|
||||
RUN apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
g++ \
|
||||
g++-10 \
|
||||
libglib2.0-dev \
|
||||
libexpat1-dev \
|
||||
libjpeg-dev \
|
||||
libpng-dev \
|
||||
libimagequant-dev \
|
||||
libexif-dev \
|
||||
liborc-0.4-dev \
|
||||
&& rm -rf /var/lib/apt/lists
|
||||
|
||||
# TODO: Vendored source to remove test/ and doc/ with patches to remove test/ from configure.
|
||||
# This would also remove the need to install ca-certificates + curl.
|
||||
|
||||
# TODO: libspng build with meson, miniz to replace libpng-dev.
|
||||
# https://github.com/randy408/libspng/blob/master/docs/build.md#meson
|
||||
# Then, publish the final image somewhere.
|
||||
|
||||
WORKDIR /build
|
||||
RUN curl -sL https://github.com/libvips/libvips/releases/download/v8.10.1/vips-8.10.1.tar.gz | \
|
||||
tar -xz -f- --strip-components=1
|
||||
|
||||
# XXX: -static doesn't work here. I'm using staticx to make the final vips binary static.
|
||||
# Could also try clang.
|
||||
# TODO: webp support
|
||||
RUN CFLAGS="-O2 -flto -pipe" CXXFLAGS="-O2 -flto -pipe" \
|
||||
./configure \
|
||||
--disable-deprecated \
|
||||
--disable-shared \
|
||||
--disable-static \
|
||||
--disable-dependency-tracking \
|
||||
--disable-gtk-doc
|
||||
|
||||
# This is the fastest easiest way I found to compile the
|
||||
# CLI as fast as possible. You can probably get more optimal,
|
||||
# but it'd be a lot harder wrestling autotools.
|
||||
RUN cd libvips \
|
||||
&& make -j"$(nproc)"
|
||||
|
||||
RUN cd tools \
|
||||
&& make -j"$(nproc)" vips
|
||||
|
||||
RUN cd tools \
|
||||
&& staticx vips /bin/vips \
|
||||
&& strip -s /bin/vips
|
||||
|
||||
ENTRYPOINT ["/bin/vips"]
|
||||
CMD ["--help"]
|
||||
@@ -1,38 +0,0 @@
|
||||
FROM --platform=linux/arm64/v8 alpine:3.18
|
||||
|
||||
ARG VIPS_VERSION=8.14.5
|
||||
ARG ALPINE_VERSION=3.18
|
||||
|
||||
# Environment variables
|
||||
ENV VIPS_HOME=/usr/local/vips-${VIPS_VERSION}
|
||||
ENV VIPS_BLOCK_UNTRUSTED=true \
|
||||
LD_LIBRARY_PATH=$VIPS_HOME/lib \
|
||||
PKG_CONFIG_PATH=$VIPS_HOME/lib/pkgconfig \
|
||||
PATH=$PATH:$VIPS_HOME/bin \
|
||||
WORKDIR=/usr/local/src
|
||||
|
||||
WORKDIR $WORKDIR
|
||||
|
||||
RUN apk add xz \
|
||||
&& wget https://github.com/libvips/libvips/releases/download/v${VIPS_VERSION}/vips-${VIPS_VERSION}.tar.xz \
|
||||
&& tar -xf vips-${VIPS_VERSION}.tar.xz \
|
||||
&& cd vips-${VIPS_VERSION} \
|
||||
&& apk add \
|
||||
meson \
|
||||
build-base \
|
||||
vips-dev \
|
||||
fftw-dev \
|
||||
glib-dev \
|
||||
expat-dev expat \
|
||||
libjpeg-turbo-dev \
|
||||
libheif-dev \
|
||||
libspng-dev \
|
||||
curl
|
||||
|
||||
RUN APK add curl-dev
|
||||
RUN meson configure -Dintrospection=false -Dmodules=disabled -Dexamples=false -Dheif=disabled -Djpeg=disabled -Dopenjpeg=disabled -Ddeprecated=false -Dcplusplus=false --default-library=static --prefer-static --buildtype release
|
||||
|
||||
# RUN meson setup build-dir -Dintrospection=false -Dmodules=disabled -Dexamples=false --prefer-static --buildtype release \
|
||||
# && cd build-dir \
|
||||
# && meson compile \
|
||||
# && meson install
|
||||
@@ -1,6 +0,0 @@
|
||||
Experimenting with libvips.
|
||||
|
||||
```sh
|
||||
docker build -t vips-test .
|
||||
docker run -it --rm -v $(pwd):/w vips-test vips copy /w/1.heic /w/1.jpeg
|
||||
```
|
||||
@@ -10,14 +10,15 @@
|
||||
*/
|
||||
|
||||
import { nativeImage, shell } from "electron/common";
|
||||
import type { WebContents } from "electron/main";
|
||||
import {
|
||||
BrowserWindow,
|
||||
Menu,
|
||||
Tray,
|
||||
app,
|
||||
dialog,
|
||||
nativeTheme,
|
||||
protocol,
|
||||
type WebContents,
|
||||
} from "electron/main";
|
||||
import serveNextAt from "next-electron-server";
|
||||
import { existsSync } from "node:fs";
|
||||
@@ -95,10 +96,10 @@ const main = () => {
|
||||
/**
|
||||
* Handle an open URL request, but ensuring that we have a mainWindow.
|
||||
*/
|
||||
const handleOpenURLEnsuringWindow = (url: string) => {
|
||||
const handleOpenEnteURLEnsuringWindow = (url: string) => {
|
||||
log.info(`Attempting to handle request to open URL: ${url}`);
|
||||
if (mainWindow) handleEnteLinks(mainWindow, url);
|
||||
else setTimeout(() => handleOpenURLEnsuringWindow(url), 1000);
|
||||
else setTimeout(() => handleOpenEnteURLEnsuringWindow(url), 1000);
|
||||
};
|
||||
|
||||
app.on("second-instance", (_, argv: string[]) => {
|
||||
@@ -109,9 +110,15 @@ const main = () => {
|
||||
mainWindow.focus();
|
||||
}
|
||||
// On Windows and Linux, this is how we get deeplinks.
|
||||
//
|
||||
// See: registerForEnteLinks
|
||||
const url = argv.pop();
|
||||
if (url) handleOpenURLEnsuringWindow(url);
|
||||
//
|
||||
// Note that Chromium reserves the right to fudge with the order of the
|
||||
// command line arguments, including inserting things in arbitrary
|
||||
// places, so we need to go through the args to find the one that is
|
||||
// pertinent to us (if any) instead of looking at a fixed position.
|
||||
const url = argv.find((arg) => arg.startsWith("ente://app"));
|
||||
if (url) handleOpenEnteURLEnsuringWindow(url);
|
||||
});
|
||||
|
||||
// Emitted once, when Electron has finished initializing.
|
||||
@@ -145,7 +152,7 @@ const main = () => {
|
||||
void mainWindow.loadURL(rendererURL);
|
||||
|
||||
// Continue on with the rest of the startup sequence.
|
||||
Menu.setApplicationMenu(await createApplicationMenu(mainWindow));
|
||||
Menu.setApplicationMenu(createApplicationMenu(mainWindow));
|
||||
setupTrayItem(mainWindow);
|
||||
setupAutoUpdater(mainWindow);
|
||||
|
||||
@@ -170,7 +177,7 @@ const main = () => {
|
||||
});
|
||||
|
||||
// On macOS, this is how we get deeplinks. See: registerForEnteLinks
|
||||
app.on("open-url", (_, url) => handleOpenURLEnsuringWindow(url));
|
||||
app.on("open-url", (_, url) => handleOpenEnteURLEnsuringWindow(url));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -272,7 +279,7 @@ const handleEnteLinks = (mainWindow: BrowserWindow, url: string) => {
|
||||
// - the protocol we're using to serve/ our bundled web app
|
||||
//
|
||||
// use the same scheme ("ente://"), so the URL can directly be forwarded.
|
||||
mainWindow.webContents.send("openURL", url);
|
||||
mainWindow.webContents.send("openEnteURL", url);
|
||||
};
|
||||
|
||||
/** Attach handlers to the (node) process. */
|
||||
@@ -341,9 +348,41 @@ const createMainWindow = () => {
|
||||
...(bounds ?? {}),
|
||||
// Enforce a minimum size
|
||||
...minimumWindowSize(),
|
||||
// [Note: Customize the desktop title bar]
|
||||
//
|
||||
// 1. Remove the default title bar.
|
||||
// 2. Reintroduce the title bar controls.
|
||||
// 3. Show a custom title bar in the renderer.
|
||||
//
|
||||
// For step 3, we use `app-region: drag` to allow dragging the window by
|
||||
// the title bar, and use the Window Controls Overlay CSS environment
|
||||
// variables to determine its dimensions. Note that these overlay CSS
|
||||
// environment vars are only available when titleBarOverlay is true, so
|
||||
// unlike the tutorial which enables it only for Windows and Linux, we
|
||||
// do it (Step 2) unconditionally (i.e., on macOS too).
|
||||
//
|
||||
// https://www.electronjs.org/docs/latest/tutorial/custom-title-bar#create-a-custom-title-bar
|
||||
//
|
||||
// Note that by default on Windows, the color of the WCO title bar
|
||||
// overlay (three buttons - minimize, maximize, close - on the top
|
||||
// right) is static, and unlike Linux, doesn't adapt to the theme /
|
||||
// content. Explicitly choosing a dark background, while it won't work
|
||||
// always (if the user's theme is light), is better than picking a light
|
||||
// background since the main image viewer is always dark.
|
||||
titleBarStyle: "hidden",
|
||||
titleBarOverlay:
|
||||
process.platform == "win32"
|
||||
? { color: "black", symbolColor: "#cdcdcd" }
|
||||
: true,
|
||||
// The color to show in the window until the web content gets loaded.
|
||||
// See: https://www.electronjs.org/docs/latest/api/browser-window#setting-the-backgroundcolor-property
|
||||
backgroundColor: "black",
|
||||
// https://www.electronjs.org/docs/latest/api/browser-window#setting-the-backgroundcolor-property
|
||||
//
|
||||
// To avoid a flash, we want to use the same background color as the
|
||||
// theme of their choice. Unless the user has modified their preference
|
||||
// to not follow the system, we can deduce it from the current OS theme.
|
||||
//
|
||||
// See: https://www.electronjs.org/docs/latest/tutorial/dark-mode
|
||||
backgroundColor: nativeTheme.shouldUseDarkColors ? "black" : "white",
|
||||
// We'll show it conditionally depending on `wasAutoLaunched` later.
|
||||
show: false,
|
||||
});
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
updateAndRestart,
|
||||
updateOnNextRestart,
|
||||
} from "./services/app-update";
|
||||
import autoLauncher from "./services/auto-launcher";
|
||||
import {
|
||||
openDirectory,
|
||||
openLogDirectory,
|
||||
@@ -117,6 +118,10 @@ export const attachIPCHandlers = () => {
|
||||
setLastShownChangelogVersion(version),
|
||||
);
|
||||
|
||||
ipcMain.handle("isAutoLaunchEnabled", () => autoLauncher.isEnabled());
|
||||
|
||||
ipcMain.handle("toggleAutoLaunch", () => autoLauncher.toggleAutoLaunch());
|
||||
|
||||
// - App update
|
||||
|
||||
ipcMain.on("updateAndRestart", () => updateAndRestart());
|
||||
|
||||
@@ -7,17 +7,14 @@ import {
|
||||
} from "electron";
|
||||
import { allowWindowClose } from "../main";
|
||||
import { forceCheckForAppUpdates } from "./services/app-update";
|
||||
import autoLauncher from "./services/auto-launcher";
|
||||
import { openLogDirectory } from "./services/dir";
|
||||
import { userPreferences } from "./stores/user-preferences";
|
||||
|
||||
/** Create and return the entries in the app's main menu bar */
|
||||
export const createApplicationMenu = async (mainWindow: BrowserWindow) => {
|
||||
export const createApplicationMenu = (mainWindow: BrowserWindow) => {
|
||||
// The state of checkboxes
|
||||
//
|
||||
// Whenever the menu is redrawn the current value of these variables is used
|
||||
// to set the checked state for the various settings checkboxes.
|
||||
let isAutoLaunchEnabled = await autoLauncher.isEnabled();
|
||||
let shouldHideDockIcon = !!userPreferences.get("hideDockIcon");
|
||||
|
||||
const macOSOnly = (options: MenuItemConstructorOptions[]) =>
|
||||
@@ -25,16 +22,6 @@ export const createApplicationMenu = async (mainWindow: BrowserWindow) => {
|
||||
|
||||
const handleCheckForUpdates = () => forceCheckForAppUpdates(mainWindow);
|
||||
|
||||
const handleViewChangelog = () =>
|
||||
void shell.openExternal(
|
||||
"https://github.com/ente-io/ente/blob/main/desktop/CHANGELOG.md",
|
||||
);
|
||||
|
||||
const toggleAutoLaunch = () => {
|
||||
void autoLauncher.toggleAutoLaunch();
|
||||
isAutoLaunchEnabled = !isAutoLaunchEnabled;
|
||||
};
|
||||
|
||||
const toggleHideDockIcon = () => {
|
||||
// Persist
|
||||
userPreferences.set("hideDockIcon", !shouldHideDockIcon);
|
||||
@@ -45,13 +32,6 @@ export const createApplicationMenu = async (mainWindow: BrowserWindow) => {
|
||||
const handleHelp = () =>
|
||||
void shell.openExternal("https://help.ente.io/photos/");
|
||||
|
||||
const handleSupport = () =>
|
||||
void shell.openExternal("mailto:support@ente.io");
|
||||
|
||||
const handleBlog = () => void shell.openExternal("https://ente.io/blog/");
|
||||
|
||||
const handleViewLogs = () => void openLogDirectory();
|
||||
|
||||
return Menu.buildFromTemplate([
|
||||
{
|
||||
label: "Ente Photos",
|
||||
@@ -67,31 +47,21 @@ export const createApplicationMenu = async (mainWindow: BrowserWindow) => {
|
||||
label: "Check for Updates...",
|
||||
click: handleCheckForUpdates,
|
||||
},
|
||||
{
|
||||
label: "View Changelog",
|
||||
click: handleViewChangelog,
|
||||
},
|
||||
{ type: "separator" },
|
||||
|
||||
{
|
||||
label: "Preferences",
|
||||
submenu: [
|
||||
{
|
||||
label: "Open Ente on Startup",
|
||||
type: "checkbox",
|
||||
checked: isAutoLaunchEnabled,
|
||||
click: toggleAutoLaunch,
|
||||
},
|
||||
...macOSOnly([
|
||||
...macOSOnly([
|
||||
{
|
||||
label: "Preferences",
|
||||
submenu: [
|
||||
{
|
||||
label: "Hide Dock Icon",
|
||||
type: "checkbox",
|
||||
checked: shouldHideDockIcon,
|
||||
click: toggleHideDockIcon,
|
||||
},
|
||||
]),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]),
|
||||
|
||||
{ type: "separator" },
|
||||
...macOSOnly([
|
||||
@@ -169,20 +139,6 @@ export const createApplicationMenu = async (mainWindow: BrowserWindow) => {
|
||||
label: "Ente Help",
|
||||
click: handleHelp,
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "Support",
|
||||
click: handleSupport,
|
||||
},
|
||||
{
|
||||
label: "Product Updates",
|
||||
click: handleBlog,
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "View Logs",
|
||||
click: handleViewLogs,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
@@ -194,7 +150,6 @@ export const createApplicationMenu = async (mainWindow: BrowserWindow) => {
|
||||
*/
|
||||
export const createTrayContextMenu = (mainWindow: BrowserWindow) => {
|
||||
const handleOpen = () => {
|
||||
mainWindow.maximize();
|
||||
mainWindow.show();
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
makeTempFilePath,
|
||||
} from "../utils/temp";
|
||||
|
||||
/* Ditto in the web app's code (used by the WASM FFmpeg invocation). */
|
||||
/* Ditto in the web app's code (used by the Wasm FFmpeg invocation). */
|
||||
const ffmpegPathPlaceholder = "FFMPEG";
|
||||
const inputPathPlaceholder = "INPUT";
|
||||
const outputPathPlaceholder = "OUTPUT";
|
||||
@@ -19,7 +19,7 @@ const outputPathPlaceholder = "OUTPUT";
|
||||
*
|
||||
* [Note: FFmpeg in Electron]
|
||||
*
|
||||
* There is a wasm build of FFmpeg, but that is currently 10-20 times slower
|
||||
* There is a Wasm build of FFmpeg, but that is currently 10-20 times slower
|
||||
* that the native build. That is slow enough to be unusable for our purposes.
|
||||
* https://ffmpegwasm.netlify.app/docs/performance
|
||||
*
|
||||
|
||||
@@ -14,7 +14,6 @@ export const convertToJPEG = async (imageData: Uint8Array) => {
|
||||
const inputFilePath = await makeTempFilePath();
|
||||
const outputFilePath = await makeTempFilePath("jpeg");
|
||||
|
||||
// Construct the command first, it may throw NotAvailable on win32.
|
||||
const command = convertToJPEGCommand(inputFilePath, outputFilePath);
|
||||
|
||||
try {
|
||||
@@ -45,14 +44,7 @@ const convertToJPEGCommand = (
|
||||
|
||||
case "linux":
|
||||
case "win32":
|
||||
return [
|
||||
imageMagickPath(),
|
||||
"convert",
|
||||
inputFilePath,
|
||||
"-quality",
|
||||
"100%",
|
||||
outputFilePath,
|
||||
];
|
||||
return [vipsPath(), "copy", inputFilePath, outputFilePath];
|
||||
|
||||
default:
|
||||
throw new Error("Not available on the current OS/arch");
|
||||
@@ -60,12 +52,12 @@ const convertToJPEGCommand = (
|
||||
};
|
||||
|
||||
/**
|
||||
* Path to the magick executable bundled with our app on Linux and Windows.
|
||||
* Path to the vips executable bundled with our app on Linux and Windows.
|
||||
*/
|
||||
const imageMagickPath = () =>
|
||||
const vipsPath = () =>
|
||||
path.join(
|
||||
isDev ? "build" : process.resourcesPath,
|
||||
process.platform == "win32" ? "magick.exe" : "magick",
|
||||
process.platform == "win32" ? "vips.exe" : "vips",
|
||||
);
|
||||
|
||||
export const generateImageThumbnail = async (
|
||||
@@ -139,19 +131,11 @@ const generateImageThumbnailCommand = (
|
||||
case "linux":
|
||||
case "win32":
|
||||
return [
|
||||
imageMagickPath(),
|
||||
"convert",
|
||||
vipsPath(),
|
||||
"thumbnail",
|
||||
inputFilePath,
|
||||
"-define",
|
||||
`jpeg:size=${2 * maxDimension}x${2 * maxDimension}`,
|
||||
"-auto-orient",
|
||||
"-thumbnail",
|
||||
`${maxDimension}x${maxDimension}`,
|
||||
"-unsharp",
|
||||
"0x.5",
|
||||
"-quality",
|
||||
`${quality}`,
|
||||
outputFilePath,
|
||||
`${outputFilePath}[Q=${quality}]`,
|
||||
`${maxDimension}`,
|
||||
];
|
||||
|
||||
default:
|
||||
|
||||
@@ -20,7 +20,7 @@ let _child: UtilityProcess | undefined;
|
||||
* [Note: ML IPC]
|
||||
*
|
||||
* The primary reason for doing ML tasks in the Node.js layer is so that we can
|
||||
* use the binary ONNX runtime, which is 10-20x faster than the WASM one that
|
||||
* use the binary ONNX runtime, which is 10-20x faster than the Wasm one that
|
||||
* can be used directly on the web layer.
|
||||
*
|
||||
* For this to work, the main and renderer process need to communicate with each
|
||||
|
||||
@@ -56,8 +56,6 @@ export const execAsync = async (command: string | string[]) => {
|
||||
const startTime = Date.now();
|
||||
const result = await execAsync_(escapedCommand);
|
||||
log.debug(() => `${escapedCommand} (${Date.now() - startTime} ms)`);
|
||||
// TODO(MR): Temp for debugging in nightlies; Remove before release.
|
||||
log.info(`${escapedCommand} (${Date.now() - startTime} ms)`);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
@@ -122,14 +122,18 @@ const lastShownChangelogVersion = () =>
|
||||
const setLastShownChangelogVersion = (version: number) =>
|
||||
ipcRenderer.invoke("setLastShownChangelogVersion", version);
|
||||
|
||||
const isAutoLaunchEnabled = () => ipcRenderer.invoke("isAutoLaunchEnabled");
|
||||
|
||||
const toggleAutoLaunch = () => ipcRenderer.invoke("toggleAutoLaunch");
|
||||
|
||||
const onMainWindowFocus = (cb: (() => void) | undefined) => {
|
||||
ipcRenderer.removeAllListeners("mainWindowFocus");
|
||||
if (cb) ipcRenderer.on("mainWindowFocus", cb);
|
||||
};
|
||||
|
||||
const onOpenURL = (cb: ((url: string) => void) | undefined) => {
|
||||
ipcRenderer.removeAllListeners("openURL");
|
||||
if (cb) ipcRenderer.on("openURL", (_, url: string) => cb(url));
|
||||
const onOpenEnteURL = (cb: ((url: string) => void) | undefined) => {
|
||||
ipcRenderer.removeAllListeners("openEnteURL");
|
||||
if (cb) ipcRenderer.on("openEnteURL", (_, url: string) => cb(url));
|
||||
};
|
||||
|
||||
// - App update
|
||||
@@ -347,8 +351,10 @@ contextBridge.exposeInMainWorld("electron", {
|
||||
saveMasterKeyB64,
|
||||
lastShownChangelogVersion,
|
||||
setLastShownChangelogVersion,
|
||||
isAutoLaunchEnabled,
|
||||
toggleAutoLaunch,
|
||||
onMainWindowFocus,
|
||||
onOpenURL,
|
||||
onOpenEnteURL,
|
||||
|
||||
// - App update
|
||||
|
||||
|
||||
@@ -177,10 +177,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.9.1.tgz#4a97e85e982099d6c7ee8410aacb55adaa576f06"
|
||||
integrity sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==
|
||||
|
||||
"@eslint/js@^9.18.0":
|
||||
version "9.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.18.0.tgz#3356f85d18ed3627ab107790b53caf7e1e3d1e84"
|
||||
integrity sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==
|
||||
"@eslint/js@^9.19.0":
|
||||
version "9.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.19.0.tgz#51dbb140ed6b49d05adc0b171c41e1a8713b7789"
|
||||
integrity sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==
|
||||
|
||||
"@eslint/object-schema@^2.1.4":
|
||||
version "2.1.4"
|
||||
@@ -417,85 +417,85 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@8.21.0":
|
||||
version "8.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.21.0.tgz#395014a75112ecdb81142b866ab6bb62e3be0f2a"
|
||||
integrity sha512-eTH+UOR4I7WbdQnG4Z48ebIA6Bgi7WO8HvFEneeYBxG8qCOYgTOFPSg6ek9ITIDvGjDQzWHcoWHCDO2biByNzA==
|
||||
"@typescript-eslint/eslint-plugin@8.23.0":
|
||||
version "8.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz#7745f4e3e4a7ae5f6f73fefcd856fd6a074189b7"
|
||||
integrity sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w==
|
||||
dependencies:
|
||||
"@eslint-community/regexpp" "^4.10.0"
|
||||
"@typescript-eslint/scope-manager" "8.21.0"
|
||||
"@typescript-eslint/type-utils" "8.21.0"
|
||||
"@typescript-eslint/utils" "8.21.0"
|
||||
"@typescript-eslint/visitor-keys" "8.21.0"
|
||||
"@typescript-eslint/scope-manager" "8.23.0"
|
||||
"@typescript-eslint/type-utils" "8.23.0"
|
||||
"@typescript-eslint/utils" "8.23.0"
|
||||
"@typescript-eslint/visitor-keys" "8.23.0"
|
||||
graphemer "^1.4.0"
|
||||
ignore "^5.3.1"
|
||||
natural-compare "^1.4.0"
|
||||
ts-api-utils "^2.0.0"
|
||||
ts-api-utils "^2.0.1"
|
||||
|
||||
"@typescript-eslint/parser@8.21.0":
|
||||
version "8.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.21.0.tgz#312c638aaba4f640d45bfde7c6795a9d75deb088"
|
||||
integrity sha512-Wy+/sdEH9kI3w9civgACwabHbKl+qIOu0uFZ9IMKzX3Jpv9og0ZBJrZExGrPpFAY7rWsXuxs5e7CPPP17A4eYA==
|
||||
"@typescript-eslint/parser@8.23.0":
|
||||
version "8.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.23.0.tgz#57acb3b65fce48d12b70d119436e145842a30081"
|
||||
integrity sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "8.21.0"
|
||||
"@typescript-eslint/types" "8.21.0"
|
||||
"@typescript-eslint/typescript-estree" "8.21.0"
|
||||
"@typescript-eslint/visitor-keys" "8.21.0"
|
||||
"@typescript-eslint/scope-manager" "8.23.0"
|
||||
"@typescript-eslint/types" "8.23.0"
|
||||
"@typescript-eslint/typescript-estree" "8.23.0"
|
||||
"@typescript-eslint/visitor-keys" "8.23.0"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/scope-manager@8.21.0":
|
||||
version "8.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.21.0.tgz#d08d94e2a34b4ccdcc975543c25bb62917437500"
|
||||
integrity sha512-G3IBKz0/0IPfdeGRMbp+4rbjfSSdnGkXsM/pFZA8zM9t9klXDnB/YnKOBQ0GoPmoROa4bCq2NeHgJa5ydsQ4mA==
|
||||
"@typescript-eslint/scope-manager@8.23.0":
|
||||
version "8.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.23.0.tgz#ee3bb7546421ca924b9b7a8b62a77d388193ddec"
|
||||
integrity sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.21.0"
|
||||
"@typescript-eslint/visitor-keys" "8.21.0"
|
||||
"@typescript-eslint/types" "8.23.0"
|
||||
"@typescript-eslint/visitor-keys" "8.23.0"
|
||||
|
||||
"@typescript-eslint/type-utils@8.21.0":
|
||||
version "8.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.21.0.tgz#2e69d1a93cdbedc73fe694cd6ae4dfedd00430a0"
|
||||
integrity sha512-95OsL6J2BtzoBxHicoXHxgk3z+9P3BEcQTpBKriqiYzLKnM2DeSqs+sndMKdamU8FosiadQFT3D+BSL9EKnAJQ==
|
||||
"@typescript-eslint/type-utils@8.23.0":
|
||||
version "8.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.23.0.tgz#271e1eecece072d92679dfda5ccfceac3faa9f76"
|
||||
integrity sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA==
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree" "8.21.0"
|
||||
"@typescript-eslint/utils" "8.21.0"
|
||||
"@typescript-eslint/typescript-estree" "8.23.0"
|
||||
"@typescript-eslint/utils" "8.23.0"
|
||||
debug "^4.3.4"
|
||||
ts-api-utils "^2.0.0"
|
||||
ts-api-utils "^2.0.1"
|
||||
|
||||
"@typescript-eslint/types@8.21.0":
|
||||
version "8.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.21.0.tgz#58f30aec8db8212fd886835dc5969cdf47cb29f5"
|
||||
integrity sha512-PAL6LUuQwotLW2a8VsySDBwYMm129vFm4tMVlylzdoTybTHaAi0oBp7Ac6LhSrHHOdLM3efH+nAR6hAWoMF89A==
|
||||
"@typescript-eslint/types@8.23.0":
|
||||
version "8.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.23.0.tgz#3355f6bcc5ebab77ef6dcbbd1113ec0a683a234a"
|
||||
integrity sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==
|
||||
|
||||
"@typescript-eslint/typescript-estree@8.21.0":
|
||||
version "8.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.21.0.tgz#5ce71acdbed3b97b959f6168afba5a03c88f69a9"
|
||||
integrity sha512-x+aeKh/AjAArSauz0GiQZsjT8ciadNMHdkUSwBB9Z6PrKc/4knM4g3UfHml6oDJmKC88a6//cdxnO/+P2LkMcg==
|
||||
"@typescript-eslint/typescript-estree@8.23.0":
|
||||
version "8.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz#f633ef08efa656e386bc44b045ffcf9537cc6924"
|
||||
integrity sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.21.0"
|
||||
"@typescript-eslint/visitor-keys" "8.21.0"
|
||||
"@typescript-eslint/types" "8.23.0"
|
||||
"@typescript-eslint/visitor-keys" "8.23.0"
|
||||
debug "^4.3.4"
|
||||
fast-glob "^3.3.2"
|
||||
is-glob "^4.0.3"
|
||||
minimatch "^9.0.4"
|
||||
semver "^7.6.0"
|
||||
ts-api-utils "^2.0.0"
|
||||
ts-api-utils "^2.0.1"
|
||||
|
||||
"@typescript-eslint/utils@8.21.0":
|
||||
version "8.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.21.0.tgz#bc4874fbc30feb3298b926e3b03d94570b3999c5"
|
||||
integrity sha512-xcXBfcq0Kaxgj7dwejMbFyq7IOHgpNMtVuDveK7w3ZGwG9owKzhALVwKpTF2yrZmEwl9SWdetf3fxNzJQaVuxw==
|
||||
"@typescript-eslint/utils@8.23.0":
|
||||
version "8.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.23.0.tgz#b269cbdc77129fd6e0e600b168b5ef740a625554"
|
||||
integrity sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.4.0"
|
||||
"@typescript-eslint/scope-manager" "8.21.0"
|
||||
"@typescript-eslint/types" "8.21.0"
|
||||
"@typescript-eslint/typescript-estree" "8.21.0"
|
||||
"@typescript-eslint/scope-manager" "8.23.0"
|
||||
"@typescript-eslint/types" "8.23.0"
|
||||
"@typescript-eslint/typescript-estree" "8.23.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@8.21.0":
|
||||
version "8.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.21.0.tgz#a89744c4cdc83b5c761eb5878befe6c33d1481b2"
|
||||
integrity sha512-BkLMNpdV6prozk8LlyK/SOoWLmUFi+ZD+pcqti9ILCbVvHGk1ui1g4jJOc2WDLaeExz2qWwojxlPce5PljcT3w==
|
||||
"@typescript-eslint/visitor-keys@8.23.0":
|
||||
version "8.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz#40405fd26a61d23f5f4c2ed0f016a47074781df8"
|
||||
integrity sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.21.0"
|
||||
"@typescript-eslint/types" "8.23.0"
|
||||
eslint-visitor-keys "^4.2.0"
|
||||
|
||||
"@xmldom/xmldom@^0.8.8":
|
||||
@@ -609,10 +609,10 @@ app-builder-bin@5.0.0-alpha.12:
|
||||
resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz#2daf82f8badc698e0adcc95ba36af4ff0650dc80"
|
||||
integrity sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==
|
||||
|
||||
app-builder-lib@26.0.0-alpha.10:
|
||||
version "26.0.0-alpha.10"
|
||||
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-26.0.0-alpha.10.tgz#3eb3f64ffa5e995595ad61497c5e7a0c2d64b817"
|
||||
integrity sha512-9K3MulGK7j+En4KjH3aq7AzDqe8nn35x7O9l5kwl16nWFdBthcdy1IKsx9CgjMSF+eTNctOZlXwnYiPiGzY+GQ==
|
||||
app-builder-lib@26.0.0:
|
||||
version "26.0.0"
|
||||
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-26.0.0.tgz#726b8b2c058f04f854aba70c7245d48454905980"
|
||||
integrity sha512-vZTt6Nc401IHBHISqspcO9tUF80ddOP5ehh2B4goLefM+zdT75CvuQUuqz7yzRgW16pHLqCvKMws0FbJQfLB5w==
|
||||
dependencies:
|
||||
"@develar/schema-utils" "~2.6.5"
|
||||
"@electron/asar" "3.2.18"
|
||||
@@ -625,15 +625,15 @@ app-builder-lib@26.0.0-alpha.10:
|
||||
"@types/fs-extra" "9.0.13"
|
||||
async-exit-hook "^2.0.1"
|
||||
bluebird-lst "^1.0.9"
|
||||
builder-util "26.0.0-alpha.10"
|
||||
builder-util-runtime "9.3.0-alpha.0"
|
||||
builder-util "26.0.0"
|
||||
builder-util-runtime "9.3.0"
|
||||
chromium-pickle-js "^0.2.0"
|
||||
config-file-ts "0.2.8-rc1"
|
||||
debug "^4.3.4"
|
||||
dotenv "^16.4.5"
|
||||
dotenv-expand "^11.0.6"
|
||||
ejs "^3.1.8"
|
||||
electron-publish "26.0.0-alpha.10"
|
||||
electron-publish "26.0.0"
|
||||
fs-extra "^10.1.0"
|
||||
hosted-git-info "^4.1.0"
|
||||
is-ci "^3.0.0"
|
||||
@@ -784,24 +784,24 @@ buffer@^5.1.0, buffer@^5.5.0:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.1.13"
|
||||
|
||||
builder-util-runtime@9.3.0-alpha.0:
|
||||
version "9.3.0-alpha.0"
|
||||
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.3.0-alpha.0.tgz#c4639ae24a74d2e0f4eb324100af3040300bae62"
|
||||
integrity sha512-EriE6Uf15niqdkyjBOS09OrXlhEV0HKhnATlI9n63vCoisnvvRTQNgoR2MV9vnBmNGhavBPZXPWPItv4QMDVfw==
|
||||
builder-util-runtime@9.3.0:
|
||||
version "9.3.0"
|
||||
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.3.0.tgz#58d97c279bb8626a10d779e1cf22fea0eb25f5e8"
|
||||
integrity sha512-wR81YIybr41JITLSltwtTsZXkgTwcpBol7LGOyB5A8fKCcZaYLDWgUqDwmsjhlgADD6sGD5ieyzS/5wbL2l/qQ==
|
||||
dependencies:
|
||||
debug "^4.3.4"
|
||||
sax "^1.2.4"
|
||||
|
||||
builder-util@26.0.0-alpha.10:
|
||||
version "26.0.0-alpha.10"
|
||||
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-26.0.0-alpha.10.tgz#f445a530c28da6e3650b93e92263c06c6f89a2cc"
|
||||
integrity sha512-RMVOAgdd+tzwpyF5C8gx9KjzwdUvkUEubpsHTvb2JwlQnBcyBc6hyVCU2gt2MivQCLbjCOEgsUX1/zHrWDqGfg==
|
||||
builder-util@26.0.0:
|
||||
version "26.0.0"
|
||||
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-26.0.0.tgz#e5bc122f3e9e94fa2e3afd2e837e81ce9f177359"
|
||||
integrity sha512-iLN4R0UAzSz4MxPmz+6vnXMqaY5BMd2FSNlM9f7eHSRYqZrsoTHCSrd7W4Kr4qFIdUxLlRz3X2npATapXzomIg==
|
||||
dependencies:
|
||||
"7zip-bin" "~5.2.0"
|
||||
"@types/debug" "^4.1.6"
|
||||
app-builder-bin "5.0.0-alpha.12"
|
||||
bluebird-lst "^1.0.9"
|
||||
builder-util-runtime "9.3.0-alpha.0"
|
||||
builder-util-runtime "9.3.0"
|
||||
chalk "^4.1.2"
|
||||
cross-spawn "^7.0.6"
|
||||
debug "^4.3.4"
|
||||
@@ -1178,14 +1178,14 @@ dir-compare@^4.2.0:
|
||||
minimatch "^3.0.5"
|
||||
p-limit "^3.1.0 "
|
||||
|
||||
dmg-builder@26.0.0-alpha.10:
|
||||
version "26.0.0-alpha.10"
|
||||
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-26.0.0-alpha.10.tgz#d4d908922005a0c852d0919a7dd0b8f77d3c4bd0"
|
||||
integrity sha512-RWzCNLLu4dGIvBf8kBzjF/zI5aMOSA149S1V2NgAA4La8f8ghdJAm/DI5crSb2zDijFLyTNmUGTtvU6eHgiZyQ==
|
||||
dmg-builder@26.0.0:
|
||||
version "26.0.0"
|
||||
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-26.0.0.tgz#6dc81be31f7ffe9f8a5fc77ce7f83eba33ae9aa7"
|
||||
integrity sha512-NyyTgm1U56ytpFvuGjj63PYug3v+oYYbPc8e08EiHP6G4TvMwYabmSzFtanfoO1iI7xOljpW/fW7SNCHHElsfw==
|
||||
dependencies:
|
||||
app-builder-lib "26.0.0-alpha.10"
|
||||
builder-util "26.0.0-alpha.10"
|
||||
builder-util-runtime "9.3.0-alpha.0"
|
||||
app-builder-lib "26.0.0"
|
||||
builder-util "26.0.0"
|
||||
builder-util-runtime "9.3.0"
|
||||
fs-extra "^10.1.0"
|
||||
iconv-lite "^0.6.2"
|
||||
js-yaml "^4.1.0"
|
||||
@@ -1232,35 +1232,35 @@ ejs@^3.1.8:
|
||||
dependencies:
|
||||
jake "^10.8.5"
|
||||
|
||||
electron-builder@^26.0.0-alpha.10:
|
||||
version "26.0.0-alpha.10"
|
||||
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-26.0.0-alpha.10.tgz#6f629f5f1f3340286af71cabd12d94edc53f15ea"
|
||||
integrity sha512-QTitqOlP5aZ/8zhnxqjRb6BxSR7Kvwv07PoBGeIXADwSPHQhKhZ+S+GRFzUSYQrMTTJLGzUHbnAes6fZ3uThEA==
|
||||
electron-builder@^26.0.0:
|
||||
version "26.0.0"
|
||||
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-26.0.0.tgz#f5c03b049e3e9b0d3da7737f93bf1a830d1f17bb"
|
||||
integrity sha512-R1ZNTCtwjApiELkE4LTNIF6UkV+FMgyDIjILlsVvFak8Jr60cI9gu4q3lVALYzGBcFyzHKn2RPp6j0gl5kuVow==
|
||||
dependencies:
|
||||
app-builder-lib "26.0.0-alpha.10"
|
||||
builder-util "26.0.0-alpha.10"
|
||||
builder-util-runtime "9.3.0-alpha.0"
|
||||
app-builder-lib "26.0.0"
|
||||
builder-util "26.0.0"
|
||||
builder-util-runtime "9.3.0"
|
||||
chalk "^4.1.2"
|
||||
dmg-builder "26.0.0-alpha.10"
|
||||
dmg-builder "26.0.0"
|
||||
fs-extra "^10.1.0"
|
||||
is-ci "^3.0.0"
|
||||
lazy-val "^1.0.5"
|
||||
simple-update-notifier "2.0.0"
|
||||
yargs "^17.6.2"
|
||||
|
||||
electron-log@^5.2.4:
|
||||
version "5.2.4"
|
||||
resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-5.2.4.tgz#6b488d9db80aa3c6f3dc39bcd635fc9d1f79c8af"
|
||||
integrity sha512-iX12WXc5XAaKeHg2QpiFjVwL+S1NVHPFd3V5RXtCmKhpAzXsVQnR3UEc0LovM6p6NkUQxDWnkdkaam9FNUVmCA==
|
||||
electron-log@^5.3.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-5.3.0.tgz#503a911983db09156965595a7ee9a39f2d9d6384"
|
||||
integrity sha512-ILgbh2k9IKbSaN8NAbQriVteEhmkdLo/e4J1dg+JIBTFzXS/kO8zNRZBh/4YPwIT/zeyxF1jP6Xz8GLsPE2IBQ==
|
||||
|
||||
electron-publish@26.0.0-alpha.10:
|
||||
version "26.0.0-alpha.10"
|
||||
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-26.0.0-alpha.10.tgz#16ac95acca2d796ca00c7a90ca27ebf31855f284"
|
||||
integrity sha512-yUkCJD7MLN57d6PJ8PMcBCR35xytA+jHyrOiS/H0hlmTOWq1sXN+tIBylX4h0dD/C6mn75/y5eE156Pe2nccPw==
|
||||
electron-publish@26.0.0:
|
||||
version "26.0.0"
|
||||
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-26.0.0.tgz#f37b9babe62885c2ee552af2817bf2048b566637"
|
||||
integrity sha512-0MOeYp1IRDj+jdkWluEVMer8fpc/htwWJZdGQUMbbbhgMnX8AvDdwHuR0UdaPFLDJ076E9YHd2urkeFyLm7PUQ==
|
||||
dependencies:
|
||||
"@types/fs-extra" "^9.0.11"
|
||||
builder-util "26.0.0-alpha.10"
|
||||
builder-util-runtime "9.3.0-alpha.0"
|
||||
builder-util "26.0.0"
|
||||
builder-util-runtime "9.3.0"
|
||||
chalk "^4.1.2"
|
||||
form-data "^4.0.0"
|
||||
fs-extra "^10.1.0"
|
||||
@@ -1275,12 +1275,12 @@ electron-store@^8.2.0:
|
||||
conf "^10.2.0"
|
||||
type-fest "^2.17.0"
|
||||
|
||||
electron-updater@^6.4.0-alpha.3:
|
||||
version "6.4.0-alpha.3"
|
||||
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.4.0-alpha.3.tgz#4c33647c79f7ea1bcd184aac8a0b15d5a2b37cf1"
|
||||
integrity sha512-pqbEqfKVly49UO3QhnRnzghK75BW6v6ZrpW/2vs+ZVVxHmrdwEl1bTjJFQl1LSIBABpBEwT5W9uwf3cKfrD+Bg==
|
||||
electron-updater@^6.4.0:
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.4.0.tgz#f413e5d1cb4fadde451eb7daa585ddb6332e2409"
|
||||
integrity sha512-E2fqL3GrVaXGZm2w95s4kJuPIF633pi5GhEy1/ReOHjDW9h/C0mZ1LXcLq0LsyQ4vyVj9UsdRb4E+Zy/d7RKUw==
|
||||
dependencies:
|
||||
builder-util-runtime "9.3.0-alpha.0"
|
||||
builder-util-runtime "9.3.0"
|
||||
fs-extra "^10.1.0"
|
||||
js-yaml "^4.1.0"
|
||||
lazy-val "^1.0.5"
|
||||
@@ -1289,10 +1289,10 @@ electron-updater@^6.4.0-alpha.3:
|
||||
semver "^7.6.3"
|
||||
tiny-typed-emitter "^2.1.0"
|
||||
|
||||
electron@^34.0.0:
|
||||
version "34.0.0"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-34.0.0.tgz#30ccedbc02d2f036868b8278960fd0e438ec0e52"
|
||||
integrity sha512-fpaPb0lifoUJ6UJa4Lk8/0B2Ku/xDZWdc1Gkj67jbygTCrvSon0qquju6Ltx1Kz23GRqqlIHXiy9EvrjpY7/Wg==
|
||||
electron@^34.1.1:
|
||||
version "34.1.1"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-34.1.1.tgz#1fc766e406401834fedb9747c4ca58671d9a1e46"
|
||||
integrity sha512-1aDYk9Gsv1/fFeClMrxWGoVMl7uCUgl1pe26BiTnLXmAoqEXCa3f3sCKFWV+cuDzUjQGAZcpkWhGYTgWUSQrLA==
|
||||
dependencies:
|
||||
"@electron/get" "^2.0.0"
|
||||
"@types/node" "^20.9.0"
|
||||
@@ -3202,10 +3202,10 @@ truncate-utf8-bytes@^1.0.0:
|
||||
dependencies:
|
||||
utf8-byte-length "^1.0.1"
|
||||
|
||||
ts-api-utils@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.0.0.tgz#b9d7d5f7ec9f736f4d0f09758b8607979044a900"
|
||||
integrity sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==
|
||||
ts-api-utils@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.0.1.tgz#660729385b625b939aaa58054f45c058f33f10cd"
|
||||
integrity sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==
|
||||
|
||||
tslib@^2.1.0, tslib@^2.6.2:
|
||||
version "2.7.0"
|
||||
@@ -3234,14 +3234,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.21.0:
|
||||
version "8.21.0"
|
||||
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.21.0.tgz#78bdb83a6d771f0312b128297d84a3111885fd08"
|
||||
integrity sha512-txEKYY4XMKwPXxNkN8+AxAdX6iIJAPiJbHE/FpQccs/sxw8Lf26kqwC3cn0xkHlW8kEbLhkhCsjWuMveaY9Rxw==
|
||||
typescript-eslint@^8.23.0:
|
||||
version "8.23.0"
|
||||
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.23.0.tgz#796deb48f040146b68fcc8cb07db68b87219a8d2"
|
||||
integrity sha512-/LBRo3HrXr5LxmrdYSOCvoAMm7p2jNizNfbIpCgvG4HMsnoprRUOce/+8VJ9BDYWW68rqIENE/haVLWPeFZBVQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/eslint-plugin" "8.21.0"
|
||||
"@typescript-eslint/parser" "8.21.0"
|
||||
"@typescript-eslint/utils" "8.21.0"
|
||||
"@typescript-eslint/eslint-plugin" "8.23.0"
|
||||
"@typescript-eslint/parser" "8.23.0"
|
||||
"@typescript-eslint/utils" "8.23.0"
|
||||
|
||||
typescript@^5.4.3:
|
||||
version "5.5.4"
|
||||
|
||||
@@ -138,6 +138,10 @@ export const sidebar = [
|
||||
text: "Machine Learning",
|
||||
link: "/photos/faq/machine-learning",
|
||||
},
|
||||
{
|
||||
text: "Video Streaming",
|
||||
link: "/photos/faq/video-streaming",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
63
docs/docs/photos/faq/video-streaming.md
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
title: Video Streaming FAQ
|
||||
description:
|
||||
Frequently asked questions about Ente's Video Streaming feature
|
||||
---
|
||||
|
||||
# Video Streaming
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> Video streaming is available in beta on mobile apps starting v0.9.98.
|
||||
|
||||
### How to enable video streaming?
|
||||
|
||||
- Open Settings -> General -> Advanced
|
||||
- Switch on the toggle for `Video streaming`
|
||||
|
||||
### What happens when I enable video streaming?
|
||||
|
||||
Enabling video streaming will start processing videos captured in the last 30
|
||||
days, generating streams for each. Both local and remote videos will be
|
||||
processed, so this may consume bandwidth for downloading of remote files and
|
||||
uploading of the generated streams.
|
||||
|
||||
### How can I view video streams?
|
||||
|
||||
Settings -> Backup > Backup status will show details regarding the processing
|
||||
status for videos. Processed videos will have a green play button next to them.
|
||||
You can open these videos by tapping on them.
|
||||
|
||||
Processed videos will show a `Play stream` button, clicking which will load and
|
||||
play the stream.
|
||||
|
||||
Clicking on the `Info` icon within the original video will show details
|
||||
about the generated stream.
|
||||
|
||||
### What is a stream?
|
||||
|
||||
Stream is an encrypted HLS file with an `.m3u8` playlist that helps play a video
|
||||
with support for seeking **without** downloading the full file.
|
||||
|
||||
Currently it converts videos into `720p` with `2mbps` bitrate in `H.264` format.
|
||||
The generated stream is single blob (encrypted with AES) while the playlist file
|
||||
(`.m3u8`) is another blob (encrypted using XChaCha20).
|
||||
|
||||
We cannot read the contents, duration or the number of chunks within the
|
||||
generated stream.
|
||||
|
||||
### Will streams consume space in my storage?
|
||||
|
||||
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
|
||||
|
||||
### Something doesn't seem right, what to do?
|
||||
|
||||
As video streaming is still in beta, some things might not work correctly.
|
||||
Please create a thread within the `#feedback` channel on
|
||||
[Discord](https://discord.com/channels/948937918347608085/1121126215995113552)
|
||||
or reach out to [support@ente.io](mailto:support@ente.io).
|
||||
@@ -43,6 +43,10 @@ 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 doesn’t allow the app to run any background processes.
|
||||
As a result, background sync will not work.
|
||||
|
||||
### Desktop
|
||||
|
||||
In addition to our mobile apps, the background sync also works on our desktop
|
||||
|
||||
@@ -20,23 +20,25 @@ the logs just make the process a bit faster and easier.
|
||||
- Select for the option to _Report a Bug_.
|
||||
- Tap on _Report a bug_.
|
||||
|
||||
## Desktop and Web
|
||||
|
||||
- Open settings (click on the three horizontal lines button located at the top
|
||||
left corner of the screen).
|
||||
- Click on the _Help_ option towards the bottom of settings.
|
||||
- Click on _View logs_. This will show you the location of the logs on your
|
||||
system (desktop), or download them from the browser onto your computer (web).
|
||||
- Go back to settings.
|
||||
- Click on _Support_. This will open your email client where you can attach the
|
||||
logs in the email and describe the issue.
|
||||
|
||||
## Desktop
|
||||
|
||||
- Click on _Help_ menu at the top of your screen, and select the _View logs_
|
||||
option.
|
||||
- Open settings (click on the three horizontal lines button located at the top
|
||||
left corner of the screen).
|
||||
- Click on _Support_. This will open your email client where you can attach the
|
||||
logs in the email and describe the issue.
|
||||
On the desktop app, you can also directly view the logs on your computer at the
|
||||
following locations:
|
||||
|
||||
## Web
|
||||
|
||||
- Open settings (click on the three horizontal lines button located at the top
|
||||
left corner of the screen).
|
||||
- Click on _Debug Logs_ towards the bottom of settings.
|
||||
- Click on _Download logs_
|
||||
- Click on _Support_. This will open your email client where you can attach the
|
||||
logs in the email and describe the issue.
|
||||
- macOS: `~/Library/Logs/ente/ente.log`
|
||||
- Linux: `~/.config/ente/logs/ente.log`
|
||||
- Windows: `%USERPROFILE%\AppData\Roaming\ente\logs\ente.log`
|
||||
|
||||
## Send email manually
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ interface Subscription {
|
||||
originalTransactionID: string;
|
||||
expiryTime: number;
|
||||
userID: string;
|
||||
attributes: {
|
||||
customerID: string;
|
||||
stripeAccountCountry: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface UserDataResponse {
|
||||
@@ -40,6 +44,10 @@ interface FormValues {
|
||||
transactionId: string;
|
||||
expiryTime: string | Date | null;
|
||||
userId: string;
|
||||
attributes: {
|
||||
customerID: string;
|
||||
stripeAccountCountry: string;
|
||||
};
|
||||
}
|
||||
|
||||
const UpdateSubscription: React.FC<UpdateSubscriptionProps> = ({
|
||||
@@ -53,6 +61,10 @@ const UpdateSubscription: React.FC<UpdateSubscriptionProps> = ({
|
||||
transactionId: "",
|
||||
expiryTime: "",
|
||||
userId: "",
|
||||
attributes: {
|
||||
"customerID": "",
|
||||
"stripeAccountCountry": ""
|
||||
},
|
||||
});
|
||||
|
||||
const [isDatePickerOpen, setIsDatePickerOpen] = useState(false);
|
||||
@@ -95,6 +107,10 @@ const UpdateSubscription: React.FC<UpdateSubscriptionProps> = ({
|
||||
"",
|
||||
expiryTime: expiryTime,
|
||||
userId: userDataResponse.subscription.userID || "",
|
||||
attributes: {
|
||||
customerID: userDataResponse.subscription.attributes.customerID || "",
|
||||
stripeAccountCountry: userDataResponse.subscription.attributes.stripeAccountCountry || ""
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
@@ -156,6 +172,10 @@ const UpdateSubscription: React.FC<UpdateSubscriptionProps> = ({
|
||||
productId: values.productId,
|
||||
paymentProvider: values.provider,
|
||||
transactionId: values.transactionId,
|
||||
attributes: {
|
||||
customerID: values.attributes.customerID,
|
||||
stripeAccountCountry: values.attributes.stripeAccountCountry
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
2
mobile/android/app/proguard-rules.pro
vendored
@@ -2,3 +2,5 @@
|
||||
# To ensure that stack traces is unambiguous
|
||||
# https://developer.android.com/studio/build/shrink-code#decode-stack-trace
|
||||
-keepattributes LineNumberTable,SourceFile
|
||||
|
||||
-keep class org.chromium.net.** { *; }
|
||||
|
||||
@@ -12,6 +12,11 @@ allprojects {
|
||||
url "${project(':background_fetch').projectDir}/libs"
|
||||
}
|
||||
}
|
||||
ext {
|
||||
compileSdkVersion = 34
|
||||
targetSdkVersion = 34
|
||||
appCompatVersion = "1.7.0"
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = '../build'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx4608m
|
||||
android.enableR8=true
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
BIN
mobile/assets/2.0x/processing-video-failed.png
Executable file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
mobile/assets/2.0x/processing-video-success.png
Executable file
|
After Width: | Height: | Size: 922 B |
BIN
mobile/assets/2.0x/processing-video.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
mobile/assets/2.0x/video-processing-queued.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
mobile/assets/3.0x/processing-video-failed.png
Executable file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
mobile/assets/3.0x/processing-video-success.png
Executable file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
mobile/assets/3.0x/processing-video.png
Executable file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
mobile/assets/3.0x/video-processing-queued.png
Executable file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
mobile/assets/processing-video-failed.png
Executable file
|
After Width: | Height: | Size: 645 B |
BIN
mobile/assets/processing-video-success.png
Executable file
|
After Width: | Height: | Size: 527 B |
BIN
mobile/assets/processing-video.png
Executable file
|
After Width: | Height: | Size: 750 B |
BIN
mobile/assets/video-processing-queued.png
Executable file
|
After Width: | Height: | Size: 744 B |
@@ -6,16 +6,19 @@ PODS:
|
||||
- connectivity_plus (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- cupertino_http (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- dart_ui_isolate (0.0.1):
|
||||
- Flutter
|
||||
- device_info_plus (0.0.1):
|
||||
- Flutter
|
||||
- ffmpeg-kit-ios-min (6.0)
|
||||
- ffmpeg_kit_flutter_min (6.0.3):
|
||||
- ffmpeg_kit_flutter_min/min (= 6.0.3)
|
||||
- ffmpeg-kit-ios-full-gpl (6.0)
|
||||
- ffmpeg_kit_flutter_full_gpl (6.0.3):
|
||||
- ffmpeg_kit_flutter_full_gpl/full-gpl (= 6.0.3)
|
||||
- Flutter
|
||||
- ffmpeg_kit_flutter_min/min (6.0.3):
|
||||
- ffmpeg-kit-ios-min (= 6.0)
|
||||
- ffmpeg_kit_flutter_full_gpl/full-gpl (6.0.3):
|
||||
- ffmpeg-kit-ios-full-gpl (= 6.0)
|
||||
- Flutter
|
||||
- file_saver (0.0.1):
|
||||
- Flutter
|
||||
@@ -35,9 +38,9 @@ PODS:
|
||||
- FirebaseCoreInternal (~> 11.0)
|
||||
- GoogleUtilities/Environment (~> 8.0)
|
||||
- GoogleUtilities/Logger (~> 8.0)
|
||||
- FirebaseCoreInternal (11.3.0):
|
||||
- FirebaseCoreInternal (11.6.0):
|
||||
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||
- FirebaseInstallations (11.3.0):
|
||||
- FirebaseInstallations (11.4.0):
|
||||
- FirebaseCore (~> 11.0)
|
||||
- GoogleUtilities/Environment (~> 8.0)
|
||||
- GoogleUtilities/UserDefaults (~> 8.0)
|
||||
@@ -158,6 +161,8 @@ PODS:
|
||||
- nanopb/encode (3.30910.0)
|
||||
- native_video_player (1.0.0):
|
||||
- Flutter
|
||||
- objective_c (0.0.1):
|
||||
- Flutter
|
||||
- onnxruntime (0.0.1):
|
||||
- Flutter
|
||||
- onnxruntime-objc (= 1.18.0)
|
||||
@@ -186,9 +191,9 @@ PODS:
|
||||
- Flutter
|
||||
- screen_brightness_ios (0.1.0):
|
||||
- Flutter
|
||||
- SDWebImage (5.19.7):
|
||||
- SDWebImage/Core (= 5.19.7)
|
||||
- SDWebImage/Core (5.19.7)
|
||||
- SDWebImage (5.20.0):
|
||||
- SDWebImage/Core (= 5.20.0)
|
||||
- SDWebImage/Core (5.20.0)
|
||||
- SDWebImageWebPCoder (0.14.6):
|
||||
- libwebp (~> 1.0)
|
||||
- SDWebImage/Core (~> 5.17)
|
||||
@@ -247,9 +252,10 @@ DEPENDENCIES:
|
||||
- background_fetch (from `.symlinks/plugins/background_fetch/ios`)
|
||||
- battery_info (from `.symlinks/plugins/battery_info/ios`)
|
||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/darwin`)
|
||||
- cupertino_http (from `.symlinks/plugins/cupertino_http/darwin`)
|
||||
- dart_ui_isolate (from `.symlinks/plugins/dart_ui_isolate/ios`)
|
||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||
- ffmpeg_kit_flutter_min (from `.symlinks/plugins/ffmpeg_kit_flutter_min/ios`)
|
||||
- ffmpeg_kit_flutter_full_gpl (from `.symlinks/plugins/ffmpeg_kit_flutter_full_gpl/ios`)
|
||||
- file_saver (from `.symlinks/plugins/file_saver/ios`)
|
||||
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
|
||||
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
|
||||
@@ -278,6 +284,7 @@ DEPENDENCIES:
|
||||
- motionphoto (from `.symlinks/plugins/motionphoto/ios`)
|
||||
- move_to_background (from `.symlinks/plugins/move_to_background/ios`)
|
||||
- native_video_player (from `.symlinks/plugins/native_video_player/ios`)
|
||||
- objective_c (from `.symlinks/plugins/objective_c/ios`)
|
||||
- onnxruntime (from `.symlinks/plugins/onnxruntime/ios`)
|
||||
- open_mail_app (from `.symlinks/plugins/open_mail_app/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
@@ -303,7 +310,7 @@ DEPENDENCIES:
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- ffmpeg-kit-ios-min
|
||||
- ffmpeg-kit-ios-full-gpl
|
||||
- Firebase
|
||||
- FirebaseCore
|
||||
- FirebaseCoreInternal
|
||||
@@ -331,12 +338,14 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/battery_info/ios"
|
||||
connectivity_plus:
|
||||
:path: ".symlinks/plugins/connectivity_plus/darwin"
|
||||
cupertino_http:
|
||||
:path: ".symlinks/plugins/cupertino_http/darwin"
|
||||
dart_ui_isolate:
|
||||
:path: ".symlinks/plugins/dart_ui_isolate/ios"
|
||||
device_info_plus:
|
||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||
ffmpeg_kit_flutter_min:
|
||||
:path: ".symlinks/plugins/ffmpeg_kit_flutter_min/ios"
|
||||
ffmpeg_kit_flutter_full_gpl:
|
||||
:path: ".symlinks/plugins/ffmpeg_kit_flutter_full_gpl/ios"
|
||||
file_saver:
|
||||
:path: ".symlinks/plugins/file_saver/ios"
|
||||
firebase_core:
|
||||
@@ -393,6 +402,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/move_to_background/ios"
|
||||
native_video_player:
|
||||
:path: ".symlinks/plugins/native_video_player/ios"
|
||||
objective_c:
|
||||
:path: ".symlinks/plugins/objective_c/ios"
|
||||
onnxruntime:
|
||||
:path: ".symlinks/plugins/onnxruntime/ios"
|
||||
open_mail_app:
|
||||
@@ -439,82 +450,84 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/wakelock_plus/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
background_fetch: 39f11371c0dce04b001c4bfd5e782bcccb0a85e2
|
||||
battery_info: 09f5c9ee65394f2291c8c6227bedff345b8a730c
|
||||
connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db
|
||||
dart_ui_isolate: d5bcda83ca4b04f129d70eb90110b7a567aece14
|
||||
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
|
||||
ffmpeg-kit-ios-min: 4e9a088f4ee9629435960b9d68e54848975f1931
|
||||
ffmpeg_kit_flutter_min: 5eff47f4965bf9d1150e98961eb6129f5ae3f28c
|
||||
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
|
||||
background_fetch: 94b36ee293e82972852dba8ede1fbcd3bd3d9d57
|
||||
battery_info: a06b00c06a39bc94c92beebf600f1810cb6c8c87
|
||||
connectivity_plus: 3f6c9057f4cd64198dc826edfb0542892f825343
|
||||
cupertino_http: 94ac07f5ff090b8effa6c5e2c47871d48ab7c86c
|
||||
dart_ui_isolate: 46f6714abe6891313267153ef6f9748d8ecfcab1
|
||||
device_info_plus: 335f3ce08d2e174b9fdc3db3db0f4e3b1f66bd89
|
||||
ffmpeg-kit-ios-full-gpl: 80adc341962e55ef709e36baa8ed9a70cf4ea62b
|
||||
ffmpeg_kit_flutter_full_gpl: ce18b888487c05c46ed252cd2e7956812f2e3bd1
|
||||
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
|
||||
Firebase: 98e6bf5278170668a7983e12971a66b2cd57fc8c
|
||||
firebase_core: 2bedc3136ec7c7b8561c6123ed0239387b53f2af
|
||||
firebase_messaging: 15d114e1a41fc31e4fbabcd48d765a19eec94a38
|
||||
firebase_core: 085320ddfaacb80d1a96eac3a87857afcc150db1
|
||||
firebase_messaging: d398edc15fe825f832836e74f6ac61e8cd2f3ad3
|
||||
FirebaseCore: a282032ae9295c795714ded2ec9c522fc237f8da
|
||||
FirebaseCoreInternal: ac26d09a70c730e497936430af4e60fb0c68ec4e
|
||||
FirebaseInstallations: 58cf94dabf1e2bb2fa87725a9be5c2249171cda0
|
||||
FirebaseCoreInternal: d98ab91e2d80a56d7b246856a8885443b302c0c2
|
||||
FirebaseInstallations: 6ef4a1c7eb2a61ee1f74727d7f6ce2e72acf1414
|
||||
FirebaseMessaging: c9ec7b90c399c7a6100297e9d16f8a27fc7f7152
|
||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||
flutter_email_sender: 02d7443217d8c41483223627972bfdc09f74276b
|
||||
flutter_image_compress: 5a5e9aee05b6553048b8df1c3bc456d0afaac433
|
||||
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
|
||||
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
|
||||
flutter_native_splash: edf599c81f74d093a4daf8e17bd7a018854bc778
|
||||
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
|
||||
flutter_sodium: c84426b4de738514b5b66cfdeb8a06634e72fe0b
|
||||
fluttertoast: e9a18c7be5413da53898f660530c56f35edfba9c
|
||||
flutter_email_sender: cd533cdc7ea5eda6fabb2c7f78521c71207778a4
|
||||
flutter_image_compress: 4b058288a81f76e5e80340af37c709abafff34c4
|
||||
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
|
||||
flutter_local_notifications: ad39620c743ea4c15127860f4b5641649a988100
|
||||
flutter_native_splash: 35ddbc7228eafcb3969dcc5f1fbbe27c1145a4f0
|
||||
flutter_secure_storage: 2c2ff13db9e0a5647389bff88b0ecac56e3f3418
|
||||
flutter_sodium: 152647449ba89a157fd48d7e293dcd6d29c6ab0e
|
||||
fluttertoast: 76fea30fcf04176325f6864c87306927bd7d2038
|
||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||
home_widget: 0434835a4c9a75704264feff6be17ea40e0f0d57
|
||||
image_editor_common: d6f6644ae4a6de80481e89fe6d0a8c49e30b4b43
|
||||
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
||||
in_app_purchase_storekit: 8c3b0b3eb1b0f04efbff401c3de6266d4258d433
|
||||
integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573
|
||||
home_widget: f169fc41fd807b4d46ab6615dc44d62adbf9f64f
|
||||
image_editor_common: 3de87e7c4804f4ae24c8f8a998362b98c105cac1
|
||||
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
|
||||
in_app_purchase_storekit: e126ef1b89e4a9fdf07e28f005f82632b4609437
|
||||
integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e
|
||||
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
|
||||
local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3
|
||||
local_auth_ios: 5046a18c018dd973247a0564496c8898dbb5adf9
|
||||
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
|
||||
local_auth_ios: f7a1841beef3151d140a967c2e46f30637cdf451
|
||||
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
|
||||
maps_launcher: 2e5b6a2d664ec6c27f82ffa81b74228d770ab203
|
||||
media_extension: 6d30dc1431ebaa63f43c397c37917b1a0a597a4c
|
||||
media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1
|
||||
media_kit_native_event_loop: e6b2ab20cf0746eb1c33be961fcf79667304fa2a
|
||||
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e
|
||||
motion_sensors: 03f55b7c637a7e365a0b5f9697a449f9059d5d91
|
||||
motionphoto: d4a432b8c8f22fb3ad966258597c0103c9c5ff16
|
||||
move_to_background: 39a5b79b26d577b0372cbe8a8c55e7aa9fcd3a2d
|
||||
maps_launcher: edf829809ba9e894d70e569bab11c16352dedb45
|
||||
media_extension: a1fec16ee9c8241a6aef9613578ebf097d6c5e64
|
||||
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
|
||||
media_kit_native_event_loop: 5fba1a849a6c87a34985f1e178a0de5bd444a0cf
|
||||
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
|
||||
motion_sensors: 741e702c17467b9569a92165dda8d4d88c6167f1
|
||||
motionphoto: 584b43031ead3060225cdff08fa49818879801d2
|
||||
move_to_background: 155f7bfbd34d43ad847cb630d2d2d87c17199710
|
||||
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||
native_video_player: d12af78a1a4a8cf09775a5177d5b392def6fd23c
|
||||
onnxruntime: e7c2ae44385191eaad5ae64c935a72debaddc997
|
||||
native_video_player: b65c58951ede2f93d103a25366bdebca95081265
|
||||
objective_c: 89e720c30d716b036faf9c9684022048eee1eee2
|
||||
onnxruntime: f9b296392c96c42882be020a59dbeac6310d81b2
|
||||
onnxruntime-c: a909204639a1f035f575127ac406f781ac797c9c
|
||||
onnxruntime-objc: b6fab0f1787aa6f7190c2013f03037df4718bd8b
|
||||
open_mail_app: 794172f6a22cd16319d3ddaf45e945b2f74952b0
|
||||
open_mail_app: 06d5a4162866388a92b1df3deb96e56be20cf45c
|
||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||
package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85
|
||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
|
||||
photo_manager: ff695c7a1dd5bc379974953a2b5c0a293f7c4c8a
|
||||
privacy_screen: 1a131c052ceb3c3659934b003b0d397c2381a24e
|
||||
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
|
||||
photo_manager: d2fbcc0f2d82458700ee6256a15018210a81d413
|
||||
privacy_screen: 3159a541f5d3a31bea916cfd4e58f9dc722b3fd4
|
||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||
receive_sharing_intent: df9c334dc9feadcbd3266e5cb49c8443405e1c9f
|
||||
screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625
|
||||
SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3
|
||||
receive_sharing_intent: f6a12b7e8f7ed745f61c982de8a65de88db44a44
|
||||
screen_brightness_ios: 5ed898fa50fa82a26171c086ca5e28228f932576
|
||||
SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8
|
||||
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
|
||||
Sentry: f8374b5415bc38dfb5645941b3ae31230fbeae57
|
||||
sentry_flutter: 0eb93e5279eb41e2392212afe1ccd2fecb4f8cbe
|
||||
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
|
||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||
sqflite_darwin: a553b1fd6fe66f53bbb0fe5b4f5bab93f08d7a13
|
||||
sentry_flutter: 0a211008f52553ba5dd81ceb71f48d78f0f1f6ab
|
||||
share_plus: 011d6fb4f9d2576b83179a3a5c5e323202cdabcf
|
||||
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||
sqflite_darwin: 44bb54cc302bff1fbe5752293aba1820b157cf1c
|
||||
sqlite3: 0bb0e6389d824e40296f531b858a2a0b71c0d2fb
|
||||
sqlite3_flutter_libs: c00457ebd31e59fa6bb830380ddba24d44fbcd3b
|
||||
system_info_plus: 5393c8da281d899950d751713575fbf91c7709aa
|
||||
sqlite3_flutter_libs: 9379996d65aa23dcda7585a5b58766cebe0aa042
|
||||
system_info_plus: 555ce7047fbbf29154726db942ae785c29211740
|
||||
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
|
||||
ua_client_hints: 46bb5817a868f9e397c0ba7e3f2f5c5d90c35156
|
||||
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
|
||||
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
||||
video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
|
||||
video_thumbnail: c4e2a3c539e247d4de13cd545344fd2d26ffafd1
|
||||
volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9
|
||||
wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47
|
||||
ua_client_hints: 0b48eae1134283f5b131ee0871fa878377f07a01
|
||||
uni_links: ed8c961e47ed9ce42b6d91e1de8049e38a4b3152
|
||||
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
||||
video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b
|
||||
video_thumbnail: b637e0ad5f588ca9945f6e2c927f73a69a661140
|
||||
volume_controller: ca1cde542ee70fad77d388f82e9616488110942b
|
||||
wakelock_plus: 04623e3f525556020ebd4034310f20fe7fda8b49
|
||||
|
||||
PODFILE CHECKSUM: 20e086e6008977d43a3d40260f3f9bffcac748dd
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
DA6BE5E826B3BC8600656280 /* (null) in Resources */ = {isa = PBXBuildFile; };
|
||||
DA6BE5E826B3BC8600656280 /* BuildFile in Resources */ = {isa = PBXBuildFile; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@@ -230,7 +230,7 @@
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
||||
DA6BE5E826B3BC8600656280 /* (null) in Resources */,
|
||||
DA6BE5E826B3BC8600656280 /* BuildFile in Resources */,
|
||||
277218A0270F596900FFE3CC /* GoogleService-Info.plist in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -292,6 +292,7 @@
|
||||
"${BUILT_PRODUCTS_DIR}/background_fetch/background_fetch.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/battery_info/battery_info.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/connectivity_plus/connectivity_plus.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/cupertino_http/cupertino_http.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/dart_ui_isolate/dart_ui_isolate.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/device_info_plus/device_info_plus.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/file_saver/file_saver.framework",
|
||||
@@ -321,6 +322,7 @@
|
||||
"${BUILT_PRODUCTS_DIR}/move_to_background/move_to_background.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/native_video_player/native_video_player.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/objective_c/objective_c.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/open_mail_app/open_mail_app.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/package_info_plus/package_info_plus.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework",
|
||||
@@ -342,14 +344,14 @@
|
||||
"${BUILT_PRODUCTS_DIR}/video_thumbnail/video_thumbnail.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/volume_controller/volume_controller.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/wakelock_plus/wakelock_plus.framework",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/ffmpegkit.framework/ffmpegkit",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavcodec.framework/libavcodec",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavdevice.framework/libavdevice",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavfilter.framework/libavfilter",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavformat.framework/libavformat",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavutil.framework/libavutil",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libswresample.framework/libswresample",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libswscale.framework/libswscale",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-full-gpl/ffmpegkit.framework/ffmpegkit",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-full-gpl/libavcodec.framework/libavcodec",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-full-gpl/libavdevice.framework/libavdevice",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-full-gpl/libavfilter.framework/libavfilter",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-full-gpl/libavformat.framework/libavformat",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-full-gpl/libavutil.framework/libavutil",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-full-gpl/libswresample.framework/libswresample",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-full-gpl/libswscale.framework/libswscale",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/media_kit_libs_ios_video/Ass.framework/Ass",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/media_kit_libs_ios_video/Avcodec.framework/Avcodec",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/media_kit_libs_ios_video/Avfilter.framework/Avfilter",
|
||||
@@ -387,6 +389,7 @@
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/background_fetch.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/battery_info.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity_plus.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/cupertino_http.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/dart_ui_isolate.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info_plus.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_saver.framework",
|
||||
@@ -416,6 +419,7 @@
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/move_to_background.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/native_video_player.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/objective_c.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/open_mail_app.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info_plus.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework",
|
||||
|
||||
@@ -18,6 +18,7 @@ import 'package:photos/core/error-reporting/tunneled_transport.dart';
|
||||
import "package:photos/core/errors.dart";
|
||||
import 'package:photos/models/typedefs.dart';
|
||||
import "package:photos/utils/device_info.dart";
|
||||
import "package:photos/utils/ram_check_util.dart";
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
@@ -205,6 +206,12 @@ class SuperLogging {
|
||||
}),
|
||||
);
|
||||
|
||||
unawaited(
|
||||
checkDeviceTotalRAM().then((ram) {
|
||||
if (ram != null) $.info("Device RAM: ${ram}MB");
|
||||
}),
|
||||
);
|
||||
|
||||
if (appConfig.body == null) return;
|
||||
|
||||
if (enable && sentryIsEnabled) {
|
||||
@@ -236,7 +243,7 @@ class SuperLogging {
|
||||
}
|
||||
|
||||
static _shouldSkipSentry(Object error) {
|
||||
if (error is DioError) {
|
||||
if (error is DioException) {
|
||||
return true;
|
||||
}
|
||||
final bool result = error is StorageLimitExceededError ||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:native_dio_adapter/native_dio_adapter.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import "package:photos/core/configuration.dart";
|
||||
import "package:photos/core/event_bus.dart";
|
||||
@@ -8,18 +9,17 @@ import 'package:photos/core/network/ente_interceptor.dart';
|
||||
import "package:photos/events/endpoint_updated_event.dart";
|
||||
import "package:ua_client_hints/ua_client_hints.dart";
|
||||
|
||||
int kConnectTimeout = 15000;
|
||||
|
||||
class NetworkClient {
|
||||
late Dio _dio;
|
||||
late Dio _enteDio;
|
||||
static const kConnectTimeout = 15;
|
||||
|
||||
Future<void> init(PackageInfo packageInfo) async {
|
||||
final String ua = await userAgent();
|
||||
final endpoint = Configuration.instance.getHttpEndpoint();
|
||||
_dio = Dio(
|
||||
BaseOptions(
|
||||
connectTimeout: kConnectTimeout,
|
||||
connectTimeout: const Duration(seconds: kConnectTimeout),
|
||||
headers: {
|
||||
HttpHeaders.userAgentHeader: ua,
|
||||
'X-Client-Version': packageInfo.version,
|
||||
@@ -30,7 +30,7 @@ class NetworkClient {
|
||||
_enteDio = Dio(
|
||||
BaseOptions(
|
||||
baseUrl: endpoint,
|
||||
connectTimeout: kConnectTimeout,
|
||||
connectTimeout: const Duration(seconds: kConnectTimeout),
|
||||
headers: {
|
||||
HttpHeaders.userAgentHeader: ua,
|
||||
'X-Client-Version': packageInfo.version,
|
||||
@@ -38,6 +38,10 @@ class NetworkClient {
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
_dio.httpClientAdapter = NativeAdapter();
|
||||
_enteDio.httpClientAdapter = NativeAdapter();
|
||||
|
||||
_setupInterceptors(endpoint);
|
||||
|
||||
Bus.instance.on<EndpointUpdatedEvent>().listen((event) {
|
||||
|
||||
@@ -251,20 +251,20 @@ class CollectionsDB {
|
||||
Map<String, dynamic> _getRowForCollection(Collection collection) {
|
||||
final row = <String, dynamic>{};
|
||||
row[columnID] = collection.id;
|
||||
row[columnOwner] = collection.owner!.toJson();
|
||||
row[columnOwner] = collection.owner.toJson();
|
||||
row[columnEncryptedKey] = collection.encryptedKey;
|
||||
row[columnKeyDecryptionNonce] = collection.keyDecryptionNonce;
|
||||
row[columnName] = collection.name;
|
||||
row[columnEncryptedName] = collection.encryptedName;
|
||||
row[columnNameDecryptionNonce] = collection.nameDecryptionNonce;
|
||||
row[columnType] = Collection.typeToString(collection.type);
|
||||
row[columnType] = typeToString(collection.type);
|
||||
row[columnEncryptedPath] = collection.attributes.encryptedPath;
|
||||
row[columnPathDecryptionNonce] = collection.attributes.pathDecryptionNonce;
|
||||
row[columnVersion] = collection.attributes.version;
|
||||
row[columnSharees] =
|
||||
json.encode(collection.sharees?.map((x) => x?.toMap()).toList());
|
||||
json.encode(collection.sharees.map((x) => x.toMap()).toList());
|
||||
row[columnPublicURLs] =
|
||||
json.encode(collection.publicURLs?.map((x) => x?.toMap()).toList());
|
||||
json.encode(collection.publicURLs.map((x) => x.toMap()).toList());
|
||||
row[columnUpdationTime] = collection.updationTime;
|
||||
if (collection.isDeleted) {
|
||||
row[columnIsDeleted] = _sqlBoolTrue;
|
||||
@@ -290,7 +290,7 @@ class CollectionsDB {
|
||||
row[columnName],
|
||||
row[columnEncryptedName],
|
||||
row[columnNameDecryptionNonce],
|
||||
Collection.typeFromString(row[columnType]),
|
||||
typeFromString(row[columnType]),
|
||||
CollectionAttributes(
|
||||
encryptedPath: row[columnEncryptedPath],
|
||||
pathDecryptionNonce: row[columnPathDecryptionNonce],
|
||||
|
||||
@@ -1730,6 +1730,26 @@ class FilesDB {
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<EnteFile>> getAllFilesAfterDate({
|
||||
required FileType fileType,
|
||||
required DateTime beginDate,
|
||||
required int userID,
|
||||
}) async {
|
||||
final db = await instance.sqliteAsyncDB;
|
||||
final results = await db.getAll(
|
||||
'''
|
||||
SELECT * FROM $filesTable
|
||||
WHERE $columnFileType = ?
|
||||
AND $columnCreationTime > ?
|
||||
AND $columnUploadedFileID != -1
|
||||
AND $columnOwnerID = $userID
|
||||
ORDER BY $columnCreationTime DESC
|
||||
''',
|
||||
[getInt(fileType), beginDate.microsecondsSinceEpoch],
|
||||
);
|
||||
return convertToFiles(results);
|
||||
}
|
||||
|
||||
Future<List<EnteFile>> getAllFilesFromDB(
|
||||
Set<int> collectionsToIgnore, {
|
||||
bool dedupeByUploadId = true,
|
||||
|
||||
118
mobile/lib/db/ml/base.dart
Normal file
@@ -0,0 +1,118 @@
|
||||
import "dart:typed_data";
|
||||
|
||||
import "package:photos/models/ml/clip.dart";
|
||||
import "package:photos/models/ml/face/face.dart";
|
||||
import "package:photos/models/ml/vector.dart";
|
||||
import "package:photos/services/machine_learning/face_ml/face_clustering/face_db_info_for_clustering.dart";
|
||||
|
||||
abstract class IMLDataDB<T> {
|
||||
Future<void> bulkInsertFaces(List<Face> faces);
|
||||
Future<void> updateFaceIdToClusterId(Map<String, String> faceIDToClusterID);
|
||||
Future<Map<int, int>> faceIndexedFileIds({int minimumMlVersion});
|
||||
Future<int> getFaceIndexedFileCount({int minimumMlVersion});
|
||||
Future<Map<String, int>> clusterIdToFaceCount();
|
||||
Future<Set<String>> getPersonIgnoredClusters(String personID);
|
||||
Future<Set<String>> getPersonClusterIDs(String personID);
|
||||
Future<Set<String>> getPersonsClusterIDs(List<String> personID);
|
||||
Future<void> clearTable();
|
||||
Future<Iterable<Uint8List>> getFaceEmbeddingsForCluster(
|
||||
String clusterID, {
|
||||
int? limit,
|
||||
});
|
||||
Future<Map<String, Iterable<Uint8List>>> getFaceEmbeddingsForClusters(
|
||||
Iterable<String> clusterIDs, {
|
||||
int? limit,
|
||||
});
|
||||
Future<Face?> getCoverFaceForPerson({
|
||||
required T recentFileID,
|
||||
String? personID,
|
||||
String? avatarFaceId,
|
||||
String? clusterID,
|
||||
});
|
||||
Future<List<Face>?> getFacesForGivenFileID(T fileUploadID);
|
||||
Future<Map<String, Iterable<String>>> getClusterToFaceIDs(
|
||||
Set<String> clusterIDs,
|
||||
);
|
||||
Future<String?> getClusterIDForFaceID(String faceID);
|
||||
Future<Map<String, Iterable<String>>> getAllClusterIdToFaceIDs();
|
||||
Future<Iterable<String>> getFaceIDsForCluster(String clusterID);
|
||||
Future<Map<String, Map<String, Set<String>>>> getPersonToClusterIdToFaceIds();
|
||||
Future<Map<String, Set<String>>> getClusterIdToFaceIdsForPerson(
|
||||
String personID,
|
||||
);
|
||||
Future<Set<String>> getFaceIDsForPerson(String personID);
|
||||
Future<Iterable<double>> getBlurValuesForCluster(String clusterID);
|
||||
Future<Map<String, String?>> getFaceIdsToClusterIds(Iterable<String> faceIds);
|
||||
Future<Map<T, Set<String>>> getFileIdToClusterIds();
|
||||
Future<void> forceUpdateClusterIds(Map<String, String> faceIDToClusterID);
|
||||
Future<void> removeFaceIdToClusterId(Map<String, String> faceIDToClusterID);
|
||||
Future<void> removePerson(String personID);
|
||||
Future<List<FaceDbInfoForClustering>> getFaceInfoForClustering({
|
||||
int maxFaces,
|
||||
int offset,
|
||||
int batchSize,
|
||||
});
|
||||
Future<Map<String, Uint8List>> getFaceEmbeddingMapForFaces(
|
||||
Iterable<String> faceIDs,
|
||||
);
|
||||
Future<int> getTotalFaceCount();
|
||||
Future<int> getErroredFaceCount();
|
||||
Future<Set<T>> getErroredFileIDs();
|
||||
Future<void> deleteFaceIndexForFiles(List<T> fileIDs);
|
||||
Future<int> getClusteredOrFacelessFileCount();
|
||||
Future<double> getClusteredToIndexableFilesRatio();
|
||||
Future<int> getUnclusteredFaceCount();
|
||||
Future<void> assignClusterToPerson({
|
||||
required String personID,
|
||||
required String clusterID,
|
||||
});
|
||||
Future<void> bulkAssignClusterToPersonID(
|
||||
Map<String, String> clusterToPersonID,
|
||||
);
|
||||
Future<void> captureNotPersonFeedback({
|
||||
required String personID,
|
||||
required String clusterID,
|
||||
});
|
||||
Future<void> bulkCaptureNotPersonFeedback(
|
||||
Map<String, String> clusterToPersonID,
|
||||
);
|
||||
Future<void> removeNotPersonFeedback({
|
||||
required String personID,
|
||||
required String clusterID,
|
||||
});
|
||||
Future<void> removeClusterToPerson({
|
||||
required String personID,
|
||||
required String clusterID,
|
||||
});
|
||||
Future<Map<T, Set<String>>> getFileIdToClusterIDSet(String personID);
|
||||
Future<Map<T, Set<String>>> getFileIdToClusterIDSetForCluster(
|
||||
Set<String> clusterIDs,
|
||||
);
|
||||
Future<void> clusterSummaryUpdate(Map<String, (Uint8List, int)> summary);
|
||||
Future<void> deleteClusterSummary(String clusterID);
|
||||
Future<Map<String, (Uint8List, int)>> getAllClusterSummary([
|
||||
int? minClusterSize,
|
||||
]);
|
||||
Future<Map<String, (Uint8List, int)>> getClusterToClusterSummary(
|
||||
Iterable<String> clusterIDs,
|
||||
);
|
||||
Future<Map<String, String>> getClusterIDToPersonID();
|
||||
Future<void> dropClustersAndPersonTable({bool faces});
|
||||
Future<void> dropFacesFeedbackTables();
|
||||
Future<List<T>> getFileIDsOfPersonID(String personID);
|
||||
Future<List<T>> getFileIDsOfClusterID(String clusterID);
|
||||
Future<Set<T>> getAllFileIDsOfFaceIDsNotInAnyCluster();
|
||||
Future<Set<T>> getAllFilesAssociatedWithAllClusters({
|
||||
List<String>? exceptClusters,
|
||||
});
|
||||
|
||||
Future<List<EmbeddingVector>> getAllClipVectors();
|
||||
Future<Map<int, int>> clipIndexedFileWithVersion();
|
||||
Future<Map<int, EmbeddingVector>> getClipVectorsForFileIDs(
|
||||
Iterable<int> fileIDs,
|
||||
);
|
||||
Future<int> getClipIndexedFileCount({int minimumMlVersion});
|
||||
Future<void> putClip(List<ClipEmbedding> embeddings);
|
||||
Future<void> deleteClipEmbeddings(List<T> fileIDs);
|
||||
Future<void> deleteClipIndexes();
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
import "dart:typed_data";
|
||||
|
||||
import "package:logging/logging.dart";
|
||||
import "package:photos/core/event_bus.dart";
|
||||
import "package:photos/db/ml/db.dart";
|
||||
import "package:photos/db/ml/db_fields.dart";
|
||||
import "package:photos/events/embedding_updated_event.dart";
|
||||
import "package:photos/models/ml/clip.dart";
|
||||
import "package:photos/models/ml/ml_versions.dart";
|
||||
import "package:photos/models/ml/vector.dart";
|
||||
|
||||
extension ClipDB on MLDataDB {
|
||||
Future<List<EmbeddingVector>> getAllClipVectors() async {
|
||||
Logger("ClipDB").info("reading all embeddings from DB");
|
||||
final db = await MLDataDB.instance.asyncDB;
|
||||
final results = await db.getAll('SELECT * FROM $clipTable');
|
||||
return _convertToVectors(results);
|
||||
}
|
||||
|
||||
// Get indexed FileIDs
|
||||
Future<Map<int, int>> clipIndexedFileWithVersion() async {
|
||||
final db = await MLDataDB.instance.asyncDB;
|
||||
final maps = await db
|
||||
.getAll('SELECT $fileIDColumn , $mlVersionColumn FROM $clipTable');
|
||||
final Map<int, int> result = {};
|
||||
for (final map in maps) {
|
||||
result[map[fileIDColumn] as int] = map[mlVersionColumn] as int;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<int> getClipIndexedFileCount({
|
||||
int minimumMlVersion = clipMlVersion,
|
||||
}) async {
|
||||
final db = await MLDataDB.instance.asyncDB;
|
||||
final String query =
|
||||
'SELECT COUNT(DISTINCT $fileIDColumn) as count FROM $clipTable WHERE $mlVersionColumn >= $minimumMlVersion';
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(query);
|
||||
return maps.first['count'] as int;
|
||||
}
|
||||
|
||||
Future<void> put(ClipEmbedding embedding) async {
|
||||
final db = await MLDataDB.instance.asyncDB;
|
||||
await db.execute(
|
||||
'INSERT OR REPLACE INTO $clipTable ($fileIDColumn, $embeddingColumn, $mlVersionColumn) VALUES (?, ?, ?)',
|
||||
_getRowFromEmbedding(embedding),
|
||||
);
|
||||
Bus.instance.fire(EmbeddingUpdatedEvent());
|
||||
}
|
||||
|
||||
Future<void> putMany(List<ClipEmbedding> embeddings) async {
|
||||
if (embeddings.isEmpty) return;
|
||||
final db = await MLDataDB.instance.asyncDB;
|
||||
final inputs = embeddings.map((e) => _getRowFromEmbedding(e)).toList();
|
||||
await db.executeBatch(
|
||||
'INSERT OR REPLACE INTO $clipTable ($fileIDColumn, $embeddingColumn, $mlVersionColumn) values(?, ?, ?)',
|
||||
inputs,
|
||||
);
|
||||
Bus.instance.fire(EmbeddingUpdatedEvent());
|
||||
}
|
||||
|
||||
Future<void> deleteClipEmbeddings(List<int> fileIDs) async {
|
||||
final db = await MLDataDB.instance.asyncDB;
|
||||
await db.execute(
|
||||
'DELETE FROM $clipTable WHERE $fileIDColumn IN (${fileIDs.join(", ")})',
|
||||
);
|
||||
Bus.instance.fire(EmbeddingUpdatedEvent());
|
||||
}
|
||||
|
||||
Future<void> deleteClipIndexes() async {
|
||||
final db = await MLDataDB.instance.asyncDB;
|
||||
await db.execute('DELETE FROM $clipTable');
|
||||
Bus.instance.fire(EmbeddingUpdatedEvent());
|
||||
}
|
||||
|
||||
List<EmbeddingVector> _convertToVectors(List<Map<String, dynamic>> results) {
|
||||
final List<EmbeddingVector> embeddings = [];
|
||||
for (final result in results) {
|
||||
final embedding = _getVectorFromRow(result);
|
||||
if (embedding.isEmpty) continue;
|
||||
embeddings.add(embedding);
|
||||
}
|
||||
return embeddings;
|
||||
}
|
||||
|
||||
EmbeddingVector _getVectorFromRow(Map<String, dynamic> row) {
|
||||
final fileID = row[fileIDColumn] as int;
|
||||
final bytes = row[embeddingColumn] as Uint8List;
|
||||
final list = Float32List.view(bytes.buffer);
|
||||
return EmbeddingVector(fileID: fileID, embedding: list);
|
||||
}
|
||||
|
||||
List<Object?> _getRowFromEmbedding(ClipEmbedding embedding) {
|
||||
return [
|
||||
embedding.fileID,
|
||||
Float32List.fromList(embedding.embedding).buffer.asUint8List(),
|
||||
embedding.version,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,16 @@ import "package:flutter/foundation.dart";
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:path/path.dart' show join;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import "package:photos/core/event_bus.dart";
|
||||
import "package:photos/db/ml/base.dart";
|
||||
import 'package:photos/db/ml/db_fields.dart';
|
||||
import "package:photos/db/ml/db_model_mappers.dart";
|
||||
import "package:photos/events/embedding_updated_event.dart";
|
||||
import "package:photos/extensions/stop_watch.dart";
|
||||
import "package:photos/models/ml/clip.dart";
|
||||
import "package:photos/models/ml/face/face.dart";
|
||||
import "package:photos/models/ml/ml_versions.dart";
|
||||
import "package:photos/models/ml/vector.dart";
|
||||
import "package:photos/services/machine_learning/face_ml/face_clustering/face_db_info_for_clustering.dart";
|
||||
import 'package:photos/services/machine_learning/face_ml/face_filtering/face_filtering_constants.dart';
|
||||
import "package:photos/services/machine_learning/ml_result.dart";
|
||||
@@ -28,7 +33,7 @@ import 'package:sqlite_async/sqlite_async.dart';
|
||||
///
|
||||
/// [clipTable] - Stores the embeddings of the CLIP model
|
||||
/// [fileDataTable] - Stores data about the files that are already processed by the ML models
|
||||
class MLDataDB {
|
||||
class MLDataDB extends IMLDataDB<int> {
|
||||
static final Logger _logger = Logger("MLDataDB");
|
||||
|
||||
static const _databaseName = "ente.ml.db";
|
||||
@@ -108,6 +113,7 @@ class MLDataDB {
|
||||
// bulkInsertFaces inserts the faces in the database in batches of 1000.
|
||||
// This is done to avoid the error "too many SQL variables" when inserting
|
||||
// a large number of faces.
|
||||
@override
|
||||
Future<void> bulkInsertFaces(List<Face> faces) async {
|
||||
final db = await instance.asyncDB;
|
||||
const batchSize = 500;
|
||||
@@ -143,6 +149,7 @@ class MLDataDB {
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateFaceIdToClusterId(
|
||||
Map<String, String> faceIDToClusterID,
|
||||
) async {
|
||||
@@ -166,6 +173,7 @@ class MLDataDB {
|
||||
}
|
||||
|
||||
/// Returns a map of fileID to the indexed ML version
|
||||
@override
|
||||
Future<Map<int, int>> faceIndexedFileIds({
|
||||
int minimumMlVersion = faceMlVersion,
|
||||
}) async {
|
||||
@@ -183,6 +191,7 @@ class MLDataDB {
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> getFaceIndexedFileCount({
|
||||
int minimumMlVersion = faceMlVersion,
|
||||
}) async {
|
||||
@@ -193,6 +202,7 @@ class MLDataDB {
|
||||
return maps.first['count'] as int;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, int>> clusterIdToFaceCount() async {
|
||||
final db = await instance.asyncDB;
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(
|
||||
@@ -205,6 +215,7 @@ class MLDataDB {
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Set<String>> getPersonIgnoredClusters(String personID) async {
|
||||
final db = await instance.asyncDB;
|
||||
// find out clusterIds that are assigned to other persons using the clusters table
|
||||
@@ -223,6 +234,7 @@ class MLDataDB {
|
||||
return ignoredClusterIDs.union(rejectClusterIDs);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Set<String>> getPersonClusterIDs(String personID) async {
|
||||
final db = await instance.asyncDB;
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(
|
||||
@@ -232,6 +244,7 @@ class MLDataDB {
|
||||
return maps.map((e) => e[clusterIDColumn] as String).toSet();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Set<String>> getPersonsClusterIDs(List<String> personID) async {
|
||||
final db = await instance.asyncDB;
|
||||
final inParam = personID.map((e) => "'$e'").join(',');
|
||||
@@ -241,6 +254,7 @@ class MLDataDB {
|
||||
return maps.map((e) => e[clusterIDColumn] as String).toSet();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> clearTable() async {
|
||||
final db = await instance.asyncDB;
|
||||
|
||||
@@ -253,6 +267,7 @@ class MLDataDB {
|
||||
await db.execute(deleteFileDataTable);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Iterable<Uint8List>> getFaceEmbeddingsForCluster(
|
||||
String clusterID, {
|
||||
int? limit,
|
||||
@@ -265,6 +280,7 @@ class MLDataDB {
|
||||
return maps.map((e) => e[embeddingColumn] as Uint8List);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, Iterable<Uint8List>>> getFaceEmbeddingsForClusters(
|
||||
Iterable<String> clusterIDs, {
|
||||
int? limit,
|
||||
@@ -297,6 +313,7 @@ class MLDataDB {
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Face?> getCoverFaceForPerson({
|
||||
required int recentFileID,
|
||||
String? personID,
|
||||
@@ -325,11 +342,6 @@ class MLDataDB {
|
||||
);
|
||||
final clusterIDs =
|
||||
clusterRows.map((e) => e[clusterIDColumn] as String).toList();
|
||||
// final List<Map<String, dynamic>> faceMaps = await db.getAll(
|
||||
// 'SELECT * FROM $facesTable where '
|
||||
// '$faceIDColumn in (SELECT $faceIDColumn from $faceClustersTable where $clusterIDColumn IN (${clusterIDs.join(",")}))'
|
||||
// 'AND $fileIDColumn in (${fileId.join(",")}) AND $faceScore > $kMinimumQualityFaceScore ORDER BY $faceScore DESC',
|
||||
// );
|
||||
|
||||
final List<Map<String, dynamic>> faceMaps = await db.getAll(
|
||||
'''
|
||||
@@ -340,10 +352,9 @@ class MLDataDB {
|
||||
WHERE $clusterIDColumn IN (${List.filled(clusterIDs.length, '?').join(',')})
|
||||
)
|
||||
AND $fileIDColumn IN (${List.filled(fileId.length, '?').join(',')})
|
||||
AND $faceScore > ?
|
||||
ORDER BY $faceScore DESC
|
||||
''',
|
||||
[...clusterIDs, ...fileId, kMinimumQualityFaceScore],
|
||||
[...clusterIDs, ...fileId],
|
||||
);
|
||||
if (faceMaps.isNotEmpty) {
|
||||
if (avatarFileId != null) {
|
||||
@@ -384,6 +395,7 @@ class MLDataDB {
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Face>?> getFacesForGivenFileID(int fileUploadID) async {
|
||||
final db = await instance.asyncDB;
|
||||
const String query = '''
|
||||
@@ -400,6 +412,29 @@ class MLDataDB {
|
||||
return maps.map((e) => mapRowToFace(e)).toList();
|
||||
}
|
||||
|
||||
Future<Map<int, List<Face>>> getFacesForFileIDs(
|
||||
Iterable<int> fileUploadIDs,
|
||||
) async {
|
||||
final db = await instance.asyncDB;
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(
|
||||
'''
|
||||
SELECT * FROM $facesTable
|
||||
WHERE $fileIDColumn IN (${fileUploadIDs.map((id) => "'$id'").join(",")})
|
||||
''',
|
||||
);
|
||||
if (maps.isEmpty) {
|
||||
return {};
|
||||
}
|
||||
final result = <int, List<Face>>{};
|
||||
for (final map in maps) {
|
||||
final face = mapRowToFace(map);
|
||||
final fileID = map[fileIDColumn] as int;
|
||||
result.putIfAbsent(fileID, () => <Face>[]).add(face);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, Iterable<String>>> getClusterToFaceIDs(
|
||||
Set<String> clusterIDs,
|
||||
) async {
|
||||
@@ -423,6 +458,7 @@ class MLDataDB {
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String?> getClusterIDForFaceID(String faceID) async {
|
||||
final db = await instance.asyncDB;
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(
|
||||
@@ -435,6 +471,7 @@ class MLDataDB {
|
||||
return maps.first[clusterIDColumn] as String;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, Iterable<String>>> getAllClusterIdToFaceIDs() async {
|
||||
final db = await instance.asyncDB;
|
||||
final Map<String, List<String>> result = {};
|
||||
@@ -449,6 +486,7 @@ class MLDataDB {
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Iterable<String>> getFaceIDsForCluster(String clusterID) async {
|
||||
final db = await instance.asyncDB;
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(
|
||||
@@ -460,6 +498,7 @@ class MLDataDB {
|
||||
}
|
||||
|
||||
// Get Map of personID to Map of clusterID to faceIDs
|
||||
@override
|
||||
Future<Map<String, Map<String, Set<String>>>>
|
||||
getPersonToClusterIdToFaceIds() async {
|
||||
final db = await instance.asyncDB;
|
||||
@@ -480,6 +519,23 @@ class MLDataDB {
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<Map<String, String>> getFaceIdToPersonIdForFaces(
|
||||
Iterable<String> faceIDs,
|
||||
) async {
|
||||
final db = await instance.asyncDB;
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(
|
||||
'SELECT $faceIDColumn, $personIdColumn FROM $clusterPersonTable '
|
||||
'INNER JOIN $faceClustersTable ON $clusterPersonTable.$clusterIDColumn = $faceClustersTable.$clusterIDColumn '
|
||||
'WHERE $faceIDColumn IN (${faceIDs.map((id) => "'$id'").join(",")})',
|
||||
);
|
||||
final Map<String, String> result = {};
|
||||
for (final map in maps) {
|
||||
result[map[faceIDColumn] as String] = map[personIdColumn] as String;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, Set<String>>> getClusterIdToFaceIdsForPerson(
|
||||
String personID,
|
||||
) async {
|
||||
@@ -499,6 +555,7 @@ class MLDataDB {
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Set<String>> getFaceIDsForPerson(String personID) async {
|
||||
final db = await instance.asyncDB;
|
||||
final faceIdsResult = await db.getAll(
|
||||
@@ -510,6 +567,7 @@ class MLDataDB {
|
||||
return faceIdsResult.map((e) => e[faceIDColumn] as String).toSet();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Iterable<double>> getBlurValuesForCluster(String clusterID) async {
|
||||
final db = await instance.asyncDB;
|
||||
const String query = '''
|
||||
@@ -530,6 +588,7 @@ class MLDataDB {
|
||||
return maps.map((e) => e[faceBlur] as double).toSet();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, String?>> getFaceIdsToClusterIds(
|
||||
Iterable<String> faceIds,
|
||||
) async {
|
||||
@@ -544,6 +603,7 @@ class MLDataDB {
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<int, Set<String>>> getFileIdToClusterIds() async {
|
||||
final Map<int, Set<String>> result = {};
|
||||
final db = await instance.asyncDB;
|
||||
@@ -554,12 +614,13 @@ class MLDataDB {
|
||||
for (final map in maps) {
|
||||
final clusterID = map[clusterIDColumn] as String;
|
||||
final faceID = map[faceIDColumn] as String;
|
||||
final fileID = getFileIdFromFaceId(faceID);
|
||||
final fileID = getFileIdFromFaceId<int>(faceID);
|
||||
result[fileID] = (result[fileID] ?? {})..add(clusterID);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> forceUpdateClusterIds(
|
||||
Map<String, String> faceIDToClusterID,
|
||||
) async {
|
||||
@@ -575,6 +636,7 @@ class MLDataDB {
|
||||
await db.executeBatch(sql, parameterSets);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> removeFaceIdToClusterId(
|
||||
Map<String, String> faceIDToClusterID,
|
||||
) async {
|
||||
@@ -588,6 +650,7 @@ class MLDataDB {
|
||||
await db.executeBatch(sql, parameterSets);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> removePerson(String personID) async {
|
||||
final db = await instance.asyncDB;
|
||||
|
||||
@@ -613,6 +676,7 @@ class MLDataDB {
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<FaceDbInfoForClustering>> getFaceInfoForClustering({
|
||||
int maxFaces = 20000,
|
||||
int offset = 0,
|
||||
@@ -668,6 +732,7 @@ class MLDataDB {
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, Uint8List>> getFaceEmbeddingMapForFaces(
|
||||
Iterable<String> faceIDs,
|
||||
) async {
|
||||
@@ -706,6 +771,7 @@ class MLDataDB {
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> getTotalFaceCount() async {
|
||||
final db = await instance.asyncDB;
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(
|
||||
@@ -714,6 +780,7 @@ class MLDataDB {
|
||||
return maps.first['count'] as int;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> getErroredFaceCount() async {
|
||||
final db = await instance.asyncDB;
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(
|
||||
@@ -722,6 +789,7 @@ class MLDataDB {
|
||||
return maps.first['count'] as int;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Set<int>> getErroredFileIDs() async {
|
||||
final db = await instance.asyncDB;
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(
|
||||
@@ -730,6 +798,7 @@ class MLDataDB {
|
||||
return maps.map((e) => e[fileIDColumn] as int).toSet();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteFaceIndexForFiles(List<int> fileIDs) async {
|
||||
final db = await instance.asyncDB;
|
||||
final String sql = '''
|
||||
@@ -738,6 +807,7 @@ class MLDataDB {
|
||||
await db.execute(sql);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> getClusteredOrFacelessFileCount() async {
|
||||
final db = await instance.asyncDB;
|
||||
final List<Map<String, dynamic>> clustered = await db.getAll(
|
||||
@@ -745,7 +815,7 @@ class MLDataDB {
|
||||
);
|
||||
final Set<int> clusteredFileIDs = {};
|
||||
for (final map in clustered) {
|
||||
final int fileID = getFileIdFromFaceId(map[faceIDColumn] as String);
|
||||
final int fileID = getFileIdFromFaceId<int>(map[faceIDColumn] as String);
|
||||
clusteredFileIDs.add(fileID);
|
||||
}
|
||||
|
||||
@@ -768,6 +838,7 @@ class MLDataDB {
|
||||
return clusteredFileIDs.length + trulyFacelessFiles.length;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> getClusteredToIndexableFilesRatio() async {
|
||||
final int indexableFiles = (await getIndexableFileIDs()).length;
|
||||
final int clusteredFiles = await getClusteredOrFacelessFileCount();
|
||||
@@ -775,6 +846,7 @@ class MLDataDB {
|
||||
return clusteredFiles / indexableFiles;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> getUnclusteredFaceCount() async {
|
||||
final db = await instance.asyncDB;
|
||||
const String query = '''
|
||||
@@ -791,6 +863,7 @@ class MLDataDB {
|
||||
|
||||
/// WARNING: Only use this method if the person has just been created.
|
||||
/// Otherwise, use [ClusterFeedbackService.instance.addClusterToExistingPerson] instead.
|
||||
@override
|
||||
Future<void> assignClusterToPerson({
|
||||
required String personID,
|
||||
required String clusterID,
|
||||
@@ -803,6 +876,7 @@ class MLDataDB {
|
||||
await db.execute(sql, [personID, clusterID]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> bulkAssignClusterToPersonID(
|
||||
Map<String, String> clusterToPersonID,
|
||||
) async {
|
||||
@@ -816,6 +890,7 @@ class MLDataDB {
|
||||
await db.executeBatch(sql, parameterSets);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> captureNotPersonFeedback({
|
||||
required String personID,
|
||||
required String clusterID,
|
||||
@@ -828,6 +903,7 @@ class MLDataDB {
|
||||
await db.execute(sql, [personID, clusterID]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> bulkCaptureNotPersonFeedback(
|
||||
Map<String, String> clusterToPersonID,
|
||||
) async {
|
||||
@@ -842,6 +918,7 @@ class MLDataDB {
|
||||
await db.executeBatch(sql, parameterSets);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> removeNotPersonFeedback({
|
||||
required String personID,
|
||||
required String clusterID,
|
||||
@@ -854,6 +931,7 @@ class MLDataDB {
|
||||
await db.execute(sql, [personID, clusterID]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> removeClusterToPerson({
|
||||
required String personID,
|
||||
required String clusterID,
|
||||
@@ -867,6 +945,7 @@ class MLDataDB {
|
||||
}
|
||||
|
||||
// for a given personID, return a map of clusterID to fileIDs using join query
|
||||
@override
|
||||
Future<Map<int, Set<String>>> getFileIdToClusterIDSet(String personID) {
|
||||
final db = instance.asyncDB;
|
||||
return db.then((db) async {
|
||||
@@ -881,13 +960,14 @@ class MLDataDB {
|
||||
for (final map in maps) {
|
||||
final clusterID = map[clusterIDColumn] as String;
|
||||
final String faceID = map[faceIDColumn] as String;
|
||||
final fileID = getFileIdFromFaceId(faceID);
|
||||
final fileID = getFileIdFromFaceId<int>(faceID);
|
||||
result[fileID] = (result[fileID] ?? {})..add(clusterID);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<int, Set<String>>> getFileIdToClusterIDSetForCluster(
|
||||
Set<String> clusterIDs,
|
||||
) {
|
||||
@@ -905,13 +985,14 @@ class MLDataDB {
|
||||
for (final map in maps) {
|
||||
final clusterID = map[clusterIDColumn] as String;
|
||||
final faceID = map[faceIDColumn] as String;
|
||||
final fileID = getFileIdFromFaceId(faceID);
|
||||
final fileID = getFileIdFromFaceId<int>(faceID);
|
||||
result[fileID] = (result[fileID] ?? {})..add(clusterID);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> clusterSummaryUpdate(
|
||||
Map<String, (Uint8List, int)> summary,
|
||||
) async {
|
||||
@@ -937,6 +1018,7 @@ class MLDataDB {
|
||||
await db.executeBatch(sql, parameterSets);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteClusterSummary(String clusterID) async {
|
||||
final db = await instance.asyncDB;
|
||||
const String sqlDelete =
|
||||
@@ -945,6 +1027,7 @@ class MLDataDB {
|
||||
}
|
||||
|
||||
/// Returns a map of clusterID to (avg embedding, count)
|
||||
@override
|
||||
Future<Map<String, (Uint8List, int)>> getAllClusterSummary([
|
||||
int? minClusterSize,
|
||||
]) async {
|
||||
@@ -962,6 +1045,7 @@ class MLDataDB {
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, (Uint8List, int)>> getClusterToClusterSummary(
|
||||
Iterable<String> clusterIDs,
|
||||
) async {
|
||||
@@ -982,6 +1066,7 @@ class MLDataDB {
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, String>> getClusterIDToPersonID() async {
|
||||
final db = await instance.asyncDB;
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(
|
||||
@@ -995,6 +1080,7 @@ class MLDataDB {
|
||||
}
|
||||
|
||||
/// WARNING: This will delete ALL data in the database! Only use this for debug/testing purposes!
|
||||
@override
|
||||
Future<void> dropClustersAndPersonTable({bool faces = false}) async {
|
||||
try {
|
||||
final db = await instance.asyncDB;
|
||||
@@ -1022,6 +1108,7 @@ class MLDataDB {
|
||||
}
|
||||
|
||||
/// WARNING: This will delete ALL data in the tables! Only use this for debug/testing purposes!
|
||||
@override
|
||||
Future<void> dropFacesFeedbackTables() async {
|
||||
try {
|
||||
final db = await instance.asyncDB;
|
||||
@@ -1038,6 +1125,7 @@ class MLDataDB {
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<int>> getFileIDsOfPersonID(String personID) async {
|
||||
final db = await instance.asyncDB;
|
||||
final result = await db.getAll(
|
||||
@@ -1054,6 +1142,7 @@ class MLDataDB {
|
||||
return [for (final row in result) row[fileIDColumn]];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<int>> getFileIDsOfClusterID(String clusterID) async {
|
||||
final db = await instance.asyncDB;
|
||||
final result = await db.getAll(
|
||||
@@ -1069,6 +1158,7 @@ class MLDataDB {
|
||||
return [for (final row in result) row[fileIDColumn]];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Set<int>> getAllFileIDsOfFaceIDsNotInAnyCluster() async {
|
||||
final db = await instance.asyncDB;
|
||||
final result = await db.getAll(
|
||||
@@ -1082,6 +1172,7 @@ class MLDataDB {
|
||||
return <int>{for (final row in result) row[fileIDColumn]};
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Set<int>> getAllFilesAssociatedWithAllClusters({
|
||||
List<String>? exceptClusters,
|
||||
}) async {
|
||||
@@ -1096,4 +1187,112 @@ class MLDataDB {
|
||||
|
||||
return <int>{for (final row in result) row[fileIDColumn]};
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<EmbeddingVector>> getAllClipVectors() async {
|
||||
Logger("ClipDB").info("reading all embeddings from DB");
|
||||
final db = await instance.asyncDB;
|
||||
final results = await db.getAll('SELECT * FROM $clipTable');
|
||||
return _convertToVectors(results);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<int, EmbeddingVector>> getClipVectorsForFileIDs(
|
||||
Iterable<int> fileIDs,
|
||||
) async {
|
||||
final db = await MLDataDB.instance.asyncDB;
|
||||
final results = await db.getAll(
|
||||
'SELECT * FROM $clipTable WHERE $fileIDColumn IN (${fileIDs.join(", ")})',
|
||||
);
|
||||
final Map<int, EmbeddingVector> embeddings = {};
|
||||
for (final result in results) {
|
||||
final embedding = _getVectorFromRow(result);
|
||||
embeddings[embedding.fileID] = embedding;
|
||||
}
|
||||
return embeddings;
|
||||
}
|
||||
|
||||
// Get indexed FileIDs
|
||||
@override
|
||||
Future<Map<int, int>> clipIndexedFileWithVersion() async {
|
||||
final db = await instance.asyncDB;
|
||||
final maps = await db
|
||||
.getAll('SELECT $fileIDColumn , $mlVersionColumn FROM $clipTable');
|
||||
final Map<int, int> result = {};
|
||||
for (final map in maps) {
|
||||
result[map[fileIDColumn] as int] = map[mlVersionColumn] as int;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> getClipIndexedFileCount({
|
||||
int minimumMlVersion = clipMlVersion,
|
||||
}) async {
|
||||
final db = await instance.asyncDB;
|
||||
final String query =
|
||||
'SELECT COUNT(DISTINCT $fileIDColumn) as count FROM $clipTable WHERE $mlVersionColumn >= $minimumMlVersion';
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(query);
|
||||
return maps.first['count'] as int;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> putClip(List<ClipEmbedding> embeddings) async {
|
||||
if (embeddings.isEmpty) return;
|
||||
final db = await instance.asyncDB;
|
||||
if (embeddings.length == 1) {
|
||||
await db.execute(
|
||||
'INSERT OR REPLACE INTO $clipTable ($fileIDColumn, $embeddingColumn, $mlVersionColumn) VALUES (?, ?, ?)',
|
||||
_getRowFromEmbedding(embeddings.first),
|
||||
);
|
||||
} else {
|
||||
final inputs = embeddings.map((e) => _getRowFromEmbedding(e)).toList();
|
||||
await db.executeBatch(
|
||||
'INSERT OR REPLACE INTO $clipTable ($fileIDColumn, $embeddingColumn, $mlVersionColumn) values(?, ?, ?)',
|
||||
inputs,
|
||||
);
|
||||
}
|
||||
Bus.instance.fire(EmbeddingUpdatedEvent());
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteClipEmbeddings(List<int> fileIDs) async {
|
||||
final db = await instance.asyncDB;
|
||||
await db.execute(
|
||||
'DELETE FROM $clipTable WHERE $fileIDColumn IN (${fileIDs.join(", ")})',
|
||||
);
|
||||
Bus.instance.fire(EmbeddingUpdatedEvent());
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteClipIndexes() async {
|
||||
final db = await instance.asyncDB;
|
||||
await db.execute('DELETE FROM $clipTable');
|
||||
Bus.instance.fire(EmbeddingUpdatedEvent());
|
||||
}
|
||||
|
||||
List<EmbeddingVector> _convertToVectors(List<Map<String, dynamic>> results) {
|
||||
final List<EmbeddingVector> embeddings = [];
|
||||
for (final result in results) {
|
||||
final embedding = _getVectorFromRow(result);
|
||||
if (embedding.isEmpty) continue;
|
||||
embeddings.add(embedding);
|
||||
}
|
||||
return embeddings;
|
||||
}
|
||||
|
||||
EmbeddingVector _getVectorFromRow(Map<String, dynamic> row) {
|
||||
final fileID = row[fileIDColumn] as int;
|
||||
final bytes = row[embeddingColumn] as Uint8List;
|
||||
final list = Float32List.view(bytes.buffer);
|
||||
return EmbeddingVector(fileID: fileID, embedding: list);
|
||||
}
|
||||
|
||||
List<Object?> _getRowFromEmbedding(ClipEmbedding embedding) {
|
||||
return [
|
||||
embedding.fileID,
|
||||
Float32List.fromList(embedding.embedding).buffer.asUint8List(),
|
||||
embedding.version,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:photos/services/machine_learning/face_ml/face_filtering/face_fil
|
||||
|
||||
const facesTable = 'faces';
|
||||
const fileIDColumn = 'file_id';
|
||||
const objectIdColumn = 'obj_id';
|
||||
const faceIDColumn = 'face_id';
|
||||
const faceDetectionColumn = 'detection';
|
||||
const embeddingColumn = 'embedding';
|
||||
@@ -114,7 +115,7 @@ CREATE TABLE IF NOT EXISTS $fileDataTable (
|
||||
user_id INTEGER NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
size INTEGER NOT NULL,
|
||||
obj_id TEXT,
|
||||
$objectIdColumn TEXT,
|
||||
obj_nonce TEXT,
|
||||
updated_at INTEGER NOT NULL,
|
||||
PRIMARY KEY ($fileIDColumn, type)
|
||||
|
||||
@@ -26,6 +26,22 @@ extension FileDataTable on MLDataDB {
|
||||
);
|
||||
}
|
||||
|
||||
Future<Map<int, PreviewInfo>> getFileIDsVidPreview() async {
|
||||
final db = await MLDataDB.instance.asyncDB;
|
||||
final res = await db.execute(
|
||||
"SELECT $fileIDColumn, $objectIdColumn, size FROM $fileDataTable WHERE type='vid_preview'",
|
||||
);
|
||||
return res.asMap().map(
|
||||
(i, e) => MapEntry(
|
||||
e[fileIDColumn] as int,
|
||||
PreviewInfo(
|
||||
objectId: e[objectIdColumn] as String,
|
||||
objectSize: e['size'] as int,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<Set<int>> getFileIDsWithFDData() async {
|
||||
final db = await MLDataDB.instance.asyncDB;
|
||||
final res = await db.execute('SELECT $fileIDColumn FROM $fileDataTable');
|
||||
|
||||
@@ -322,22 +322,20 @@ class _AddContactPage extends State<AddContactPage> {
|
||||
final int ownerID = Configuration.instance.getUserID()!;
|
||||
existingEmails.add(Configuration.instance.getEmail()!);
|
||||
for (final c in CollectionsService.instance.getActiveCollections()) {
|
||||
if (c.owner?.id == ownerID) {
|
||||
for (final User? u in c.sharees ?? []) {
|
||||
if (u != null &&
|
||||
u.id != null &&
|
||||
if (c.owner.id == ownerID) {
|
||||
for (final User u in c.sharees) {
|
||||
if (u.id != null &&
|
||||
u.email.isNotEmpty &&
|
||||
!existingEmails.contains(u.email)) {
|
||||
existingEmails.add(u.email);
|
||||
suggestedUsers.add(u);
|
||||
}
|
||||
}
|
||||
} else if (c.owner != null &&
|
||||
c.owner!.id != null &&
|
||||
c.owner!.email.isNotEmpty &&
|
||||
!existingEmails.contains(c.owner!.email)) {
|
||||
existingEmails.add(c.owner!.email);
|
||||
suggestedUsers.add(c.owner!);
|
||||
} else if (c.owner.id != null &&
|
||||
c.owner.email.isNotEmpty &&
|
||||
!existingEmails.contains(c.owner.email)) {
|
||||
existingEmails.add(c.owner.email);
|
||||
suggestedUsers.add(c.owner);
|
||||
}
|
||||
}
|
||||
final cachedUserDetails = UserService.instance.getCachedUserDetails();
|
||||
|
||||
10
mobile/lib/events/preview_updated_event.dart
Normal file
@@ -0,0 +1,10 @@
|
||||
import "dart:collection";
|
||||
|
||||
import "package:photos/events/event.dart";
|
||||
import "package:photos/models/preview/preview_item.dart";
|
||||
|
||||
class PreviewUpdatedEvent extends Event {
|
||||
final LinkedHashMap<int, PreviewItem> items;
|
||||
|
||||
PreviewUpdatedEvent(this.items);
|
||||
}
|
||||
5
mobile/lib/events/video_streaming_changed.dart
Normal file
@@ -0,0 +1,5 @@
|
||||
import "package:photos/events/event.dart";
|
||||
|
||||
// todo: consider removing this once we opt for riverpod or similar state management
|
||||
// solution
|
||||
class VideoStreamingChanged extends Event {}
|
||||
@@ -4,6 +4,11 @@ import "package:photos/services/machine_learning/face_ml/person/person_service.d
|
||||
extension UserExtension on User {
|
||||
//Some initial users have name in name field.
|
||||
String? get displayName =>
|
||||
PersonService.instance.emailToNameMapCache[email] ??
|
||||
PersonService.instance.emailToPartialPersonDataMapCache[email]
|
||||
?[PersonService.kNameKey] ??
|
||||
((name?.isEmpty ?? true) ? null : name);
|
||||
|
||||
String? get linkedPersonID =>
|
||||
PersonService.instance.emailToPartialPersonDataMapCache[email]
|
||||
?[PersonService.kPersonIDKey];
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class CastGateway {
|
||||
);
|
||||
return response.data["publicKey"];
|
||||
} catch (e) {
|
||||
if (e is DioError && e.response != null) {
|
||||
if (e is DioException && e.response != null) {
|
||||
if (e.response!.statusCode == 404) {
|
||||
return null;
|
||||
} else if (e.response!.statusCode == 403) {
|
||||
|
||||
@@ -32,7 +32,7 @@ class EntityGateway {
|
||||
},
|
||||
);
|
||||
return EntityKey.fromMap(response.data);
|
||||
} on DioError catch (e) {
|
||||
} on DioException catch (e) {
|
||||
if (e.response != null && (e.response!.statusCode ?? 0) == 404) {
|
||||
throw EntityKeyNotFound();
|
||||
} else {
|
||||
|
||||
6
mobile/lib/generated/intl/messages_ar.dart
generated
@@ -41,14 +41,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("مفتاح الاسترداد غير صحيح"),
|
||||
"invalidEmailAddress": MessageLookupByLibrary.simpleMessage(
|
||||
"عنوان البريد الإلكتروني غير صالح"),
|
||||
"link": MessageLookupByLibrary.simpleMessage("Link"),
|
||||
"linkEmail": MessageLookupByLibrary.simpleMessage("Link email"),
|
||||
"noEnteAccountExclamation":
|
||||
MessageLookupByLibrary.simpleMessage("No Ente account!"),
|
||||
"noRecoveryKey":
|
||||
MessageLookupByLibrary.simpleMessage("ما من مفتاح استرداد؟"),
|
||||
"noRecoveryKeyNoDecryption": MessageLookupByLibrary.simpleMessage(
|
||||
"لا يمكن فك تشفير بياناتك دون كلمة المرور أو مفتاح الاسترداد بسبب طبيعة بروتوكول التشفير الخاص بنا من النهاية إلى النهاية"),
|
||||
"orPickFromYourContacts":
|
||||
MessageLookupByLibrary.simpleMessage("or pick from your contacts"),
|
||||
"recoverButton": MessageLookupByLibrary.simpleMessage("استرداد"),
|
||||
"recoverySuccessful":
|
||||
MessageLookupByLibrary.simpleMessage("نجح الاسترداد!"),
|
||||
|
||||
6
mobile/lib/generated/intl/messages_be.dart
generated
@@ -156,8 +156,6 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"kindlyHelpUsWithThisInformation": MessageLookupByLibrary.simpleMessage(
|
||||
"Калі ласка, дапамажыце нам з гэтай інфармацыяй"),
|
||||
"lightTheme": MessageLookupByLibrary.simpleMessage("Светлая"),
|
||||
"link": MessageLookupByLibrary.simpleMessage("Link"),
|
||||
"linkEmail": MessageLookupByLibrary.simpleMessage("Link email"),
|
||||
"lockscreen": MessageLookupByLibrary.simpleMessage("Экран блакіроўкі"),
|
||||
"logInLabel": MessageLookupByLibrary.simpleMessage("Увайсці"),
|
||||
"loginTerms": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -170,8 +168,6 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"never": MessageLookupByLibrary.simpleMessage("Ніколі"),
|
||||
"noDuplicates":
|
||||
MessageLookupByLibrary.simpleMessage("✨ Няма дублікатаў"),
|
||||
"noEnteAccountExclamation":
|
||||
MessageLookupByLibrary.simpleMessage("No Ente account!"),
|
||||
"noRecoveryKey":
|
||||
MessageLookupByLibrary.simpleMessage("Няма ключа аднаўлення?"),
|
||||
"noRecoveryKeyNoDecryption": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -179,6 +175,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"notifications": MessageLookupByLibrary.simpleMessage("Апавяшчэнні"),
|
||||
"ok": MessageLookupByLibrary.simpleMessage("Добра"),
|
||||
"oops": MessageLookupByLibrary.simpleMessage("Вой"),
|
||||
"orPickFromYourContacts":
|
||||
MessageLookupByLibrary.simpleMessage("or pick from your contacts"),
|
||||
"password": MessageLookupByLibrary.simpleMessage("Пароль"),
|
||||
"passwordChangedSuccessfully":
|
||||
MessageLookupByLibrary.simpleMessage("Пароль паспяхова зменены"),
|
||||
|
||||
6
mobile/lib/generated/intl/messages_bg.dart
generated
@@ -22,9 +22,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
|
||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||
"link": MessageLookupByLibrary.simpleMessage("Link"),
|
||||
"linkEmail": MessageLookupByLibrary.simpleMessage("Link email"),
|
||||
"noEnteAccountExclamation":
|
||||
MessageLookupByLibrary.simpleMessage("No Ente account!")
|
||||
"orPickFromYourContacts":
|
||||
MessageLookupByLibrary.simpleMessage("or pick from your contacts")
|
||||
};
|
||||
}
|
||||
|
||||
6
mobile/lib/generated/intl/messages_ca.dart
generated
@@ -22,9 +22,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
|
||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||
"link": MessageLookupByLibrary.simpleMessage("Link"),
|
||||
"linkEmail": MessageLookupByLibrary.simpleMessage("Link email"),
|
||||
"noEnteAccountExclamation":
|
||||
MessageLookupByLibrary.simpleMessage("No Ente account!")
|
||||
"orPickFromYourContacts":
|
||||
MessageLookupByLibrary.simpleMessage("or pick from your contacts")
|
||||
};
|
||||
}
|
||||
|
||||
6
mobile/lib/generated/intl/messages_cs.dart
generated
@@ -27,9 +27,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"checkInboxAndSpamFolder": MessageLookupByLibrary.simpleMessage(
|
||||
"Zkontrolujte prosím svou doručenou poštu (a spam) pro dokončení ověření"),
|
||||
"incorrectRecoveryKeyBody": MessageLookupByLibrary.simpleMessage(""),
|
||||
"link": MessageLookupByLibrary.simpleMessage("Link"),
|
||||
"linkEmail": MessageLookupByLibrary.simpleMessage("Link email"),
|
||||
"noEnteAccountExclamation":
|
||||
MessageLookupByLibrary.simpleMessage("No Ente account!")
|
||||
"orPickFromYourContacts":
|
||||
MessageLookupByLibrary.simpleMessage("or pick from your contacts")
|
||||
};
|
||||
}
|
||||
|
||||
230
mobile/lib/generated/intl/messages_da.dart
generated
@@ -20,31 +20,83 @@ typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
|
||||
class MessageLookup extends MessageLookupByLibrary {
|
||||
String get localeName => 'da';
|
||||
|
||||
static String m3(count, formattedCount) =>
|
||||
static String m3(user) =>
|
||||
"${user} vil ikke kunne tilføje flere billeder til dette album\n\nDe vil stadig kunne fjerne eksisterende billeder tilføjet af dem";
|
||||
|
||||
static String m4(storageAmountInGB) =>
|
||||
"${storageAmountInGB} GB hver gang nogen tilmelder sig et betalt abonnement og anvender din kode";
|
||||
|
||||
static String m5(count, formattedCount) =>
|
||||
"${Intl.plural(count, zero: 'ingen minder', one: '${formattedCount} minde', other: '${formattedCount} minder')}";
|
||||
|
||||
static String m4(count) => "${count} valgt";
|
||||
static String m0(passwordStrengthValue) =>
|
||||
"Kodeordets styrke: ${passwordStrengthValue}";
|
||||
|
||||
static String m5(verificationID) =>
|
||||
static String m6(count) => "${count} valgt";
|
||||
|
||||
static String m7(verificationID) =>
|
||||
"Hey, kan du bekræfte, at dette er dit ente.io verifikation ID: ${verificationID}";
|
||||
|
||||
static String m1(storageAmountInGB) => "${storageAmountInGB} GB";
|
||||
|
||||
static String m8(storageAmountInGB) => "De får også ${storageAmountInGB} GB";
|
||||
|
||||
static String m2(email) =>
|
||||
"Vi har sendt en email til <green>${email}</green>";
|
||||
|
||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||
"accountWelcomeBack":
|
||||
MessageLookupByLibrary.simpleMessage("Velkommen tilbage!"),
|
||||
"ackPasswordLostWarning": MessageLookupByLibrary.simpleMessage(
|
||||
"Jeg forstår at hvis jeg mister min adgangskode kan jeg miste mine data, da mine data er <underline>end-to-end krypteret</underline>."),
|
||||
"activeSessions":
|
||||
MessageLookupByLibrary.simpleMessage("Aktive sessioner"),
|
||||
"addMore": MessageLookupByLibrary.simpleMessage("Tilføj flere"),
|
||||
"addOnPageSubtitle":
|
||||
MessageLookupByLibrary.simpleMessage("Oplysninger om tilføjelser"),
|
||||
"addedAs": MessageLookupByLibrary.simpleMessage("Tilføjet som"),
|
||||
"addingToFavorites":
|
||||
MessageLookupByLibrary.simpleMessage("Tilføjer til favoritter..."),
|
||||
"advancedSettings": MessageLookupByLibrary.simpleMessage("Avanceret"),
|
||||
"after1Day": MessageLookupByLibrary.simpleMessage("Efter 1 dag"),
|
||||
"after1Hour": MessageLookupByLibrary.simpleMessage("Efter 1 time"),
|
||||
"after1Month": MessageLookupByLibrary.simpleMessage("Efter 1 måned"),
|
||||
"after1Week": MessageLookupByLibrary.simpleMessage("Efter 1 uge"),
|
||||
"after1Year": MessageLookupByLibrary.simpleMessage("Efter 1 år"),
|
||||
"albumOwner": MessageLookupByLibrary.simpleMessage("Ejer"),
|
||||
"allowDownloads":
|
||||
MessageLookupByLibrary.simpleMessage("Tillad downloads"),
|
||||
"askDeleteReason": MessageLookupByLibrary.simpleMessage(
|
||||
"Hvad er hovedårsagen til, at du sletter din konto?"),
|
||||
"backedUpFolders":
|
||||
MessageLookupByLibrary.simpleMessage("Sikkerhedskopierede mapper"),
|
||||
"backupStatusDescription": MessageLookupByLibrary.simpleMessage(
|
||||
"Elementer, der er blevet sikkerhedskopieret, vil blive vist her"),
|
||||
"canNotOpenBody": MessageLookupByLibrary.simpleMessage(
|
||||
"Beklager, dette album kan ikke åbnes i appen."),
|
||||
"canOnlyRemoveFilesOwnedByYou": MessageLookupByLibrary.simpleMessage(
|
||||
"Kan kun fjerne filer ejet af dig"),
|
||||
"cancel": MessageLookupByLibrary.simpleMessage("Annuller"),
|
||||
"cannotAddMorePhotosAfterBecomingViewer": m3,
|
||||
"cannotDeleteSharedFiles":
|
||||
MessageLookupByLibrary.simpleMessage("Kan ikke slette delte filer"),
|
||||
"changeEmail":
|
||||
MessageLookupByLibrary.simpleMessage("Skift email adresse"),
|
||||
"changePasswordTitle":
|
||||
MessageLookupByLibrary.simpleMessage("Skift adgangskode"),
|
||||
"checkInboxAndSpamFolder": MessageLookupByLibrary.simpleMessage(
|
||||
"Tjek venligst din indbakke (og spam) for at færdiggøre verificeringen"),
|
||||
"clearIndexes": MessageLookupByLibrary.simpleMessage("Ryd indekser"),
|
||||
"collectPhotos":
|
||||
MessageLookupByLibrary.simpleMessage("Indsaml billeder"),
|
||||
"confirmAccountDeletion":
|
||||
MessageLookupByLibrary.simpleMessage("Bekræft Sletning Af Konto"),
|
||||
"confirmPassword":
|
||||
MessageLookupByLibrary.simpleMessage("Bekræft adgangskode"),
|
||||
"contactSupport":
|
||||
MessageLookupByLibrary.simpleMessage("Kontakt support"),
|
||||
"continueLabel": MessageLookupByLibrary.simpleMessage("Fortsæt"),
|
||||
"copypasteThisCodentoYourAuthenticatorApp":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Kopiér denne kode\ntil din autentificeringsapp"),
|
||||
@@ -53,11 +105,15 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"createAccount": MessageLookupByLibrary.simpleMessage("Opret konto"),
|
||||
"createNewAccount":
|
||||
MessageLookupByLibrary.simpleMessage("Opret en ny konto"),
|
||||
"creatingLink":
|
||||
MessageLookupByLibrary.simpleMessage("Opretter link..."),
|
||||
"decrypting": MessageLookupByLibrary.simpleMessage("Dekrypterer..."),
|
||||
"deleteAccount": MessageLookupByLibrary.simpleMessage("Slet konto"),
|
||||
"deleteAccountFeedbackPrompt": MessageLookupByLibrary.simpleMessage(
|
||||
"Vi er kede af at du forlader os. Forklar venligst hvorfor, så vi kan forbedre os."),
|
||||
"deleteAccountPermanentlyButton":
|
||||
MessageLookupByLibrary.simpleMessage("Slet konto permanent"),
|
||||
"deleteAlbum": MessageLookupByLibrary.simpleMessage("Slet album"),
|
||||
"deleteEmailRequest": MessageLookupByLibrary.simpleMessage(
|
||||
"Send venligst en email til <warning>account-deletion@ente.io</warning> fra din registrerede email adresse."),
|
||||
"deleteReason1": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -68,14 +124,50 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Min grund er ikke angivet"),
|
||||
"deleteRequestSLAText": MessageLookupByLibrary.simpleMessage(
|
||||
"Din anmodning vil blive behandlet inden for 72 timer."),
|
||||
"deleteSharedAlbum":
|
||||
MessageLookupByLibrary.simpleMessage("Slet delt album?"),
|
||||
"details": MessageLookupByLibrary.simpleMessage("Detaljer"),
|
||||
"developerSettingsWarning": MessageLookupByLibrary.simpleMessage(
|
||||
"Er du sikker på, at du vil ændre udviklerindstillingerne?"),
|
||||
"disableDownloadWarningTitle":
|
||||
MessageLookupByLibrary.simpleMessage("Bemærk venligst"),
|
||||
"discover_food": MessageLookupByLibrary.simpleMessage("Mad"),
|
||||
"discover_identity": MessageLookupByLibrary.simpleMessage("Identitet"),
|
||||
"discover_memes": MessageLookupByLibrary.simpleMessage("Memes"),
|
||||
"discover_notes": MessageLookupByLibrary.simpleMessage("Noter"),
|
||||
"discover_pets": MessageLookupByLibrary.simpleMessage("Kæledyr"),
|
||||
"discover_screenshots":
|
||||
MessageLookupByLibrary.simpleMessage("Skærmbilleder"),
|
||||
"discover_selfies": MessageLookupByLibrary.simpleMessage("Selfier"),
|
||||
"discover_sunset": MessageLookupByLibrary.simpleMessage("Solnedgang"),
|
||||
"discover_wallpapers":
|
||||
MessageLookupByLibrary.simpleMessage("Baggrundsbilleder"),
|
||||
"eligible": MessageLookupByLibrary.simpleMessage("kvalificeret"),
|
||||
"email": MessageLookupByLibrary.simpleMessage("Email"),
|
||||
"emailAlreadyRegistered": MessageLookupByLibrary.simpleMessage(
|
||||
"E-mail er allerede registreret."),
|
||||
"emailNotRegistered":
|
||||
MessageLookupByLibrary.simpleMessage("E-mail er ikke registreret."),
|
||||
"encryption": MessageLookupByLibrary.simpleMessage("Kryptering"),
|
||||
"encryptionKeys":
|
||||
MessageLookupByLibrary.simpleMessage("Krypteringsnøgler"),
|
||||
"enterEmail":
|
||||
MessageLookupByLibrary.simpleMessage("Indtast email adresse"),
|
||||
"enterNewPasswordToEncrypt": MessageLookupByLibrary.simpleMessage(
|
||||
"Indtast en ny adgangskode vi kan bruge til at kryptere dine data"),
|
||||
"enterPassword":
|
||||
MessageLookupByLibrary.simpleMessage("Indtast adgangskode"),
|
||||
"enterPasswordToEncrypt": MessageLookupByLibrary.simpleMessage(
|
||||
"Indtast en adgangskode vi kan bruge til at kryptere dine data"),
|
||||
"enterPin": MessageLookupByLibrary.simpleMessage("Indtast PIN"),
|
||||
"enterValidEmail": MessageLookupByLibrary.simpleMessage(
|
||||
"Indtast venligst en gyldig email adresse."),
|
||||
"enterYourEmailAddress":
|
||||
MessageLookupByLibrary.simpleMessage("Indtast din email adresse"),
|
||||
"enterYourPassword":
|
||||
MessageLookupByLibrary.simpleMessage("Indtast adgangskode"),
|
||||
"enterYourRecoveryKey": MessageLookupByLibrary.simpleMessage(
|
||||
"Indtast din gendannelsesnøgle"),
|
||||
"familyPlanPortalTitle":
|
||||
MessageLookupByLibrary.simpleMessage("Familie"),
|
||||
"feedback": MessageLookupByLibrary.simpleMessage("Feedback"),
|
||||
@@ -85,59 +177,177 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Find folk hurtigt ved navn"),
|
||||
"forgotPassword":
|
||||
MessageLookupByLibrary.simpleMessage("Glemt adgangskode"),
|
||||
"freeStorageOnReferralSuccess": m4,
|
||||
"freeUpDeviceSpace":
|
||||
MessageLookupByLibrary.simpleMessage("Frigør enhedsplads"),
|
||||
"freeUpDeviceSpaceDesc": MessageLookupByLibrary.simpleMessage(
|
||||
"Spar plads på din enhed ved at rydde filer, der allerede er sikkerhedskopieret."),
|
||||
"generatingEncryptionKeys": MessageLookupByLibrary.simpleMessage(
|
||||
"Genererer krypteringsnøgler..."),
|
||||
"help": MessageLookupByLibrary.simpleMessage("Hjælp"),
|
||||
"howItWorks":
|
||||
MessageLookupByLibrary.simpleMessage("Sådan fungerer det"),
|
||||
"incorrectPasswordTitle":
|
||||
MessageLookupByLibrary.simpleMessage("Forkert adgangskode"),
|
||||
"incorrectRecoveryKeyBody": MessageLookupByLibrary.simpleMessage(
|
||||
"Den gendannelsesnøgle du indtastede er forkert"),
|
||||
"incorrectRecoveryKeyTitle":
|
||||
MessageLookupByLibrary.simpleMessage("Forkert gendannelsesnøgle"),
|
||||
"indexedItems":
|
||||
MessageLookupByLibrary.simpleMessage("Indekserede elementer"),
|
||||
"insecureDevice": MessageLookupByLibrary.simpleMessage("Usikker enhed"),
|
||||
"invalidEmailAddress":
|
||||
MessageLookupByLibrary.simpleMessage("Ugyldig email adresse"),
|
||||
"invite": MessageLookupByLibrary.simpleMessage("Inviter"),
|
||||
"inviteYourFriends":
|
||||
MessageLookupByLibrary.simpleMessage("Inviter dine venner"),
|
||||
"itemsWillBeRemovedFromAlbum": MessageLookupByLibrary.simpleMessage(
|
||||
"Valgte elementer vil blive fjernet fra dette album"),
|
||||
"keepPhotos": MessageLookupByLibrary.simpleMessage("Behold billeder"),
|
||||
"kindlyHelpUsWithThisInformation": MessageLookupByLibrary.simpleMessage(
|
||||
"Hjælp os venligst med disse oplysninger"),
|
||||
"link": MessageLookupByLibrary.simpleMessage("Link"),
|
||||
"linkEmail": MessageLookupByLibrary.simpleMessage("Link email"),
|
||||
"linkEnabled": MessageLookupByLibrary.simpleMessage("Aktiveret"),
|
||||
"linkExpired": MessageLookupByLibrary.simpleMessage("Udløbet"),
|
||||
"linkNeverExpires": MessageLookupByLibrary.simpleMessage("Aldrig"),
|
||||
"loadingModel":
|
||||
MessageLookupByLibrary.simpleMessage("Downloader modeller..."),
|
||||
"lockButtonLabel": MessageLookupByLibrary.simpleMessage("Lås"),
|
||||
"logInLabel": MessageLookupByLibrary.simpleMessage("Log ind"),
|
||||
"loggingOut": MessageLookupByLibrary.simpleMessage("Logger ud..."),
|
||||
"longPressAnEmailToVerifyEndToEndEncryption":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Langt tryk på en e-mail for at bekræfte slutningen af krypteringen."),
|
||||
"machineLearning": MessageLookupByLibrary.simpleMessage("Maskinlæring"),
|
||||
"magicSearch": MessageLookupByLibrary.simpleMessage("Magisk søgning"),
|
||||
"manage": MessageLookupByLibrary.simpleMessage("Administrér"),
|
||||
"memoryCount": m3,
|
||||
"manageDeviceStorageDesc": MessageLookupByLibrary.simpleMessage(
|
||||
"Gennemgå og ryd lokal cache-lagring."),
|
||||
"memoryCount": m5,
|
||||
"mlConsent":
|
||||
MessageLookupByLibrary.simpleMessage("Aktiver maskinlæring"),
|
||||
"mlConsentPrivacy": MessageLookupByLibrary.simpleMessage(
|
||||
"Klik her for flere detaljer om denne funktion i vores privatlivspolitik"),
|
||||
"mlConsentTitle":
|
||||
MessageLookupByLibrary.simpleMessage("Aktiver maskinlæring?"),
|
||||
"mlIndexingDescription": MessageLookupByLibrary.simpleMessage(
|
||||
"Bemærk venligst, at maskinindlæring vil resultere i en højere båndbredde og batteriforbrug, indtil alle elementer er indekseret. Overvej at bruge desktop app til hurtigere indeksering, vil alle resultater blive synkroniseret automatisk."),
|
||||
"moments": MessageLookupByLibrary.simpleMessage("Øjeblikke"),
|
||||
"never": MessageLookupByLibrary.simpleMessage("Aldrig"),
|
||||
"newAlbum": MessageLookupByLibrary.simpleMessage("Nyt album"),
|
||||
"next": MessageLookupByLibrary.simpleMessage("Næste"),
|
||||
"noEnteAccountExclamation":
|
||||
MessageLookupByLibrary.simpleMessage("No Ente account!"),
|
||||
"noRecoveryKey":
|
||||
MessageLookupByLibrary.simpleMessage("Ingen gendannelsesnøgle?"),
|
||||
"ok": MessageLookupByLibrary.simpleMessage("Ok"),
|
||||
"oops": MessageLookupByLibrary.simpleMessage("Ups"),
|
||||
"oopsSomethingWentWrong":
|
||||
MessageLookupByLibrary.simpleMessage("Ups, noget gik galt"),
|
||||
"orPickFromYourContacts":
|
||||
MessageLookupByLibrary.simpleMessage("or pick from your contacts"),
|
||||
"password": MessageLookupByLibrary.simpleMessage("Adgangskode"),
|
||||
"passwordChangedSuccessfully": MessageLookupByLibrary.simpleMessage(
|
||||
"Adgangskoden er blevet ændret"),
|
||||
"passwordStrength": m0,
|
||||
"passwordWarning": MessageLookupByLibrary.simpleMessage(
|
||||
"Vi gemmer ikke denne adgangskode, så hvis du glemmer den <underline>kan vi ikke dekryptere dine data</underline>"),
|
||||
"pendingItems":
|
||||
MessageLookupByLibrary.simpleMessage("Afventende elementer"),
|
||||
"peopleUsingYourCode": MessageLookupByLibrary.simpleMessage(
|
||||
"Personer, der bruger din kode"),
|
||||
"pleaseContactSupportAndWeWillBeHappyToHelp":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Kontakt support@ente.io og vi vil være glade for at hjælpe!"),
|
||||
"pleaseWait": MessageLookupByLibrary.simpleMessage("Vent venligst..."),
|
||||
"privacyPolicyTitle":
|
||||
MessageLookupByLibrary.simpleMessage("Privatlivspolitik"),
|
||||
"recoverButton": MessageLookupByLibrary.simpleMessage("Gendan"),
|
||||
"referralStep2": MessageLookupByLibrary.simpleMessage(
|
||||
"2. De tilmelder sig en betalt plan"),
|
||||
"removeFromAlbum":
|
||||
MessageLookupByLibrary.simpleMessage("Fjern fra album"),
|
||||
"removeFromAlbumTitle":
|
||||
MessageLookupByLibrary.simpleMessage("Fjern fra album?"),
|
||||
"removeLink": MessageLookupByLibrary.simpleMessage("Fjern link"),
|
||||
"removeParticipant":
|
||||
MessageLookupByLibrary.simpleMessage("Fjern deltager"),
|
||||
"removeWithQuestionMark":
|
||||
MessageLookupByLibrary.simpleMessage("Fjern?"),
|
||||
"removingFromFavorites":
|
||||
MessageLookupByLibrary.simpleMessage("Fjerner fra favoritter..."),
|
||||
"renameFile": MessageLookupByLibrary.simpleMessage("Omdøb fil"),
|
||||
"resendEmail": MessageLookupByLibrary.simpleMessage("Send email igen"),
|
||||
"resetPasswordTitle":
|
||||
MessageLookupByLibrary.simpleMessage("Nulstil adgangskode"),
|
||||
"retry": MessageLookupByLibrary.simpleMessage("Prøv igen"),
|
||||
"scanThisBarcodeWithnyourAuthenticatorApp":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Skan denne QR-kode med godkendelses-appen"),
|
||||
"searchHint1":
|
||||
MessageLookupByLibrary.simpleMessage("Hurtig, søgning på enheden"),
|
||||
"selectAll": MessageLookupByLibrary.simpleMessage("Vælg alle"),
|
||||
"selectFoldersForBackup": MessageLookupByLibrary.simpleMessage(
|
||||
"Vælg mapper til sikkerhedskopiering"),
|
||||
"selectReason": MessageLookupByLibrary.simpleMessage("Vælg årsag"),
|
||||
"selectedPhotos": m4,
|
||||
"selectedFoldersWillBeEncryptedAndBackedUp":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Valgte mapper vil blive krypteret og sikkerhedskopieret"),
|
||||
"selectedPhotos": m6,
|
||||
"sendEmail": MessageLookupByLibrary.simpleMessage("Send email"),
|
||||
"shareTextConfirmOthersVerificationID": m5,
|
||||
"sendLink": MessageLookupByLibrary.simpleMessage("Send link"),
|
||||
"setPasswordTitle":
|
||||
MessageLookupByLibrary.simpleMessage("Angiv adgangskode"),
|
||||
"shareTextConfirmOthersVerificationID": m7,
|
||||
"showMemories": MessageLookupByLibrary.simpleMessage("Vis minder"),
|
||||
"signUpTerms": MessageLookupByLibrary.simpleMessage(
|
||||
"Jeg er enig i <u-terms>betingelser for brug</u-terms> og <u-policy>privatlivspolitik</u-policy>"),
|
||||
"skip": MessageLookupByLibrary.simpleMessage("Spring over"),
|
||||
"somethingWentWrongPleaseTryAgain":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Noget gik galt, prøv venligst igen"),
|
||||
"sorryCouldNotAddToFavorites": MessageLookupByLibrary.simpleMessage(
|
||||
"Beklager, kunne ikke føje til favoritter!"),
|
||||
"sorryCouldNotRemoveFromFavorites":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Beklager, kunne ikke fjernes fra favoritter!"),
|
||||
"sorryWeCouldNotGenerateSecureKeysOnThisDevicennplease":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Beklager, vi kunne ikke generere sikre krypteringsnøgler på denne enhed.\n\nForsøg venligst at oprette en konto fra en anden enhed."),
|
||||
"status": MessageLookupByLibrary.simpleMessage("Status"),
|
||||
"storageInGB": m1,
|
||||
"strongStrength": MessageLookupByLibrary.simpleMessage("Stærkt"),
|
||||
"subscribe": MessageLookupByLibrary.simpleMessage("Abonner"),
|
||||
"subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage(
|
||||
"Du skal have et aktivt betalt abonnement for at aktivere deling."),
|
||||
"tapToEnterCode":
|
||||
MessageLookupByLibrary.simpleMessage("Tryk for at indtaste kode"),
|
||||
"terminateSession":
|
||||
MessageLookupByLibrary.simpleMessage("Afslut session?"),
|
||||
"termsOfServicesTitle":
|
||||
MessageLookupByLibrary.simpleMessage("Betingelser"),
|
||||
"theyAlsoGetXGb": m8,
|
||||
"thisDevice": MessageLookupByLibrary.simpleMessage("Denne enhed"),
|
||||
"thisWillLogYouOutOfTheFollowingDevice":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Dette vil logge dig ud af følgende enhed:"),
|
||||
"thisWillLogYouOutOfThisDevice": MessageLookupByLibrary.simpleMessage(
|
||||
"Dette vil logge dig ud af denne enhed!"),
|
||||
"toResetVerifyEmail": MessageLookupByLibrary.simpleMessage(
|
||||
"For at nulstille din adgangskode, bekræft venligst din email adresse."),
|
||||
"unavailableReferralCode": MessageLookupByLibrary.simpleMessage(
|
||||
"Beklager, denne kode er ikke tilgængelig."),
|
||||
"unselectAll": MessageLookupByLibrary.simpleMessage("Fravælg alle"),
|
||||
"updatingFolderSelection":
|
||||
MessageLookupByLibrary.simpleMessage("Opdaterer mappevalg..."),
|
||||
"verify": MessageLookupByLibrary.simpleMessage("Bekræft"),
|
||||
"viewAddOnButton":
|
||||
MessageLookupByLibrary.simpleMessage("Vis tilføjelser"),
|
||||
"waitingForWifi":
|
||||
MessageLookupByLibrary.simpleMessage("Venter på Wi-fi..."),
|
||||
"weHaveSendEmailTo": m2,
|
||||
"weakStrength": MessageLookupByLibrary.simpleMessage("Svagt"),
|
||||
"welcomeBack":
|
||||
MessageLookupByLibrary.simpleMessage("Velkommen tilbage!"),
|
||||
"yesRemove": MessageLookupByLibrary.simpleMessage("Ja, fjern"),
|
||||
"you": MessageLookupByLibrary.simpleMessage("Dig"),
|
||||
"yourAccountHasBeenDeleted":
|
||||
MessageLookupByLibrary.simpleMessage("Din konto er blevet slettet")
|
||||
};
|
||||
|
||||
307
mobile/lib/generated/intl/messages_de.dart
generated
@@ -20,37 +20,37 @@ typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
|
||||
class MessageLookup extends MessageLookupByLibrary {
|
||||
String get localeName => 'de';
|
||||
|
||||
static String m6(count) =>
|
||||
static String m9(count) =>
|
||||
"${Intl.plural(count, one: 'Teilnehmer', other: 'Teilnehmer')} hinzufügen";
|
||||
|
||||
static String m7(count) =>
|
||||
static String m10(count) =>
|
||||
"${Intl.plural(count, one: 'Element hinzufügen', other: 'Elemente hinzufügen')}";
|
||||
|
||||
static String m8(storageAmount, endDate) =>
|
||||
static String m11(storageAmount, endDate) =>
|
||||
"Dein ${storageAmount} Add-on ist gültig bis ${endDate}";
|
||||
|
||||
static String m9(count) =>
|
||||
static String m12(count) =>
|
||||
"${Intl.plural(count, one: 'Betrachter', other: 'Betrachter')} hinzufügen";
|
||||
|
||||
static String m10(emailOrName) => "Von ${emailOrName} hinzugefügt";
|
||||
static String m13(emailOrName) => "Von ${emailOrName} hinzugefügt";
|
||||
|
||||
static String m11(albumName) => "Erfolgreich zu ${albumName} hinzugefügt";
|
||||
static String m14(albumName) => "Erfolgreich zu ${albumName} hinzugefügt";
|
||||
|
||||
static String m12(count) =>
|
||||
static String m15(count) =>
|
||||
"${Intl.plural(count, zero: 'Keine Teilnehmer', one: '1 Teilnehmer', other: '${count} Teilnehmer')}";
|
||||
|
||||
static String m13(versionValue) => "Version: ${versionValue}";
|
||||
static String m16(versionValue) => "Version: ${versionValue}";
|
||||
|
||||
static String m14(freeAmount, storageUnit) =>
|
||||
static String m17(freeAmount, storageUnit) =>
|
||||
"${freeAmount} ${storageUnit} frei";
|
||||
|
||||
static String m15(paymentProvider) =>
|
||||
static String m18(paymentProvider) =>
|
||||
"Bitte kündige dein aktuelles Abo über ${paymentProvider} zuerst";
|
||||
|
||||
static String m16(user) =>
|
||||
static String m3(user) =>
|
||||
"Der Nutzer \"${user}\" wird keine weiteren Fotos zum Album hinzufügen können.\n\nJedoch kann er weiterhin vorhandene Bilder, welche durch ihn hinzugefügt worden sind, wieder entfernen";
|
||||
|
||||
static String m17(isFamilyMember, storageAmountInGb) =>
|
||||
static String m19(isFamilyMember, storageAmountInGb) =>
|
||||
"${Intl.select(isFamilyMember, {
|
||||
'true':
|
||||
'Deine Familiengruppe hat bereits ${storageAmountInGb} GB erhalten',
|
||||
@@ -58,181 +58,181 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
'other': 'Du hast bereits ${storageAmountInGb} GB erhalten!',
|
||||
})}";
|
||||
|
||||
static String m18(albumName) =>
|
||||
static String m20(albumName) =>
|
||||
"Kollaborativer Link für ${albumName} erstellt";
|
||||
|
||||
static String m19(count) =>
|
||||
static String m21(count) =>
|
||||
"${Intl.plural(count, zero: '0 Mitarbeiter hinzugefügt', one: '1 Mitarbeiter hinzugefügt', other: '${count} Mitarbeiter hinzugefügt')}";
|
||||
|
||||
static String m20(email, numOfDays) =>
|
||||
static String m22(email, numOfDays) =>
|
||||
"Du bist dabei, ${email} als vertrauenswürdigen Kontakt hinzuzufügen. Die Person wird in der Lage sein, dein Konto wiederherzustellen, wenn du für ${numOfDays} Tage abwesend bist.";
|
||||
|
||||
static String m21(familyAdminEmail) =>
|
||||
static String m23(familyAdminEmail) =>
|
||||
"Bitte kontaktiere <green>${familyAdminEmail}</green> um dein Abo zu verwalten";
|
||||
|
||||
static String m22(provider) =>
|
||||
static String m24(provider) =>
|
||||
"Bitte kontaktiere uns über support@ente.io, um dein ${provider} Abo zu verwalten.";
|
||||
|
||||
static String m23(endpoint) => "Verbunden mit ${endpoint}";
|
||||
static String m25(endpoint) => "Verbunden mit ${endpoint}";
|
||||
|
||||
static String m24(count) =>
|
||||
static String m26(count) =>
|
||||
"${Intl.plural(count, one: 'Lösche ${count} Element', other: 'Lösche ${count} Elemente')}";
|
||||
|
||||
static String m25(currentlyDeleting, totalCount) =>
|
||||
static String m27(currentlyDeleting, totalCount) =>
|
||||
"Lösche ${currentlyDeleting} / ${totalCount}";
|
||||
|
||||
static String m26(albumName) =>
|
||||
static String m28(albumName) =>
|
||||
"Der öffentliche Link zum Zugriff auf \"${albumName}\" wird entfernt.";
|
||||
|
||||
static String m27(supportEmail) =>
|
||||
static String m29(supportEmail) =>
|
||||
"Bitte sende eine E-Mail an ${supportEmail} von deiner registrierten E-Mail-Adresse";
|
||||
|
||||
static String m28(count, storageSaved) =>
|
||||
static String m30(count, storageSaved) =>
|
||||
"Du hast ${Intl.plural(count, one: '${count} duplizierte Datei', other: '${count} dupliziere Dateien')} gelöscht und (${storageSaved}!) freigegeben";
|
||||
|
||||
static String m29(count, formattedSize) =>
|
||||
static String m31(count, formattedSize) =>
|
||||
"${count} Dateien, ${formattedSize} jede";
|
||||
|
||||
static String m30(newEmail) => "E-Mail-Adresse geändert zu ${newEmail}";
|
||||
static String m32(newEmail) => "E-Mail-Adresse geändert zu ${newEmail}";
|
||||
|
||||
static String m31(email) =>
|
||||
static String m33(email) =>
|
||||
"${email} hat kein Ente-Konto.\n\nSende eine Einladung, um Fotos zu teilen.";
|
||||
|
||||
static String m32(text) => "Zusätzliche Fotos für ${text} gefunden";
|
||||
static String m34(text) => "Zusätzliche Fotos für ${text} gefunden";
|
||||
|
||||
static String m33(count, formattedNumber) =>
|
||||
static String m35(count, formattedNumber) =>
|
||||
"${Intl.plural(count, one: '1 Datei', other: '${formattedNumber} Dateien')} auf diesem Gerät wurde(n) sicher gespeichert";
|
||||
|
||||
static String m34(count, formattedNumber) =>
|
||||
static String m36(count, formattedNumber) =>
|
||||
"${Intl.plural(count, one: '1 Datei', other: '${formattedNumber} Dateien')} in diesem Album wurde(n) sicher gespeichert";
|
||||
|
||||
static String m35(storageAmountInGB) =>
|
||||
static String m4(storageAmountInGB) =>
|
||||
"${storageAmountInGB} GB jedes Mal, wenn sich jemand mit deinem Code für einen bezahlten Tarif anmeldet";
|
||||
|
||||
static String m36(endDate) => "Kostenlose Demo verfügbar bis zum ${endDate}";
|
||||
static String m37(endDate) => "Kostenlose Demo verfügbar bis zum ${endDate}";
|
||||
|
||||
static String m37(count) =>
|
||||
static String m38(count) =>
|
||||
"Du kannst immernoch über Ente ${Intl.plural(count, one: 'darauf', other: 'auf sie')} zugreifen, solange du ein aktives Abo hast";
|
||||
|
||||
static String m38(sizeInMBorGB) => "${sizeInMBorGB} freigeben";
|
||||
static String m39(sizeInMBorGB) => "${sizeInMBorGB} freigeben";
|
||||
|
||||
static String m39(count, formattedSize) =>
|
||||
static String m40(count, formattedSize) =>
|
||||
"${Intl.plural(count, one: 'Es kann vom Gerät gelöscht werden, um ${formattedSize} freizugeben', other: 'Sie können vom Gerät gelöscht werden, um ${formattedSize} freizugeben')}";
|
||||
|
||||
static String m40(currentlyProcessing, totalCount) =>
|
||||
static String m41(currentlyProcessing, totalCount) =>
|
||||
"Verarbeite ${currentlyProcessing} / ${totalCount}";
|
||||
|
||||
static String m41(count) =>
|
||||
static String m42(count) =>
|
||||
"${Intl.plural(count, one: '${count} Objekt', other: '${count} Objekte')}";
|
||||
|
||||
static String m42(email) =>
|
||||
static String m43(email) =>
|
||||
"${email} hat dich eingeladen, ein vertrauenswürdiger Kontakt zu werden";
|
||||
|
||||
static String m43(expiryTime) => "Link läuft am ${expiryTime} ab";
|
||||
static String m44(expiryTime) => "Link läuft am ${expiryTime} ab";
|
||||
|
||||
static String m3(count, formattedCount) =>
|
||||
static String m5(count, formattedCount) =>
|
||||
"${Intl.plural(count, zero: 'keine Erinnerungsstücke', one: '${formattedCount} Erinnerung', other: '${formattedCount} Erinnerungsstücke')}";
|
||||
|
||||
static String m44(count) =>
|
||||
static String m45(count) =>
|
||||
"${Intl.plural(count, one: 'Element verschieben', other: 'Elemente verschieben')}";
|
||||
|
||||
static String m45(albumName) => "Erfolgreich zu ${albumName} hinzugefügt";
|
||||
static String m46(albumName) => "Erfolgreich zu ${albumName} hinzugefügt";
|
||||
|
||||
static String m46(personName) => "Keine Vorschläge für ${personName}";
|
||||
static String m47(personName) => "Keine Vorschläge für ${personName}";
|
||||
|
||||
static String m47(name) => "Nicht ${name}?";
|
||||
static String m48(name) => "Nicht ${name}?";
|
||||
|
||||
static String m48(familyAdminEmail) =>
|
||||
static String m49(familyAdminEmail) =>
|
||||
"Bitte wende Dich an ${familyAdminEmail}, um den Code zu ändern.";
|
||||
|
||||
static String m0(passwordStrengthValue) =>
|
||||
"Passwortstärke: ${passwordStrengthValue}";
|
||||
|
||||
static String m49(providerName) =>
|
||||
static String m50(providerName) =>
|
||||
"Bitte kontaktiere den Support von ${providerName}, falls etwas abgebucht wurde";
|
||||
|
||||
static String m50(count) =>
|
||||
static String m51(count) =>
|
||||
"${Intl.plural(count, zero: '0 Fotos', one: '1 Foto', other: '${count} Fotos')}";
|
||||
|
||||
static String m51(endDate) =>
|
||||
static String m52(endDate) =>
|
||||
"Kostenlose Testversion gültig bis ${endDate}.\nDu kannst anschließend ein bezahltes Paket auswählen.";
|
||||
|
||||
static String m52(toEmail) => "Bitte sende uns eine E-Mail an ${toEmail}";
|
||||
static String m53(toEmail) => "Bitte sende uns eine E-Mail an ${toEmail}";
|
||||
|
||||
static String m53(toEmail) => "Bitte sende die Protokolle an ${toEmail}";
|
||||
static String m54(toEmail) => "Bitte sende die Protokolle an ${toEmail}";
|
||||
|
||||
static String m54(folderName) => "Verarbeite ${folderName}...";
|
||||
static String m55(folderName) => "Verarbeite ${folderName}...";
|
||||
|
||||
static String m55(storeName) => "Bewerte uns auf ${storeName}";
|
||||
static String m56(storeName) => "Bewerte uns auf ${storeName}";
|
||||
|
||||
static String m56(days, email) =>
|
||||
static String m57(days, email) =>
|
||||
"Du kannst nach ${days} Tagen auf das Konto zugreifen. Eine Benachrichtigung wird an ${email} versendet.";
|
||||
|
||||
static String m57(email) =>
|
||||
static String m58(email) =>
|
||||
"Du kannst jetzt das Konto von ${email} wiederherstellen, indem du ein neues Passwort setzt.";
|
||||
|
||||
static String m58(email) =>
|
||||
static String m59(email) =>
|
||||
"${email} versucht, dein Konto wiederherzustellen.";
|
||||
|
||||
static String m59(storageInGB) =>
|
||||
static String m60(storageInGB) =>
|
||||
"3. Ihr beide erhaltet ${storageInGB} GB* kostenlos";
|
||||
|
||||
static String m60(userEmail) =>
|
||||
static String m61(userEmail) =>
|
||||
"${userEmail} wird aus diesem geteilten Album entfernt\n\nAlle von ihnen hinzugefügte Fotos werden ebenfalls aus dem Album entfernt";
|
||||
|
||||
static String m61(endDate) => "Erneuert am ${endDate}";
|
||||
static String m62(endDate) => "Erneuert am ${endDate}";
|
||||
|
||||
static String m62(count) =>
|
||||
static String m63(count) =>
|
||||
"${Intl.plural(count, one: '${count} Ergebnis gefunden', other: '${count} Ergebnisse gefunden')}";
|
||||
|
||||
static String m63(snapshotLength, searchLength) =>
|
||||
static String m64(snapshotLength, searchLength) =>
|
||||
"Abschnittslänge stimmt nicht überein: ${snapshotLength} != ${searchLength}";
|
||||
|
||||
static String m4(count) => "${count} ausgewählt";
|
||||
static String m6(count) => "${count} ausgewählt";
|
||||
|
||||
static String m64(count, yourCount) =>
|
||||
static String m65(count, yourCount) =>
|
||||
"${count} ausgewählt (${yourCount} von Ihnen)";
|
||||
|
||||
static String m65(verificationID) =>
|
||||
static String m66(verificationID) =>
|
||||
"Hier ist meine Verifizierungs-ID: ${verificationID} für ente.io.";
|
||||
|
||||
static String m5(verificationID) =>
|
||||
static String m7(verificationID) =>
|
||||
"Hey, kannst du bestätigen, dass dies deine ente.io Verifizierungs-ID ist: ${verificationID}";
|
||||
|
||||
static String m66(referralCode, referralStorageInGB) =>
|
||||
static String m67(referralCode, referralStorageInGB) =>
|
||||
"Ente Weiterempfehlungs-Code: ${referralCode} \n\nEinlösen unter Einstellungen → Allgemein → Weiterempfehlungen, um ${referralStorageInGB} GB kostenlos zu erhalten, sobald Sie einen kostenpflichtigen Tarif abgeschlossen haben\n\nhttps://ente.io";
|
||||
|
||||
static String m67(numberOfPeople) =>
|
||||
static String m68(numberOfPeople) =>
|
||||
"${Intl.plural(numberOfPeople, zero: 'Teile mit bestimmten Personen', one: 'Teilen mit 1 Person', other: 'Teilen mit ${numberOfPeople} Personen')}";
|
||||
|
||||
static String m68(emailIDs) => "Geteilt mit ${emailIDs}";
|
||||
|
||||
static String m69(fileType) =>
|
||||
"Dieses ${fileType} wird von deinem Gerät gelöscht.";
|
||||
static String m69(emailIDs) => "Geteilt mit ${emailIDs}";
|
||||
|
||||
static String m70(fileType) =>
|
||||
"Dieses ${fileType} wird von deinem Gerät gelöscht.";
|
||||
|
||||
static String m71(fileType) =>
|
||||
"Diese Datei ist sowohl in Ente als auch auf deinem Gerät.";
|
||||
|
||||
static String m71(fileType) => "Diese Datei wird von Ente gelöscht.";
|
||||
static String m72(fileType) => "Diese Datei wird von Ente gelöscht.";
|
||||
|
||||
static String m1(storageAmountInGB) => "${storageAmountInGB} GB";
|
||||
|
||||
static String m72(
|
||||
static String m73(
|
||||
usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) =>
|
||||
"${usedAmount} ${usedStorageUnit} von ${totalAmount} ${totalStorageUnit} verwendet";
|
||||
|
||||
static String m73(id) =>
|
||||
static String m74(id) =>
|
||||
"Dein ${id} ist bereits mit einem anderen Ente-Konto verknüpft.\nWenn du deine ${id} mit diesem Konto verwenden möchtest, kontaktiere bitte unseren Support";
|
||||
|
||||
static String m74(endDate) => "Dein Abo endet am ${endDate}";
|
||||
static String m75(endDate) => "Dein Abo endet am ${endDate}";
|
||||
|
||||
static String m75(completed, total) =>
|
||||
static String m76(completed, total) =>
|
||||
"${completed}/${total} Erinnerungsstücke gesichert";
|
||||
|
||||
static String m76(ignoreReason) =>
|
||||
static String m77(ignoreReason) =>
|
||||
"Zum Hochladen tippen, Hochladen wird derzeit ignoriert, da ${ignoreReason}";
|
||||
|
||||
static String m77(storageAmountInGB) =>
|
||||
static String m8(storageAmountInGB) =>
|
||||
"Diese erhalten auch ${storageAmountInGB} GB";
|
||||
|
||||
static String m78(email) => "Dies ist ${email}s Verifizierungs-ID";
|
||||
@@ -291,11 +291,11 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"Neue E-Mail-Adresse hinzufügen"),
|
||||
"addCollaborator":
|
||||
MessageLookupByLibrary.simpleMessage("Bearbeiter hinzufügen"),
|
||||
"addCollaborators": m6,
|
||||
"addCollaborators": m9,
|
||||
"addFiles": MessageLookupByLibrary.simpleMessage("Dateien hinzufügen"),
|
||||
"addFromDevice":
|
||||
MessageLookupByLibrary.simpleMessage("Vom Gerät hinzufügen"),
|
||||
"addItem": m7,
|
||||
"addItem": m10,
|
||||
"addLocation": MessageLookupByLibrary.simpleMessage("Ort hinzufügen"),
|
||||
"addLocationButton": MessageLookupByLibrary.simpleMessage("Hinzufügen"),
|
||||
"addMore": MessageLookupByLibrary.simpleMessage("Mehr hinzufügen"),
|
||||
@@ -307,7 +307,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Neue Person hinzufügen"),
|
||||
"addOnPageSubtitle":
|
||||
MessageLookupByLibrary.simpleMessage("Details der Add-ons"),
|
||||
"addOnValidTill": m8,
|
||||
"addOnValidTill": m11,
|
||||
"addOns": MessageLookupByLibrary.simpleMessage("Add-ons"),
|
||||
"addPhotos": MessageLookupByLibrary.simpleMessage("Fotos hinzufügen"),
|
||||
"addSelected":
|
||||
@@ -320,12 +320,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"addTrustedContact": MessageLookupByLibrary.simpleMessage(
|
||||
"Vertrauenswürdigen Kontakt hinzufügen"),
|
||||
"addViewer": MessageLookupByLibrary.simpleMessage("Album teilen"),
|
||||
"addViewers": m9,
|
||||
"addViewers": m12,
|
||||
"addYourPhotosNow":
|
||||
MessageLookupByLibrary.simpleMessage("Füge deine Foto jetzt hinzu"),
|
||||
"addedAs": MessageLookupByLibrary.simpleMessage("Hinzugefügt als"),
|
||||
"addedBy": m10,
|
||||
"addedSuccessfullyTo": m11,
|
||||
"addedBy": m13,
|
||||
"addedSuccessfullyTo": m14,
|
||||
"addingToFavorites": MessageLookupByLibrary.simpleMessage(
|
||||
"Wird zu Favoriten hinzugefügt..."),
|
||||
"advanced": MessageLookupByLibrary.simpleMessage("Erweitert"),
|
||||
@@ -336,7 +336,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"after1Week": MessageLookupByLibrary.simpleMessage("Nach 1 Woche"),
|
||||
"after1Year": MessageLookupByLibrary.simpleMessage("Nach 1 Jahr"),
|
||||
"albumOwner": MessageLookupByLibrary.simpleMessage("Besitzer"),
|
||||
"albumParticipantsCount": m12,
|
||||
"albumParticipantsCount": m15,
|
||||
"albumTitle": MessageLookupByLibrary.simpleMessage("Albumtitel"),
|
||||
"albumUpdated":
|
||||
MessageLookupByLibrary.simpleMessage("Album aktualisiert"),
|
||||
@@ -386,7 +386,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"appLock": MessageLookupByLibrary.simpleMessage("App-Sperre"),
|
||||
"appLockDescriptions": MessageLookupByLibrary.simpleMessage(
|
||||
"Wähle zwischen dem Standard-Sperrbildschirm deines Gerätes und einem eigenen Sperrbildschirm mit PIN oder Passwort."),
|
||||
"appVersion": m13,
|
||||
"appVersion": m16,
|
||||
"appleId": MessageLookupByLibrary.simpleMessage("Apple ID"),
|
||||
"apply": MessageLookupByLibrary.simpleMessage("Anwenden"),
|
||||
"applyCodeTitle": MessageLookupByLibrary.simpleMessage("Code nutzen"),
|
||||
@@ -470,7 +470,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"autoPairDesc": MessageLookupByLibrary.simpleMessage(
|
||||
"Automatisches Verbinden funktioniert nur mit Geräten, die Chromecast unterstützen."),
|
||||
"available": MessageLookupByLibrary.simpleMessage("Verfügbar"),
|
||||
"availableStorageSpace": m14,
|
||||
"availableStorageSpace": m17,
|
||||
"backedUpFolders":
|
||||
MessageLookupByLibrary.simpleMessage("Gesicherte Ordner"),
|
||||
"backup": MessageLookupByLibrary.simpleMessage("Backup"),
|
||||
@@ -510,10 +510,10 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Wiederherstellung abbrechen"),
|
||||
"cancelAccountRecoveryBody": MessageLookupByLibrary.simpleMessage(
|
||||
"Bist du sicher, dass du die Wiederherstellung abbrechen möchtest?"),
|
||||
"cancelOtherSubscription": m15,
|
||||
"cancelOtherSubscription": m18,
|
||||
"cancelSubscription":
|
||||
MessageLookupByLibrary.simpleMessage("Abonnement kündigen"),
|
||||
"cannotAddMorePhotosAfterBecomingViewer": m16,
|
||||
"cannotAddMorePhotosAfterBecomingViewer": m3,
|
||||
"cannotDeleteSharedFiles": MessageLookupByLibrary.simpleMessage(
|
||||
"Konnte geteilte Dateien nicht löschen"),
|
||||
"castAlbum": MessageLookupByLibrary.simpleMessage("Album übertragen"),
|
||||
@@ -564,7 +564,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Freien Speicher einlösen"),
|
||||
"claimMore": MessageLookupByLibrary.simpleMessage("Mehr einlösen!"),
|
||||
"claimed": MessageLookupByLibrary.simpleMessage("Eingelöst"),
|
||||
"claimedStorageSoFar": m17,
|
||||
"claimedStorageSoFar": m19,
|
||||
"cleanUncategorized":
|
||||
MessageLookupByLibrary.simpleMessage("Unkategorisiert leeren"),
|
||||
"cleanUncategorizedDescription": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -593,12 +593,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"Erstelle einen Link, mit dem andere Fotos in dem geteilten Album sehen und selbst welche hinzufügen können - ohne dass sie die ein Ente-Konto oder die App benötigen. Ideal um gemeinsam Fotos von Events zu sammeln."),
|
||||
"collaborativeLink":
|
||||
MessageLookupByLibrary.simpleMessage("Gemeinschaftlicher Link"),
|
||||
"collaborativeLinkCreatedFor": m18,
|
||||
"collaborativeLinkCreatedFor": m20,
|
||||
"collaborator": MessageLookupByLibrary.simpleMessage("Bearbeiter"),
|
||||
"collaboratorsCanAddPhotosAndVideosToTheSharedAlbum":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Bearbeiter können Fotos & Videos zu dem geteilten Album hinzufügen."),
|
||||
"collaboratorsSuccessfullyAdded": m19,
|
||||
"collaboratorsSuccessfullyAdded": m21,
|
||||
"collageLayout": MessageLookupByLibrary.simpleMessage("Layout"),
|
||||
"collageSaved": MessageLookupByLibrary.simpleMessage(
|
||||
"Collage in Galerie gespeichert"),
|
||||
@@ -615,7 +615,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"Bist du sicher, dass du die Zwei-Faktor-Authentifizierung (2FA) deaktivieren willst?"),
|
||||
"confirmAccountDeletion":
|
||||
MessageLookupByLibrary.simpleMessage("Kontolöschung bestätigen"),
|
||||
"confirmAddingTrustedContact": m20,
|
||||
"confirmAddingTrustedContact": m22,
|
||||
"confirmDeletePrompt": MessageLookupByLibrary.simpleMessage(
|
||||
"Ja, ich möchte dieses Konto und alle enthaltenen Daten über alle Apps hinweg endgültig löschen."),
|
||||
"confirmPassword":
|
||||
@@ -628,10 +628,10 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"Bestätige deinen Wiederherstellungsschlüssel"),
|
||||
"connectToDevice":
|
||||
MessageLookupByLibrary.simpleMessage("Mit Gerät verbinden"),
|
||||
"contactFamilyAdmin": m21,
|
||||
"contactFamilyAdmin": m23,
|
||||
"contactSupport":
|
||||
MessageLookupByLibrary.simpleMessage("Support kontaktieren"),
|
||||
"contactToManageSubscription": m22,
|
||||
"contactToManageSubscription": m24,
|
||||
"contacts": MessageLookupByLibrary.simpleMessage("Kontakte"),
|
||||
"contents": MessageLookupByLibrary.simpleMessage("Inhalte"),
|
||||
"continueLabel": MessageLookupByLibrary.simpleMessage("Weiter"),
|
||||
@@ -679,7 +679,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"currentlyRunning":
|
||||
MessageLookupByLibrary.simpleMessage("läuft gerade"),
|
||||
"custom": MessageLookupByLibrary.simpleMessage("Benutzerdefiniert"),
|
||||
"customEndpoint": m23,
|
||||
"customEndpoint": m25,
|
||||
"darkTheme": MessageLookupByLibrary.simpleMessage("Dunkel"),
|
||||
"dayToday": MessageLookupByLibrary.simpleMessage("Heute"),
|
||||
"dayYesterday": MessageLookupByLibrary.simpleMessage("Gestern"),
|
||||
@@ -717,11 +717,11 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Vom Gerät löschen"),
|
||||
"deleteFromEnte":
|
||||
MessageLookupByLibrary.simpleMessage("Von Ente löschen"),
|
||||
"deleteItemCount": m24,
|
||||
"deleteItemCount": m26,
|
||||
"deleteLocation":
|
||||
MessageLookupByLibrary.simpleMessage("Standort löschen"),
|
||||
"deletePhotos": MessageLookupByLibrary.simpleMessage("Fotos löschen"),
|
||||
"deleteProgress": m25,
|
||||
"deleteProgress": m27,
|
||||
"deleteReason1": MessageLookupByLibrary.simpleMessage(
|
||||
"Es fehlt eine zentrale Funktion, die ich benötige"),
|
||||
"deleteReason2": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -759,7 +759,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"Zuschauer können weiterhin Screenshots oder mit anderen externen Programmen Kopien der Bilder machen."),
|
||||
"disableDownloadWarningTitle":
|
||||
MessageLookupByLibrary.simpleMessage("Bitte beachten Sie:"),
|
||||
"disableLinkMessage": m26,
|
||||
"disableLinkMessage": m28,
|
||||
"disableTwofactor": MessageLookupByLibrary.simpleMessage(
|
||||
"Zweiten Faktor (2FA) deaktivieren"),
|
||||
"disablingTwofactorAuthentication":
|
||||
@@ -802,9 +802,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"Herunterladen fehlgeschlagen"),
|
||||
"downloading":
|
||||
MessageLookupByLibrary.simpleMessage("Wird heruntergeladen..."),
|
||||
"dropSupportEmail": m27,
|
||||
"duplicateFileCountWithStorageSaved": m28,
|
||||
"duplicateItemsGroup": m29,
|
||||
"dropSupportEmail": m29,
|
||||
"duplicateFileCountWithStorageSaved": m30,
|
||||
"duplicateItemsGroup": m31,
|
||||
"edit": MessageLookupByLibrary.simpleMessage("Bearbeiten"),
|
||||
"editLocation":
|
||||
MessageLookupByLibrary.simpleMessage("Standort bearbeiten"),
|
||||
@@ -820,8 +820,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"email": MessageLookupByLibrary.simpleMessage("E-Mail"),
|
||||
"emailAlreadyRegistered": MessageLookupByLibrary.simpleMessage(
|
||||
"E-Mail ist bereits registriert."),
|
||||
"emailChangedTo": m30,
|
||||
"emailNoEnteAccount": m31,
|
||||
"emailChangedTo": m32,
|
||||
"emailNoEnteAccount": m33,
|
||||
"emailNotRegistered":
|
||||
MessageLookupByLibrary.simpleMessage("E-Mail nicht registriert."),
|
||||
"emailVerificationToggle":
|
||||
@@ -906,7 +906,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Daten exportieren"),
|
||||
"extraPhotosFound":
|
||||
MessageLookupByLibrary.simpleMessage("Zusätzliche Fotos gefunden"),
|
||||
"extraPhotosFoundFor": m32,
|
||||
"extraPhotosFoundFor": m34,
|
||||
"faceNotClusteredYet": MessageLookupByLibrary.simpleMessage(
|
||||
"Gesicht ist noch nicht gruppiert, bitte komm später zurück"),
|
||||
"faceRecognition":
|
||||
@@ -956,8 +956,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"fileTypes": MessageLookupByLibrary.simpleMessage("Dateitypen"),
|
||||
"fileTypesAndNames":
|
||||
MessageLookupByLibrary.simpleMessage("Dateitypen und -namen"),
|
||||
"filesBackedUpFromDevice": m33,
|
||||
"filesBackedUpInAlbum": m34,
|
||||
"filesBackedUpFromDevice": m35,
|
||||
"filesBackedUpInAlbum": m36,
|
||||
"filesDeleted":
|
||||
MessageLookupByLibrary.simpleMessage("Dateien gelöscht"),
|
||||
"filesSavedToGallery": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -975,28 +975,28 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Gesichter gefunden"),
|
||||
"freeStorageClaimed": MessageLookupByLibrary.simpleMessage(
|
||||
"Kostenlos hinzugefügter Speicherplatz"),
|
||||
"freeStorageOnReferralSuccess": m35,
|
||||
"freeStorageOnReferralSuccess": m4,
|
||||
"freeStorageUsable": MessageLookupByLibrary.simpleMessage(
|
||||
"Freier Speicherplatz nutzbar"),
|
||||
"freeTrial":
|
||||
MessageLookupByLibrary.simpleMessage("Kostenlose Testphase"),
|
||||
"freeTrialValidTill": m36,
|
||||
"freeUpAccessPostDelete": m37,
|
||||
"freeUpAmount": m38,
|
||||
"freeTrialValidTill": m37,
|
||||
"freeUpAccessPostDelete": m38,
|
||||
"freeUpAmount": m39,
|
||||
"freeUpDeviceSpace":
|
||||
MessageLookupByLibrary.simpleMessage("Gerätespeicher freiräumen"),
|
||||
"freeUpDeviceSpaceDesc": MessageLookupByLibrary.simpleMessage(
|
||||
"Spare Speicherplatz auf deinem Gerät, indem du Dateien löschst, die bereits gesichert wurden."),
|
||||
"freeUpSpace":
|
||||
MessageLookupByLibrary.simpleMessage("Speicherplatz freigeben"),
|
||||
"freeUpSpaceSaving": m39,
|
||||
"freeUpSpaceSaving": m40,
|
||||
"gallery": MessageLookupByLibrary.simpleMessage("Galerie"),
|
||||
"galleryMemoryLimitInfo": MessageLookupByLibrary.simpleMessage(
|
||||
"Bis zu 1000 Erinnerungsstücke angezeigt in der Galerie"),
|
||||
"general": MessageLookupByLibrary.simpleMessage("Allgemein"),
|
||||
"generatingEncryptionKeys": MessageLookupByLibrary.simpleMessage(
|
||||
"Generierung von Verschlüsselungscodes..."),
|
||||
"genericProgress": m40,
|
||||
"genericProgress": m41,
|
||||
"goToSettings":
|
||||
MessageLookupByLibrary.simpleMessage("Zu den Einstellungen"),
|
||||
"googlePlayId": MessageLookupByLibrary.simpleMessage("Google Play ID"),
|
||||
@@ -1082,7 +1082,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"itLooksLikeSomethingWentWrongPleaseRetryAfterSome":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Etwas ist schiefgelaufen. Bitte versuche es später noch einmal. Sollte der Fehler weiter bestehen, kontaktiere unser Supportteam."),
|
||||
"itemCount": m41,
|
||||
"itemCount": m42,
|
||||
"itemsShowTheNumberOfDaysRemainingBeforePermanentDeletion":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Elemente zeigen die Anzahl der Tage bis zum dauerhaften Löschen an"),
|
||||
@@ -1113,7 +1113,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"legacy": MessageLookupByLibrary.simpleMessage("Digitales Erbe"),
|
||||
"legacyAccounts":
|
||||
MessageLookupByLibrary.simpleMessage("Digital geerbte Konten"),
|
||||
"legacyInvite": m42,
|
||||
"legacyInvite": m43,
|
||||
"legacyPageDesc": MessageLookupByLibrary.simpleMessage(
|
||||
"Das digitale Erbe erlaubt vertrauenswürdigen Kontakten den Zugriff auf dein Konto in deiner Abwesenheit."),
|
||||
"legacyPageDesc2": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -1124,10 +1124,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"linkCopiedToClipboard": MessageLookupByLibrary.simpleMessage(
|
||||
"Link in Zwischenablage kopiert"),
|
||||
"linkDeviceLimit": MessageLookupByLibrary.simpleMessage("Geräte-Limit"),
|
||||
"linkEmail": MessageLookupByLibrary.simpleMessage("Link email"),
|
||||
"linkEnabled": MessageLookupByLibrary.simpleMessage("Aktiviert"),
|
||||
"linkExpired": MessageLookupByLibrary.simpleMessage("Abgelaufen"),
|
||||
"linkExpiresOn": m43,
|
||||
"linkExpiresOn": m44,
|
||||
"linkExpiry":
|
||||
MessageLookupByLibrary.simpleMessage("Ablaufdatum des Links"),
|
||||
"linkHasExpired":
|
||||
@@ -1218,7 +1217,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"maps": MessageLookupByLibrary.simpleMessage("Karten"),
|
||||
"mastodon": MessageLookupByLibrary.simpleMessage("Mastodon"),
|
||||
"matrix": MessageLookupByLibrary.simpleMessage("Matrix"),
|
||||
"memoryCount": m3,
|
||||
"memoryCount": m5,
|
||||
"merchandise": MessageLookupByLibrary.simpleMessage("Merchandise"),
|
||||
"mergeWithExisting": MessageLookupByLibrary.simpleMessage(
|
||||
"Mit vorhandenem zusammenführen"),
|
||||
@@ -1248,12 +1247,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"moreDetails": MessageLookupByLibrary.simpleMessage("Weitere Details"),
|
||||
"mostRecent": MessageLookupByLibrary.simpleMessage("Neuste"),
|
||||
"mostRelevant": MessageLookupByLibrary.simpleMessage("Nach Relevanz"),
|
||||
"moveItem": m44,
|
||||
"moveItem": m45,
|
||||
"moveToAlbum":
|
||||
MessageLookupByLibrary.simpleMessage("Zum Album verschieben"),
|
||||
"moveToHiddenAlbum": MessageLookupByLibrary.simpleMessage(
|
||||
"Zu verstecktem Album verschieben"),
|
||||
"movedSuccessfullyTo": m45,
|
||||
"movedSuccessfullyTo": m46,
|
||||
"movedToTrash": MessageLookupByLibrary.simpleMessage(
|
||||
"In den Papierkorb verschoben"),
|
||||
"movingFilesToAlbum": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -1282,7 +1281,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"noDuplicates":
|
||||
MessageLookupByLibrary.simpleMessage("✨ Keine Duplikate"),
|
||||
"noEnteAccountExclamation":
|
||||
MessageLookupByLibrary.simpleMessage("No Ente account!"),
|
||||
MessageLookupByLibrary.simpleMessage("Kein Ente-Konto!"),
|
||||
"noExifData": MessageLookupByLibrary.simpleMessage("Keine Exif-Daten"),
|
||||
"noFacesFound":
|
||||
MessageLookupByLibrary.simpleMessage("Keine Gesichter gefunden"),
|
||||
@@ -1306,10 +1305,10 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"noResults": MessageLookupByLibrary.simpleMessage("Keine Ergebnisse"),
|
||||
"noResultsFound":
|
||||
MessageLookupByLibrary.simpleMessage("Keine Ergebnisse gefunden"),
|
||||
"noSuggestionsForPerson": m46,
|
||||
"noSuggestionsForPerson": m47,
|
||||
"noSystemLockFound":
|
||||
MessageLookupByLibrary.simpleMessage("Keine Systemsperre gefunden"),
|
||||
"notPersonLabel": m47,
|
||||
"notPersonLabel": m48,
|
||||
"nothingSharedWithYouYet":
|
||||
MessageLookupByLibrary.simpleMessage("Noch nichts mit Dir geteilt"),
|
||||
"nothingToSeeHere": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -1320,7 +1319,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"onDevice": MessageLookupByLibrary.simpleMessage("Auf dem Gerät"),
|
||||
"onEnte": MessageLookupByLibrary.simpleMessage(
|
||||
"Auf <branding>ente</branding>"),
|
||||
"onlyFamilyAdminCanChangeCode": m48,
|
||||
"onlyFamilyAdminCanChangeCode": m49,
|
||||
"onlyThem": MessageLookupByLibrary.simpleMessage("Nur diese"),
|
||||
"oops": MessageLookupByLibrary.simpleMessage("Hoppla"),
|
||||
"oopsCouldNotSaveEdits": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -1343,6 +1342,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"Oder mit existierenden zusammenführen"),
|
||||
"orPickAnExistingOne": MessageLookupByLibrary.simpleMessage(
|
||||
"Oder eine vorherige auswählen"),
|
||||
"orPickFromYourContacts":
|
||||
MessageLookupByLibrary.simpleMessage("or pick from your contacts"),
|
||||
"pair": MessageLookupByLibrary.simpleMessage("Koppeln"),
|
||||
"pairWithPin":
|
||||
MessageLookupByLibrary.simpleMessage("Mit PIN verbinden"),
|
||||
@@ -1368,7 +1369,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Zahlung fehlgeschlagen"),
|
||||
"paymentFailedMessage": MessageLookupByLibrary.simpleMessage(
|
||||
"Leider ist deine Zahlung fehlgeschlagen. Wende dich an unseren Support und wir helfen dir weiter!"),
|
||||
"paymentFailedTalkToProvider": m49,
|
||||
"paymentFailedTalkToProvider": m50,
|
||||
"pendingItems":
|
||||
MessageLookupByLibrary.simpleMessage("Ausstehende Elemente"),
|
||||
"pendingSync":
|
||||
@@ -1392,14 +1393,14 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"photosAddedByYouWillBeRemovedFromTheAlbum":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Von dir hinzugefügte Fotos werden vom Album entfernt"),
|
||||
"photosCount": m50,
|
||||
"photosCount": m51,
|
||||
"pickCenterPoint":
|
||||
MessageLookupByLibrary.simpleMessage("Mittelpunkt auswählen"),
|
||||
"pinAlbum": MessageLookupByLibrary.simpleMessage("Album anheften"),
|
||||
"pinLock": MessageLookupByLibrary.simpleMessage("PIN-Sperre"),
|
||||
"playOnTv": MessageLookupByLibrary.simpleMessage(
|
||||
"Album auf dem Fernseher wiedergeben"),
|
||||
"playStoreFreeTrialValidTill": m51,
|
||||
"playStoreFreeTrialValidTill": m52,
|
||||
"playstoreSubscription":
|
||||
MessageLookupByLibrary.simpleMessage("PlayStore Abo"),
|
||||
"pleaseCheckYourInternetConnectionAndTryAgain":
|
||||
@@ -1411,14 +1412,14 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"pleaseContactSupportIfTheProblemPersists":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Bitte wenden Sie sich an den Support, falls das Problem weiterhin besteht"),
|
||||
"pleaseEmailUsAt": m52,
|
||||
"pleaseEmailUsAt": m53,
|
||||
"pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage(
|
||||
"Bitte erteile die nötigen Berechtigungen"),
|
||||
"pleaseLoginAgain":
|
||||
MessageLookupByLibrary.simpleMessage("Bitte logge dich erneut ein"),
|
||||
"pleaseSelectQuickLinksToRemove": MessageLookupByLibrary.simpleMessage(
|
||||
"Bitte wähle die zu entfernenden schnellen Links"),
|
||||
"pleaseSendTheLogsTo": m53,
|
||||
"pleaseSendTheLogsTo": m54,
|
||||
"pleaseTryAgain":
|
||||
MessageLookupByLibrary.simpleMessage("Bitte versuche es erneut"),
|
||||
"pleaseVerifyTheCodeYouHaveEntered":
|
||||
@@ -1447,7 +1448,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Privates Teilen"),
|
||||
"proceed": MessageLookupByLibrary.simpleMessage("Fortfahren"),
|
||||
"processed": MessageLookupByLibrary.simpleMessage("Verarbeitet"),
|
||||
"processingImport": m54,
|
||||
"processingImport": m55,
|
||||
"publicLinkCreated":
|
||||
MessageLookupByLibrary.simpleMessage("Öffentlicher Link erstellt"),
|
||||
"publicLinkEnabled":
|
||||
@@ -1457,7 +1458,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"raiseTicket": MessageLookupByLibrary.simpleMessage("Ticket erstellen"),
|
||||
"rateTheApp": MessageLookupByLibrary.simpleMessage("App bewerten"),
|
||||
"rateUs": MessageLookupByLibrary.simpleMessage("Bewerte uns"),
|
||||
"rateUsOnStore": m55,
|
||||
"rateUsOnStore": m56,
|
||||
"recover": MessageLookupByLibrary.simpleMessage("Wiederherstellen"),
|
||||
"recoverAccount":
|
||||
MessageLookupByLibrary.simpleMessage("Konto wiederherstellen"),
|
||||
@@ -1467,7 +1468,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Konto wiederherstellen"),
|
||||
"recoveryInitiated":
|
||||
MessageLookupByLibrary.simpleMessage("Wiederherstellung gestartet"),
|
||||
"recoveryInitiatedDesc": m56,
|
||||
"recoveryInitiatedDesc": m57,
|
||||
"recoveryKey": MessageLookupByLibrary.simpleMessage(
|
||||
"Wiederherstellungs-Schlüssel"),
|
||||
"recoveryKeyCopiedToClipboard": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -1482,12 +1483,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"Wiederherstellungs-Schlüssel überprüft"),
|
||||
"recoveryKeyVerifyReason": MessageLookupByLibrary.simpleMessage(
|
||||
"Dein Wiederherstellungsschlüssel ist die einzige Möglichkeit, auf deine Fotos zuzugreifen, solltest du dein Passwort vergessen. Du findest ihn unter Einstellungen > Konto.\n\nBitte gib deinen Wiederherstellungsschlüssel hier ein, um sicherzugehen, dass du ihn korrekt gesichert hast."),
|
||||
"recoveryReady": m57,
|
||||
"recoveryReady": m58,
|
||||
"recoverySuccessful": MessageLookupByLibrary.simpleMessage(
|
||||
"Wiederherstellung erfolgreich!"),
|
||||
"recoveryWarning": MessageLookupByLibrary.simpleMessage(
|
||||
"Ein vertrauenswürdiger Kontakt versucht, auf dein Konto zuzugreifen"),
|
||||
"recoveryWarningBody": m58,
|
||||
"recoveryWarningBody": m59,
|
||||
"recreatePasswordBody": MessageLookupByLibrary.simpleMessage(
|
||||
"Das aktuelle Gerät ist nicht leistungsfähig genug, um dein Passwort zu verifizieren, aber wir können es neu erstellen, damit es auf allen Geräten funktioniert.\n\nBitte melde dich mit deinem Wiederherstellungs-Schlüssel an und erstelle dein Passwort neu (Wenn du willst, kannst du dasselbe erneut verwenden)."),
|
||||
"recreatePasswordTitle":
|
||||
@@ -1503,7 +1504,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"1. Gib diesen Code an deine Freunde"),
|
||||
"referralStep2": MessageLookupByLibrary.simpleMessage(
|
||||
"2. Sie schließen ein bezahltes Abo ab"),
|
||||
"referralStep3": m59,
|
||||
"referralStep3": m60,
|
||||
"referrals": MessageLookupByLibrary.simpleMessage("Weiterempfehlungen"),
|
||||
"referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage(
|
||||
"Einlösungen sind derzeit pausiert"),
|
||||
@@ -1535,7 +1536,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"removeLink": MessageLookupByLibrary.simpleMessage("Link entfernen"),
|
||||
"removeParticipant":
|
||||
MessageLookupByLibrary.simpleMessage("Teilnehmer entfernen"),
|
||||
"removeParticipantBody": m60,
|
||||
"removeParticipantBody": m61,
|
||||
"removePersonLabel":
|
||||
MessageLookupByLibrary.simpleMessage("Personenetikett entfernen"),
|
||||
"removePublicLink":
|
||||
@@ -1555,7 +1556,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"renameFile": MessageLookupByLibrary.simpleMessage("Datei umbenennen"),
|
||||
"renewSubscription":
|
||||
MessageLookupByLibrary.simpleMessage("Abonnement erneuern"),
|
||||
"renewsOn": m61,
|
||||
"renewsOn": m62,
|
||||
"reportABug": MessageLookupByLibrary.simpleMessage("Fehler melden"),
|
||||
"reportBug": MessageLookupByLibrary.simpleMessage("Fehler melden"),
|
||||
"resendEmail":
|
||||
@@ -1634,8 +1635,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"Laden Sie Personen ein, damit Sie geteilte Fotos hier einsehen können"),
|
||||
"searchPersonsEmptySection": MessageLookupByLibrary.simpleMessage(
|
||||
"Personen werden hier angezeigt, sobald Verarbeitung und Synchronisierung abgeschlossen sind"),
|
||||
"searchResultCount": m62,
|
||||
"searchSectionsLengthMismatch": m63,
|
||||
"searchResultCount": m63,
|
||||
"searchSectionsLengthMismatch": m64,
|
||||
"security": MessageLookupByLibrary.simpleMessage("Sicherheit"),
|
||||
"seePublicAlbumLinksInApp": MessageLookupByLibrary.simpleMessage(
|
||||
"Öffentliche Album-Links in der App ansehen"),
|
||||
@@ -1669,8 +1670,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"selectedItemsWillBeDeletedFromAllAlbumsAndMoved":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Ausgewählte Elemente werden aus allen Alben gelöscht und in den Papierkorb verschoben."),
|
||||
"selectedPhotos": m4,
|
||||
"selectedPhotosWithYours": m64,
|
||||
"selectedPhotos": m6,
|
||||
"selectedPhotosWithYours": m65,
|
||||
"send": MessageLookupByLibrary.simpleMessage("Absenden"),
|
||||
"sendEmail": MessageLookupByLibrary.simpleMessage("E-Mail senden"),
|
||||
"sendInvite": MessageLookupByLibrary.simpleMessage("Einladung senden"),
|
||||
@@ -1700,16 +1701,16 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"shareAnAlbumNow":
|
||||
MessageLookupByLibrary.simpleMessage("Teile jetzt ein Album"),
|
||||
"shareLink": MessageLookupByLibrary.simpleMessage("Link teilen"),
|
||||
"shareMyVerificationID": m65,
|
||||
"shareMyVerificationID": m66,
|
||||
"shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage(
|
||||
"Teile mit ausgewählten Personen"),
|
||||
"shareTextConfirmOthersVerificationID": m5,
|
||||
"shareTextConfirmOthersVerificationID": m7,
|
||||
"shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage(
|
||||
"Hol dir Ente, damit wir ganz einfach Fotos und Videos in Originalqualität teilen können\n\nhttps://ente.io"),
|
||||
"shareTextReferralCode": m66,
|
||||
"shareTextReferralCode": m67,
|
||||
"shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage(
|
||||
"Mit Nicht-Ente-Benutzern teilen"),
|
||||
"shareWithPeopleSectionTitle": m67,
|
||||
"shareWithPeopleSectionTitle": m68,
|
||||
"shareYourFirstAlbum":
|
||||
MessageLookupByLibrary.simpleMessage("Teile dein erstes Album"),
|
||||
"sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -1720,7 +1721,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Neue geteilte Fotos"),
|
||||
"sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage(
|
||||
"Erhalte Benachrichtigungen, wenn jemand ein Foto zu einem gemeinsam genutzten Album hinzufügt, dem du angehörst"),
|
||||
"sharedWith": m68,
|
||||
"sharedWith": m69,
|
||||
"sharedWithMe": MessageLookupByLibrary.simpleMessage("Mit mir geteilt"),
|
||||
"sharedWithYou":
|
||||
MessageLookupByLibrary.simpleMessage("Mit dir geteilt"),
|
||||
@@ -1736,11 +1737,11 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Andere Geräte abmelden"),
|
||||
"signUpTerms": MessageLookupByLibrary.simpleMessage(
|
||||
"Ich stimme den <u-terms>Nutzungsbedingungen</u-terms> und der <u-policy>Datenschutzerklärung</u-policy> zu"),
|
||||
"singleFileDeleteFromDevice": m69,
|
||||
"singleFileDeleteFromDevice": m70,
|
||||
"singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage(
|
||||
"Es wird aus allen Alben gelöscht."),
|
||||
"singleFileInBothLocalAndRemote": m70,
|
||||
"singleFileInRemoteOnly": m71,
|
||||
"singleFileInBothLocalAndRemote": m71,
|
||||
"singleFileInRemoteOnly": m72,
|
||||
"skip": MessageLookupByLibrary.simpleMessage("Überspringen"),
|
||||
"social": MessageLookupByLibrary.simpleMessage("Social Media"),
|
||||
"someItemsAreInBothEnteAndYourDevice":
|
||||
@@ -1792,10 +1793,10 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"storageInGB": m1,
|
||||
"storageLimitExceeded": MessageLookupByLibrary.simpleMessage(
|
||||
"Speichergrenze überschritten"),
|
||||
"storageUsageInfo": m72,
|
||||
"storageUsageInfo": m73,
|
||||
"strongStrength": MessageLookupByLibrary.simpleMessage("Stark"),
|
||||
"subAlreadyLinkedErrMessage": m73,
|
||||
"subWillBeCancelledOn": m74,
|
||||
"subAlreadyLinkedErrMessage": m74,
|
||||
"subWillBeCancelledOn": m75,
|
||||
"subscribe": MessageLookupByLibrary.simpleMessage("Abonnieren"),
|
||||
"subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage(
|
||||
"Du benötigst ein aktives, bezahltes Abonnement, um das Teilen zu aktivieren."),
|
||||
@@ -1812,7 +1813,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"suggestFeatures":
|
||||
MessageLookupByLibrary.simpleMessage("Verbesserung vorschlagen"),
|
||||
"support": MessageLookupByLibrary.simpleMessage("Support"),
|
||||
"syncProgress": m75,
|
||||
"syncProgress": m76,
|
||||
"syncStopped":
|
||||
MessageLookupByLibrary.simpleMessage("Synchronisierung angehalten"),
|
||||
"syncing": MessageLookupByLibrary.simpleMessage("Synchronisiere …"),
|
||||
@@ -1825,7 +1826,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Zum Entsperren antippen"),
|
||||
"tapToUpload":
|
||||
MessageLookupByLibrary.simpleMessage("Zum Hochladen antippen"),
|
||||
"tapToUploadIsIgnoredDue": m76,
|
||||
"tapToUploadIsIgnoredDue": m77,
|
||||
"tempErrorContactSupportIfPersists": MessageLookupByLibrary.simpleMessage(
|
||||
"Etwas ist schiefgelaufen. Bitte versuche es später noch einmal. Sollte der Fehler weiter bestehen, kontaktiere unser Supportteam."),
|
||||
"terminate": MessageLookupByLibrary.simpleMessage("Beenden"),
|
||||
@@ -1849,7 +1850,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"theseItemsWillBeDeletedFromYourDevice":
|
||||
MessageLookupByLibrary.simpleMessage(
|
||||
"Diese Elemente werden von deinem Gerät gelöscht."),
|
||||
"theyAlsoGetXGb": m77,
|
||||
"theyAlsoGetXGb": m8,
|
||||
"theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage(
|
||||
"Sie werden aus allen Alben gelöscht."),
|
||||
"thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage(
|
||||
|
||||