Compare commits

...

652 Commits

Author SHA1 Message Date
laurenspriem
74994a3b63 Merge branch 'main' into swipe_images 2025-09-10 17:58:08 +05:30
laurenspriem
7d4897b08f Change folders 2025-09-10 17:55:18 +05:30
Neeraj
c82b829fe3 [mobile] Add debug option to enable database logging (#7133)
Add option for internal users to enable database logging in release
builds for debugging purposes.
2025-09-10 17:33:56 +05:30
Neeraj
1dbdb270b4 [mob][i] Allow internal users to enable db logging 2025-09-10 17:28:12 +05:30
Neeraj
1d1efc286f [mob][internal] Add QR code sharing feature for album links (#7132)
## Summary
- Add QR code sharing feature for album links behind internal user flag
- Integrate QR option in manage links and share collection pages  
- Auto-close dialog after share operation for better UX

## Implementation
- **New QrCodeDialogWidget**: Custom dialog with album name, QR code,
and ente branding
- **Share functionality**: Captures QR as image and shares with album
context
- **Feature gating**: Hidden behind `flagService.internalUser` for
internal testing
- **UI integration**: Available in both share collection page and manage
links page
- **Dependencies**: Added `qr_flutter: ^4.1.0` for QR generation

## Test Plan
-  QR code generation works for album URLs
-  Share functionality captures and exports QR as image
-  Dialog auto-closes after share operation
-  Feature properly hidden behind internal user flag
-  UI integrates seamlessly with existing sharing flow
-  Visual hierarchy: QR primary, album name secondary, branding
tertiary
2025-09-10 16:48:36 +05:30
Neeraj
dc500795a1 Add QR code sharing feature for album links
- Add QrCodeDialogWidget with album branding and share functionality
- Integrate QR code option in manage links and share collection pages
- Feature gated behind flagService.internalUser for testing
- QR codes include album name, scannable link, and ente branding
- Auto-close dialog after share operation for better UX
- Add qr_flutter dependency for QR code generation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-10 16:31:09 +05:30
Neeraj
11afcd92af [server] Support for changing server port (#7131)
## Description
Ref: https://github.com/ente-io/ente/issues/7122

## Tests
Tested locally
2025-09-10 16:22:43 +05:30
Manav Rathi
f20c8caff0 [server] Improve support for idn domains (#7124)
## Description

## Tests
2025-09-10 16:17:12 +05:30
Neeraj Gupta
074f68146f [server] Support for changing server port 2025-09-10 14:47:06 +05:30
Neeraj
68caa3f7c6 [mob] Add in-app log viewer for mobile debugging (#7129)
## Description
Introduces a comprehensive log viewer package for Flutter mobile apps
with:
- Real-time log viewing with filtering by level, logger name, and search
- SQLite-based storage with automatic log rotation (10k entries default)
- Timeline visualization and export functionality
- Integration with SuperLogging for seamless log capture

Only enabled in debug mode to avoid production impact.

## Tests



https://github.com/user-attachments/assets/badb2a4a-a9a2-4aec-b0ae-d825cc4fe23e
2025-09-10 13:53:43 +05:30
Neeraj
5e5d5f4aad Lint fixes for log_viewer 2025-09-10 13:36:39 +05:30
Neeraj
8713dd0707 Do null check before try block 2025-09-10 13:19:33 +05:30
Neeraj
102313f686 Clean up 2025-09-10 13:16:19 +05:30
Neeraj
7ef9fdcaaa Add in-app log viewer for mobile debugging
Introduces a comprehensive log viewer package for Flutter mobile apps with:
- Real-time log viewing with filtering by level, logger name, and search
- SQLite-based storage with automatic log rotation (10k entries default)
- Timeline visualization and export functionality
- Integration with SuperLogging for seamless log capture

Only enabled in debug mode to avoid production impact.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-10 13:06:05 +05:30
Manav Rathi
d902733809 [mob][photos] symlink for agents.md (#7128)
## Description

symlink for [agents.md](https://agents.md)
2025-09-10 11:59:51 +05:30
laurenspriem
0ef990de5a Make CLAUDE.md agent-agnostic, add AGENTS.md symlink
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-10 11:22:16 +05:30
Manav Rathi
7722c4e16b Fix command to reload Caddy (#7125)
```
$ sudo systemctl caddy reload
Unknown command verb 'caddy', did you mean 'cat'?
```
2025-09-10 09:23:46 +05:30
Hans Lemuet
6f5fdfb7b7 Fix command to reload Caddy
$ sudo systemctl caddy reload
Unknown command verb 'caddy', did you mean 'cat'?
2025-09-10 02:14:56 +02:00
Neeraj Gupta
135124a487 Improve err handling 2025-09-10 05:07:31 +05:30
Neeraj Gupta
d3c53794cf Add alert for exactDomain mismatch 2025-09-10 04:52:20 +05:30
Neeraj Gupta
270cee8b09 [server] Support for idn domain 2025-09-10 04:40:27 +05:30
Neeraj
9b05cc8c23 [server] Minor improvements in link middleware (#7104)
## Description

## Tests
2025-09-10 04:25:23 +05:30
Manav Rathi
5b6c3e1b6e [destkop] Update typo in translation (#7118)
See: https://github.com/ente-io/ente/pull/5546#issuecomment-3268874821

Updated the strings in crowdin by `gh workflow run
web-crowdin-push-both.yml`
2025-09-09 17:41:34 +05:30
Manav Rathi
636793d5b1 [destkop] Update typo in translation
See: https://github.com/ente-io/ente/pull/5546#issuecomment-3268874821
2025-09-09 17:32:18 +05:30
Manav Rathi
700e52d11a [web] Harden workflows (#7114) 2025-09-09 13:30:32 +05:30
Manav Rathi
82c7d1865c Update 2025-09-09 12:49:08 +05:30
Manav Rathi
f08ee15cea [web] Harden workflows 2025-09-09 12:00:56 +05:30
Laurens Priem
901bfc945e [mob][photos] Fix copy paste mistake in claude.md (#7109)
## Description

Fix copy paste mistake in claude.md
2025-09-08 16:48:46 +05:30
laurenspriem
6c25b094be Fix copy paste mistake in claude.md 2025-09-08 16:47:21 +05:30
Laurens Priem
4f5af8dcfa [mob][photos] Lower cluster size threshold on discover page (#7105)
## Description

Lower cluster size threshold on discover page
2025-09-08 15:15:12 +05:30
laurenspriem
8079d44c68 Lower cluster size threshold on discover page 2025-09-08 15:05:22 +05:30
Neeraj Gupta
575314c8a1 [server] Relax origin check for localhost for dev 2025-09-08 14:37:22 +05:30
Neeraj Gupta
2684f9ce11 [server] whitelist shared url 2025-09-08 14:33:31 +05:30
Neeraj
cd5582219c [mob] pin in_app_purchase to v3.2.1 (#7103)
## Description

Ref: https://github.com/flutter/flutter/issues/169335

## Tests
Tested via TF.
2025-09-08 14:27:19 +05:30
Neeraj Gupta
69332c78ad Update daily changelog 2025-09-08 14:26:00 +05:30
Aman Raj Singh Mourya
cba30e386d [locker] Update Locker asset & icons (#7102)
## Description
Add background images, svgs for locker.
Update imports & add `flutter_lints` dependencies for
`mobile/pubspec.yaml`
2025-09-08 13:49:57 +05:30
Neeraj Gupta
7663e76deb [mob] pin in_app_purchase to v3.2.1 2025-09-08 13:32:09 +05:30
AmanRajSinghMourya
697d6f854d Add lockscreen background photos 2025-09-08 13:02:42 +05:30
AmanRajSinghMourya
7aadb54ef1 Add icons directory to asset list in pubspec.yaml 2025-09-08 13:02:21 +05:30
AmanRajSinghMourya
2a2443efea Fix dependencies of mobile, add flutter_lints 2025-09-08 13:02:08 +05:30
AmanRajSinghMourya
d2bc2627a3 Move to /icons 2025-09-08 13:01:35 +05:30
AmanRajSinghMourya
b1971810fb Fix imports 2025-09-08 12:20:16 +05:30
AmanRajSinghMourya
bd25af2b4b Assets for legacy 2025-09-08 12:20:06 +05:30
Neeraj
833b4656fe [mob][photos] Dart format (#7101)
## Description

- Formats the flutter code in `/photos`
- Adds format instructions to claude.md
2025-09-08 11:38:42 +05:30
laurenspriem
315c4ae6b7 Tell Claude to format after every code change 2025-09-08 11:03:46 +05:30
laurenspriem
49d9b3c928 dart format . 2025-09-08 11:00:47 +05:30
Neeraj
ba6b326f97 [mob][n] Cast app for tvOS (#7085)
## Description

## Tests
2025-09-07 08:33:46 +05:30
Neeraj Gupta
aeea35e32a Fix empty album flash after auth expiry
- Invalidate slide timer during reset and guard nextSlide() when payload cleared to stop stale timer triggering false "No media files" state
- Remove sensitive logging from EnteCrypto and CastFileService
- Redact cast token from logs

Bug fix identified with GPT-5 preview assistance.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-07 08:28:51 +05:30
Neeraj Gupta
614c6c63aa Remove unused file 2025-09-07 07:48:48 +05:30
Manav Rathi
ba6cee23d9 [docs] Custom domains blog link (#7076) 2025-09-06 17:27:26 +05:30
Manav Rathi
e43266c176 [docs] Custom domains blog link 2025-09-06 17:24:54 +05:30
Manav Rathi
f4168cb9a3 [Docs] Similar images help entry (#6964)
## Description

Similar images help entry.
2025-09-06 16:46:31 +05:30
Neeraj Gupta
1e551b4084 Add Apple TV cast app for Ente Photos
Introduces a new tvOS application that enables users to cast and view
their Ente Photos on Apple TV. The app includes pairing functionality,
slideshow capabilities, and video playback support.

Key components:
- Cast app with SwiftUI interface for Apple TV
- EnteCast package for casting functionality and file management
- EnteNetwork package for API communication
- EnteCrypto package for secure authentication
- EnteCore package for shared utilities
- Custom fonts and branding assets
- Pairing view for device connection
- Slideshow and video player views
- Screen saver management

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-06 16:44:44 +05:30
Aman Raj Singh Mourya
df6392fd19 [locker] Update sharing package (#7071)
## Description
Move `notification_widget`, `user_avatar_widget` & `user_extension` to
`sharing` package.
Update imports, extract strings and update configuration.
2025-09-06 16:19:00 +05:30
Aman Raj Singh Mourya
e4a851072d [locker] Legacy package (#7072)
## Description

## Tests
2025-09-06 16:18:44 +05:30
AmanRajSinghMourya
f9c4442223 Update pubspec.lock 2025-09-06 15:47:33 +05:30
AmanRajSinghMourya
c4e7139ecb Fix sharing package dependencies 2025-09-06 15:15:25 +05:30
AmanRajSinghMourya
ddd4b733d3 Move user_extension to sharing package 2025-09-06 15:14:22 +05:30
Manav Rathi
3836cac109 [docs] Update custom domain docs (#7074) 2025-09-06 13:56:17 +05:30
Manav Rathi
06eda153be [docs] Update custom domain docs 2025-09-06 13:49:44 +05:30
Manav Rathi
6137d07ba8 Fix minor grammar error in deduplicate.md (#7073)
Just a minor doc fix :)
2025-09-06 13:40:22 +05:30
Waldir Pimenta
0f92b098b7 Fix minor grammar error in deduplicate.md 2025-09-06 07:51:10 +01:00
AmanRajSinghMourya
7bde215427 Extract strings 2025-09-06 06:54:43 +05:30
AmanRajSinghMourya
4953310876 Add ente_legacy package and integrate emergency services 2025-09-06 06:54:35 +05:30
AmanRajSinghMourya
2932ee7d4c Legacy package 2025-09-06 06:52:21 +05:30
AmanRajSinghMourya
0e0ba2d5af Extract strings 2025-09-06 06:47:22 +05:30
AmanRajSinghMourya
3b54fa41f6 Remove duplicate import of user_dialogs in collection_actions.dart 2025-09-06 06:45:17 +05:30
AmanRajSinghMourya
c51dff5a29 Move user_dialog to package 2025-09-06 06:45:02 +05:30
AmanRajSinghMourya
e985200e67 Minor fix 2025-09-06 06:11:31 +05:30
AmanRajSinghMourya
7e5e11ba87 Update package strings 2025-09-06 06:07:42 +05:30
AmanRajSinghMourya
13c9646f58 MInor fix 2025-09-06 05:51:39 +05:30
AmanRajSinghMourya
678b556f5f Refactor sharing components: move UserAvatarWidget and VerifyIdentityDialog to ente_sharing package, update imports, and adjust configurations 2025-09-06 05:51:30 +05:30
AmanRajSinghMourya
a3b432799a Update dependencies 2025-09-06 05:45:12 +05:30
AmanRajSinghMourya
8eaa2603dd Add VerifyIdentifyDialog widget to sharing package 2025-09-06 05:43:37 +05:30
AmanRajSinghMourya
b51febf8f5 Update dependencies 2025-09-05 23:48:32 +05:30
AmanRajSinghMourya
df522658bb Move user_avator_widget to sharing package 2025-09-05 23:46:59 +05:30
AmanRajSinghMourya
9a13b99b20 Extract strings 2025-09-05 23:45:09 +05:30
AmanRajSinghMourya
a142b660fd Add golden color properties to EnteColorScheme 2025-09-05 23:44:17 +05:30
AmanRajSinghMourya
b7dcb7b34c Add UserExtension to package 2025-09-05 23:43:53 +05:30
AmanRajSinghMourya
e8de5940fd Update dependency overrides to include ente_network and ente_sharing 2025-09-05 23:43:26 +05:30
AmanRajSinghMourya
d5f8c9eb24 Add notification widget to packages/ui 2025-09-05 23:40:15 +05:30
Neeraj
f092396133 [server] Support for coupons (#7065) 2025-09-05 15:01:15 +05:30
Neeraj Gupta
7f718438aa Minor refactor 2025-09-05 14:44:58 +05:30
Neeraj Gupta
cf7a4d989d [server] Support for coupons 2025-09-05 12:10:19 +05:30
Aman Raj Singh Mourya
e444c1801a [locker] Remove redundant packages (#7039)
## Description

## Tests
2025-09-04 22:38:47 +05:30
AmanRajSinghMourya
f2a2ee188c Update dependency & fix merge conflicts 2025-09-04 22:38:34 +05:30
AmanRajSinghMourya
356622cbb1 Merge branch 'main' into fix_packages 2025-09-04 22:25:49 +05:30
Aman Raj Singh Mourya
86c92a9217 [locker] Fix authentication not popping up on android (#7060)
## Description
Authentication service was not working on android as `local_auth`
requires the use of a `FragmentActivity` instead of an `Activity` in
`MainActivity.kt`

Also updated `AndroidManifest.xml` file to include the USE_BIOMETRIC
permissions:
2025-09-04 17:48:20 +05:30
laurenspriem
20afda080d Merge branch 'main' into swipe_images 2025-09-04 16:18:37 +05:30
AmanRajSinghMourya
bcc2a30105 Add USE_BIOMETRIC permission to AndroidManifest.xml 2025-09-04 16:01:33 +05:30
AmanRajSinghMourya
dcc36d2d35 Extract strings 2025-09-04 15:59:16 +05:30
AmanRajSinghMourya
d650886749 Check if isDeviceSupported for lockscreen 2025-09-04 15:58:49 +05:30
laurenspriem
b95640f0f7 Update todo 2025-09-04 15:58:26 +05:30
AmanRajSinghMourya
a73d5548a0 Fix: local_auth requires the use of a FragmentActivity instead of an Activity 2025-09-04 15:58:17 +05:30
laurenspriem
92974a5d6e Update todo 2025-09-04 15:54:11 +05:30
laurenspriem
a26643d932 Stack all cards 2025-09-04 15:42:20 +05:30
Aman Raj Singh Mourya
bf0b11ebfd [locker] Locker sharing (#7013)
## Description

### Collection Sharing Feature Implementation
This PR implements a collection sharing functionality for locker,
allowing users to share collections with others and manage shared access
through various methods.

## Key Features
1. **Collection Sharing Mechanisms**
   - Share collections via links
   - Manage shared access with specific users
   - Configure link expiry and device limits

2. **User Management** in shared collections
   - Added participant (viewer/ collaborator)
   - Implemented leave collection functionality
   - Added user permissions and access controls

3. **UI Enhancements**
   - New collection view types (main, outgoing, incoming)
   - Grid view for collections
   - Enhanced menu sections and descriptions
   - Improved sharing dialogs and UI components
2025-09-04 12:32:02 +05:30
laurenspriem
757cb486f8 Add smooth undo animation with AnimatedSwitcher
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-04 12:29:31 +05:30
laurenspriem
512cbb29b3 Implement cross-group undo behavior
- Undo button now navigates to last group with changes when current group has no history
- Automatically jumps to the correct image position after cross-group undo
- Keeps controller alive during group switches for better state management
2025-09-04 12:10:01 +05:30
Neeraj
49c90a802a [mob] Fix changelog scrolling on small devices (#7059)
## Description

## Tests
2025-09-04 12:02:11 +05:30
Neeraj Gupta
8b2db5e576 [mob] Fix changelog scrolling on small devices 2025-09-04 12:00:11 +05:30
laurenspriem
0bc8029541 Fix carousel darkening caused by ColorFilter bleed
Replace ColorFilter.darken with isolated opacity and overlay to prevent
affecting carousel brightness when preview card is shown.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-04 11:38:41 +05:30
laurenspriem
b5febe9ba4 Add stacked image preview with subtle top peek 2025-09-04 10:49:37 +05:30
laurenspriem
fb0179b081 Add double-tap to zoom functionality for swipeable images 2025-09-04 10:25:46 +05:30
laurenspriem
289f969d08 Use circular replay icon for undo button 2025-09-04 10:14:42 +05:30
laurenspriem
1b60a4fb38 delete accidentally commited screenshots 2025-09-04 09:43:29 +05:30
laurenspriem
9000529509 Fix pixel overflow for tall portrait images 2025-09-03 22:50:32 +05:30
laurenspriem
18872a329a Fix card border issue - Container wraps image tightly without fixed sizes 2025-09-03 22:43:48 +05:30
laurenspriem
dc843eb618 Fix card border issue - apply constraints to Image not Container 2025-09-03 22:41:53 +05:30
laurenspriem
009dec1e08 Fix card centering and keep file info with image 2025-09-03 22:29:04 +05:30
laurenspriem
82032a182b Mark all remaining fixes as complete in progress.md 2025-09-03 22:22:42 +05:30
laurenspriem
4bd21e2a7a Improve bottom button styling with proper sizing and Ente design 2025-09-03 22:22:18 +05:30
laurenspriem
278dd83a3d Fix swipe card pixel overflow by separating file info from card 2025-09-03 22:20:49 +05:30
laurenspriem
0a04c3b4aa Remove duplicate file info display 2025-09-03 22:11:11 +05:30
laurenspriem
6b760fd611 Fix badge display for partially processed groups 2025-09-03 21:53:23 +05:30
laurenspriem
2518bf5b2d Update todo 2025-09-03 18:33:44 +05:30
laurenspriem
a0eb38c584 Improve swipe culling UI and functionality
- Group summary popup: Changed header to "Decisions", updated button text to "Confirm" and "Undo decisions"
- Added file name and size display below thumbnails in grid view
- Made thumbnails square with better aspect ratio
- Implemented consistent badge design (delete, keep, undecided) in top-right corner
- Added long press to zoom into images with hero animation
- Hide "Undo decisions" button when no decisions made
- Progressive image loading in swipeable photo card (cache → large thumbnail → full)
- Auto-scroll carousel to follow group progression
- Larger action buttons (100x100) positioned higher on screen
- Left-aligned text under thumbnails for better visual alignment

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-03 18:33:02 +05:30
laurenspriem
e32ac8d3b5 Update todos 2025-09-03 16:54:10 +05:30
laurenspriem
1d02d18937 Refine swipe culling UI with improved visual design
• Rectangular thumbnails (72x90px) with better stacking effect
• Improved delete button design matching small delete buttons
• Fixed clipping issues with rotated carousel thumbnails
• Enhanced badge visibility with white text/icons
• Better spacing and visual hierarchy throughout

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-03 16:46:16 +05:30
AmanRajSinghMourya
57382af3a2 Update imports 2025-09-03 15:44:19 +05:30
AmanRajSinghMourya
80bc848d1e Add ente_sharing package dependency to pubspec files 2025-09-03 15:41:43 +05:30
Aman Raj Singh Mourya
b11f86175e [packages] Sharing package (#7048)
## Description
Extract sharing related api to a common sharing package.
2025-09-03 15:38:48 +05:30
Neeraj
b5d4839e04 [mob] Update change log and bump version (#7052)
## Description

## Tests
2025-09-03 15:22:36 +05:30
Neeraj Gupta
ac57097eb4 Update change log and bump version 2025-09-03 15:21:12 +05:30
laurenspriem
c34cfdcb54 merge main 2025-09-03 13:40:16 +05:30
Ashil
4e08e38bf6 [mob][photos] Update claude md documentation (#7051)
## Description

See commit messages.
2025-09-03 13:29:55 +05:30
ashilkn
a7d3cf4178 Update storage dependencies to reflect current usage
Replace sqflite with sqlite_async as the primary database package since the project has migrated to using sqlite_async.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-03 13:21:35 +05:30
ashilkn
c63dfc36e9 Remove integration and performance test sections from CLAUDE.md
These test commands are not confirmed to be working correctly and have been removed from the documentation.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-03 13:20:12 +05:30
Manav Rathi
2985503254 Update CONTRIBUTING.md (#7050) 2025-09-03 12:54:24 +05:30
Laurens Priem
9be023d68a [mob][photos] Add claude.md (#7044)
## Description

Add claude.md
2025-09-03 12:35:53 +05:30
laurenspriem
6a6e1b3c47 Individual preferences 2025-09-03 12:03:51 +05:30
Neeraj
7516363715 [mob][photos] Prevent vectorDB index file corruption (#7049)
## Description

- Use `load` instead of `view`, since latter is read-only
- When loading fails in rust, delete index file in dart side and try
again
- Atomically save index file by first writing to temp file

## Tests

Tested in debug mode on my pixel phone.
2025-09-03 11:54:31 +05:30
laurenspriem
2b76b71db8 atomic save of index file 2025-09-03 11:15:07 +05:30
Manav Rathi
c32a70fb25 Update CONTRIBUTING.md 2025-09-03 10:52:03 +05:30
laurenspriem
4098c1a072 Delete index file on load error 2025-09-03 10:36:03 +05:30
laurenspriem
972be1f41e Use load for usearch index 2025-09-03 10:27:30 +05:30
AmanRajSinghMourya
2e58400962 Add analysis.yaml and minor fix 2025-09-03 10:07:27 +05:30
AmanRajSinghMourya
b0fce602aa Sharing package - extract all sharing api to a common package 2025-09-03 09:55:32 +05:30
laurenspriem
3acb2136d0 [mob][photos] Add documentation sync requirement to CLAUDE.md
Require updating associated spec documents when code changes are made

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-02 18:21:57 +05:30
laurenspriem
eba729625f commit instructions 2025-09-02 18:19:34 +05:30
Manav Rathi
a477742cd0 [web] Fix European date format search support (#7043)
Fixes #7025
2025-09-02 17:48:10 +05:30
laurenspriem
c974bde11c Don't go to setup on error 2025-09-02 17:02:51 +05:30
Manav Rathi
ecc654bae0 [web] Fix European date format search support
Fixes #7025

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-02 10:56:53 +00:00
Ashil
201ef88305 [mob][debug] Thumbnail issue debug (#7042)
## Description

For figuring out root cause of thumbnail not loading issue. This change
will not introduce any regressions or bugs.
2025-09-02 16:26:46 +05:30
Ashil
742035d7cc Merge branch 'main' into thunmbail_issue_debug 2025-09-02 16:20:43 +05:30
ashilkn
8f29d5aa19 Update internal change log 2025-09-02 16:18:15 +05:30
laurenspriem
8a4e76fb6f Small rectification 2025-09-02 16:17:10 +05:30
ashilkn
c03eaf83aa Complete completer with error if getThumbnailFromLocal throws error for task in local thumbnail task queue 2025-09-02 16:13:49 +05:30
laurenspriem
378878538d [mob][photos] Add critical coding requirements to CLAUDE.md
Add three mandatory development practices:
1. Run flutter analyze after every change - zero issues required
2. Always reuse existing components - search before creating
3. Use Ente design system - no hardcoded colors or text styles

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-02 16:06:42 +05:30
laurenspriem
01c3d6b105 [mob][photos] Add CLAUDE.md with initial project documentation
Create comprehensive development guide from /init command including:
- Project philosophy and privacy focus
- Monorepo context and structure
- Development commands (melos and flutter)
- Architecture overview with service patterns
- Security architecture details
- Development setup requirements

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-02 15:48:43 +05:30
laurenspriem
ef66d422b7 Fix swipe culling UI issues and improve user experience 2025-09-02 15:39:44 +05:30
AmanRajSinghMourya
2bdf62c490 Add melos support for photos/plugins 2025-09-02 14:08:04 +05:30
laurenspriem
dc5c3d8af6 Merge branch 'main' into swipe_images 2025-09-02 14:03:17 +05:30
Neeraj
c6f5c68f1e [mob] Update copy (#7040)
## Description

## Tests
2025-09-02 13:52:53 +05:30
Neeraj Gupta
d0c8925ff3 Update playstore changelog 2025-09-02 13:42:46 +05:30
AmanRajSinghMourya
2cab943647 Organize imports 2025-09-02 13:41:52 +05:30
Neeraj Gupta
d6c84421ce [mob][photos] Update changelog copy translations
Updated cLTitle2 from "Manual video stream generation" to "Video streaming enhancements" across all supported locales to match the updated English copy.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-02 13:41:46 +05:30
AmanRajSinghMourya
990485d796 Remove redundant dependencies from locker 2025-09-02 13:41:43 +05:30
AmanRajSinghMourya
96e9030d40 Move list extension to packages 2025-09-02 12:37:59 +05:30
Neeraj
0d1f20f9e2 [mob][photos] Clear up flutter analyze (#7035)
## Description

- Replace withOpacity() with withValues(alpha:)
- Replace onPopInvoked with onPopInvokedWithResult
- Update MaterialState references to WidgetState
- Organize imports
- Remove unneeded nullability
- Dangling library docs
- collectionName deprecation warning
- TextInputWidget isPasswordInput deprecation warning
2025-09-02 12:29:26 +05:30
Ashil
c55447a08f [mob][debug] To debug thumbnail not loading (#7036) 2025-09-02 12:28:34 +05:30
Ashil
98d56e8fa4 Merge branch 'main' into thunmbail_issue_debug 2025-09-02 12:26:48 +05:30
ashilkn
f244c94ebf Update internal change log 2025-09-02 12:24:01 +05:30
laurenspriem
88f2b88f4d Remove deprecation warnings 2025-09-02 12:15:07 +05:30
Neeraj
db1fef40db [mob] Update changelog (#7034)
## Description

## Tests
2025-09-02 12:14:36 +05:30
laurenspriem
1fd29cdd13 dangling library doc 2025-09-02 12:02:53 +05:30
laurenspriem
947d294afe non nullable dialog 2025-09-02 12:02:36 +05:30
ashilkn
515715660e Add option to config local thumbnail queue to debug thumbnail not displaying issue + add more logging + show local ID of file on thumbnails (configurable) 2025-09-02 11:53:21 +05:30
laurenspriem
324221171d organize imports 2025-09-02 11:50:01 +05:30
laurenspriem
f5f2ff1b2c Fix Flutter deprecation warnings
- Replace withOpacity() with withValues(alpha:)
- Replace onPopInvoked with onPopInvokedWithResult
- Update MaterialState references to WidgetState

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-02 11:49:12 +05:30
Neeraj Gupta
244d41621c Bump version 2025-09-02 11:41:40 +05:30
Neeraj Gupta
91b6a08a35 Update changelog entries with new features
- Replace old changelog entries with new ones across all supported languages
- Add Similar Images, Manual video stream generation, and Performance Improvements features
- Remove outdated entries for Advanced Image Editor, Smart Albums, Improved Gallery, and Faster Scroll

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-02 11:39:54 +05:30
Neeraj
770a311da5 [auth] Fix manual app lock with macos touch id (#6793)
## Description
This fixes https://github.com/ente-io/ente/issues/3428
This was broken because of
https://github.com/eaceto/flutter_local_authentication/issues/8
I've also added that if the app is locked manually, the macOS Touch ID
API won't be called until the user either presses the unlock button
again or unfocuses the app and then focuses back on it. This behavior
also applies when the app window is closed and then reopened.
2025-09-02 10:46:56 +05:30
Neeraj
db76dee639 fix: only show when video streaming is enabled (#7031)
## Description

## Tests
2025-09-02 10:45:37 +05:30
laurenspriem
bb5c0db8d3 Fix all Flutter analyze warnings 2025-09-02 10:32:08 +05:30
laurenspriem
76c5f5cbb6 Fix all Flutter analyze errors and warnings 2025-09-02 10:28:03 +05:30
laurenspriem
5446f8dd68 Fix localization imports and linting issues 2025-09-02 10:06:23 +05:30
Manav Rathi
20ce760e85 feat(rust): Initialize Rust CLI foundation (#6915)
## Summary
Rust CLI achieves feature parity with Go CLI for photos app core
functionality

## Changes
- Export, sync, and incremental updates working
- Hash-based deduplication and live photo support
- Public magic metadata for renamed files
- Progress indicators for downloads

## Remaining
- Export filters (album, date range)
- Resume interrupted downloads
- Shared/hidden album support
2025-09-02 09:57:56 +05:30
laurenspriem
52e3f22abf Complete swipe culling feature implementation 2025-09-02 09:44:14 +05:30
laurenspriem
0caaf8b966 Add swipe culling feature with CardSwiper implementation 2025-09-02 09:39:00 +05:30
Prateek Sunal
df1bfbe839 fix: initialize compute controllers async with values 2025-09-02 02:51:09 +05:30
Prateek Sunal
27d72eb821 fix: make continuation and releasing compute better 2025-09-02 02:44:11 +05:30
Prateek Sunal
98786c5824 fix: move logs at better place 2025-09-02 01:04:24 +05:30
Prateek Sunal
d38a09c3f0 perf: optimize video stream processing state management
- Move isCurrentlyProcessing to widget state for better performance
- Only call setState when processing state actually changes
- Add comprehensive processing status handling (retry, compressing, uploading)
- Remove redundant service calls from build method
- Clean up unnecessary early returns and duplicate logic

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-01 18:50:00 +00:00
Aman Raj Singh Mourya
91785d8c90 Add Parallels custom icon (#7026)
## Description
This PR adds a custom icon for Parallels.

- Added `parallels.svg` under
`mobile/apps/auth/assets/custom-icons/icons/`
- Updated `custom-icons.json` with:
  - title: "Parallels"
  - slug: "parallels"
  - hex: #E61E25
  - altNames: ["Parallels Desktop", "Parallels VM"]

The icon is optimized (well under 50KB) and uses the official Parallels
red (#E61E25).
2025-09-02 00:19:46 +05:30
Prateek Sunal
b1f28e3f2e chore: update locks 2025-09-01 23:35:43 +05:30
Prateek Sunal
c155bdd058 chore: lint fixes 2025-09-01 23:35:30 +05:30
Prateek Sunal
a859f28e2c fix: show queueed or creatingStream based on context 2025-09-01 23:35:25 +05:30
Prateek Sunal
8d75528aa5 fix: introduce in queue and creating stream two types of statuses 2025-09-01 23:35:08 +05:30
Prateek Sunal
7f43c11985 fix: only show when video streaming is enabled 2025-09-01 21:22:17 +05:30
Manav Rathi
aadda7e3f6 feat(export): Add file deletion and rename detection to match Go CLI
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-01 18:01:01 +05:30
Ashil
210c18d244 Update internal changes (#7030) 2025-09-01 17:32:12 +05:30
Ashil
6636849838 update internal changes 2025-09-01 17:26:20 +05:30
Neeraj
5500315351 [mob][photos] fix unsupported locales in language selector (#7029) 2025-09-01 17:24:32 +05:30
laurenspriem
06a05659a6 Add implementation progress tracker for swipe culling 2025-09-01 17:14:47 +05:30
Prateek Sunal
562292e642 fix: remove unsupported languages from language picker
Remove languages from _getLanguageName that don't have >90% translation
coverage and aren't in appSupportedLocales (Finnish, Korean, Arabic).
Also improve Chinese locale display.

- Removed fi, ko, ar cases that don't meet translation threshold
- Fixed Chinese locale handling to properly show "中文 (简体)" for zh_CN
- Ensures only properly translated languages appear in the picker

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-01 17:13:58 +05:30
Prateek Sunal
4aa80edbcf fix: resolve unsupported locales appearing in language selector
Replace AppLocalizations.supportedLocales with a curated list of properly
translated locales in the Photos app. This fixes the issue where unsupported
language codes (Bg, Be, Ca, Cs, etc.) were appearing in the language selector
without proper language name formatting.

- Add custom appSupportedLocales list with only >90% translated languages
- Update all references throughout Photos app to use the custom locale list
- Ensures only properly supported languages appear in the language picker

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-01 17:02:15 +05:30
Neeraj
9524a639cd [server] Fix collection link for locker (#6961)
## Description

## Tests
2025-09-01 16:28:19 +05:30
Neeraj
b8eb793c16 [mobile/photos] New translations (#7022)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-app)
2025-09-01 16:26:51 +05:30
Ashil
4b514f1e1a [mob][photos] Revert "Revert diskLoadDeferDuration to 500ms" (#7028)
This reverts commit a295f223b6.
2025-09-01 16:25:59 +05:30
eYdr1en
bee2bb9621 remove unusuded variable 2025-09-01 12:45:27 +02:00
ashilkn
772121c22e Revert "Revert diskLoadDeferDuration to 500ms"
This reverts commit a295f223b6.
2025-09-01 16:07:40 +05:30
laurenspriem
f014a36eba Add photo swipe culling feature spec and implementation plan 2025-09-01 16:06:05 +05:30
eYdr1en
3c49ca0f6e Merge branch 'main' into touch-id 2025-09-01 12:35:27 +02:00
Onurcan
f2e51893ad Update Parallels custom-icons.json 2025-09-01 11:59:32 +03:00
Onurcan
c08b78c775 dd Parallels custom icon 2025-09-01 11:58:26 +03:00
Manav Rathi
233f03355f Fix security issues and match Go CLI error handling
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-01 13:16:03 +05:30
Laurens Priem
73ab50f113 [mob][photos] Run vectorDB migration is memory safe way (#7024)
## Description

- Add ability to block computeController temporarily
- Block computeController when vectorDB migration is running
2025-09-01 11:44:39 +05:30
laurenspriem
4a2346fe93 Block compute when vectorDB migration is happening 2025-09-01 11:11:10 +05:30
laurenspriem
68b5cce158 Add option to block compute tasks (ml, streaming) 2025-09-01 11:09:51 +05:30
laurenspriem
e907a9e8cb comment 2025-09-01 10:59:02 +05:30
Manav Rathi
92a40afca2 [web] New translations (#7021)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-09-01 10:22:50 +05:30
Aman Raj Singh Mourya
0c2b38c059 Fixing dev build on macos (#7012)
This should fix this error
https://github.com/ente-io/ente/pull/6768#discussion_r2310164866
2025-09-01 09:26:51 +05:30
Crowdin Bot
19650bcd57 New Crowdin translations by GitHub Action 2025-09-01 01:05:33 +00:00
Crowdin Bot
2b9ca073ce New Crowdin translations by GitHub Action 2025-09-01 00:45:39 +00:00
Manav Rathi
2257087bb2 Fix file rename handling to match Go CLI behavior
- Add rename detection by tracking files via ID in metadata
- Remove old files (including live photo MOV components) when renamed
- Copy live photo MOV components during hash deduplication
- Preserve file deduplication optimization while handling renames correctly

This ensures that when a file is renamed in Ente, the old file is removed
and replaced with the renamed version, matching the Go CLI's behavior.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-31 21:56:14 +05:30
Manav Rathi
2a5bce2ae4 Fix live photo export to preserve original file extensions
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-31 10:36:25 +05:30
Manav Rathi
1e0a6eb1ea Add persistent storage for public magic metadata
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-31 09:28:00 +05:30
Manav Rathi
187a729013 Update CLAUDE.md documentation to reflect current codebase
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-31 09:10:50 +05:30
Manav Rathi
c98f4dfffd fix(rust): Match Go CLI email filtering behavior
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-31 07:39:59 +05:30
Manav Rathi
4140a0f6fe feat(rust): Add shared album decryption support
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-31 06:54:33 +05:30
Aman Raj Singh Mourya
cf4b87dad9 [locker] Refactor theme handling in Locker to fix DynamicFAB style (#7016)
## Description
DynamicFAB theme was not getting applied from the commons package. This
PR fix that issue.

## Tests

**Before**

<img width="300" height="750" alt="Simulator Screenshot - iPhone 16 Plus
- 2025-08-30 at 15 53 26"
src="https://github.com/user-attachments/assets/17dfc778-b652-4e10-ad8f-3c8aed2656f6"
/>


**After**

<img width="300" height="750" alt="Simulator Screenshot - iPhone 16 Plus
- 2025-08-30 at 15 52 58"
src="https://github.com/user-attachments/assets/9e0c2feb-8204-4875-9bad-f9d4eaab8f36"
/>
2025-08-30 16:01:01 +05:30
AmanRajSinghMourya
3fd0db6a90 Refactor theme handling in locker to fix DynamicFAB 2025-08-30 15:52:34 +05:30
AmanRajSinghMourya
a9d5773b9a Fix sync after leaving collection 2025-08-30 15:12:37 +05:30
Manav Rathi
ac68b99ecf Fix shared collection deserialization
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-30 10:53:44 +05:30
Manav Rathi
82e1a0e358 Fix hidden album filtering to match Go CLI
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-30 10:37:45 +05:30
Laurens Priem
ce1701d211 [mob][photos] Similar small fixes (#7008)
## Description

Small design changes and fixes.

## Tests

Tested in debug mode on my pixel phone.
2025-08-30 07:29:27 +05:30
Manav Rathi
034e789242 fix(rust): Validate account exists before update/delete
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 22:02:35 +05:30
Manav Rathi
ccfec4071f fix(rust): Match Go CLI JSON field naming for ID fields
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 21:51:34 +05:30
Manav Rathi
c4830732fd fix(rust): Format timestamps as ISO 8601 in metadata JSON
Changed metadata export to match Go CLI's timestamp format.
Timestamps now serialize as ISO 8601 strings with timezone offset
(e.g., "2025-07-23T19:48:06.098+05:30") instead of Unix microseconds.

Also fixed clippy warnings to ensure CI compliance.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 21:41:33 +05:30
Manav Rathi
72dc56e41f fix(rust): Correct album-based export to match Go CLI
Fixed export to properly organize files into album folders by:
- Fetching files from all collections using /collections/v2/diff endpoint
- Decrypting encrypted collection names to get actual album names
- Using decrypted album names for folder organization

Files now export to proper album folders instead of all going to
"Uncategorized". Tested and verified with local data.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 21:20:30 +05:30
AmanRajSinghMourya
8dd3ad9f5b Extract strings + minor fix 2025-08-29 20:23:46 +05:30
AmanRajSinghMourya
2ebb920faa Show leave collection options 2025-08-29 20:20:49 +05:30
AmanRajSinghMourya
e9f55b968a Refactor home page to manage collection file counts separately for main, outgoing, and incoming collections 2025-08-29 20:20:26 +05:30
AmanRajSinghMourya
5036a8da59 Add method to leave collection 2025-08-29 20:20:16 +05:30
Laurens Priem
aaed336991 [infra] Release action changes (#7010)
## Description

- Disk space cleanup
- Generate rust bindings
2025-08-29 20:05:31 +05:30
eYdr1en
0b85dfe7e4 fixing dev build on macos 2025-08-29 15:53:56 +02:00
Prateek Sunal
68422b172f [mob][photos] fix manual video streaming when ML is enabled (#7009) 2025-08-29 18:53:53 +05:30
laurenspriem
db99dae3e1 log line 2025-08-29 18:48:00 +05:30
laurenspriem
3717a156d3 Logging unexpected embeddings 2025-08-29 18:47:01 +05:30
Prateek Sunal
ca9930e01b style: fix import directive ordering in thumbnail_widget 2025-08-29 12:50:13 +00:00
laurenspriem
eb23a4e770 rust bindings 2025-08-29 18:19:50 +05:30
laurenspriem
e03303e5b3 release workflow disk cleanup 2025-08-29 18:18:45 +05:30
laurenspriem
2ad27f1c6e Clear similar images json cache 2025-08-29 18:03:27 +05:30
Prateek Sunal
202e6a9f7c fix: trigger processing for already-queued manual stream files
When users click "Create Stream" on files already in queue from
previous sessions, ensure processing actually starts even if the
file was previously stalled due to ML blocking.

Add forceProcess parameter to queueFiles() to bypass the existing
queue check and trigger processing of stalled manual queue items.
2025-08-29 12:28:48 +00:00
laurenspriem
ceaedad327 debug option to delete vectorDB index 2025-08-29 17:57:21 +05:30
Prateek Sunal
fd963a1c8e fix: allow manual video stream creation when ML is waiting
When ML is enabled but not running, the compute controller blocks
all stream requests due to _waitingToRunML flag. This prevents
users from manually creating video streams even though ML isn't
actively using resources.

Add bypassMLWaiting parameter to allow manual stream creation
to proceed regardless of ML waiting state, improving UX.
2025-08-29 12:22:08 +00:00
laurenspriem
b40b5bb1ae delete progress 2025-08-29 17:07:44 +05:30
laurenspriem
91827626b2 dot dot dot 2025-08-29 17:04:33 +05:30
laurenspriem
42318335ae Fix issue with deleting favorites 2025-08-29 16:16:51 +05:30
laurenspriem
858db62385 Left align large files 2025-08-29 16:09:10 +05:30
laurenspriem
46e36612d3 Scroll to top after delete 2025-08-29 15:49:09 +05:30
laurenspriem
62cf236e3b Cycle through loading screen texts 2025-08-29 15:27:11 +05:30
Ashil
c2b1ab86f2 [mob][photos] Fix incorrect file deletion from db when widget unmounts during thumbnail loading (#7007)
## Description

Previously, when _loadWithRetry returned null due to widget unmounting,
the code incorrectly assumed the local file was deleted and would remove
database reference of the file and which would trigger re-upload of the
file.
2025-08-29 15:17:55 +05:30
laurenspriem
43adf42281 Don't auto select favorites for deletions 2025-08-29 15:00:42 +05:30
laurenspriem
1e2a65281c Fix delete button bug 2025-08-29 14:32:12 +05:30
ashilkn
70eb68b13c Fix incorrect file deletion when widget unmounts during thumbnail loading
Previously, when _loadWithRetry returned null due to widget unmounting,
the code incorrectly assumed the local file was deleted and would remove
database references or delete the file. This could lead to data loss.

Changes:
- Add new WidgetUnmountedException to centralized exceptions.dart for reuse
- Throw WidgetUnmountedException instead of returning null when widget unmounts
- Handle WidgetUnmountedException separately in error handler with appropriate logging
- Still set _errorLoadingLocalThumbnail flag to prevent retry attempts

Using Exception instead of Error follows Dart conventions:
- Exceptions are for recoverable runtime conditions (like widget unmounting)
- Errors are for programming mistakes that shouldn't be caught

This ensures that widget unmounting is properly distinguished from actual
file access failures.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 14:17:49 +05:30
Ashil
fa86b19307 [mob][photos] Update internal change log (#7006) 2025-08-29 14:10:19 +05:30
Ashil
e632dc7771 Merge branch 'main' into update_int_change_log 2025-08-29 14:08:58 +05:30
ashilkn
7fa9adb636 update internal change log 2025-08-29 14:08:00 +05:30
Ashil
83f885f158 [mob][photos] Revert diskLoadDeferDuration to 500ms (#7005)
## Description
2025-08-29 13:58:58 +05:30
ashilkn
a295f223b6 Revert diskLoadDeferDuration to 500ms
Reverts the change from commit 1f1cad181f
which reduced galleryThumbnailDiskLoadDeferDuration from 500ms to 80ms.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 12:57:42 +05:30
AmanRajSinghMourya
6775faf0d0 Fix naming 2025-08-29 12:43:30 +05:30
Laurens Priem
cc64ef8035 [infra] Create more space for internal release action (#7004)
## Description

- Removed redundant SDKs
- Removed redundant rust install (already pre-installed)
- Delete old other action
2025-08-29 12:41:28 +05:30
Ashil
69dd7b6233 [mob][photos] Spacing (#7002)
## Description

Add spacing in similar images page.
2025-08-29 12:41:11 +05:30
AmanRajSinghMourya
367dc18caa Add sharing functionality for collections and update routing logic 2025-08-29 12:33:41 +05:30
AmanRajSinghMourya
0c6db4661e Refractor item_list_view.dart and split code into multiple file for better redability 2025-08-29 12:33:17 +05:30
Ashil
bcc9f1be73 [mob][photos] Revert cache extent changes (#7000)
## Description

The reverted changes were intended to solve the issue #6957 fixed. So
these changes are no longer needed and there are doubts if they are
causing regressions related to thumbnail loading.

## Tests
2025-08-29 12:26:29 +05:30
Ashil
296b2a2a6c Merge branch 'main' into revert-cache-extent-changes 2025-08-29 12:24:03 +05:30
laurenspriem
6b48c9bc34 Remove ineffective cleanup steps 2025-08-29 12:23:47 +05:30
ashilkn
6a951bcc72 Update internal change log 2025-08-29 12:23:28 +05:30
laurenspriem
38914981a1 Fix disk space calculation in cleanup step 2025-08-29 11:52:36 +05:30
laurenspriem
66f4d5b1a6 Add disk cleanup step to free space in GitHub Actions
Removes unused pre-installed software to free ~30-45GB:
- .NET SDK (~20-25GB)
- Haskell compiler (~5-8GB)
- Boost libraries (~1-2GB)
- Cached tool versions (~5-10GB)

Includes timing and space metrics for each removal

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 11:43:07 +05:30
laurenspriem
9ee3781320 spacing 2025-08-29 10:30:05 +05:30
laurenspriem
907d1d2bb8 delete rust install (already on runner env by default) 2025-08-29 10:27:46 +05:30
laurenspriem
8218283463 delete old action 2025-08-29 10:26:32 +05:30
Laurens Priem
bd43385949 [mob][photos] Similar index clear (#6997)
## Description

- Clear vectorDB index on logout
- Revert to using `view` on index
- Use `.usearch` for index file
- Minor design changes

## Tests

Tested in debug mode on my pixel phone.
2025-08-28 18:57:28 +05:30
Laurens Priem
2e6a9acaf9 Merge branch 'main' into similar_index_clear 2025-08-28 18:57:11 +05:30
Ashil
a02dcace7d [mob][photos] New Ducky launcher icons (#6999) 2025-08-28 18:56:34 +05:30
Laurens Priem
cf4285de6d Merge branch 'main' into similar_index_clear 2025-08-28 18:50:12 +05:30
laurenspriem
f831491e4a log changes 2025-08-28 18:30:29 +05:30
laurenspriem
af154d82de ducky analyzing riv animation 2025-08-28 18:17:11 +05:30
Prateek Sunal
ff2f75ea74 [mob][photos] bypass size/duration limits for manual video stream requests (#6998)
## Summary
- Modified `_checkFileForPreviewCreation` method to accept `isManual`
parameter
- Bypass 500MB file size and 60 second duration limits when user
manually triggers video stream processing
- Maintains size/duration restrictions for automatic streaming to
preserve device performance

## Test plan
- [x] Manual Create/Recreate Stream button bypasses 500MB and 60 second
limits
- [x] Automatic streaming still respects size and duration restrictions
- [x] Files larger than 500MB or longer than 60 seconds can be manually
processed
2025-08-28 17:51:26 +05:30
laurenspriem
97e3ef819a Change migration key because index file was changed (internal only) 2025-08-28 17:43:18 +05:30
Prateek Sunal
3685cd2154 fix: don't show create stream if file size is null 2025-08-28 17:34:29 +05:30
laurenspriem
c64fff8ca4 empty tab state ducky 2025-08-28 17:25:54 +05:30
ashilkn
23dc809589 Remove hardcoded cacheExtent to use Flutter's default value 2025-08-28 17:07:46 +05:30
laurenspriem
33d1242c6d strings 2025-08-28 17:03:53 +05:30
laurenspriem
b8ee9fafd1 Better confirmation dialog 2025-08-28 17:03:24 +05:30
ashilkn
f72c9fa068 Revert "Different cache extents for different photoGridSizes"
This reverts commit 769adb75c5.
2025-08-28 16:55:39 +05:30
Ashil
1a7275a101 Merge branch 'main' into ducky_icon 2025-08-28 16:17:58 +05:30
Prateek Sunal
fa7ccbd180 fix: if fileSize is null for manual way then skip 10MB check 2025-08-28 16:16:15 +05:30
ashilkn
79e26d6993 Update internal change log 2025-08-28 16:16:04 +05:30
ashilkn
023135afb5 Remove green background from ducky icon display
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-28 16:07:32 +05:30
Prateek Sunal
04aaa3a5e4 fix: bypass size/duration limits for manual video stream requests
Allow manual stream requests to bypass the 500MB file size and 60-second
duration limits by passing isManual parameter to _checkFileForPreviewCreation.
This ensures users can manually process large files even if they exceed the
automatic streaming limits.
2025-08-28 10:25:45 +00:00
laurenspriem
848857f409 same close related 2025-08-28 15:27:33 +05:30
ashilkn
137033be67 Update Android ducky launcher icon
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-28 15:23:51 +05:30
AmanRajSinghMourya
b6489f4c41 Add color for avatar 2025-08-28 15:17:53 +05:30
AmanRajSinghMourya
e7d7f1cdd0 Add user management features to sharing collection page and actions 2025-08-28 15:17:42 +05:30
AmanRajSinghMourya
bbbdd96c9e Add functionality for managing album participants and sharing settings 2025-08-28 15:17:12 +05:30
AmanRajSinghMourya
3c23d3b480 Extract strings 2025-08-28 15:16:45 +05:30
AmanRajSinghMourya
3805cddeba Add ListExtension and UserExtension for enhanced list and user functionalities 2025-08-28 15:16:29 +05:30
AmanRajSinghMourya
824c324342 Add MenuSectionDescriptionWidget and MenuSectionTitle components 2025-08-28 15:16:18 +05:30
laurenspriem
04b6f4a765 right threshold 2025-08-28 15:05:58 +05:30
laurenspriem
2645ba0949 Change index file name to use usearch 2025-08-28 13:13:16 +05:30
laurenspriem
5958647fa8 Delete vectorDB index file on logout 2025-08-28 13:11:05 +05:30
laurenspriem
b7b91631f6 revert back to view on index 2025-08-28 13:01:26 +05:30
Prateek Sunal
67d7f586b2 [mob][photos] bypass interaction check for manual stream requests (#6993)
## Summary
- Manual Create/Recreate Stream button presses now bypass user
interaction timer for immediate processing
- Fixed multiple concurrent streaming processes bug in ComputeController
- Fixed video streaming description text display spacing in advanced
settings
- Maintains device health and ML priority checks for all streaming
requests

## Tests
- [x] Manual Create/Recreate Stream button bypasses interaction timer  
- [x] Automatic streaming still respects interaction timer
- [x] Only one streaming process allowed at a time
2025-08-27 21:15:55 +05:30
Prateek Sunal
7c22a8bb25 chore: lint fix 2025-08-27 21:10:18 +05:30
Prateek Sunal
ff3864a09a fix: check only if permission granted before chunking 2025-08-27 21:09:10 +05:30
Prateek Sunal
4484b9e4ad update: add video streaming improvements to change logs
Co-authored-by: Claude <noreply@anthropic.com>
2025-08-27 13:21:59 +00:00
Prateek Sunal
e9554ffbcb fix: prevent multiple concurrent streaming processes
Remove condition allowing additional stream requests when already streaming to ensure only one stream process runs at a time.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-27 13:15:10 +00:00
Prateek Sunal
ad3901d484 fix: remove conditional clearQueue for manual processing
Co-authored-by: Claude <noreply@anthropic.com>
2025-08-27 13:08:12 +00:00
Prateek Sunal
ecca4c3dc8 feat: bypass interaction check for manual stream requests
Co-authored-by: Claude <noreply@anthropic.com>
2025-08-27 13:00:21 +00:00
Prateek Sunal
d05521f884 [mob][photos] video streaming description spacing and alignment (#6992)
## Summary
- Split videoStreamingDescription into separate line1/line2 localization
keys
- Remove TextAlign.justify from enabled state to fix awkward word
spacing
- Standardize text rendering between enabled and disabled states
- Both states now display description consistently without spacing
issues

## Test plan
- [x] Verify enabled state displays as single line without spacing
issues
- [x] Verify disabled state shows proper line breaks in onboarding
- [x] Confirm localization keys generate correctly
- [x] Run dart format and dart analyze (no issues)

Fixes video streaming settings page text display inconsistencies.
2025-08-27 18:08:28 +05:30
Prateek Sunal
ff37c4bf81 fix: video streaming description spacing and alignment
- Split videoStreamingDescription into separate line1/line2 localization keys
- Remove TextAlign.justify from enabled state to fix awkward word spacing
- Standardize text rendering between enabled and disabled states
- Both states now display description consistently without spacing issues

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-27 12:03:31 +00:00
ashilkn
446df755fa Add ducky icon for iOS
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-27 17:23:31 +05:30
Manav Rathi
0f5e30e96b feat(rust): Add metadata export matching Go CLI format
Export album and file metadata to .meta folders within each album directory.
Enables incremental sync and compatibility with Go CLI exports.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-27 17:22:17 +05:30
Manav Rathi
35ded7bc59 fix(rust): Match Go CLI's album-based export directory structure
Switch from date-based (YYYY/MM-Month) to album-based directory structure
to ensure compatibility with Go CLI. Files now export to AlbumName/ folders
with "Uncategorized" for files without albums.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-27 17:06:40 +05:30
ashilkn
a7805784b7 Add ducky icon for Android
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-27 17:01:09 +05:30
Manav Rathi
8e3f6e56d2 feat(rust): Remove sync command to match Go CLI interface
Align with Go CLI by integrating sync into export workflow.
Update CLAUDE.md to prevent default template usage in commits.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-27 16:51:04 +05:30
AmanRajSinghMourya
6ded21fe87 Add CollectionViewType enum and update CollectionPage 2025-08-27 14:35:11 +05:30
AmanRajSinghMourya
be4b521879 Extract strings 2025-08-27 14:32:34 +05:30
AmanRajSinghMourya
326eb3ff8a Add getPublicKey method to UserService for retrieving public keys by email 2025-08-27 13:49:01 +05:30
AmanRajSinghMourya
adef8bd466 Extract strings & add constants 2025-08-27 13:48:08 +05:30
AmanRajSinghMourya
a1d9fb5969 Add function to handle sharing actions 2025-08-27 13:46:58 +05:30
AmanRajSinghMourya
6da615b7dc Refactor ManageSharedLinkWidget to enable link expiry and device limit features with updated UI components 2025-08-27 13:45:56 +05:30
AmanRajSinghMourya
41a268b1cb Add crypto, bip39, dotted_border packages 2025-08-27 13:43:57 +05:30
AmanRajSinghMourya
ed07e64fa5 Add new UI components and dialogs for sharing features 2025-08-27 13:42:56 +05:30
Neeraj
84a5ad0b86 [mob][photos] More minor design changes for similar images (#6986)
## Description

- Change tab order
- Make tabs distinct
- Change default ordering to size

## Tests

Tested in debug mode on my pixel phone.
2025-08-27 13:25:40 +05:30
laurenspriem
44ad11343a Better empty state prompt for emtpy tab 2025-08-27 13:17:41 +05:30
laurenspriem
07e50e3cfe Change default sort to size 2025-08-27 13:03:30 +05:30
laurenspriem
df8bbdb788 Make identical and similar distinct 2025-08-27 13:01:56 +05:30
laurenspriem
1ed381fe52 Change order of tabs 2025-08-27 12:52:45 +05:30
ashilkn
55090436ce Add new ducky-icon assets 2025-08-27 11:21:36 +05:30
Manav Rathi
150534aa1a feat(rust): Add deduplication, live photos, and update docs
- Hash-based file deduplication prevents duplicate exports
- Live photo extraction from ZIP archives
- Update conversion status documenting feature completion
- Make commit guidelines prominent in CLAUDE.md
- Remove redundant commit format section

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-27 07:53:22 +05:30
Laurens Priem
ddd1d5ac86 [mob][photos] Similar images UX changes (#6981)
## Description

Similar images UX changes

## Tests

Tested in debug mode on my pixel phone.
2025-08-26 23:50:33 +05:30
Laurens Priem
26845a502e [mob][photos] Use load instead of view on index (#6980)
## Description

Use load instead of index
2025-08-26 23:48:59 +05:30
laurenspriem
21aac29020 format count properly 2025-08-26 23:48:31 +05:30
AmanRajSinghMourya
bdfe363066 Minor UI fix 2025-08-26 23:46:38 +05:30
laurenspriem
c1ff02df14 Always select all on tab change 2025-08-26 23:39:21 +05:30
laurenspriem
e4927c4022 Merge branch 'main' into similar_ux_changes 2025-08-26 23:30:32 +05:30
laurenspriem
4fd797338b Empty state 2025-08-26 23:26:51 +05:30
laurenspriem
eca0e5943d tab button look 2025-08-26 23:24:37 +05:30
laurenspriem
56cc7309a5 Show progress only for multiple albums symlinking 2025-08-26 23:05:04 +05:30
laurenspriem
b740d1af05 Show modal on 100+ deleted files only 2025-08-26 23:01:30 +05:30
laurenspriem
6d21b73367 faster select 2025-08-26 22:59:30 +05:30
laurenspriem
a5704eef25 Use load instead of view on index 2025-08-26 22:46:33 +05:30
laurenspriem
7e83682686 tiny margin in threshold 2025-08-26 22:42:04 +05:30
laurenspriem
18d5aa61b0 Extract string 2025-08-26 22:34:59 +05:30
laurenspriem
7c2a719ba8 (un)select all 2025-08-26 22:32:11 +05:30
Manav Rathi
2a136ba087 fix(rust): Fix file counting logic in sync and export commands
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 21:46:52 +05:30
laurenspriem
47313a74ff Tab bar filter 2025-08-26 21:28:21 +05:30
Manav Rathi
3abb479fbf feat(rust): Add progress indicators for downloads
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 21:26:39 +05:30
Manav Rathi
7eda60a493 fix(rust): Fix incremental sync to properly track per-collection timestamps
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 21:15:11 +05:30
Manav Rathi
bb8c5caa8d feat(rust): Handle renamed files using public magic metadata
Check both public magic metadata (for edited names) and regular metadata
when determining file names during export and sync, matching Go CLI behavior

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 21:00:11 +05:30
Prateek Sunal
65a7a16298 [mob][photos] fixes (#6979)
## Description

- [x] Fix Spacing in Video streaming settings
- [x] Update copy in Video Streaming settings
- [x] Disable debug notifications for work manager in iOS

## Tests
2025-08-26 20:57:02 +05:30
Prateek Sunal
9251e4f5b6 fix: update spacing and remove cross icon from top right 2025-08-26 19:07:44 +05:30
Prateek Sunal
c4bc6abf83 fix: remove debug mode notification flag 2025-08-26 19:07:27 +05:30
Manav Rathi
0384819c01 Take 2 2025-08-26 18:06:05 +05:30
Manav Rathi
f55973367d feat(rust): Add retry logic and export filters
- Add configurable retry with exponential backoff for API calls
- Handle 429 and 5xx errors with automatic retries
- Add export filters for albums, shared, and hidden collections
- Fix formatting and clippy warnings to pass CI checks

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 17:54:57 +05:30
laurenspriem
3165289483 Remove header 2025-08-26 17:48:39 +05:30
laurenspriem
01aab41c25 Select all by default 2025-08-26 17:46:53 +05:30
laurenspriem
1826258161 Copy 2025-08-26 17:43:58 +05:30
laurenspriem
df5917060b Copy change 2025-08-26 17:40:20 +05:30
Prateek Sunal
b5aa05cc1b [mob][photos] merge migration scripts (#6974)
## Description

Fixes #6923

## Tests
2025-08-26 17:16:10 +05:30
Prateek Sunal
cd865992f2 chore: directly use database 2025-08-26 17:02:21 +05:30
Prateek Sunal
370c0ab54a fix: merge migration scripts 2025-08-26 16:02:15 +05:30
Manav Rathi
699794226f fix(rust): Fix sync command file downloads
- Handle non-interactive mode in account add command
- Fix cross-filesystem file move issue by using copy+delete instead of rename
- Successfully tested downloading files from local server

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 16:00:15 +05:30
Manav Rathi
dee68acfc3 docs(rust): Reduce verbosity
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 15:31:06 +05:30
eYdr1en
0bd5452837 Merge remote-tracking branch 'upstream/main' into touch-id 2025-08-26 11:07:30 +02:00
Neeraj
923f2484fb [auth] Fix missing token (#6971)
## Description
When using Auth without backup, it was giving a error `Offline key is
missing`

**Reason**: During the `init` of `BaseConfiguration` if the `tokenKey`
is not set, we clear all the keys in the secure storage, and in this
process the `offlineAuthSecretKey` was also getting cleared

**Fix** Fixed by skipping the deletion of `offlineAuthSecretKey`  

## Tests
[Test Video](https://wormhole.app/qz3mol#Dlhr0NRpVQVQsrid2X-quA)
2025-08-26 13:02:43 +05:30
AmanRajSinghMourya
37928cd2c6 Code refractoring 2025-08-26 12:40:03 +05:30
AmanRajSinghMourya
fc32ba97c1 Refactor BaseConfiguration to ensure preserved keys are not deleted 2025-08-26 12:26:01 +05:30
AmanRajSinghMourya
e49084867e Revert "Refactor BaseConfiguration to preserve offlineAuthSecretKey during logout"
This reverts commit 5b5f563d47.
2025-08-26 12:21:00 +05:30
Manav Rathi
e53ddb8b51 refactor(rust): Remove backward compatibility code
Since the CLI hasn't been released yet, we don't need to maintain
backward compatibility. This commit removes unnecessary compatibility
code to simplify the codebase.

Changes:
- Remove id field from Account struct (use user_id directly)
- Remove update_file_local_path legacy wrapper method
- Use mark_file_synced directly instead of the wrapper
- Update all references from account.id to account.user_id

This results in cleaner, more maintainable code without unnecessary
compatibility layers.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 10:12:26 +05:30
Laurens Priem
a046748ded [mob][photos] Minor fixes and changes (#6969)
## Description

Minor fixes and changes based on testing.

## Tests

Tested in debug mode on my pixel phone.
2025-08-26 10:08:42 +05:30
laurenspriem
047d708ef1 Merge branch 'main' into fix_modal 2025-08-26 10:08:18 +05:30
Manav Rathi
95d167878e refactor(rust): Eliminate redundant primary keys using global uniqueness
Since user_id is globally unique in Ente's system (like collection_id and
file_id), we can eliminate artificial primary keys and use the actual IDs
directly. This simplifies the schema and reduces redundancy.

Changes:
- Use (user_id, app) composite primary key in accounts table
- Use (user_id, app) composite primary key in secrets table
- Remove account_id references, use user_id directly
- Update collections table to use owner field (user_id)
- Update files table to use owner_id field (user_id)
- Remove account_id from album_files table
- Update sync_state table to use (user_id, app) primary key
- Update all storage methods to use new schema
- Update commands to pass correct parameters to storage methods
- Update indices for better query performance

This aligns with Ente's API design where these IDs are guaranteed to be
globally unique, eliminating the need for artificial primary keys.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 10:04:24 +05:30
AmanRajSinghMourya
5b5f563d47 Refactor BaseConfiguration to preserve offlineAuthSecretKey during logout 2025-08-26 10:02:19 +05:30
Ashil
2b60ad3748 [mob][packages] Organize imports (#6968) 2025-08-26 10:01:40 +05:30
Neeraj
1f70043c83 [mob][photos] video streaming settings & create/recreate stream (#6923) 2025-08-26 10:00:08 +05:30
laurenspriem
7ce6f6a346 Check symlink permissions 2025-08-26 09:55:17 +05:30
Manav Rathi
653fc47aed fix(rust): Fix clippy warning for collapsible if statement
Collapsed nested if statement in sync.rs to satisfy clippy's
collapsible-if lint rule. This change is required for CI to pass
with the updated Rust version.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 09:43:21 +05:30
ashilkn
03814bff0c Organize imports 2025-08-26 09:34:00 +05:30
Manav Rathi
34325691e7 refactor(rust): Use collection_id and file_id as primary keys
Since collection_id and file_id are globally unique across all users in
Ente's API, we can use them directly as primary keys instead of creating
artificial auto-increment IDs. This simplifies the schema and reduces
redundancy.

Changes:
- Use collection_id as primary key in collections table
- Use file_id as primary key in files table
- Use composite primary key (album_id, file_id) in album_files table
- Update all related SQL queries to match new schema
- Add appropriate foreign key constraints
- Optimize indices for the new structure

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 09:30:05 +05:30
laurenspriem
4c63a0ff13 Copy changes 2025-08-26 09:21:59 +05:30
Manav Rathi
e474114e22 fix(rust): Fix clippy warnings and improve CI documentation
- Fix collapsible if statement warnings in sync.rs and files.rs
- Update CLAUDE.md with clearer CI requirements
- Remove misleading auto-fix command that doesn't catch all issues
- Emphasize that ALL checks must pass before committing

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 09:14:33 +05:30
laurenspriem
93552fb872 vectorDB flag check ML enabled 2025-08-26 09:05:06 +05:30
laurenspriem
1b61becdcf Fix modal on group-level delete 2025-08-26 08:37:16 +05:30
Manav Rathi
80c07d36a9 feat(rust): Complete sync command with file downloads
- Integrated DownloadManager with sync command for actual file downloads
- Implemented proper sync state tracking using is_synced_locally flag
- Fixed database persistence by preserving sync state during updates
- Added proper collection key decryption for file downloads
- Files are only downloaded once and marked as synced
- Cleaned up schema - removed migrations since this is new code
- Fixed deserialization issues with RemoteFile thumbnail field
- Added proper error handling for missing collection keys

The sync command now:
1. Fetches metadata for collections and files
2. Downloads files that haven't been synced yet
3. Marks files as synced to avoid re-downloading
4. Properly handles existing files on disk

This matches the Go CLI's approach of using a synced flag rather than
checking file existence on every sync.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 06:27:09 +05:30
Manav Rathi
8581742a73 feat(rust): Integrate DownloadManager with sync command
- Added local_path column to files table for tracking downloaded files
- Implemented get_pending_downloads() to find files without local_path
- Integrated DownloadManager into sync command for full file downloads
- Added collection key decryption for file downloads
- Generate proper export paths with date/album structure
- Track successful downloads and update database with local paths
- Added migration to add local_path column to existing databases

The sync command now supports full file downloads (not just metadata).
Files are downloaded to the export directory with proper organization.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 05:55:03 +05:30
Manav Rathi
042dae8790 fix(rust): Apply cargo fmt and clippy fixes
- Fixed formatting issues in sync/engine.rs
- Added #[allow(dead_code)] for unused storage field in DownloadManager
- Replaced manual clamp with .clamp() method

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 05:41:33 +05:30
Prateek Sunal
0499cad3c9 chore: ignore generated mocks file 2025-08-26 04:48:32 +05:30
Prateek Sunal
79752ef4b8 chore: update file name 2025-08-26 04:35:51 +05:30
Prateek Sunal
c1bd6d3fdb Merge branch 'taking-streaming-oob' of https://github.com/ente-io/ente into taking-streaming-oob 2025-08-26 04:35:30 +05:30
Prateek Sunal
621423d9a4 fix: refactor code 2025-08-26 04:35:27 +05:30
Prateek Sunal
edb11c89ba fix: update mobile/apps/photos/lib/ui/settings/streaming/video_streaming_settings_page.dart
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-26 04:31:44 +05:30
Prateek Sunal
adb71fe09c fix: update mobile/apps/photos/lib/services/video_preview_service.dart
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-26 04:31:12 +05:30
Prateek Sunal
c20cee2406 feat: state update event, tests, total logic 2025-08-26 04:27:38 +05:30
Prateek Sunal
dcfad86c47 fix: ensure preview ids are present 2025-08-25 23:32:57 +05:30
Prateek Sunal
0a2bff67bf fix: delete file from upload locks db if not found 2025-08-25 23:31:51 +05:30
Prateek Sunal
7aaa689cfb fix: simplify logic 2025-08-25 23:26:34 +05:30
Prateek Sunal
ad2a0ce897 refactor: simplify StreamingStatus handling in VideoPreviewService 2025-08-25 23:22:39 +05:30
Prateek Sunal
d99615b24f fix: remove skipped 2025-08-25 22:16:22 +05:30
Prateek Sunal
09cc48ae55 fix: add comments 2025-08-25 21:50:07 +05:30
Prateek Sunal
6ab2223a80 fix: mostly all review comments 2025-08-25 21:42:40 +05:30
Prateek Sunal
6fd86162e0 Merge remote-tracking branch 'origin/main' into taking-streaming-oob 2025-08-25 20:58:09 +05:30
Prateek Sunal
707e8dbfcf fix: show processing status, fix when to not show popup buttons, update getFiles logic 2025-08-25 20:57:18 +05:30
Prateek Sunal
5869bec781 feat: create and recreate stream buttons 2025-08-25 20:11:08 +05:30
laurenspriem
45249e0cdf add similar images entry 2025-08-25 18:24:02 +05:30
laurenspriem
ebfcedac7b update outdated 2025-08-25 18:22:32 +05:30
Laurens Priem
e311a8bb32 [mob][photos] Similar images UI (#6963)
## Description

Minor fixes and UI changes.

## Tests

Tested in debug mode on my pixel phone.
2025-08-25 16:55:29 +05:30
laurenspriem
547ccfceca Use shared preferences for tracking migration 2025-08-25 16:53:33 +05:30
AmanRajSinghMourya
2900ca55f5 Extract Strings + minor fix 2025-08-25 15:10:08 +05:30
AmanRajSinghMourya
2a40aa472e Add parameters to share URL request 2025-08-25 14:53:03 +05:30
Keerthana
3a1917949b [mobile/photos] New translations (#6955)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-app)
2025-08-25 13:30:03 +05:30
Keerthana
3a1ce3258e [auth] New translations (#6956)
New translations from
[Crowdin](https://crowdin.com/project/ente-authenticator-app)
2025-08-25 13:10:39 +05:30
Prateek Sunal
13b2542bea fix: update logic 2025-08-25 12:02:56 +05:30
Prateek Sunal
6db3741a3b Merge remote-tracking branch 'origin/main' into taking-streaming-oob 2025-08-25 11:48:49 +05:30
AmanRajSinghMourya
62cb67f3bf Minor UI improvements 2025-08-25 11:47:11 +05:30
AmanRajSinghMourya
e393b92a3d Add sharing functionality to CollectionPage 2025-08-25 11:46:51 +05:30
AmanRajSinghMourya
e06d65e8a0 Minor fix 2025-08-25 11:46:08 +05:30
AmanRajSinghMourya
a4ec8c939a Add ManageSharedLinkWidget and ShareCollectionPage for link management functionality 2025-08-25 11:45:59 +05:30
AmanRajSinghMourya
b8dd379306 Enhance AllCollectionsPage to support multiple collection view types 2025-08-25 11:44:49 +05:30
AmanRajSinghMourya
42229bd331 Refactor HomePage to integrate shared collections 2025-08-25 11:41:49 +05:30
AmanRajSinghMourya
ad9a3977a3 add helper method & cache collections for faster access 2025-08-25 11:35:16 +05:30
AmanRajSinghMourya
afb93df48f Add CollectionFlexGridViewWidget and SectionTitle components 2025-08-25 11:31:32 +05:30
AmanRajSinghMourya
4ce38ecea0 Added sharedCollections 2025-08-25 11:30:37 +05:30
AmanRajSinghMourya
4c63c8fc25 Add shareURL methods to CollectionApiClient 2025-08-25 11:30:09 +05:30
laurenspriem
ce17eccd68 Fix delete issue 2025-08-25 11:11:57 +05:30
Ashil
95dc683088 Update internal change log (#6959) 2025-08-25 11:11:28 +05:30
Neeraj
cf9d5f72f7 [mob] Fix query for duplicate cleanup (#6962)
## Description
Only consider owned files
## Tests
2025-08-25 11:10:36 +05:30
Neeraj Gupta
3096e1550a Merge remote-tracking branch 'origin/main' into fixQuery 2025-08-25 11:03:45 +05:30
Neeraj Gupta
1b39435735 Fix query 2025-08-25 11:02:25 +05:30
laurenspriem
8f3d8505bb Better UI when selection is not possible 2025-08-25 11:02:03 +05:30
Manav Rathi
47e8aafe25 [desktop] Update changelog (#6960) 2025-08-25 10:50:10 +05:30
Neeraj Gupta
bc6506cb10 Fix link for locker 2025-08-25 10:50:05 +05:30
Manav Rathi
edf32d065e [desktop] Update changelog 2025-08-25 10:47:43 +05:30
ashilkn
1fa6a0c3b9 Update internal change log 2025-08-25 10:41:16 +05:30
Neeraj Gupta
f2a26ba391 Minor refactor 2025-08-25 10:35:47 +05:30
Manav Rathi
2388989dd0 [web] Enable Czech (#6958) 2025-08-25 10:35:06 +05:30
laurenspriem
9e392277b1 Fix initState issue 2025-08-25 10:31:41 +05:30
Neeraj
4609c375db Revert "[auth] Add smaller Activision icon" (#6953)
Reverts ente-io/ente#6950

I rushed a bit, sorry. The PR wasn't meant to be merged yet (if ever)
and it won't work right now anyway. It was meant to create conversation
on the topic and then possibly merged and there may be concerns to this
as a company may not want their logo/wordmark altered but I'm not well
versed in this topic (idk maybe I'm overthinking this).

Discussion: #6951
2025-08-25 10:31:20 +05:30
Manav Rathi
839c62ea72 [web] Enable Czech 2025-08-25 10:28:23 +05:30
Neeraj
dceef49f33 [mob][photos] Pre-cache thumbnails fetched from LRU cache to Flutter's ImageCache for faster rendering (#6957)
## Description

In Gallery, even if thumbnails are stored in LRU cache, there was a
delay in rendering thumbnails when scrolling fast enough. Pre-caching
these thumbnails to flutter's `ImageCache` right before they're rendered
has made the rendering fast enough for seamless UX.

#### Before:


https://github.com/user-attachments/assets/c47958fb-fbda-4e1f-9ce7-26b51ca87938

#### After:


https://github.com/user-attachments/assets/cbaf4427-f52f-4544-a0c2-820eb2b43953
2025-08-25 10:18:05 +05:30
laurenspriem
acbdc3111a Remove use of withOpacity 2025-08-25 10:15:49 +05:30
laurenspriem
98b91a6935 Remove duplicate string 2025-08-25 10:11:07 +05:30
laurenspriem
e1640e67d4 Extract strings 2025-08-25 10:09:03 +05:30
laurenspriem
e875758419 Simplify sort options 2025-08-25 09:48:33 +05:30
Manav Rathi
214b120472 [web] New translations (#6954)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2025-08-25 09:43:37 +05:30
ashilkn
f139e0a098 Fix flickering of GalleryFileWidget on hero animation after closing it's open full view 2025-08-25 09:21:57 +05:30
laurenspriem
e3c9a61887 Align 2025-08-25 09:20:19 +05:30
ashilkn
0da3dc5084 Skip clearing flutter image cache since default (current) limit is 100MB and the threshold to clear is 250MB 2025-08-25 09:20:08 +05:30
ashilkn
a856a82249 Refactor 2025-08-25 09:18:29 +05:30
ashilkn
fbdec00a62 Improve lru cache thumbnail rendering speed when scrolling gallery by precaching it it flutter's image cache 2025-08-25 09:16:59 +05:30
Crowdin Bot
6a7f980a0d New Crowdin translations by GitHub Action 2025-08-25 01:18:00 +00:00
Crowdin Bot
10a855fe27 New Crowdin translations by GitHub Action 2025-08-25 01:05:02 +00:00
Crowdin Bot
b4f8a2b27c New Crowdin translations by GitHub Action 2025-08-25 00:39:57 +00:00
dnred
89489b4d7c Revert "[auth] Add smaller Activision icon" 2025-08-24 23:48:21 +02:00
AmanRajSinghMourya
158b48e4dc Add SharingNotPermittedForFreeAccountsError error 2025-08-24 23:58:22 +05:30
Aman Raj Singh Mourya
50296f8dfa [auth] Add smaller Activision icon (#6950)
## Description

The current Activision icon is too wide and small to be nicely displayed
in Auth so this PR adds a smaller one, just like the favicon on
Activision's [website](https://activision.com).

I know the Activision icon is pulled from simple-icons and I don't want
to get rid of that, just add an option for a smaller one, but I see that
the smaller Allegro icon is also added but it isn't displayed in the
icon picker and the icon from simple-icons takes precedence so you'd
have to figure this out.

## Tests

I haven't tested this.
2025-08-24 23:15:44 +05:30
dnred
f69cec864b Rename activision2.svg to activision.svg 2025-08-24 16:42:49 +02:00
dnred
73d5d33fc5 Update custom-icons.json 2025-08-24 16:25:47 +02:00
dnred
4d8ea12ddd Add logo 2025-08-24 16:17:25 +02:00
Prateek Sunal
7beb267ba7 chore: remove unused import 2025-08-24 02:15:09 +05:30
Prateek Sunal
7e13ef3537 chore: remove formatting for files_db 2025-08-24 02:10:06 +05:30
Prateek Sunal
47edca5bf5 chore: fix formatting 2025-08-24 02:08:00 +05:30
Prateek Sunal
925ba10b15 chore: revert remote_sync formatting 2025-08-24 02:06:28 +05:30
Prateek Sunal
db2d0bb7e9 fix: remove formatting from ml_service 2025-08-24 02:04:09 +05:30
Prateek Sunal
f3a2b2af0c fix: include it in if loop 2025-08-24 02:02:47 +05:30
Prateek Sunal
967e88f88d Merge remote-tracking branch 'origin/main' into taking-streaming-oob 2025-08-24 02:00:33 +05:30
Prateek Sunal
b44734a493 fix: add streaming static image 2025-08-24 01:59:23 +05:30
Manav Rathi
6478b08a19 [docs] Minor improvements to self-hosted docs (#6936)
## Description
- Small correction on the self-hosted docker exec command.
- Added tip on how to install Ente CLI.

In spirit of starting with a small PR :p
2025-08-23 21:54:47 +05:30
Laurens Priem
314e81565b Fix linter issues (#6939)
## Description

Linter was failing because it didn't first run
`flutter_rust_bridge_codegen generate` to generate the dart bindings to
rust code.
2025-08-23 20:34:02 +05:30
laurenspriem
f95e20d00f Consistent tap behaviour 2025-08-23 17:35:12 +05:30
laurenspriem
35a04d6e7e Don't unnecessarily sort 2025-08-23 17:34:53 +05:30
laurenspriem
403264d2c9 Fix linter issues 2025-08-23 17:20:22 +05:30
Manav Rathi
84f5a5ac3d feat(rust): Add sync command and fix database path
- Add new `sync` command to fetch collections and file metadata
- Change config directory from ~/.ente/ to ~/.config/ente-cli/ to avoid conflicts with Go CLI
- Fix sync engine to use correct API endpoints (/collections/v2/diff instead of /diff)
- Implement per-collection file syncing matching Go CLI behavior
- Fix foreign key constraints in database schema
- Add metadata-only and full sync options
- Store database path in Storage struct for creating new instances
- Successfully tested with real account: syncs 5 files and exports correctly

The sync command now properly fetches all collections and files from the API,
storing them in SQLite for offline access and incremental sync support.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 16:47:08 +05:30
Toby
6b06a4c388 Add instructions on how to install Ente CLI 2025-08-23 13:13:08 +02:00
Toby
678bce89b2 Add small corrections to docker commands 2025-08-23 13:06:34 +02:00
Manav Rathi
a00fc0b1be fix(rust): Remove sensitive information from logs and docs
Security improvements:
- Remove all debug logs that output tokens, keys, or credentials
- Remove email addresses from debug output
- Remove encrypted keys and nonces from logs
- Remove specific account references from documentation
- Add security guidelines to CLAUDE.md

No sensitive information (PII, credentials, tokens) should be logged
even in debug mode. Updated guidelines to prevent future occurrences.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 15:06:28 +05:30
Manav Rathi
f5347e7436 docs(rust): Update conversion plan with completed features
- Mark streaming XChaCha20-Poly1305 implementation as complete
- Document successful export functionality with all decryption working
- Update testing status with successful real account exports
- Add recent achievements section highlighting key milestones
- Update feature parity progress checklist
- Document what components are complete vs remaining

The export functionality is now fully working with proper decryption
of collections, files, and metadata. Updated PR description as well.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 14:26:09 +05:30
Manav Rathi
3f1d574d0c feat(rust): Add progress indicators to export
- Show progress for each exported file with count
- Improve export summary with emojis and better formatting
- Add contextual success messages based on export results
- Make export output more user-friendly

The export now provides clear feedback during the process and
a helpful summary at the end.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 14:14:59 +05:30
Manav Rathi
891b68c0f4 fix(rust): Add chunked decryption for large files
- Implement chunked streaming decryption matching Go's 4MB buffer size
- Update file decryption to use decrypt_file_data instead of decrypt_stream
- Successfully tested with 33MB RAW image file
- All test files now decrypt correctly

Large files are now properly handled with chunked decryption, preventing
memory issues and matching the Go implementation's behavior.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 14:12:06 +05:30
Manav Rathi
f050c6f9d7 feat(rust): Implement streaming XChaCha20-Poly1305 decryption
- Add streaming cipher module using libsodium's secretstream API
- Update file and metadata decryption to use streaming XChaCha20-Poly1305
- Fix decryption issues - files now properly decrypt
- Successfully tested with real account - exports working for smaller files

The export now correctly decrypts files using the same streaming cipher
as the Go implementation. Large files may need chunked decryption support.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 14:01:59 +05:30
Manav Rathi
2de67b619f feat(rust): Add metadata decryption for original filenames
- Create metadata module with FileMetadata struct
- Decrypt file metadata to extract original filename
- Use original filename in export path generation
- Add proper file type detection from metadata
- Implement filename sanitization for filesystem safety

Files are now exported with their original names instead of generic IDs.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 13:25:38 +05:30
Manav Rathi
828dde5ca7 feat(rust): Implement file decryption in export command
- Add ChaCha20-Poly1305 decryption for downloaded files
- Decrypt file keys using master key
- Extract nonce from encrypted file data
- Add basic filename generation with extension detection
- Comment out sync modules temporarily due to model mismatches

The export command now properly decrypts files instead of saving them encrypted.
Next steps: extract original filenames from decrypted metadata.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 13:03:46 +05:30
Manav Rathi
2526c69896 docs(rust): Update pre-commit checklist to match CI configuration
Ensure clippy commands use --all-targets --all-features flags to match
the CI environment exactly. This prevents CI failures from warnings that
weren't caught locally.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 12:09:42 +05:30
Laurens Priem
2f1d4b9f1a Update rust to solve bindings generation issue (#6935)
## Description

Update rust to potentially solve bindings generation issue
2025-08-23 10:44:27 +05:30
laurenspriem
af20eadff0 Update rust to solve bindings generation issue 2025-08-23 10:39:54 +05:30
Manav Rathi
6e64a2067f fix(rust): Resolve all clippy warnings for CI compliance
- Fix lifetime elision warnings in storage/mod.rs by adding explicit lifetimes
- Collapse nested if-let statements in export.rs using let-chains
- Code now passes: cargo clippy --all-targets --all-features

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 09:58:29 +05:30
Manav Rathi
ab4792518f docs(rust): Add mandatory pre-commit checklist to CLAUDE.md
Add explicit pre-commit commands that must be run before every commit
to ensure CI passes. These commands simulate the CI environment locally.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 09:29:28 +05:30
Manav Rathi
d4ae8d63fc fix(rust): Fix linting and formatting issues for CI
- Applied cargo fmt to ensure consistent formatting
- Fixed all clippy warnings (uninlined_format_args)
- Code now passes all CI checks with RUSTFLAGS="-D warnings"

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 09:01:56 +05:30
Prateek Sunal
3264ea046c [mob][photos] add named params for translations (#6932)
## Description

Parameters were sorted based on name by intl plugin which is a breaking
change.

We now have shifted to named params for translations so position won't
change.

## Tests
2025-08-22 22:50:07 +05:30
Manav Rathi
618753cb1a feat(rust): Implement export command with collection-based file fetching
- Fix token encoding to use base64 URL with padding (matching Go implementation)
- Add export command that iterates through collections and fetches files
- Update API models to handle actual server response field names (ownerID vs ownerId)
- Fix file download URLs for local/dev environments
- Implement proper directory structure creation (YYYY/MM-Month format)
- Add collection attributes and public URL models for complete API compatibility
- Successfully exports encrypted files from both local and production endpoints

The export command now:
- Fetches all collections for an account
- Iterates through each collection to get files
- Downloads encrypted files and saves them to the export directory
- Skips already downloaded files to support incremental exports

Note: Files are still encrypted; decryption will be implemented in a future commit.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 21:13:52 +05:30
Laurens Priem
d81a73c833 [mob][photos] Similar images various improvements (#6931)
## Description

- Put the rust generated bindings in gitignore
- Use `view` instead of `load` on VectorDB index to use less RAM
- Various UI changes

## Tests

Tested in debug mode on my pixel phone.
2025-08-22 21:12:00 +05:30
laurenspriem
ac9c63fe29 Log updates 2025-08-22 21:11:25 +05:30
laurenspriem
53cb217dbc Fix MediaQuery in initState issue (for large files view) 2025-08-22 21:06:59 +05:30
Manav Rathi
f84bd20bbf feat(rust): Store API endpoint per account for better environment isolation
- Add endpoint field to accounts database table with default to production API
- Update Account model to include endpoint field
- Add --endpoint flag to account add command only
- Remove ENTE_ENDPOINT environment variable support
- Update account list to display endpoints in readable format
- Each account now maintains its own endpoint, preventing confusion between test and production environments

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 20:25:39 +05:30
Prateek Sunal
fca9a42e0a fix: add named params for translations to fix position 2025-08-22 19:41:45 +05:30
Prateek Sunal
8b708228be fix: add different ui for enabling it 2025-08-22 19:04:16 +05:30
laurenspriem
d379262f56 Small animation 2025-08-22 18:57:37 +05:30
Manav Rathi
6ae7aa70d6 fix(rust): Fix FFI type cast and clippy warnings for CI
- Use std::ffi::c_char for libsodium FFI context parameter cast
- Fix all clippy warnings to pass CI with RUSTFLAGS="-D warnings"
- Update CLAUDE.md with FFI casting guidance for future development

This ensures the code passes all CI checks including the stricter
clippy settings used in GitHub Actions.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 18:49:24 +05:30
Manav Rathi
48757af5d0 fix(rust): Fix SRP authentication implementation
Fixed issues preventing successful authentication:
- Corrected Argon2 memory limit handling (API sends bytes, not KB)
- Replaced Blake2b with crypto_kdf_derive_from_key for login subkey derivation
- Fixed serde field names to match API expectations (srpUserID, sessionID)
- Added non-interactive mode for CLI testing
- Added support for ENTE_ENDPOINT environment variable

The implementation now matches the web client's key derivation exactly,
enabling successful authentication with both local and production servers.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 18:23:16 +05:30
laurenspriem
9282632af1 Exclude dart linter checks for rust 2025-08-22 18:14:13 +05:30
laurenspriem
6a43d6a567 Generate rust bindings on internal release 2025-08-22 18:11:53 +05:30
laurenspriem
1cdbef1a01 More fancy loading 2025-08-22 15:12:12 +05:30
laurenspriem
fa84bb0845 Delete progress indicator 2025-08-22 14:33:19 +05:30
Manav Rathi
cd20a98850 feat(rust): Implement account management commands
Add comprehensive account management functionality with secure SRP authentication.
This enables users to add, list, update, and manage multiple Ente accounts
for photos, locker, and auth apps.

Key features:
- Complete account add flow with SRP authentication
- Two-factor authentication support (TOTP)
- Secure key decryption and storage
- Multi-account support with per-app configuration
- Account list and update commands
- Export directory management
- Interactive CLI prompts with dialoguer

The implementation integrates with the API client for authentication and
securely stores account credentials in SQLite.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 13:57:29 +05:30
laurenspriem
cbb6f07d0d Improve empty state 2025-08-22 12:38:37 +05:30
Manav Rathi
9ac9e6bd26 feat(rust): Implement comprehensive API client for Ente services
Add complete API client implementation with authentication, file operations,
and collection management. This enables the Rust CLI to interact with Ente
servers for photo backup and sync operations.

Key features:
- Multi-account token management with secure storage
- SRP authentication flow matching Go implementation
- Retry logic with exponential backoff for network resilience
- Full API coverage: auth, collections, files, trash, user details
- Request/response models for all API endpoints
- Separate download client for large file transfers
- Smart CDN routing for production file downloads

The implementation follows the conversion plan and maintains compatibility
with the existing Go CLI API patterns.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 12:14:05 +05:30
laurenspriem
fad9cf8559 Add rust bindings generation to readme 2025-08-22 11:57:45 +05:30
laurenspriem
371ba9c552 Put generated rust bindings in gitignore 2025-08-22 11:54:59 +05:30
laurenspriem
19086e43cc Remove generated rust bindings 2025-08-22 11:54:24 +05:30
laurenspriem
964c837c40 Remove scrollbar 2025-08-22 11:36:48 +05:30
laurenspriem
d85121862d Use view of index instead of loading in memory 2025-08-22 11:34:40 +05:30
Manav Rathi
0b640c9062 docs(rust): Enhance CLAUDE.md with comprehensive codebase guidance
Add detailed development commands, architecture overview, and module
descriptions to help future Claude instances understand the codebase
structure and development workflow.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 10:38:57 +05:30
Manav Rathi
2d87aba165 docs(rust): Add comprehensive conversion plan
- Document current implementation status
- Detail API client implementation steps
- List all remaining components with specifications
- Include testing strategy and migration notes
- Provide file structure reference for navigation
- Add implementation guidelines and environment variables

This plan enables any developer to understand the project state
and continue the conversion work from the current point.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 10:03:01 +05:30
Manav Rathi
7dffdfaecf feat(rust): Implement SQLite storage layer
- Replace sled with SQLite for better reliability and tooling
- Create schema with tables for accounts, secrets, collections, files, and sync state
- Implement account storage with multi-account support
- Add configuration and sync state management
- Support for storing encrypted credentials separately
- Add indices for performance optimization

SQLite provides ACID transactions, better debugging tools, and a proven
track record for reliability with user data.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 09:50:59 +05:30
Manav Rathi
a4da7b5555 main safeguard 2025-08-22 09:26:55 +05:30
Prateek Sunal
42d31a73a3 fix: update localization & fix lint 2025-08-21 23:32:45 +05:30
Prateek Sunal
946d2ae522 fix: remove unnecessary blank line in analysis_options.yaml + circular button 2025-08-21 22:51:01 +05:30
Prateek Sunal
8e9eb50783 fix: downgrade Dart SDK version to 3.7.2 2025-08-21 22:50:24 +05:30
Prateek Sunal
af3bc7757f fix: downgrade dart sdk again 2025-08-21 22:50:04 +05:30
Prateek Sunal
eda1d05216 fix: revert dart sdk 2025-08-21 22:49:49 +05:30
Prateek Sunal
b58e0f8331 fix: remove analysis options for now 2025-08-21 22:49:37 +05:30
Prateek Sunal
6dcf53650d fix: re-add captioned text 2025-08-21 22:48:42 +05:30
Prateek Sunal
bff53d9081 chore: add back space 2025-08-21 22:47:42 +05:30
Prateek Sunal
f3306e14c7 fix: revert 2025-08-21 22:47:30 +05:30
Prateek Sunal
b5c075bac4 fix: add space at end 2025-08-21 22:45:38 +05:30
Prateek Sunal
241d21c2aa fix: revert things 2025-08-21 22:44:34 +05:30
Prateek Sunal
789d77747c fix: update other contact page 2025-08-21 22:35:24 +05:30
Prateek Sunal
35050aa32f fix: delete generated intl_utils locale 2025-08-21 22:33:23 +05:30
Prateek Sunal
40e6bd9fae Merge remote-tracking branch 'origin/main' into taking-streaming-oob 2025-08-21 22:32:41 +05:30
Prateek Sunal
9fe15d7ff0 [mob][photos] remove generated locals (#6925)
## Description

We depended on intl_utils but that had problems + it was not
auto-generating things when running `flutter pub get`

Now we are using pure intl implementation of l10n, by which generated
code would be less.

- [x] Removes generated locals

## Tests
2025-08-21 22:27:09 +05:30
Prateek Sunal
28a2afe275 Merge remote-tracking branch 'origin/main' into remove-intl_utils 2025-08-21 22:26:54 +05:30
Aman Raj Singh Mourya
c072097c11 Add custom icons (#6924)
## Description
Adds custom SVG icons for "CoinTracing", "VHV Versicherungen (German
Insurance Company)" and "HR Document Box".
SVG sourced from official CoinTracking press assets.
SVG sourced from Wikipedia for VHV Versicherungen.
For HR Document Box was no svg available, so i used a png to svg
converter.

## Tests
2025-08-21 19:27:57 +05:30
Prateek Sunal
b317df2000 Merge branch 'main' into taking-streaming-oob 2025-08-21 18:11:42 +05:30
Prateek Sunal
dd420a80a4 Merge remote-tracking branch 'origin/main' into remove-intl_utils 2025-08-21 18:08:31 +05:30
Prateek Sunal
3dc0620e18 chore: update flutter again for auth 2025-08-21 18:04:29 +05:30
Prateek Sunal
173d075f8b feat: remove generated locals 2025-08-21 18:04:20 +05:30
Daniel
48283282e5 Merge branch 'ente-io:main' into main 2025-08-21 14:30:49 +02:00
Laurens Priem
fa555c448f [mob][photos] Various similar images improvements (#6922)
## Description

Various improvements for similar images, mainly caching and UI changes.

## Tests

Tested in debug mode on my pixel phone.
2025-08-21 17:59:13 +05:30
laurenspriem
6f6770d677 Selection options 2025-08-21 17:58:43 +05:30
Daniel
0b894e9724 Update custom-icons.json 2025-08-21 14:21:02 +02:00
Daniel
0670550cb1 Add files via upload 2025-08-21 14:18:48 +02:00
Daniel
45783cf527 Update custom-icons.json 2025-08-21 14:07:32 +02:00
Daniel
1615779eb8 Add files via upload 2025-08-21 14:05:48 +02:00
Daniel
02e4c9d8fd Add files via upload 2025-08-21 14:00:23 +02:00
Prateek Sunal
2e706228ee feat: separate settings page improvements 2025-08-21 17:22:57 +05:30
Daniel
6eab6457ee Update custom-icons.json 2025-08-21 13:34:14 +02:00
Daniel
25490a7238 Add files via upload 2025-08-21 13:30:49 +02:00
Manav Rathi
85b766b5d0 Safeguard 2025-08-21 16:31:35 +05:30
Manav Rathi
62f715d3c1 fix(rust): Use std::ffi::c_char for FFI type casting
- Replace libc::c_char with std::ffi::c_char for password parameter
- Remove unnecessary libc dependency
- Use standard library FFI types (available since Rust 1.64)

This fixes the CI build error where libsodium expects *const c_char
for the password parameter in crypto_pwhash.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-21 16:27:50 +05:30
Neeraj
f519ff8a51 [auth] Option to scan image using native plugin (#6920)
## Description

## Tests
Tested on physical device (android and ios)
2025-08-21 16:20:45 +05:30
Neeraj Gupta
afebe1ade1 Clean up 2025-08-21 16:15:44 +05:30
laurenspriem
3862644dd5 Show info at top 2025-08-21 16:07:52 +05:30
Neeraj Gupta
274a7d207d Improve scanning 2025-08-21 15:59:53 +05:30
laurenspriem
add2f0c8de Debug option for full refresh 2025-08-21 15:34:05 +05:30
Neeraj Gupta
8e807616e0 Bump version 2025-08-21 15:29:08 +05:30
laurenspriem
70f4325c71 Refresh for small size 2025-08-21 15:18:05 +05:30
Neeraj Gupta
38ea2248b8 Show option on mobile only 2025-08-21 15:16:21 +05:30
laurenspriem
9600b26359 More stable sort 2025-08-21 15:10:40 +05:30
Neeraj Gupta
5b3e996aaa Option to scan image using native plugin 2025-08-21 15:08:11 +05:30
laurenspriem
4d4cce091f Fix json decoding issue 2025-08-21 14:13:49 +05:30
Neeraj
aaca140d1b [mobile] Use same lint rule file (#6917)
## Description
Had verified that hash for these rules were same.
## Tests
2025-08-21 14:06:37 +05:30
Neeraj Gupta
596ffcd4c4 [mobile] Use same lint rule file 2025-08-21 14:04:04 +05:30
laurenspriem
41ef85a294 Add scroll bars 2025-08-21 13:08:51 +05:30
Neeraj
f722d82835 [server]: add one click verify button for verification email (#5654)
OG (ott.html):

<img width="701" height="590" alt="image"
src="https://github.com/user-attachments/assets/80b926d1-c65f-44a8-9de4-7b591258bf3c"
/>



New (ott_mobile.html):

<img width="642" height="811" alt="image"
src="https://github.com/user-attachments/assets/aa18a778-1161-4b4e-ad82-cf472da06ff7"
/>
2025-08-21 12:44:24 +05:30
Neeraj Gupta
cbb3096534 use mobile ott template for only photos 2025-08-21 12:41:56 +05:30
Manav Rathi
e35ae86fa5 Ask it to run cargo fmt etc
For the current session cc was able to use that instruction to figure out all the linters etc to run. If that doesn't work in future sessions, we can use a longer instruction, something like what it itself suggested

    ## CI/CD Requirements
    - Must pass `cargo fmt --check`
    - Must pass `cargo clippy --all-targets --all-features`
    - Must pass `RUSTFLAGS="-D warnings" cargo build`
    - Fix all formatting before committing
    - Address all clippy warnings
    - Use `#![allow(dead_code)]` during development for unused code

    ## Code Quality
    - Run `cargo fmt` before committing
    - Fix clippy warnings: remove unnecessary casts, use idiomatic Rust
    - Prefix unused variables with underscore
    - Remove unused imports
2025-08-21 12:33:14 +05:30
Manav Rathi
ea843eba7a fix(rust): Address cargo fmt and clippy warnings
- Fix code formatting with cargo fmt
- Remove unnecessary type casts
- Use range contains instead of manual comparison
- Prefix unused variables with underscore
- Remove unused imports
- Add allow(dead_code) for development phase

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-21 12:24:04 +05:30
laurenspriem
f635e1e856 Merge branch 'main' into smart_dedupe 2025-08-21 12:22:29 +05:30
laurenspriem
c6734a5cb7 More logging 2025-08-21 12:15:37 +05:30
laurenspriem
e26b4796d3 Match to closest group 2025-08-21 12:04:31 +05:30
laurenspriem
99c0194c0f Check cache parameters 2025-08-21 11:54:10 +05:30
laurenspriem
e824c02d7f Fix bug 2025-08-21 11:45:08 +05:30
laurenspriem
a11f66b51d Caching and partial compute logic for similar files calculation 2025-08-21 11:35:42 +05:30
laurenspriem
f202fef266 JSON caching of similar files 2025-08-21 11:35:12 +05:30
Neeraj
ff8cfd3e87 [auth] Additional import option (#6916)
## Description

## Tests
2025-08-21 11:22:04 +05:30
Neeraj Gupta
431ab7fcc7 [auth] Additional import option 2025-08-21 11:11:48 +05:30
Manav Rathi
b845f4d893 Keep co-author but remove the self promo link
Typical Claude Code commit message:
feat: implement user authentication

- Added login endpoint
- Implemented JWT tokens
- Created middleware

Created with Claude Code: https://claude.ai/code  # <-- The promotional link
Co-authored-by: Claude <claude@anthropic.com>      # <-- The co-author line

This memory is to ask claude to keep the co-author line but remove the self promo from the commit message it creates.
2025-08-21 06:51:22 +05:30
Manav Rathi
8ea36acb7a feat(rust): Initialize Rust CLI foundation with libsodium crypto
- Set up project structure mirroring Go CLI architecture
- Add dependencies with libsodium-sys-stable for all crypto operations
- Implement core crypto module with Argon2, ChaCha20-Poly1305, and Blake2b
- Create data models for accounts, files, and collections
- Set up Clap-based CLI framework with account, export, and version commands
- Add error handling with thiserror
- Configure for static linking to create standalone binaries

This establishes the foundation for converting the Ente CLI from Go to Rust,
with a focus on maintaining compatibility with existing libsodium-based crypto.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-21 06:50:23 +05:30
Ashil
2ac1d58dac [mob][photos] Fix jank when scrolling gallery when lot of selected items are in view (#6913)
## Description

Using `ColorFiltered` with `Blendmode.darken` introduces a performance
[issue](https://github.com/flutter/flutter/issues/174118) with flutter's
new rendering engine Impeller.

The fix uses an alternative method to that maintains the same UI
appearance as before.
2025-08-20 19:09:46 +05:30
ashilkn
5533e6a71d Fix performance issue (jank) when scrolling gallery when lot of selected items in view
This was only bad enough to be noticed on one device (Samsung A54) out of few
2025-08-20 18:46:32 +05:30
laurenspriem
a8ae0727a8 Fix potential duplicates 2025-08-20 18:24:21 +05:30
Aman Raj Singh Mourya
6955788724 Add custom icon for Mobile01 (#6908)
Custom icon for [Mobile01](https://www.mobile01.com/)

- Add optimised SVG file
- Add entry to custom-icons.json
2025-08-20 15:49:42 +05:30
Neeraj Gupta
f6dd35f5e7 Update templates 2025-08-20 15:11:28 +05:30
Neeraj Gupta
9148916d88 Merge remote-tracking branch 'origin/main' into ott_email_one_click 2025-08-20 15:02:57 +05:30
Neeraj
68545f8947 [auth] add import from gallery using zxing2 (#6909)
This pr implements the feature to add a 2FA account by importing a QR
code image from the device gallery..
Adds a new "Import from gallery" button to the Floating Action Button
menu.

The button's text is localized, and its styling is consistent with the
app's theme.

How to Test:

    Open the FAB menu and tap "Import from gallery".
    
1) Test with a valid 2FA QR code image. Expected: The account gets added
successfully.
2) Test with an image that has no QR code. Expected: A "No QR code
found" toast message appears.
3) Test with a QR code of plain text (like "hello "). Expected: An
"Invalid QR Code" dialog appears.
2025-08-20 14:44:02 +05:30
Prateek Sunal
fe40185889 fix: redirect video streaming to setting page 2025-08-20 14:43:54 +05:30
Prateek Sunal
6bb4428a8a chore: update generated translations 2025-08-20 14:41:57 +05:30
Neeraj
76c5c12c53 [mobile] Setup melos (#6907)
## Description

```
dart pub global activate melos
```
Run following command to get all dependencies for projects
```
melos bootstrap
```


## Tests
2025-08-20 14:36:10 +05:30
Prateek Sunal
0881685915 feat: add video streaming settings page 2025-08-20 14:34:16 +05:30
Prateek Sunal
3e13932d03 chore: format files and update analysis file 2025-08-20 14:33:35 +05:30
Dxball ☕
8d749a2dc8 Add custom icon fo Mobile01 2025-08-20 09:01:14 +00:00
a5xwin
56af818482 add qr code scanning from gallery using zxing2 2025-08-20 14:28:41 +05:30
Neeraj
fc1096c985 [mob] Include mobile flag during ott (#6906)
## Description
Need this to identify which OTT template to send from backend.
Ref: https://github.com/ente-io/ente/pull/5654
## Tests
2025-08-20 14:25:22 +05:30
Neeraj Gupta
88260a05e3 Setup melos 2025-08-20 14:14:35 +05:30
Neeraj Gupta
4b5f91a428 [mob] Send ismobile flag 2025-08-20 13:14:59 +05:30
Neeraj
29b12fc6b5 [docs] Lint (#6905)
## Description

## Tests
2025-08-20 11:01:44 +05:30
Neeraj Gupta
c3eec71d60 [docs] Lint 2025-08-20 11:01:25 +05:30
Neeraj
2fccdee0d6 [server] Add optional TLS/SSL encryption for SMTP (#6863)
## Description

Implement TLS/SSL encryption for sending emails via SMTP. When an SMTP
provider explicitly requires TLS/SSL communication the current
implementation runs in a timeout and fails. A new configuration
parameter for smtp was added to enable TLS/SSL communication.

This would solve #5958 

## Tests

I built a local docker image of my branch. The email provider I was
using is mailbox.org and using the tls configuration. Registering a new
user then resulted in a sent email containing the verification code.

I did not test a setup without TLS/SSL.
2025-08-20 11:00:36 +05:30
Neeraj
8f053e7a7b [m][photos] Fix for duplicate entries for local file (#6904)
## Description

## Tests
2025-08-20 10:42:41 +05:30
Neeraj
de7291f5d4 [mobile][photos] don't show lock screen on deep link (#6899)
## Description

Fixes the clicking on widget behavior

## Tests
2025-08-20 10:06:06 +05:30
Neeraj Gupta
e09c952198 Fix for duplicate enteries for file 2025-08-20 10:01:51 +05:30
laurenspriem
28a842b006 Show size 2025-08-20 09:51:27 +05:30
laurenspriem
19eb342f59 Move internal things to debug mode only 2025-08-20 09:47:36 +05:30
laurenspriem
2b82c79be9 Merge branch 'main' into smart_dedupe 2025-08-20 09:13:43 +05:30
Prateek Sunal
86a9dee49d fix: add note, revert old code, remove default redirect 2025-08-20 00:25:33 +05:30
Vishnu Mohandas
33b1a7e4f8 [mob] Remove generated code (#6901) 2025-08-19 20:22:51 +05:30
vishnukvmd
de783e91dc Ignore build 2025-08-19 20:22:22 +05:30
vishnukvmd
554c8f4b7a Remove noise 2025-08-19 20:22:11 +05:30
Vishnu Mohandas
f438142646 [locker] Icon (#6900) 2025-08-19 19:00:07 +05:30
vishnukvmd
aa6c010562 Update Android icon 2025-08-19 18:59:33 +05:30
vishnukvmd
2830c89bde Set icons 2025-08-19 18:58:21 +05:30
Prateek Sunal
4de530b882 fix: don't show lock sreen if not required 2025-08-19 18:27:33 +05:30
Vishnu Mohandas
62d7c87dc7 [locker] Update deps (#6898) 2025-08-19 18:23:51 +05:30
vishnukvmd
3a1b6dbf15 [locker] Update deps 2025-08-19 18:23:19 +05:30
laurenspriem
58182cc8ab Remove slider interface in release 2025-08-19 17:11:12 +05:30
Laurens Priem
5e0bba390b [mob][photos] Decoded image minor refactor (#6897)
## Description

Minor refactor (no functional change) in the way we're decoding and
returning images for indexing.
2025-08-19 16:42:24 +05:30
Vishnu Mohandas
df6a3b94db [mobile][locker] Add Drawer & Setting section in locker (#6895) 2025-08-19 15:35:41 +05:30
AmanRajSinghMourya
72b7e12768 Merge branch 'main' into drawer 2025-08-19 15:24:29 +05:30
AmanRajSinghMourya
3a7d82a799 Add setting section 2025-08-19 14:58:15 +05:30
Neeraj
5f1cfb9ba5 [server] Fail request on customDomain mismatch (#6893)
## Description

## Tests
2025-08-19 14:23:00 +05:30
Neeraj Gupta
298e3695c7 [server] Fail request on customDomain mismatch 2025-08-19 12:34:31 +05:30
Vishnu Mohandas
621713d0b4 [mob] Remove unused import (#6892) 2025-08-19 12:33:15 +05:30
vishnukvmd
34813d2fae [mob] Remove unused import 2025-08-19 12:32:58 +05:30
laurenspriem
bb177bc3f6 Merge branch 'main' into smart_dedupe 2025-08-19 11:47:19 +05:30
Vishnu Mohandas
d8e4418d78 Remove ignore (#6890) 2025-08-19 11:43:36 +05:30
vishnukvmd
9771a5bc5d Remove ignore 2025-08-19 11:41:44 +05:30
laurenspriem
65f7e3f6c6 Exclude rust_builder in linter 2025-08-19 11:39:03 +05:30
Neeraj
aa4207f878 [auth] New translations (#6877)
New translations from
[Crowdin](https://crowdin.com/project/ente-authenticator-app)
2025-08-19 10:13:12 +05:30
laurenspriem
37c1d0f6a8 Unify UI 2025-08-18 18:23:14 +05:30
laurenspriem
be1bf28cd8 Add cacheExtend for smoother scroll 2025-08-18 17:25:44 +05:30
laurenspriem
cad8613e81 Remove "select extra" button 2025-08-18 10:28:57 +05:30
laurenspriem
b46e51f64d Prefer smaller names 2025-08-18 10:25:06 +05:30
laurenspriem
e6bf64548c Use cached files 2025-08-18 10:21:28 +05:30
laurenspriem
5729e0cf3e no shared or hidden files 2025-08-18 10:11:04 +05:30
laurenspriem
b353539328 Sort by highest size first 2025-08-18 09:54:31 +05:30
Crowdin Bot
f2049ac7fa New Crowdin translations by GitHub Action 2025-08-18 01:18:04 +00:00
Kilian Hohm
cf938eca91 Add CLI command to send a test email via admin API 2025-08-16 10:33:23 +02:00
Kilian Hohm
a3d3ee24f8 Document optional TLS/SSL encryption for sending emails via SMTP 2025-08-15 15:48:59 +02:00
Kilian Hohm
6b37cc46a5 Add optional TLS/SSL encryption for sending emails via SMTP 2025-08-15 15:48:41 +02:00
laurenspriem
ad39694026 report changes at correct place 2025-08-14 19:06:03 +05:30
eYdr1en
279df8ff57 fixes lint error 2025-08-13 12:52:13 +02:00
Adrián Horváth
d83994c692 Update mobile/apps/auth/lib/ui/tools/lock_screen.dart
Co-authored-by: Prateek Sunal <prtksunal@gmail.com>
2025-08-13 12:37:11 +02:00
eYdr1en
be506bdad1 fixes macos touch id lock 2025-08-08 17:22:12 +02:00
anandbaburajan
1752192688 [email]: different ott templates for with and without verify btn 2025-06-09 19:21:49 +05:30
anandbaburajan
873ee3ac14 [email]: different views for mobile and desktop 2025-04-18 16:54:21 +05:30
anandbaburajan
cfce2d00f5 [email]: add one click verify button for verification email 2025-04-18 13:45:04 +05:30
966 changed files with 61592 additions and 74797 deletions

View File

@@ -8,7 +8,7 @@ on:
env:
FLUTTER_VERSION: "3.32.8"
RUST_VERSION: "1.85.1"
RUST_VERSION: "1.86.0"
permissions:
contents: read
@@ -27,6 +27,38 @@ jobs:
with:
submodules: recursive
- name: Free up disk space
run: |
echo "Initial disk usage:"
df -h /
# Get available space in KB
INITIAL=$(df / | awk 'NR==2 {print $4}')
echo -e "\n=== Removing .NET SDK (~20-25GB) ==="
BEFORE=$(df / | awk 'NR==2 {print $4}')
START=$(date +%s)
sudo rm -rf /usr/share/dotnet
END=$(date +%s)
AFTER=$(df / | awk 'NR==2 {print $4}')
FREED=$(( (AFTER - BEFORE) / 1048576 )) # Convert KB to GB
echo "Time: $((END-START))s | Freed: ${FREED}GB"
echo -e "\n=== Removing cached tools (~5-10GB) ==="
BEFORE=$(df / | awk 'NR==2 {print $4}')
START=$(date +%s)
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
END=$(date +%s)
AFTER=$(df / | awk 'NR==2 {print $4}')
FREED=$(( (AFTER - BEFORE) / 1048576 ))
echo "Time: $((END-START))s | Freed: ${FREED}GB"
echo -e "\n=== Final Summary ==="
FINAL=$(df / | awk 'NR==2 {print $4}')
TOTAL_FREED=$(( (FINAL - INITIAL) / 1048576 ))
echo "Total space freed: ${TOTAL_FREED}GB"
echo "Final disk usage:"
df -h /
- name: Setup JDK 17
uses: actions/setup-java@v1
with:
@@ -39,14 +71,12 @@ jobs:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Install Rust ${{ env.RUST_VERSION }}
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.RUST_VERSION }}
- name: Install Flutter Rust Bridge
run: cargo install flutter_rust_bridge_codegen
- name: Generate Rust bindings
run: flutter_rust_bridge_codegen generate
- name: Increment version code for build
run: |
CURRENT_VERSION=$(grep '^version:' pubspec.yaml | sed 's/version: //')

View File

@@ -1,77 +0,0 @@
name: "Old Internal release (photos)"
on:
workflow_dispatch: # Allow manually running the action
env:
FLUTTER_VERSION: "3.32.8"
RUST_VERSION: "1.85.1"
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: mobile/apps/photos
steps:
- name: Checkout code and submodules
uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup JDK 17
uses: actions/setup-java@v1
with:
java-version: 17
- name: Install Flutter ${{ env.FLUTTER_VERSION }}
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Install Rust ${{ env.RUST_VERSION }}
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.RUST_VERSION }}
- name: Install Flutter Rust Bridge
run: cargo install flutter_rust_bridge_codegen
- name: Setup keys
uses: timheuer/base64-to-file@v1
with:
fileName: "keystore/ente_photos_key.jks"
encodedString: ${{ secrets.SIGNING_KEY_PHOTOS }}
- name: Build PlayStore AAB
run: |
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 }}
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD_PHOTOS }}
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD_PHOTOS }}
- name: Upload AAB to PlayStore
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
packageName: io.ente.photos
releaseFiles: mobile/apps/photos/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 Photos (Branch: ${{ github.ref_name }})"
description: "[Download](https://play.google.com/store/apps/details?id=io.ente.photos)"
color: 0x00ff00

View File

@@ -9,6 +9,7 @@ on:
env:
FLUTTER_VERSION: "3.32.8"
RUST_VERSION: "1.86.0"
permissions:
contents: read
@@ -31,7 +32,18 @@ jobs:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- run: flutter pub get
- name: Install Rust ${{ env.RUST_VERSION }}
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.RUST_VERSION }}
- name: Install Flutter Rust Bridge
run: cargo install flutter_rust_bridge_codegen
- name: Generate Rust bindings
run: flutter_rust_bridge_codegen generate
- run: flutter analyze --no-fatal-infos

View File

@@ -28,6 +28,38 @@ jobs:
with:
submodules: recursive
- name: Free up disk space
run: |
echo "Initial disk usage:"
df -h /
# Get available space in KB
INITIAL=$(df / | awk 'NR==2 {print $4}')
echo -e "\n=== Removing .NET SDK (~20-25GB) ==="
BEFORE=$(df / | awk 'NR==2 {print $4}')
START=$(date +%s)
sudo rm -rf /usr/share/dotnet
END=$(date +%s)
AFTER=$(df / | awk 'NR==2 {print $4}')
FREED=$(( (AFTER - BEFORE) / 1048576 )) # Convert KB to GB
echo "Time: $((END-START))s | Freed: ${FREED}GB"
echo -e "\n=== Removing cached tools (~5-10GB) ==="
BEFORE=$(df / | awk 'NR==2 {print $4}')
START=$(date +%s)
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
END=$(date +%s)
AFTER=$(df / | awk 'NR==2 {print $4}')
FREED=$(( (AFTER - BEFORE) / 1048576 ))
echo "Time: $((END-START))s | Freed: ${FREED}GB"
echo -e "\n=== Final Summary ==="
FINAL=$(df / | awk 'NR==2 {print $4}')
TOTAL_FREED=$(( (FINAL - INITIAL) / 1048576 ))
echo "Total space freed: ${TOTAL_FREED}GB"
echo "Final disk usage:"
df -h /
- name: Setup JDK 17
uses: actions/setup-java@v1
with:
@@ -40,6 +72,12 @@ jobs:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Install Flutter Rust Bridge
run: cargo install flutter_rust_bridge_codegen
- name: Generate Rust bindings
run: flutter_rust_bridge_codegen generate
- name: Setup keys
uses: timheuer/base64-to-file@v1
with:

View File

@@ -29,6 +29,8 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
@@ -38,7 +40,7 @@ jobs:
cache-dependency-path: "web/yarn.lock"
- name: Install dependencies
run: yarn install
run: yarn install --frozen-lockfile
- name: Build ${{ inputs.app }}
run: yarn build:${{ inputs.app }}

View File

@@ -29,6 +29,8 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
@@ -38,7 +40,7 @@ jobs:
cache-dependency-path: "web/yarn.lock"
- name: Install dependencies
run: yarn install
run: yarn install --frozen-lockfile
- name: Build ${{ inputs.app }}
run: yarn build:${{ inputs.app }}

View File

@@ -37,6 +37,7 @@ jobs:
uses: actions/checkout@v4
with:
ref: ${{ steps.select-branch.outputs.branch }}
persist-credentials: false
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
@@ -46,7 +47,7 @@ jobs:
cache-dependency-path: "web/yarn.lock"
- name: Install dependencies
run: yarn install
run: yarn install --frozen-lockfile
- name: Build photos
run: yarn build:photos

View File

@@ -33,6 +33,8 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
@@ -42,7 +44,15 @@ jobs:
cache-dependency-path: "web/yarn.lock"
- name: Install dependencies
run: yarn install
run: yarn install --frozen-lockfile
- name: Audit dependencies
run: |
yarn audit --level critical || exit_code=$?
if [[ $exit_code -ge 16 ]]; then
echo "::error::Yarn audit found critical issues"
exit 1
fi
- name: Build photos
run: yarn build:photos

View File

@@ -24,6 +24,8 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
@@ -32,6 +34,14 @@ jobs:
cache: "yarn"
cache-dependency-path: "web/yarn.lock"
- run: yarn install
- run: yarn install --frozen-lockfile
- run: yarn lint
- name: Audit dependencies
run: |
yarn audit --level critical || exit_code=$?
if [[ $exit_code -ge 16 ]]; then
echo "::error::Yarn audit found critical issues"
exit 1
fi

113
CLAUDE.md Normal file
View File

@@ -0,0 +1,113 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Ente is a fully open-source, end-to-end encrypted platform for storing data in the cloud. This monorepo contains:
- **Ente Photos**: End-to-end encrypted photo storage app (iOS/Android/Web/Desktop)
- **Ente Auth**: 2FA authenticator app with cloud backup
- Multiple client applications across platforms
- Museum: The Go backend server powering all services
## Repository Structure
- `/mobile/` - Flutter apps (Photos, Auth, Locker)
- `/web/` - Web applications (Next.js/React)
- `/desktop/` - Electron desktop app
- `/server/` - Museum backend (Go + PostgreSQL)
- `/cli/` - Command-line tools
- `/architecture/` - Technical documentation on E2E encryption
## Common Development Commands
### Web Development
```bash
cd web
yarn install # Install dependencies
yarn dev:photos # Run photos app on port 3000
yarn dev:auth # Run auth app on port 3003
yarn build:photos # Build photos for production
yarn lint # Run prettier, eslint, and tsc checks
yarn lint-fix # Auto-fix linting issues
```
### Mobile Development (Flutter)
```bash
cd mobile
melos bootstrap # Link packages and install dependencies
melos run:photos:apk # Run photos app on Android
melos build:photos:apk # Build release APK
melos clean:all # Clean all projects
flutter test # Run tests for current project
```
### Server Development (Museum)
```bash
cd server
docker compose up --build # Start local development cluster
go mod download # Download dependencies
go build -o museum ./cmd/museum # Build binary
docker compose down # Stop cluster
```
### Desktop Development
```bash
cd desktop
yarn install # Install dependencies
yarn dev # Start development server
yarn build # Build for production
yarn lint # Run linting checks
```
## Architecture
### End-to-End Encryption
All user data is encrypted client-side using:
- **Master Key**: Generated on signup, never leaves device unencrypted
- **Key Encryption Key**: Derived from user password
- **Collection Keys**: For folders/albums
- **File Keys**: Unique for each file
- Encryption uses libsodium (XSalsa20 + Poly1305 MAC)
### Technology Stack
- **Backend**: Go with Gin framework, PostgreSQL, Docker
- **Web**: Next.js, React, TypeScript, Yarn workspaces
- **Mobile**: Flutter 3.32.8, Dart, Melos for monorepo management
- **Desktop**: Electron, TypeScript
- **Infrastructure**: Docker, S3-compatible storage, multi-cloud replication
### API Communication
- Museum server at `localhost:8080` for local development
- Authentication via JWT tokens encrypted with user's public key
- All data transmitted is end-to-end encrypted
## Testing & Quality Checks
### Before Committing
- Run appropriate lint commands for the module you're working on
- Ensure TypeScript compilation succeeds (`yarn tsc` or `tsc`)
- For Flutter: Run `flutter analyze` and `flutter test`
- For Go: Run `go fmt ./...` and `go vet ./...`
### Code Style
- Follow existing patterns in neighboring files
- Use existing libraries rather than adding new dependencies
- Match the indentation and formatting style of existing code
- TypeScript/JavaScript: Prettier + ESLint configuration
- Flutter: Standard Dart formatting
- Go: Standard Go formatting
### Localization (Flutter)
- Add new strings to `/mobile/apps/photos/lib/l10n/intl_en.arb`
- Use `AppLocalizations` to access localized strings in code
- Example: `AppLocalizations.of(context).yourStringKey`
## Important Notes
- All sensitive operations happen client-side due to E2E encryption
- Never log or expose encryption keys, passwords, or auth tokens
- The server (Museum) cannot decrypt user data
- Follow security best practices for handling encrypted data
- When modifying encryption-related code, ensure backward compatibility
- **No analytics or tracking**: Never add any analytics, telemetry, or user tracking code

View File

@@ -48,7 +48,11 @@ See [docs/](docs/README.md) for how to edit these documents.
## Code contributions
If you'd like to contribute code, it is best to start small. Consider some well-scoped changes, say like adding more [custom icons to auth](mobile/apps/auth/docs/adding-icons.md), or fixing a specific bug.
If you'd like to contribute code, it is best to start small. Consider some well-scoped changes, say like adding more [custom icons to auth](mobile/apps/auth/docs/adding-icons.md), or fixing a specific bug. There is a (possibly outdated) list of tasks with the ["help wanted" or "good first issue"](<https://github.com/ente-io/ente/issues?q=state%3Aopen%20(label%3A%22good%20first%20issue%22%20OR%20label%3A%22help%20wanted%22%20)>) label too.
If you use any form of AI assistance, please include a co-author attribution in the commit for transparency.
In your PR, please include before / after screenshots, and clearly indicate the tests that you performed.
Code that changes the behaviour of the product might not get merged, at least not initially. The PR can serve as a discussion bed, but you might find it easier to just start a discussion instead, or post your perspective in the (likely) existing thread about the behaviour change or new feature you wish for.

View File

@@ -142,6 +142,22 @@ var _updateFreeUserStorage = &cobra.Command{
},
}
var _sendMail = &cobra.Command{
Use: "send-mail <to-email> <from-email> <from-name>",
Args: cobra.ExactArgs(3),
Short: "Sends a test mail via the admin api",
RunE: func(cmd *cobra.Command, args []string) error {
recoverWithLog()
var flags = &model.AdminActionForUser{}
cmd.Flags().VisitAll(func(f *pflag.Flag) {
if f.Name == "admin-user" {
flags.AdminEmail = f.Value.String()
}
})
return ctrl.SendTestMail(context.Background(), *flags, args[0], args[1], args[2])
},
}
func init() {
rootCmd.AddCommand(_adminCmd)
_ = _userDetailsCmd.MarkFlagRequired("admin-user")
@@ -159,5 +175,6 @@ func init() {
_updateFreeUserStorage.Flags().StringP("user", "u", "", "The email of the user to update subscription for. (required)")
// add a flag with no value --no-limit
_updateFreeUserStorage.Flags().String("no-limit", "True", "When true, sets 100TB as storage limit, and expiry to current date + 100 years")
_adminCmd.AddCommand(_userDetailsCmd, _disable2faCmd, _disablePasskeyCmd, _updateFreeUserStorage, _listUsers, _deleteUser)
_sendMail.Flags().StringP("admin-user", "a", "", "The email of the admin user. ")
_adminCmd.AddCommand(_userDetailsCmd, _disable2faCmd, _disablePasskeyCmd, _updateFreeUserStorage, _listUsers, _deleteUser, _sendMail)
}

View File

@@ -139,5 +139,28 @@ func (c *Client) UpdateFreePlanSub(ctx context.Context, userDetails *models.User
}
}
return nil
}
func (c *Client) SendTestMail(ctx context.Context, toEmail, fromEmail, fromName string) error {
body := map[string]interface{}{
"to": []string{toEmail},
"fromName": fromName,
"fromEmail": fromEmail,
"subject": "Test mail from Ente",
"body": "This is a test mail from Ente",
}
r, err := c.restClient.R().
SetContext(ctx).
SetBody(body).
Post("/admin/mail")
if err != nil {
return err
}
if r.IsError() {
return &ApiError{
StatusCode: r.StatusCode(),
Message: r.String(),
}
}
return nil
}

View File

@@ -156,6 +156,23 @@ func (c *ClICtrl) UpdateFreeStorage(ctx context.Context, params model.AdminActio
return nil
}
func (c *ClICtrl) SendTestMail(ctx context.Context, params model.AdminActionForUser, to, from, fromName string) error {
accountCtx, err := c.buildAdminContext(ctx, params.AdminEmail)
if err != nil {
return err
}
err = c.Client.SendTestMail(accountCtx, to, from, fromName)
if err != nil {
if apiErr, ok := err.(*api.ApiError); ok && apiErr.StatusCode == 400 && strings.Contains(apiErr.Message, "Token is too old") {
fmt.Printf("Error: old admin token, please re-authenticate using `ente account add` \n")
return nil
}
return err
}
fmt.Printf("Successfully sent test email to %s\n", to)
return nil
}
func (c *ClICtrl) buildAdminContext(ctx context.Context, adminEmail string) (context.Context, error) {
accounts, err := c.GetAccounts(ctx)
if err != nil {

View File

@@ -2,6 +2,8 @@
## v1.7.15 (Unreleased)
- Custom domains.
- Support Czech translations.
- .
## v1.7.14

View File

@@ -44,7 +44,7 @@ The first step is to let Ente know about the domain or subdomain you wish to use
> [!WARNING]
>
> Currently (Aug 2025) the ability to link a custom domain is only present in Ente's web app, [web.ente.io](https://web.ente.io). It will come to Ente mobile and desktop when their next versions get released.
> Currently (Sep 2025) the ability to link a custom domain is only present in Ente's web app, [web.ente.io](https://web.ente.io).
Head over to Preferences > Custom domains, in the domain field enter "pics.example.org" (replace with your subdomain) and press "Save". That's it. The linking is done.
@@ -94,7 +94,7 @@ Using is trivial. When you go to an album's sharing options and copy the link to
> [!WARNING]
>
> Currently (Aug 2025) the ability to automatically substitute your custom domain is only present in Ente's web app, [web.ente.io](https://web.ente.io). It will come to Ente mobile and desktop when their next versions get released.
> Currently (Sep 2025) the ability to automatically substitute your custom domain is present in Ente's web and mobile apps, but not in the desktop app (The next desktop version to be released will have that ability too).
## Unsetting
@@ -103,3 +103,7 @@ To stop using your custom domain, we need to undo the two steps we did during se
1. Unlink your domain in Ente. This can be done just by going to Preferences > Custom Domains, clearing the value in the "Domain" input and pressing "Update".
2. Remove the CNAME record you added during setup in your DNS provider.
## Implementation
Our engineers also wrote [explainer](https://ente.io/blog/custom-domains/) of how this works behind the scenes.

View File

@@ -6,7 +6,7 @@ description: Removing duplicates photos using Ente Photos
# Deduplicate
Ente performs two different duplicate detections: one during uploads, and one
that can be manually run afterwards to remove duplicates across albums.
that can be manually run afterwards to remove duplicates and very similar files across albums.
## During uploads
@@ -16,7 +16,7 @@ When uploading, Ente will ignore exact duplicate files. This allows you to
resume interrupted uploads, or drag and drop the same folder, or reinstall the
app, and expect Ente to automatically skip duplicates and only add new files.
The duplicate detection works slightly different on each platform, to cater to
The duplicate detection works slightly differently on each platform, to cater to
the platform's nuances.
#### Mobile
@@ -48,7 +48,7 @@ to album", and the actual files are not re-uploaded.
## Manual deduplication
Ente also provides a tool for manual de-duplication in _Settings → Backup →
Ente provides a tool for manual de-duplication in _Settings → Backup → Free up space →
Remove duplicates_. This is useful if you have an existing library with
duplicates across different albums, but wish to keep only one copy.
@@ -57,6 +57,13 @@ single copy, and add symlinks to this copy within all existing albums. So your
existing album structure remains unchanged, while the space consumed by the
duplicate data is freed up.
## Filtering similar images
Ente also provides a tool for manual removal of images that are similar, but not the exact same, using our private ML. This feature can be found in _Settings → Backup → Free up space →
Similar images_. This is useful if you've taken a lot of similar photos, potentiall even in different albums, and want to keep only the best ones.
During this filtering process you can choose which photos to keep and which to delete for each set of similar images. Ente will then automatically add symlinks for the kept photos to any albums that only had the deleted images. This way you can easily prune similar images, without worrying about accidentally removing the best ones from a certain album.
## Adding to Ente album creates symlinks
Note that once a file is in Ente, adding it to another Ente album will create a

View File

@@ -8,6 +8,12 @@ description: Guide to configuring Ente CLI for Self Hosted Instance
If you are self-hosting, you can configure Ente CLI to export data & perform
basic administrative actions.
::: tip Installing Ente CLI
For instructions on installing the Ente CLI, see the [README available on Github](https://github.com/ente-io/ente/tree/main/cli/README.md).
:::
## Step 1: Configure endpoint
To do this, first configure the CLI to use your server's endpoint.

View File

@@ -89,7 +89,7 @@ cast.ente.yourdomain.tld {
Reload Caddy for changes to take effect.
```shell
sudo systemctl caddy reload
sudo systemctl reload caddy
```
## Step 4: Verify the setup

View File

@@ -22,8 +22,7 @@ can achieve this the following steps:
# Change the DB name and DB user name if you use different
# values.
# If using Docker
docker exec -it <postgres-ente-container-name>
docker exec -it <postgres-ente-container-name> sh
psql -U pguser -d ente_db
# Or when using psql directly

View File

@@ -171,6 +171,8 @@ smtp:
email:
# Optional name for sender
sender-name:
# Optional encryption
encryption:
```
| Variable | Description | Default |
@@ -181,6 +183,7 @@ smtp:
| `smtp.password` | SMTP auth password | |
| `smtp.email` | Sender email address | |
| `smtp.sender-name` | Custom name for email sender | |
| `smtp.encryption` | Encryption method (tls, ssl) | |
| `transmail.key` | Zeptomail API key | |
### WebAuthn Passkey Support

View File

@@ -46,7 +46,7 @@ If running Museum without Docker, the code should be visible in the terminal
# Change the DB name and DB user name if you use different
# values.
# If using Docker docker exec -it <postgres-ente-container-name>
# If using Docker docker exec -it <postgres-ente-container-name> sh
psql -U pguser -d ente_db
# Or when using psql directly

45
mobile/.gitignore vendored Normal file
View File

@@ -0,0 +1,45 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
melos_*.iml
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release

View File

@@ -0,0 +1,72 @@
# For more linters, we can check https://dart-lang.github.io/linter/lints/index.html
# or https://pub.dev/packages/lint (Effective dart)
# use "flutter analyze ." or "dart analyze ." for running lint checks
include: package:flutter_lints/flutter.yaml
linter:
rules:
# Ref https://github.com/flutter/packages/blob/master/packages/flutter_lints/lib/flutter.yaml
# Ref https://dart-lang.github.io/linter/lints/
- avoid_print
- avoid_unnecessary_containers
- avoid_web_libraries_in_flutter
- no_logic_in_create_state
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
- prefer_final_locals
- require_trailing_commas
- sized_box_for_whitespace
- use_full_hex_values_for_flutter_colors
- use_key_in_widget_constructors
- cancel_subscriptions
- avoid_empty_else
- exhaustive_cases
# just style suggestions
- sort_pub_dependencies
- use_rethrow_when_possible
- prefer_double_quotes
- directives_ordering
- always_use_package_imports
- sort_child_properties_last
- unawaited_futures
analyzer:
errors:
avoid_empty_else: error
exhaustive_cases: error
curly_braces_in_flow_control_structures: error
directives_ordering: error
require_trailing_commas: error
always_use_package_imports: warning
prefer_final_fields: error
unused_import: error
camel_case_types: error
prefer_is_empty: warning
use_rethrow_when_possible: info
unused_field: warning
use_key_in_widget_constructors: warning
sort_child_properties_last: warning
sort_pub_dependencies: warning
library_private_types_in_public_api: warning
constant_identifier_names: ignore
prefer_const_constructors: warning
prefer_const_declarations: warning
prefer_const_constructors_in_immutables: warning
prefer_final_locals: warning
unnecessary_const: error
cancel_subscriptions: error
unrelated_type_equality_checks: error
unnecessary_cast: info
unawaited_futures: warning # convert to warning after fixing existing issues
invalid_dependency: info
use_build_context_synchronously: ignore # experimental lint, requires many changes
prefer_interpolation_to_compose_strings: ignore # later too many warnings
prefer_double_quotes: ignore # too many warnings
avoid_renaming_method_parameters: ignore # incorrect warnings for `equals` overrides

View File

@@ -1 +0,0 @@
surprise/

View File

@@ -382,6 +382,11 @@
{
"title": "CoinDCX"
},
{
"title": "CoinTracking",
"slug": "cointracking",
"altNames": ["cointracking.info", "Coin Tracking"]
},
{
"title": "colorado",
"altNames": [
@@ -735,6 +740,11 @@
{
"title": "Hivelocity"
},
{
"title": "HRDocumentBox",
"slug": "hrdocumentbox",
"altNames": ["HRDocumentBox", "HR Document Box"]
},
{
"title": "HSA Bank",
"slug": "hsa_bank",
@@ -1040,6 +1050,13 @@
"MistralAI"
]
},
{
"title": "Mobile01",
"slug": "mobile01",
"altNames": [
"M01"
]
},
{
"title": "Mozilla"
},
@@ -1219,6 +1236,12 @@
"title": "Parqet",
"slug": "parqet"
},
{
"title": "Parallels",
"slug": "parallels",
"hex": "#E61E25",
"altNames": ["Parallels Desktop", "Parallels VM"]
},
{
"title": "Parsec"
},
@@ -1773,6 +1796,11 @@
"uollet.com.br"
]
},
{
"title": "VHV",
"slug": "vhv",
"altNames": ["VHV", "VHV Versicherung"]
},
{
"title": "Vikunja"
},

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1220.8 227.9" style="enable-background:new 0 0 1220.8 227.9;" xml:space="preserve">
<style type="text/css">
.st0{fill:#0D253E;}
.st1{fill:#008AFB;}
</style>
<title>CoinTracking light</title>
<g id="Layer_2_1_">
<g id="Layer_1-2">
<path class="st0" d="M198.1,167c-30.2,0-54.7-24.5-54.7-54.7s24.5-54.7,54.7-54.7s54.7,24.5,54.7,54.7l0,0 C252.8,142.5,228.3,167,198.1,167z M198.1,81.6c-17,0-30.7,13.7-30.7,30.7s13.7,30.7,30.7,30.7s30.7-13.7,30.7-30.7l0,0 C228.8,95.4,215,81.6,198.1,81.6z"/>
<path class="st0" d="M292.2,59.5h-23.6v107.9h23.6V59.5z"/>
<path class="st0" d="M339.5,167.4h-23.8V59.5h23.8v16.2c6.2-12.5,21-18.5,33-18.5c26.1,0,41.1,16.9,41.1,47.3v62.8h-23.8v-60.1 c0-17.1-8.8-26.8-22.6-26.8c-14.1,0-27.7,7.6-27.7,28.9V167.4z"/>
<path class="st1" d="M390.6,8.2h151.7v22.9h-65.9v136.3h-25V31.1h-60.9V8.2H390.6z"/>
<path class="st1" d="M540.3,167.4h-23.8V59.5h23.8V79c7.4-13.5,15.4-19.5,29.6-21.8c7.5-1.2,15.7,1.8,19.2,4.2l-3.9,22 c-4.9-2.5-10.4-3.8-15.9-3.7c-20.3,0-28.9,20.3-28.9,49L540.3,167.4L540.3,167.4z"/>
<path class="st1" d="M680.7,151.9c-7.2,11.8-22.9,17.8-36.3,17.8c-29.1,0-54.8-21.9-54.8-56.4s25.6-56.1,54.8-56.1 c12.9,0,28.9,5.3,36.3,17.5V59.5h23.6v107.9h-23.6V151.9z M647.2,146.6c17.6,0,33.3-12.2,33.3-33.5s-17.1-32.8-33.3-32.8 c-18,0-33,12.9-33,32.8S629.2,146.6,647.2,146.6L647.2,146.6z"/>
<path class="st1" d="M778.4,57.2c17.1,0,32.6,6.7,42.7,18.7l-18.5,14.8c-5.8-6.7-14.8-10.4-24.3-10.4c-18,0-34,12.7-34,32.8 s15.9,33.7,34,33.7c9.5,0,18.5-3.9,24.3-10.6l18.7,14.6c-10.2,12-25.6,18.9-43,18.9c-31,0-57.5-22.4-57.5-56.6 S747.4,57.2,778.4,57.2z"/>
<path class="st1" d="M860.3,117.2v50.1h-23.6V0.8h23.6V95l34.2-35.6h31.9l-46,46.9l56.4,61h-30.5L860.3,117.2z"/>
<path class="st1" d="M967.4,59.5h-23.6v107.9h23.6V59.5z"/>
<path class="st1" d="M1014.7,167.4h-23.8V59.5h23.8v16.2c6.2-12.5,21-18.5,33-18.5c26.1,0,41.1,16.9,41.1,47.3v62.8H1065v-60.1 c0-17.1-8.8-26.8-22.6-26.8c-14.1,0-27.7,7.6-27.7,28.9V167.4z"/>
<path class="st1" d="M1220.2,111.5c0-12.3-4.5-24.2-12.5-33.6l13-17.1l-19.6-13l-11.9,15.7c-8.3-4.1-17.5-6.2-26.8-6.2 c-31.9,0-57.8,24.4-57.8,54.3s25.9,54.3,57.8,54.3c20.2,0,34.2,10.2,34.2,19.3s-14.1,19.3-34.2,19.3s-34.2-10.2-34.2-19.3h-23.6 c0,24,25.4,42.9,57.8,42.9s57.8-18.8,57.8-42.9c0-13.2-7.7-24.8-19.9-32.6C1212.5,142.5,1220.2,127.8,1220.2,111.5z M1128.2,111.5 c0-16.9,15.4-30.7,34.2-30.7s34.2,13.8,34.2,30.7s-15.4,30.7-34.2,30.7S1128.2,128.4,1128.2,111.5L1128.2,111.5z"/>
<path class="st0" d="M81.4,170.5C36.4,170.5,0,134,0,89c0-21.6,8.6-42.3,23.9-57.6c31.8-31.8,83.4-31.8,115.2,0l0,0l-17.7,17.7 C99.3,27,63.6,27,41.5,49.1s-22.1,57.8,0,79.9s57.8,22.1,79.9,0l17.7,17.7C123.8,162,103.1,170.6,81.4,170.5z"/>
<circle class="st0" cx="280.7" cy="15.5" r="15.5"/>
<circle class="st1" cx="954.7" cy="15.5" r="15.5"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,26 @@
<?xml version="1.0"?>
<svg width="320" height="280" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" version="1.1">
<g class="layer">
<title>Layer 1</title>
<g id="Layer1000">
<g id="Layer1002">
<g id="Layer1003">
<path d="m123.08,34.29c-66.43,0 -120.27,53.85 -120.27,120.27c0,66.43 53.85,120.27 120.27,120.27c66.47,0 120.32,-53.85 120.32,-120.27c0,-66.43 -53.85,-120.27 -120.32,-120.27zm0,215.67c-52.67,0 -95.36,-42.73 -95.36,-95.4c0,-52.67 42.68,-95.4 95.36,-95.4c52.72,0 95.4,42.73 95.4,95.4c0,52.67 -42.68,95.4 -95.4,95.4z" fill="#2a5e00" fill-rule="evenodd" id="path7"/>
<g id="Layer1004">
<g id="Layer1005">
<path d="m138.72,146.29l59.61,-41.47l7.78,33.7l-67.39,7.78z" fill="#2a5e00" fill-rule="evenodd" id="path8"/>
<path d="m110.88,146.29l-59.61,-41.47l-7.78,33.7l67.39,7.78z" fill="#2a5e00" fill-rule="evenodd" id="path9"/>
</g>
<path d="m43.95,192.02l74.62,49.75l87.12,-78.8l-161.75,29.05z" fill="#2a5e00" fill-rule="evenodd" id="path10"/>
</g>
<path d="m94.24,59.29l-30.48,-55.1l54.26,33.24l-23.79,21.86z" fill="#2a5e00" fill-rule="evenodd" id="path11"/>
<path d="m202.64,78.1l30.43,-55.1l-54.22,33.24l23.79,21.86z" fill="#2a5e00" fill-rule="evenodd" id="path12"/>
</g>
<path d="m275.63,274.67l29.35,0l0,-240.76l-29.35,0l0,240.76z" fill="#2a5e00" fill-rule="evenodd" id="path13"/>
<path d="m317.94,125.93c0,15.3 -12.33,27.63 -27.63,27.63c-15.26,0 -27.63,-12.33 -27.63,-27.63c0,-15.26 12.37,-27.63 27.63,-27.63c15.3,0 27.63,12.37 27.63,27.63z" fill="#2a5e00" fill-rule="evenodd" id="path14"/>
<path d="m288.84,33.91l-41.76,0l16.76,45.99l23.58,0l1.42,-45.99z" fill="#2a5e00" fill-rule="evenodd" id="path15"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<rect x="20" y="10" width="10" height="80" rx="5" fill="#E61E25"/>
<rect x="50" y="10" width="10" height="80" rx="5" fill="#E61E25"/>
</svg>

After

Width:  |  Height:  |  Size: 207 B

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Created with Inkscape (http://www.inkscape.org/) by Marsupilami -->
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="1024" height="357" viewBox="-1.98252 -1.98252 201.02104 70.04904" id="svg3349">
<defs id="defs3351"/>
<path d="m 0,0 11.76,0 4.455,31.962 0.12,0 L 20.789,0 32.55,0 23.402,42.417 9.147,42.417 0,0" id="path3131" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 34.039,0 11.05,0 0,15.567 6.771,0 0,-15.567 11.05,0 0,42.417 -11.05,0 0,-17.465 -6.771,0 0,17.465 -11.05,0 0,-42.417" id="path3133" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 64.395,0 11.757,0 4.457,31.962 0.121,0 L 85.185,0 96.944,0 87.797,42.417 73.54,42.417 64.395,0" id="path3135" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 97.576,42.414 8.907,0 9.222,-42.41 -8.912,0 -9.217,42.41" id="path3137" style="fill:#f0ab00;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 111.026,42.424 8.908,-0.01 9.218,-42.41 -8.913,0 -9.213,42.42" id="path3139" style="fill:#f0ab00;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 124.564,42.414 8.906,0 9.217,-42.41 -8.906,0 -9.217,42.41" id="path3141" style="fill:#f0ab00;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 4.169,46.784 5.251,0 1.985,14.261 0.05,0 1.99,-14.261 5.247,0 -4.082,18.928 -6.363,0 -4.082,-18.928" id="path3143" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 19.356,46.784 11.216,0 0,4.031 -6.282,0 0,3.234 5.882,0 0,3.87 -5.882,0 0,3.763 6.517,0 0,4.03 -11.451,0 0,-18.928" id="path3145" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 54.93,52.247 0,-0.45 c 0,-1.117 -0.449,-2.043 -1.405,-2.043 -1.06,0 -1.538,0.823 -1.538,1.67 0,3.739 8.059,1.91 8.059,8.828 0,4.027 -2.357,5.832 -6.705,5.832 -4.082,0 -6.362,-1.404 -6.362,-5.331 l 0,-0.663 4.772,0 0,0.453 c 0,1.615 0.663,2.202 1.614,2.202 1.007,0 1.594,-0.798 1.594,-1.831 0,-3.739 -7.743,-1.88 -7.743,-8.586 0,-3.819 2.043,-5.913 6.205,-5.913 4.294,0 6.12,1.775 6.12,5.832 l -4.611,0" id="path3147" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 61.476,65.712 4.932,0 0,-18.928 -4.932,0 0,18.928 z" id="path3149" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 32.477,46.784 7.714,0 c 3.766,0 5.195,2.124 5.195,5.039 0,2.516 -0.979,4.16 -3.232,4.506 2.385,0.265 3.103,1.776 3.103,4.294 l 0,1.616 c 0,0.981 0,2.251 0.237,2.626 0.132,0.209 0.237,0.422 0.558,0.582 l 0,0.265 -5.25,0 C 40.325,64.705 40.325,62.9 40.325,62.109 l 0,-1.275 c 0,-2.147 -0.423,-2.704 -1.619,-2.704 l -1.296,0 0,7.582 -4.933,0 0,-18.928 z m 4.933,8.008 0.98,0 c 1.405,0 2.066,-0.9 2.066,-2.252 0,-1.541 -0.609,-2.202 -2.094,-2.202 l -0.952,0 0,4.454" id="path3151" style="fill:#1e1e1e;fill-opacity:1;fill-rule:evenodd;stroke:none"/>
<path d="m 75.975,52.54 c 0,-2.147 -0.396,-2.786 -1.35,-2.786 -1.513,0 -1.67,1.381 -1.67,6.494 0,5.117 0.157,6.497 1.67,6.497 1.22,0 1.485,-1.063 1.485,-4.64 l 4.771,0 0,1.405 c 0,5.3 -3.101,6.574 -6.256,6.574 -5.54,0 -6.76,-2.784 -6.76,-9.836 0,-7.236 1.642,-9.833 6.76,-9.833 4.451,0 6.12,2.334 6.12,5.992 l 0,1.19 -4.77,0 0,-1.057" id="path3153" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 82.524,46.784 4.928,0 0,6.948 3.02,0 0,-6.948 4.932,0 0,18.928 -4.932,0 0,-7.793 -3.02,0 0,7.793 -4.928,0 0,-18.928" id="path3155" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 97.606,46.784 11.21,0 0,4.031 -6.282,0 0,3.234 5.886,0 0,3.87 -5.886,0 0,3.763 6.522,0 0,4.03 -11.45,0 0,-18.928" id="path3157" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 130.526,46.784 0,13.655 c 0,1.824 0.559,2.306 1.485,2.306 0.928,0 1.485,-0.482 1.485,-2.306 l 0,-13.655 4.929,0 0,12.408 c 0,5.298 -2.28,6.892 -6.414,6.892 -4.135,0 -6.412,-1.594 -6.412,-6.892 l 0,-12.408 4.927,0" id="path3159" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 140.415,46.784 5.51,0 3.185,11.665 0.05,0 0,-11.665 4.614,0 0,18.928 -5.407,0 -3.288,-11.689 -0.05,0 0,11.689 -4.613,0 0,-18.928" id="path3161" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 110.726,46.784 7.716,0 c 3.76,0 5.192,2.124 5.192,5.039 0,2.516 -0.979,4.16 -3.234,4.506 2.383,0.265 3.101,1.776 3.101,4.294 l 0,1.616 c 0,0.981 0,2.251 0.238,2.626 0.131,0.209 0.24,0.422 0.558,0.582 l 0,0.265 -5.251,0 c -0.477,-1.007 -0.477,-2.812 -0.477,-3.603 l 0,-1.275 c 0,-2.147 -0.422,-2.704 -1.612,-2.704 l -1.301,0 0,7.582 -4.93,0 0,-18.928 z m 4.93,8.008 0.979,0 c 1.404,0 2.07,-0.9 2.07,-2.252 0,-1.541 -0.61,-2.202 -2.095,-2.202 l -0.954,0 0,4.454" id="path3163" style="fill:#1e1e1e;fill-opacity:1;fill-rule:evenodd;stroke:none"/>
<path d="m 162.334,55.428 6.361,0 0,10.284 -3.34,0 -0.113,-1.669 -0.05,0 c -0.662,1.617 -2.412,2.041 -4.082,2.041 -5.01,0 -5.459,-3.58 -5.459,-9.836 0,-6.336 1.22,-9.833 7.047,-9.833 3.502,0 5.993,1.775 5.993,6.36 l -4.771,0 c 0,-0.952 -0.07,-1.695 -0.266,-2.198 -0.185,-0.53 -0.554,-0.823 -1.139,-0.823 -1.612,0 -1.774,1.381 -1.774,6.494 0,5.117 0.161,6.497 1.67,6.497 1.034,0 1.639,-0.666 1.669,-3.978 l -1.75,0 0,-3.339" id="path3165" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 170.577,46.784 11.213,0 0,4.031 -6.28,0 0,3.234 5.885,0 0,3.87 -5.885,0 0,3.763 6.519,0 0,4.03 -11.452,0 0,-18.928" id="path3167" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<path d="m 183.697,46.784 5.514,0 3.18,11.665 0.05,0 0,-11.665 4.615,0 0,18.928 -5.408,0 -3.284,-11.689 -0.05,0 0,11.689 -4.614,0 0,-18.928" id="path3169" style="fill:#1e1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
</svg>
<!-- version: 20110311, original size: 197.056 66.084, border: 3% -->

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -39,6 +39,8 @@ PODS:
- DKPhotoGallery/Resource (0.0.19):
- SDWebImage
- SwiftyGif
- ente_qr (0.0.1):
- Flutter
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
@@ -126,6 +128,8 @@ PODS:
- sqlite3/perf-threadsafe
- sqlite3/rtree
- SwiftyGif (5.4.5)
- ua_client_hints (1.4.1):
- Flutter
- url_launcher_ios (0.0.1):
- Flutter
@@ -134,6 +138,7 @@ DEPENDENCIES:
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- cupertino_http (from `.symlinks/plugins/cupertino_http/darwin`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- ente_qr (from `.symlinks/plugins/ente_qr/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- file_saver (from `.symlinks/plugins/file_saver/ios`)
- fk_user_agent (from `.symlinks/plugins/fk_user_agent/ios`)
@@ -158,6 +163,7 @@ DEPENDENCIES:
- sodium_libs (from `.symlinks/plugins/sodium_libs/ios`)
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/darwin`)
- ua_client_hints (from `.symlinks/plugins/ua_client_hints/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
SPEC REPOS:
@@ -180,6 +186,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/cupertino_http/darwin"
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
ente_qr:
:path: ".symlinks/plugins/ente_qr/ios"
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
file_saver:
@@ -228,6 +236,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/sqflite_darwin/darwin"
sqlite3_flutter_libs:
:path: ".symlinks/plugins/sqlite3_flutter_libs/darwin"
ua_client_hints:
:path: ".symlinks/plugins/ua_client_hints/ios"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
@@ -238,6 +248,7 @@ SPEC CHECKSUMS:
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
ente_qr: f39434aa69ea0e71047b49316365b2737f8a20aa
file_picker: b159e0c068aef54932bb15dc9fd1571818edaf49
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
fk_user_agent: 1f47ec39291e8372b1d692b50084b0d54103c545
@@ -268,6 +279,7 @@ SPEC CHECKSUMS:
sqlite3: 3e82a2daae39ba3b41ae6ee84a130494585460fc
sqlite3_flutter_libs: 2c48c4ee7217fd653251975e43412250d5bcbbe2
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
ua_client_hints: aeabd123262c087f0ce151ef96fa3ab77bfc8b38
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
PODFILE CHECKSUM: 78f002751f1a8f65042b8da97902ba4124271c5a

View File

@@ -111,6 +111,7 @@
"importAegisGuide": "Použijte možnost \"Export the vault\" v nastavení aplikace Aegis.",
"import2FasGuide": "Použijte možnost \"Settings->Backup -Export\" v 2FA.\n\nPokud je Vaše záloha šifrovaná, budete muset zadat heslo pro její odemčení",
"importLastpassGuide": "V nastavení aplikace Lastpass Authenticator vyberte možnost \"Transfer accounts\" a poté \"Export accounts to file\". Vygenerovaný soubor JSON následně nahrajte sem.",
"importProtonAuthGuide": "K exportu kódů použijte možnost „Exportovat“ v nastavení aplikace Proton Authenticator.",
"exportCodes": "Exportovat kódy",
"importLabel": "Importovat",
"importInstruction": "Vyberte, prosím, soubor obsahující seznam Vašich kódů v následujícím formátu",
@@ -124,6 +125,7 @@
"authToChangeYourEmail": "Pro změnu svého e-mailu se, prosím, ověřte",
"authToChangeYourPassword": "Pro změnu svého hesla se, prosím, ověřte",
"authToViewSecrets": "Pro zobrazení svých tajných údajů se musíte ověřit",
"authToInitiateSignIn": "Proveďte ověření a přihlaste se k zálohování.",
"ok": "Ok",
"cancel": "Zrušit",
"yes": "Ano",
@@ -171,6 +173,7 @@
"invalidQRCode": "Neplatný QR kód",
"noRecoveryKeyTitle": "Nemáte obnovovací klíč?",
"enterEmailHint": "Zadejte svou e-mailovou adresu",
"enterNewEmailHint": "Zadejte svou novou e-mailovou adresu",
"invalidEmailTitle": "Neplatná e-mailová adresa",
"invalidEmailMessage": "Prosím, zadejte platnou e-mailovou adresu.",
"deleteAccount": "Odstranit účet",
@@ -509,6 +512,19 @@
"supportEnte": "Podpořte <bold-green>ente</bold-green>",
"giveUsAStarOnGithub": "Dejte nám hvězdu na Githubu",
"free5GB": "5GB zdarma na <bold-green>ente</bold-green> Fotky",
"loginWithAuthAccount": "Přihlaste se pomocí svého účtu Auth",
"freeStorageOffer": "10% sleva na <bold-green>ente</bold-green> fotky",
"freeStorageOfferDescription": "Použijte kód \"AUTH\" pro získání 10% slevy na první rok"
"freeStorageOfferDescription": "Použijte kód \"AUTH\" pro získání 10% slevy na první rok",
"advanced": "Pokročilé",
"algorithm": "Algoritmus",
"type": "Typ",
"period": "Období",
"digits": "Digitální",
"importFromGallery": "Importovat z galerie",
"errorCouldNotReadImage": "Nelze přečíst vybraný obrazový soubor.",
"errorInvalidQRCode": "Neplatný QR kód",
"errorInvalidQRCodeBody": "Naskenovaný QR kód není platným účtem 2FA.",
"errorNoQRCode": "Nenalezen žádný QR kód",
"errorGenericTitle": "Došlo k chybě",
"errorGenericBody": "Při importu došlo k neočekávané chybě."
}

View File

@@ -111,6 +111,7 @@
"importAegisGuide": "Verwenden Sie die Option \"Tresor exportieren\" in den Einstellungen von Aegis.\n\nFalls Ihr Tresor verschlüsselt ist, müssen Sie das Passwort für den Tresor eingeben, um ihn zu entschlüsseln.",
"import2FasGuide": "Verwenden Sie unter \"Einstellungen → Backup\" die Option \"Exportieren\" in 2FAS.\n\nFalls Ihr Backup verschlüsselt ist, müssen Sie das Passwort eingeben, um das Backup zu entschlüsseln.",
"importLastpassGuide": "Verwenden Sie die Option \"Konten übertragen → Konten in Datei exportieren\" in den Lastpass Authenticator Einstellungen. \nImportieren Sie anschließend die heruntergeladene JSON-Datei.",
"importProtonAuthGuide": "Verwenden Sie die Option \"Exportieren\" in den Proton Authenticator Settings um Ihre Codes zu exportieren.",
"exportCodes": "Codes exportieren",
"importLabel": "Importieren",
"importInstruction": "Bitte wählen Sie eine Datei die Codes in folgendem Format beinhaltet",
@@ -519,5 +520,12 @@
"algorithm": "Algorithmus",
"type": "Typ",
"period": "Periode",
"digits": "Ziffern"
"digits": "Ziffern",
"importFromGallery": "Aus Galerie importieren",
"errorCouldNotReadImage": "Die ausgewählte Bild-Datei konnte nicht verarbeitet werden.",
"errorInvalidQRCode": "Ungültiger QR-Code",
"errorInvalidQRCodeBody": "Der gescannte QR-Code ist kein gültiges 2FA-Konto.",
"errorNoQRCode": "Kein QR-Code gefunden",
"errorGenericTitle": "Ein Fehler ist aufgetreten",
"errorGenericBody": "Beim Importieren ist ein unerwarteter Fehler aufgetreten."
}

View File

@@ -88,6 +88,8 @@
"useRecoveryKey": "Χρήση κλειδιού ανάκτησης",
"incorrectPasswordTitle": "Λάθος κωδικός πρόσβασης",
"welcomeBack": "Καλωσορίσατε και πάλι!",
"emailAlreadyRegistered": "Το email είναι ήδη καταχωρημένο.",
"emailNotRegistered": "Το email δεν έχει καταχωρηθεί.",
"madeWithLoveAtPrefix": "φτιαγμένη με ❤️ στο ",
"supportDevs": "Εγγραφείτε στο <bold-green>ente</bold-green> για να μας υποστηρίξετε",
"supportDiscount": "Χρησιμοποιήστε τον κωδικό κουπονιού \"AUTH\" για να λάβετε 10% έκπτωση για τον πρώτο χρόνο",
@@ -171,6 +173,7 @@
"invalidQRCode": "Μη έγκυρος κωδικός QR",
"noRecoveryKeyTitle": "Χωρίς κλειδί ανάκτησης;",
"enterEmailHint": "Εισάγετε τη διεύθυνση email σας",
"enterNewEmailHint": "Εισάγετε την διεύθυνση ηλ. ταχυδρομείου σας",
"invalidEmailTitle": "Μη έγκυρη διεύθυνση email",
"invalidEmailMessage": "Παρακαλούμε εισάγετε μια έγκυρη διεύθυνση email.",
"deleteAccount": "Διαγραφή λογαριασμού",
@@ -258,6 +261,10 @@
"areYouSureYouWantToLogout": "Είστε σίγουροι ότι θέλετε να αποσυνδεθείτε;",
"yesLogout": "Ναι, αποσύνδεση",
"exit": "Εξοδος",
"theme": "Θέμα",
"lightTheme": "Φωτεινό",
"darkTheme": "Σκοτεινό",
"systemTheme": "Σύστημα",
"verifyingRecoveryKey": "Επαλήθευση κλειδιού ανάκτησης...",
"recoveryKeyVerified": "Το κλειδί ανάκτησης επαληθεύτηκε",
"recoveryKeySuccessBody": "Τέλεια! Το κλειδί ανάκτησης σας είναι έγκυρο. Σας ευχαριστούμε για την επαλήθευση.\n\nΠαρακαλώ θυμηθείτε να κρατήσετε το κλειδί ανάκτησης σας και σε αντίγραφο ασφαλείας.",
@@ -490,5 +497,24 @@
"appLockNotEnabled": "Το κλείδωμα εφαρμογής δεν είναι ενεργοποιημένο",
"appLockNotEnabledDescription": "Παρακαλώ ενεργοποιήστε το κλείδωμα εφαρμογής μέσω της επιλογής Ασφάλεια > Κλείδωμα εφαρμογής",
"authToViewPasskey": "Παρακαλώ πιστοποιηθείτε για να δείτε το κλειδί πρόσβασης",
"appLockOfflineModeWarning": "Έχετε επιλέξει να προχωρήσετε χωρίς αντίγραφα ασφαλείας. Αν ξεχάσετε τον κωδικό της εφαρμογής, θα κλειδωθείτε από την πρόσβαση στα δεδομένα σας."
"appLockOfflineModeWarning": "Έχετε επιλέξει να προχωρήσετε χωρίς αντίγραφα ασφαλείας. Αν ξεχάσετε τον κωδικό της εφαρμογής, θα κλειδωθείτε από την πρόσβαση στα δεδομένα σας.",
"duplicateCodes": "Διπλότυποι κωδικοί",
"noDuplicates": "✨ Δεν υπάρχουν διπλότυπα",
"youveNoDuplicateCodesThatCanBeCleared": "Δεν υπάρχουν διπλότυπα αρχεία που μπορούν να εκκαθαριστούν",
"deduplicateCodes": "Διπλότυποι κωδικοί",
"deselectAll": "Αποεπιλογή όλων",
"selectAll": "Επιλογή όλων",
"deleteDuplicates": "Διαγραφή διπλότυπων",
"plainHTML": "Απλό HTML",
"dropReviewiOS": "Αφήστε μια κριτική στο App Store",
"dropReviewAndroid": "Αφήστε μια κριτική στο Play Store",
"giveUsAStarOnGithub": "Δώστε μας ένα αστέρι στο Github",
"free5GB": "5GB δωρεάν στο <bold-green>ente</bold-green> Photos",
"freeStorageOffer": "10% έκπτωση στο <bold-green>ente</bold-green> photos",
"freeStorageOfferDescription": "Χρησιμοποιήστε τον κωδικό \"AUTH\" για να λάβετε 10% έκπτωση για τον πρώτο χρόνο",
"advanced": "Για προχωρημένους",
"algorithm": "Αλγόριθμος",
"type": "Τύπος",
"period": "Περίοδος",
"digits": "Ψηφία"
}

View File

@@ -111,6 +111,7 @@
"importAegisGuide": "Use the \"Export the vault\" option in Aegis's Settings.\n\nIf your vault is encrypted, you will need to enter vault password to decrypt the vault.",
"import2FasGuide": "Use the \"Settings->Backup -Export\" option in 2FAS.\n\nIf your backup is encrypted, you will need to enter the password to decrypt the backup",
"importLastpassGuide": "Use the \"Transfer accounts\" option within Lastpass Authenticator Settings and press \"Export accounts to file\". Import the JSON downloaded.",
"importProtonAuthGuide": "Use the \"Export\" option in Proton Authenticator Settings to export your codes.",
"exportCodes": "Export codes",
"importLabel": "Import",
"importInstruction": "Please select a file that contains a list of your codes in the following format",
@@ -519,5 +520,12 @@
"algorithm": "Algorithm",
"type": "Type",
"period": "Period",
"digits": "Digits"
"digits": "Digits",
"importFromGallery": "Import from gallery",
"errorCouldNotReadImage": "Could not read the selected image file.",
"errorInvalidQRCode": "Invalid QR Code",
"errorInvalidQRCodeBody": "The scanned QR code is not a valid 2FA account.",
"errorNoQRCode": "No QR code found",
"errorGenericTitle": "An Error Occurred",
"errorGenericBody": "An unexpected error occurred while importing."
}

View File

@@ -111,6 +111,7 @@
"importAegisGuide": "Utilisez l'option \"Exporter le coffre-fort\" dans les paramètres d'Aegis.\n\nSi votre coffre-fort est crypté, vous devrez saisir le mot de passe du coffre-fort pour déchiffrer le coffre-fort.",
"import2FasGuide": "Utilisez l'option \"Paramètres->Sauvegarde -Export\" dans 2FAS.\n\nSi votre sauvegarde est chiffrée, vous devrez entrer le mot de passe pour déchiffrer la sauvegarde",
"importLastpassGuide": "Utilisez l'option \"Transférer des comptes\" dans les paramètres de l'authentificateur Lastpass et appuyez sur \"Exporter des comptes vers un fichier\". Importez le JSON téléchargé.",
"importProtonAuthGuide": "Utilisez l'option \"Export\" dans les paramètres de Proton Authenticator pour exporter vos codes.",
"exportCodes": "Exporter les codes",
"importLabel": "Importer",
"importInstruction": "Veuillez sélectionner un fichier qui contient une liste de vos codes dans le format suivant",
@@ -519,5 +520,12 @@
"algorithm": "Algorithme",
"type": "Type",
"period": "Période",
"digits": "Chiffres"
"digits": "Chiffres",
"importFromGallery": "Importer depuis la galerie",
"errorCouldNotReadImage": "Impossible de lire le fichier sélectionné.",
"errorInvalidQRCode": "QR Code invalide",
"errorInvalidQRCodeBody": "Le code QR scanné n'est pas un compte 2FA valide.",
"errorNoQRCode": "Aucun code QR trouvé",
"errorGenericTitle": "Une erreur s'est produite",
"errorGenericBody": "Une erreur inattendue est survenue lors de l'importation."
}

View File

@@ -111,6 +111,7 @@
"importAegisGuide": "Naudokite „Aegis“ nustatymuose esančią parinktį Eksportuoti slėptuvę.\n\nJei jūsų saugykla užšifruota, turėsite įvesti saugyklos slaptažodį, kad iššifruotumėte saugyklą.",
"import2FasGuide": "Naudokite programoje 2FAS esančią parinktį „Settings->2FAS Backup->Export to file“.\n\nJei atsarginė kopija užšifruota, turėsite įvesti slaptažodį, kad iššifruotumėte atsarginę kopiją.",
"importLastpassGuide": "Naudokite „Lastpass Authenticator“ nustatymuose esančią parinktį „Transfer accounts“ (perkelti paskyras) ir paspauskite „Export accounts to file“ (eksportuoti paskyras į failą). Importuokite atsisiųstą JSON failą.",
"importProtonAuthGuide": "Naudokite „Proton Authenticator“ nustatymuose esančią parinktį „Export“ (eksportuoti), kad eksportuotumėte savo kodus.",
"exportCodes": "Eksportuoti kodus",
"importLabel": "Importuoti",
"importInstruction": "Pasirinkite failą, kuriame yra tokio formato jūsų kodų sąrašas",
@@ -519,5 +520,12 @@
"algorithm": "Algoritmas",
"type": "Tipas",
"period": "Laikotarpis",
"digits": "Skaitmenys"
"digits": "Skaitmenys",
"importFromGallery": "Importuoti iš galerijos",
"errorCouldNotReadImage": "Nepavyko perskaityti pasirinkto vaizdo failo.",
"errorInvalidQRCode": "Netinkamas QR kodas",
"errorInvalidQRCodeBody": "Nuskenuotas QR kodas nėra tinkama 2FA paskyra.",
"errorNoQRCode": "QR kodas nerastas.",
"errorGenericTitle": "Įvyko klaida",
"errorGenericBody": "Importuojant įvyko netikėta klaida."
}

View File

@@ -45,7 +45,7 @@
"timeBasedKeyType": "Oparte na czasie (TOTP)",
"counterBasedKeyType": "Oparte na liczniku (HOTP)",
"saveAction": "Zapisz",
"nextTotpTitle": "następny",
"nextTotpTitle": "dalej",
"deleteCodeTitle": "Usunąć kod?",
"deleteCodeMessage": "Czy na pewno chcesz usunąć ten kod? Ta akcja jest nieodwracalna.",
"trashCode": "Przenieść kod do kosza?",
@@ -111,6 +111,7 @@
"importAegisGuide": "Użyj opcji \"Eksportuj sejf\" w ustawieniach Aegis.\n\nJeśli twój sejf jest zaszyfrowany, musisz wprowadzić hasło sejfu, aby odszyfrować sejf.",
"import2FasGuide": "Użyj opcji \"Ustawienia->Kopia Zapasowa-Eksport\" w 2FAS.\n\nJeśli twoja kopia zapasowa jest zaszyfrowana, musisz wprowadzić hasło, aby odszyfrować kopię zapasową",
"importLastpassGuide": "Użyj opcji \"Przenieś konta\" w Ustawieniach Lastpass Authenticator i naciśnij \"Eksportuj konta do pliku\". Zaimportuj pobrany plik JSON.",
"importProtonAuthGuide": "Użyj opcji „Eksportuj” w ustawieniach Proton Authenticator, aby wyeksportować kody.",
"exportCodes": "Eksportuj kody",
"importLabel": "Importuj",
"importInstruction": "Wybierz plik, który zawiera listę twoich kodów w następującym formacie",
@@ -519,5 +520,12 @@
"algorithm": "Algorytm",
"type": "Rodzaj",
"period": "Okres",
"digits": "Cyfry"
"digits": "Cyfry",
"importFromGallery": "Importuj z galerii",
"errorCouldNotReadImage": "Nie można odczytać wybranego pliku obrazu.",
"errorInvalidQRCode": "Nieprawidłowy kod QR",
"errorInvalidQRCodeBody": "Zeskanowany kod QR nie wskazuje na prawidłowe konto 2FA.",
"errorNoQRCode": "Nie znaleziono kodu QR",
"errorGenericTitle": "Wystąpił błąd",
"errorGenericBody": "Podczas importowania wystąpił nieoczekiwany błąd."
}

View File

@@ -18,7 +18,7 @@
"incorrectDetails": "Felaktiga uppgifter",
"pleaseVerifyDetails": "Kontrollera dina detaljer och försök igen",
"codeIssuerHint": "Utfärdare",
"codeSecretKeyHint": "Secret Key",
"codeSecretKeyHint": "Hemlig nyckel",
"secret": "Säkerhetsnyckel",
"all": "Alla",
"notes": "Anteckningar",
@@ -33,7 +33,7 @@
}
}
},
"codeAccountHint": "Konto (du@domän.com)",
"codeAccountHint": "Konto (du@domain.com)",
"codeTagHint": "Tagg",
"accountKeyType": "Typ av nyckel",
"sessionExpired": "Sessionen har gått ut",
@@ -68,7 +68,7 @@
"reportABug": "Rapportera en bugg",
"crashAndErrorReporting": "Krasch och felrapportering",
"reportBug": "Rapportera bugg",
"emailUsMessage": "Skicka e-mail till {email}",
"emailUsMessage": "Skicka e-post till {email}",
"@emailUsMessage": {
"placeholders": {
"email": {
@@ -79,7 +79,7 @@
"contactSupport": "Kontakta support",
"rateUsOnStore": "Betygsätt på {storeName}",
"blog": "Blogg",
"merchandise": "Merchandise",
"merchandise": "Produkter",
"verifyPassword": "Bekräfta lösenord",
"pleaseWait": "Vänligen vänta...",
"generatingEncryptionKeysTitle": "Skapar krypteringsnycklar...",
@@ -104,13 +104,14 @@
"importFromApp": "Importera koder från {appName}",
"importGoogleAuthGuide": "Exportera dina konton från Google Authenticator till en QR-kod med alternativet \"Överföra konton\". Använd sedan en annan enhet och skanna QR-koden.\n\nTips: Du kan använda din bärbara dators webbkamera för att ta en bild av QR-koden.",
"importSelectJsonFile": "Välj JSON-fil",
"importSelectAppExport": "Välj {appName} exportfil",
"importSelectAppExport": "Välj {appName} exporteringsfil",
"importEnteEncGuide": "Välj den krypterade JSON-filen som exporteras från Ente",
"importRaivoGuide": "Använd alternativet \"Exportera OTPs till zip-arkiv\" i Raivos inställningar.\n\nExtrahera zip-filen och importera JSON-filen.",
"importBitwardenGuide": "Använd alternativet \"Exportera valv\" inom Bitwarden Tools och importera den okrypterade JSON-filen.",
"importAegisGuide": "Använd alternativet \"Exportera valvet\" i Aegis inställningar.\n\nOm ditt valv är krypterat måste du ange valvlösenordet för att dekryptera valvet.",
"import2FasGuide": "Använd alternativet \"Inställningar->Säkerhetskopiera -Exportera\" i 2FAS.\n\nOm din säkerhetskopia är krypterad måste du ange lösenordet för att dekryptera säkerhetskopian.",
"importLastpassGuide": "Använd alternativet \"Överför konton\" i LastPass Authenticators inställningar och tryck på \"Exportera konton till fil\". Importera JSON-filen som laddas ner.",
"importProtonAuthGuide": "Använd alternativet \"Exportera\" i Proton Authenticator-inställningarna för att exportera koder.",
"exportCodes": "Exportera koder",
"importLabel": "Importera",
"importInstruction": "Vänligen välj en fil som innehåller en lista över dina koder i följande format",
@@ -119,11 +120,11 @@
"emailVerificationToggle": "E-postverifiering",
"emailVerificationEnableWarning": "För att undvika att bli låst från ditt konto, se till att spara en kopia av din e-post 2FA utanför Ente Auth innan du aktiverar e-postverifiering.",
"authToChangeEmailVerificationSetting": "Autentisera för att ändra din e-postadress",
"authenticateGeneric": "Var god autentisera",
"authenticateGeneric": "Vänligen autentisera",
"authToViewYourRecoveryKey": "Autentisera för att visa din återställningsnyckel",
"authToChangeYourEmail": "Autentisera för att ändra din e-postadress",
"authToChangeYourPassword": "Autentisera för att ändra ditt lösenord",
"authToViewSecrets": "Autentisera för att visa din återställningsnyckel",
"authToViewSecrets": "Vänligen autentisera för att visa din återställningsnyckel",
"authToInitiateSignIn": "Vänligen autentisera för att initiera inloggning för säkerhetskopiering.",
"ok": "OK",
"cancel": "Avbryt",
@@ -147,7 +148,7 @@
"leaveFamily": "Lämna familjen",
"leaveFamilyMessage": "Är du säker på att du vill lämna familjeplanen?",
"inFamilyPlanMessage": "Du är på en familjeplan!",
"hintForMobile": "Håll i på en kod för att redigera eller ta bort.",
"hintForMobile": "Tryck länge på en kod för att redigera eller ta bort.",
"hintForDesktop": "Högerklicka på en kod för att redigera eller ta bort.",
"scan": "Skanna",
"scanACode": "Skanna kod",
@@ -191,7 +192,7 @@
"oopsSomethingWentWrong": "Hoppsan! Något gick fel.",
"selectLanguage": "Välj språk",
"language": "Språk",
"social": "Social",
"social": "Socialt",
"security": "Säkerhet",
"lockscreen": "Låsskärm",
"authToChangeLockscreenSetting": "Vänligen autentisera för att ändra låsskärms inställningar",
@@ -200,7 +201,7 @@
"authToViewYourActiveSessions": "Autentisera för att visa dina aktiva sessioner",
"searchHint": "Sök...",
"search": "Sök",
"sorryUnableToGenCode": "Tyvärr, det gick inte att generera en kod för {issuerName}",
"sorryUnableToGenCode": "Tyvärr, kunde inte generera en kod för {issuerName}",
"noResult": "Inga resultat",
"addCode": "Lägg till kod",
"scanAQrCode": "Skanna en QR-kod",
@@ -215,7 +216,7 @@
"error": "Fel",
"recoveryKeyCopiedToClipboard": "Återställningsnyckel kopierad till urklipp",
"recoveryKeyOnForgotPassword": "Om du glömmer ditt lösenord är det enda sättet du kan återställa dina data med denna nyckel.",
"recoveryKeySaveDescription": "Vi lagrar inte och har därför inte åtkomst till denna nyckel, vänligen spara denna 24 ords nyckel på en säker plats.",
"recoveryKeySaveDescription": "Vi lagrar inte och har därför inte åtkomst till denna nyckel, vänligen spara denna 24 ordsnyckeln på en säker plats.",
"doThisLater": "Gör detta senare",
"saveKey": "Spara nyckel",
"save": "Spara",
@@ -254,7 +255,7 @@
"insecureDevice": "Osäker enhet",
"sorryWeCouldNotGenerateSecureKeysOnThisDevicennplease": "Tyvärr, kunde vi inte generera säkra nycklar på den här enheten.\n\nvänligen registrera dig från en annan enhet.",
"howItWorks": "Så här fungerar det",
"ackPasswordLostWarning": "Jag förstår att om jag förlorar mitt lösenord kan jag förlora mina data eftersom min data är <underline>end-to-end-krypterad</underline>.",
"ackPasswordLostWarning": "Jag förstår att om jag förlorar mitt lösenord kan jag förlora mina data eftersom min data är <underline>totalsträckskrypterad</underline>.",
"loginTerms": "Jag samtycker till <u-terms>användarvillkoren</u-terms> och <u-policy>integritetspolicyn</u-policy>",
"logInLabel": "Logga in",
"logout": "Logga ut",
@@ -278,7 +279,7 @@
"recoveryKeyVerifyReason": "Din återställningsnyckel är det enda sättet att återställa dina foton om du glömmer ditt lösenord. Du hittar din återställningsnyckel i Inställningar > Säkerhet.\n\nAnge din återställningsnyckel här för att verifiera att du har sparat den ordentligt.",
"confirmYourRecoveryKey": "Bekräfta din återställningsnyckel",
"confirm": "Bekräfta",
"emailYourLogs": "Maila dina loggar",
"emailYourLogs": "E-posta dina loggar",
"pleaseSendTheLogsTo": "Vänligen skicka loggarna till \n{toEmail}",
"copyEmailAddress": "Kopiera e-postadress",
"exportLogs": "Exportera loggar",
@@ -297,7 +298,7 @@
"criticalUpdateAvailable": "Kritisk uppdatering tillgänglig",
"updateAvailable": "Uppdatering tillgänglig",
"update": "Uppdatera",
"checking": "Kontrollerar ...",
"checking": "Kontrollerar...",
"youAreOnTheLatestVersion": "Du är på den senaste versionen",
"warning": "Varning",
"exportWarningDesc": "Den exporterade filen innehåller känslig information. Förvara den på ett säkert sätt.",
@@ -306,7 +307,7 @@
"description": "Text for the button to confirm the user understands the warning"
},
"authToExportCodes": "Autentisera för att exportera dina koder",
"importSuccessTitle": "Jippi!",
"importSuccessTitle": "Hurra!",
"importSuccessDesc": "Du har importerat {count} koder!",
"@importSuccessDesc": {
"placeholders": {
@@ -324,7 +325,7 @@
"checkInboxAndSpamFolder": "Vänligen kontrollera din inkorg (och skräppost) för att slutföra verifieringen",
"tapToEnterCode": "Tryck för att ange kod",
"resendEmail": "Skicka e-post igen",
"weHaveSendEmailTo": "Vi har skickat ett mail till <green>{email}</green>",
"weHaveSendEmailTo": "Vi har skickat ett e-postmeddelande till <green>{email}</green>",
"@weHaveSendEmailTo": {
"description": "Text to indicate that we have sent a mail to the user",
"placeholders": {
@@ -362,7 +363,7 @@
"selectExportFormat": "Välj exportformat",
"exportDialogDesc": "Krypterad export skyddas av ett lösenord som du väljer.",
"encrypted": "Krypterad",
"plainText": "Enkel text",
"plainText": "Oformaterad text",
"passwordToEncryptExport": "Lösenord för att kryptera export",
"export": "Exportera",
"useOffline": "Använd utan säkerhetskopior",
@@ -374,14 +375,14 @@
"compactMode": "Kompakt läge",
"shouldHideCode": "Dölj koder",
"doubleTapToViewHiddenCode": "Du kan dubbeltrycka på en post för att visa koden",
"focusOnSearchBar": "Fokusera på sök vid appstart",
"focusOnSearchBar": "Fokusera på sök vid uppstart av app",
"confirmUpdatingkey": "Är du säker på att du vill uppdatera den hemliga nyckeln?",
"minimizeAppOnCopy": "Minimera appen vid kopiering",
"editCodeAuthMessage": "Autentisera för att redigera kod",
"deleteCodeAuthMessage": "Autentisera för att radera kod",
"showQRAuthMessage": "Autentisera för att visa QR-kod",
"confirmAccountDeleteTitle": "Bekräfta radering av kontot",
"confirmAccountDeleteMessage": "Detta konto är kopplat till andra Ente apps, om du använder någon.\n\nDina uppladdade data, över alla Ente appar, kommer att schemaläggas för radering och ditt konto kommer att raderas permanent.",
"confirmAccountDeleteMessage": "Detta konto är kopplat till andra Ente applikationer, om du använder någon.\n\nDina uppladdade data, över alla Ente applikationer, kommer att schemaläggas för radering och ditt konto kommer att raderas permanent.",
"androidBiometricHint": "Verifiera identitet",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
@@ -390,7 +391,7 @@
"@androidBiometricNotRecognized": {
"description": "Message to let the user know that authentication was failed. It is used on Android side. Maximum 60 characters."
},
"androidBiometricSuccess": "Slutförd",
"androidBiometricSuccess": "Lyckades",
"@androidBiometricSuccess": {
"description": "Message to let the user know that authentication was successful. It is used on Android side. Maximum 60 characters."
},
@@ -441,7 +442,7 @@
"signOutOtherDevices": "Logga ut andra enheter",
"doNotSignOut": "Logga inte ut",
"hearUsWhereTitle": "Hur hörde du talas om Ente? (valfritt)",
"hearUsExplanation": "Vi spårar inte appinstallationer, Det skulle hjälpa oss om du berättade var du hittade oss!",
"hearUsExplanation": "Vi spårar inte installationer. Det skulle hjälpa oss om du berättade hur du hittade oss!",
"recoveryKeySaved": "Återställningsnyckel sparad i nedladdningsmappen!",
"waitingForBrowserRequest": "Väntar på webbläsarbegäran...",
"waitingForVerification": "Väntar på verifiering...",
@@ -488,6 +489,8 @@
"hideContent": "Dölj innehåll",
"hideContentDescriptionAndroid": "Döljer appinnehåll i app-växlaren och inaktiverar skärmdumpar",
"hideContentDescriptioniOS": "Döljer appinnehåll i app-växlaren",
"autoLockFeatureDescription": "Tid efter vilken appen låses efter att ha satts i bakgrunden",
"appLockDescription": "Välj mellan enhetens förvalda låsskärm och en anpassad låsskärm med en PIN-kod eller lösenord.",
"pinLock": "Pinkodslås",
"enterPin": "Ange PIN-kod",
"setNewPin": "Ställ in ny PIN-kod",
@@ -498,9 +501,31 @@
"appLockOfflineModeWarning": "Du har valt att fortsätta utan säkerhetskopior. Om du glömmer ditt applås, kommer du att bli utelåst från att komma åt dina data.",
"duplicateCodes": "Dubblettkoder",
"noDuplicates": "✨ Inga dubbletter",
"youveNoDuplicateCodesThatCanBeCleared": "Du har inga dubbla koder som kan rensas",
"deduplicateCodes": "Deduplicera koder",
"deselectAll": "Avmarkera alla",
"selectAll": "Markera alla",
"deleteDuplicates": "Radera dubbletter",
"plainHTML": "Ren HTML"
"plainHTML": "Ren HTML",
"tellUsWhatYouThink": "Berätta vad du tycker",
"dropReviewiOS": "Skriv en recension på App Store",
"dropReviewAndroid": "Skriv en recension på Play Store",
"supportEnte": "Stöd <bold-green>ente</bold-green>",
"giveUsAStarOnGithub": "Ge oss en stjärna på Github",
"free5GB": "5 GB gratis på <bold-green>ente</bold-green> Foton",
"loginWithAuthAccount": "Logga in med ditt Auth-konto",
"freeStorageOffer": "10% rabatt på <bold-green>ente</bold-green> foton",
"freeStorageOfferDescription": "Använd koden \"AUTH\" för att få 10% rabatt första året",
"advanced": "Avancerad",
"algorithm": "Algoritm",
"type": "Typ",
"period": "Tidsperiod",
"digits": "Siffror",
"importFromGallery": "Importera från galleri",
"errorCouldNotReadImage": "Kunde inte läsa den valda bildfilen.",
"errorInvalidQRCode": "Ogiltig QR-kod",
"errorInvalidQRCodeBody": "Den skannade QR-koden är inte ett giltigt 2FA konto.",
"errorNoQRCode": "Ingen QR-kod hittades",
"errorGenericTitle": "Ett fel inträffade",
"errorGenericBody": "Ett oväntat fel inträffade vid import."
}

View File

@@ -6,7 +6,7 @@
"@counterAppBarTitle": {
"description": "Text shown in the AppBar of the Counter Page"
},
"onBoardingBody": "妥善保管您的两步验证码",
"onBoardingBody": "妥善保管您的双重认证代码",
"onBoardingGetStarted": "开始",
"setupFirstAccount": "设置您的第一个账户",
"importScanQrCode": "扫描二维码",
@@ -111,13 +111,14 @@
"importAegisGuide": "使用 Aegis 设置中的“导出密码库”选项。\n\n如果您的密码库已加密则需要输入密码库密码才能解密密码库。",
"import2FasGuide": "使用 2FAS 中的“设置 -> 备份 -> 导出”选项。\n\n如果您的备份已加密则需要输入密码来解密备份",
"importLastpassGuide": "使用 Lastpass Authenticator 设置中的“转移账户”选项,然后按“将账户导出到文件”。导入下载的 JSON。",
"importProtonAuthGuide": "使用 Proton Authenticator 设置中的“导出”选项导出您的代码。",
"exportCodes": "导出代码",
"importLabel": "导入",
"importInstruction": "请选择一个包含以下格式的代码列表的文件",
"importCodeDelimiterInfo": "代码可以用逗号或换行符分隔",
"selectFile": "选择文件",
"emailVerificationToggle": "电子邮件验证",
"emailVerificationEnableWarning": "为避免被锁在您的账户之外,请在启用电子邮件验证之前确保在 Ente Auth 之外存储电子邮件两步验证的副本。",
"emailVerificationEnableWarning": "为避免被锁在您的账户之外,请在启用电子邮件验证之前确保在 Ente Auth 之外存储电子邮件双重认证的副本。",
"authToChangeEmailVerificationSetting": "请进行身份验证以更改电子邮件验证",
"authenticateGeneric": "请验证",
"authToViewYourRecoveryKey": "请验证以查看您的恢复密钥",
@@ -155,7 +156,7 @@
"verifyEmail": "验证电子邮件",
"enterCodeHint": "从你的身份验证器应用中\n输入6位数字代码",
"lostDeviceTitle": "丢失了设备吗?",
"twoFactorAuthTitle": "两步验证",
"twoFactorAuthTitle": "双重认证",
"passkeyAuthTitle": "通行密钥验证",
"verifyPasskey": "验证通行密钥",
"loginWithTOTP": "使用 TOTP 登录",
@@ -519,5 +520,12 @@
"algorithm": "算法",
"type": "类型",
"period": "周期",
"digits": "数字"
"digits": "数字",
"importFromGallery": "从图库导入",
"errorCouldNotReadImage": "无法读取所选图片文件。",
"errorInvalidQRCode": "二维码无效",
"errorInvalidQRCodeBody": "扫描的二维码不是有效的双重认证账户。",
"errorNoQRCode": "未找到二维码",
"errorGenericTitle": "出错了",
"errorGenericBody": "导入时发生意外错误。"
}

View File

@@ -39,7 +39,9 @@ import 'package:ente_auth/utils/totp_util.dart';
import 'package:ente_events/event_bus.dart';
import 'package:ente_lock_screen/lock_screen_settings.dart';
import 'package:ente_lock_screen/ui/app_lock.dart';
import 'package:ente_qr/ente_qr.dart';
import 'package:ente_ui/pages/base_home_page.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -48,7 +50,7 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:logging/logging.dart';
import 'package:move_to_background/move_to_background.dart';
class HomePage extends BaseHomePage {
class HomePage extends BaseHomePage {
const HomePage({super.key});
@override
@@ -62,6 +64,7 @@ class _HomePageState extends State<HomePage> {
);
bool _hasLoaded = false;
bool _isSettingsOpen = false;
bool _isImportingFromGallery = false;
final Logger _logger = Logger("HomePage");
final scaffoldKey = GlobalKey<ScaffoldState>();
@@ -288,6 +291,63 @@ class _HomePageState extends State<HomePage> {
}
}
Future<void> _importFromGalleryNative() async {
final l10n = AppLocalizations.of(context);
if (_isImportingFromGallery) {
return;
}
_isImportingFromGallery = true;
try {
final FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.image,
);
if (result == null || result.files.single.path == null) {
return;
}
final String imagePath = result.files.single.path!;
final enteQr = EnteQr();
final QrScanResult qrResult = await enteQr.scanQrFromImage(imagePath);
if (qrResult.success && qrResult.content != null) {
try {
final newCode = Code.fromOTPAuthUrl(qrResult.content!);
await CodeStore.instance.addCode(newCode, shouldSync: false);
// Focus the new code by searching
if ((_allCodes?.where((e) => !e.hasError).length ?? 0) > 2) {
_focusNewCode(newCode);
}
} catch (e) {
_logger.severe('Error adding code from QR scan', e);
await showErrorDialog(
context,
l10n.errorInvalidQRCode,
l10n.errorInvalidQRCodeBody,
);
}
} else {
_logger.warning('QR scan failed: ${qrResult.error}');
await showErrorDialog(
context,
l10n.errorNoQRCode,
qrResult.error ?? l10n.errorNoQRCode,
);
}
} catch (e) {
await showErrorDialog(
context,
l10n.errorGenericTitle,
l10n.errorGenericBody,
);
} finally {
_isImportingFromGallery = false;
}
}
Future<void> _redirectToScannerPage() async {
final Code? code = await Navigator.of(context).push(
MaterialPageRoute(
@@ -322,7 +382,8 @@ class _HomePageState extends State<HomePage> {
final bool shouldShowLockScreen =
await LockScreenSettings.instance.shouldShowLockScreen();
if (shouldShowLockScreen) {
await AppLock.of(context)!.showLockScreen();
// Manual lock: do not auto-prompt Touch ID; wait for user tap
await AppLock.of(context)!.showManualLockScreen();
} else {
await showDialogWidget(
context: context,
@@ -745,6 +806,14 @@ class _HomePageState extends State<HomePage> {
labelWidget: SpeedDialLabelWidget(context.l10n.enterDetailsManually),
onTap: _redirectToManualEntryPage,
),
if (PlatformUtil.isMobile())
SpeedDialChild(
child: const Icon(Icons.image),
backgroundColor: Theme.of(context).colorScheme.fabBackgroundColor,
foregroundColor: Theme.of(context).colorScheme.fabForegroundColor,
labelWidget: SpeedDialLabelWidget(context.l10n.importFromGallery),
onTap: _importFromGalleryNative,
),
],
);
}

View File

@@ -4,6 +4,7 @@ import 'package:ente_auth/ui/settings/data/import/encrypted_ente_import.dart';
import 'package:ente_auth/ui/settings/data/import/google_auth_import.dart';
import 'package:ente_auth/ui/settings/data/import/lastpass_import.dart';
import 'package:ente_auth/ui/settings/data/import/plain_text_import.dart';
import 'package:ente_auth/ui/settings/data/import/proton_import.dart';
import 'package:ente_auth/ui/settings/data/import/raivo_plain_text_import.dart';
import 'package:ente_auth/ui/settings/data/import/two_fas_import.dart';
import 'package:ente_auth/ui/settings/data/import_page.dart';
@@ -43,6 +44,9 @@ class ImportService {
case ImportType.lastpass:
await showLastpassImportInstruction(context);
break;
case ImportType.proton:
await showProtonImportInstruction(context);
break;
}
}
}

View File

@@ -0,0 +1,171 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:ente_auth/l10n/l10n.dart';
import 'package:ente_auth/models/code.dart';
import 'package:ente_auth/services/authenticator_service.dart';
import 'package:ente_auth/store/code_store.dart';
import 'package:ente_auth/ui/common/progress_dialog.dart';
import 'package:ente_auth/ui/components/buttons/button_widget.dart';
import 'package:ente_auth/ui/components/dialog_widget.dart';
import 'package:ente_auth/ui/components/models/button_type.dart';
import 'package:ente_auth/ui/settings/data/import/import_success.dart';
import 'package:ente_auth/utils/dialog_util.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
Future<void> showProtonImportInstruction(BuildContext context) async {
final l10n = context.l10n;
final result = await showDialogWidget(
context: context,
title: l10n.importFromApp("Proton Authenticator"),
body: l10n.importProtonAuthGuide,
buttons: [
ButtonWidget(
buttonType: ButtonType.primary,
labelText: l10n.importSelectJsonFile,
isInAlert: true,
buttonSize: ButtonSize.large,
buttonAction: ButtonAction.first,
),
ButtonWidget(
buttonType: ButtonType.secondary,
labelText: context.l10n.cancel,
buttonSize: ButtonSize.large,
isInAlert: true,
buttonAction: ButtonAction.second,
),
],
);
if (result?.action != null && result!.action != ButtonAction.cancel) {
if (result.action == ButtonAction.first) {
await _pickProtonJsonFile(context);
}
}
}
Future<void> _pickProtonJsonFile(BuildContext context) async {
final l10n = context.l10n;
FilePickerResult? result = await FilePicker.platform
.pickFiles(dialogTitle: l10n.importSelectJsonFile);
if (result == null) {
return;
}
final ProgressDialog progressDialog =
createProgressDialog(context, l10n.pleaseWait);
await progressDialog.show();
try {
String path = result.files.single.path!;
int? count = await _processProtonExportFile(context, path, progressDialog);
await progressDialog.hide();
if (count != null) {
await importSuccessDialog(context, count);
}
} catch (e, s) {
Logger('ProtonImport')
.severe('exception while processing proton import', e, s);
await progressDialog.hide();
await showErrorDialog(
context,
context.l10n.sorry,
"${context.l10n.importFailureDescNew}\n Error: ${e.toString()}",
);
}
}
Future<int?> _processProtonExportFile(
BuildContext context,
String path,
final ProgressDialog dialog,
) async {
File file = File(path);
final jsonString = await file.readAsString();
final decodedJson = jsonDecode(jsonString);
// Validate that this is a Proton export
if (decodedJson['version'] == null || decodedJson['entries'] == null) {
await dialog.hide();
await showErrorDialog(
context,
'Invalid Proton export',
'The selected file is not a valid Proton Authenticator export.',
);
return null;
}
final parsedCodes = <Code>[];
final entries = decodedJson['entries'] as List;
for (var entry in entries) {
try {
final content = entry['content'];
if (content == null) {
continue; // Skip entries without content
}
final entryType = content['entry_type'] as String?;
if (entryType != 'Totp' && entryType != 'Steam') {
// log warning
Logger('ProtonImport').warning('Unsupported entry type: $entryType');
continue; // Skip non-TOTP and non-Steam entries
}
Code code;
if (entryType == 'Steam') {
// Handle Steam entries with steam:// format
final steamUri = content['uri'] as String?;
if (steamUri == null || !steamUri.startsWith('steam://')) {
continue; // Skip invalid Steam URIs
}
final secret = steamUri.split('steam://')[1];
final name = content['name'] as String? ?? '';
code = Code.fromAccountAndSecret(
Type.steam,
'', // Steam doesn't typically have separate account
name, // Use name as issuer
secret,
null,
Code.steamDigits,
);
} else {
// Handle TOTP entries with otpauth:// format
final otpUri = content['uri'] as String?;
if (otpUri == null || !otpUri.startsWith('otpauth://')) {
continue; // Skip invalid OTP URIs
}
// Create code from OTP auth URL
code = Code.fromOTPAuthUrl(otpUri);
}
// Add note if present
final note = entry['note'] as String?;
if (note != null && note.isNotEmpty) {
code = code.copyWith(
display: code.display.copyWith(note: note),
);
}
parsedCodes.add(code);
} catch (e, s) {
Logger('ProtonImport').warning('Failed to parse entry', e, s);
// Continue processing other entries
}
}
// Add all parsed codes to the store
for (final code in parsedCodes) {
await CodeStore.instance.addCode(code, shouldSync: false);
}
// Trigger sync
unawaited(AuthenticatorService.instance.onlineSync());
return parsedCodes.length;
}

View File

@@ -17,6 +17,7 @@ enum ImportType {
twoFas,
bitwarden,
lastpass,
proton,
}
class ImportCodePage extends StatelessWidget {
@@ -29,6 +30,7 @@ class ImportCodePage extends StatelessWidget {
ImportType.aegis,
ImportType.bitwarden,
ImportType.googleAuthenticator,
ImportType.proton,
ImportType.ravio,
ImportType.lastpass,
];
@@ -51,6 +53,8 @@ class ImportCodePage extends StatelessWidget {
return 'Bitwarden';
case ImportType.lastpass:
return 'LastPass Authenticator';
case ImportType.proton:
return 'Proton Authenticator';
}
}

View File

@@ -0,0 +1,33 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "761747bfc538b5af34aa0d3fac380f1bc331ec49"
channel: "stable"
project_type: plugin
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
- platform: android
create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
- platform: ios
create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

View File

@@ -0,0 +1,8 @@
## 0.0.1
* Initial release of ente_qr plugin
* Support for scanning QR codes from image files
* Android implementation using ZXing library
* iOS implementation using Core Image framework
* Comprehensive error handling
* Example app demonstrating usage with file picker

View File

@@ -0,0 +1,170 @@
# ente_qr
A Flutter plugin for scanning QR codes from image files. This plugin provides a simple interface to scan QR codes from images on both Android and iOS platforms.
## Features
- Scan QR codes from image files
- Support for Android (using ZXing library)
- Support for iOS (using AVFoundation/Core Image)
- Returns structured results with error handling
- Works with images from file picker or camera
## Platform Support
| Platform | Support |
|----------|---------|
| Android | ✅ |
| iOS | ✅ |
| Web | ❌ |
| macOS | ❌ |
| Windows | ❌ |
| Linux | ❌ |
## Installation
Add this to your package's `pubspec.yaml` file:
```yaml
dependencies:
ente_qr:
path: path/to/ente_qr
```
## Usage
### Basic Usage
```dart
import 'package:ente_qr/ente_qr.dart';
final qr = EnteQr();
// Scan QR code from an image file
final result = await qr.scanQrFromImage('/path/to/image.jpg');
if (result.success) {
print('QR Code content: ${result.content}');
} else {
print('Error: ${result.error}');
}
```
### Complete Example with File Picker
```dart
import 'package:flutter/material.dart';
import 'package:ente_qr/ente_qr.dart';
import 'package:file_picker/file_picker.dart';
class QrScannerPage extends StatefulWidget {
@override
_QrScannerPageState createState() => _QrScannerPageState();
}
class _QrScannerPageState extends State<QrScannerPage> {
final _enteQr = EnteQr();
String _result = 'No QR code scanned';
Future<void> _scanQrFromImage() async {
// Pick an image file
FilePickerResult? fileResult = await FilePicker.platform.pickFiles(
type: FileType.image,
allowMultiple: false,
);
if (fileResult != null && fileResult.files.single.path != null) {
final imagePath = fileResult.files.single.path!;
// Scan QR code from the selected image
final qrResult = await _enteQr.scanQrFromImage(imagePath);
setState(() {
if (qrResult.success) {
_result = 'QR Code: ${qrResult.content}';
} else {
_result = 'Error: ${qrResult.error}';
}
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('QR Scanner')),
body: Column(
children: [
ElevatedButton(
onPressed: _scanQrFromImage,
child: Text('Pick Image and Scan QR'),
),
Text(_result),
],
),
);
}
}
```
## API Reference
### EnteQr
The main class for QR code scanning operations.
#### Methods
##### `scanQrFromImage(String imagePath)`
Scans a QR code from an image file.
**Parameters:**
- `imagePath` (String): The file path to the image containing the QR code
**Returns:**
- `Future<QrScanResult>`: A result object containing either the QR code content or an error
### QrScanResult
The result object returned by QR scanning operations.
**Properties:**
- `content` (String?): The QR code content if successful, null otherwise
- `error` (String?): Error message if scanning failed, null otherwise
- `success` (bool): Whether the scanning operation was successful
**Factory Constructors:**
- `QrScanResult.success(String content)`: Creates a successful result
- `QrScanResult.error(String error)`: Creates an error result
## Implementation Details
### Android
The Android implementation uses the ZXing library (com.google.zxing) for QR code detection:
- `com.journeyapps:zxing-android-embedded:4.3.0`
- `com.google.zxing:core:3.5.1`
### iOS
The iOS implementation uses Core Image framework's built-in QR code detection capabilities via `CIDetector`.
## Error Handling
The plugin provides comprehensive error handling for common scenarios:
- File not found
- Invalid image format
- No QR code found in image
- Platform-specific errors
- Unexpected errors
All errors are returned as part of the `QrScanResult` object with descriptive error messages.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
This project is licensed under the same license as the Ente project.

View File

@@ -0,0 +1 @@
include: ../../analysis_options.yaml

View File

@@ -0,0 +1,65 @@
group 'io.ente.auth.ente_qr'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
rootProject.allprojects {
repositories {
google()
mavenCentral()
}
}
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion 33
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
test.java.srcDirs += 'src/test/kotlin'
}
defaultConfig {
minSdkVersion 16
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
implementation 'com.google.zxing:core:3.5.1'
}
testOptions {
unitTests.all {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false}
showStandardStreams = true
}
}
}
}

View File

@@ -0,0 +1 @@
rootProject.name = 'ente_qr'

View File

@@ -0,0 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.ente.auth.ente_qr">
</manifest>

View File

@@ -0,0 +1,138 @@
package io.ente.auth.ente_qr
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.annotation.NonNull
import com.google.zxing.BarcodeFormat
import com.google.zxing.BinaryBitmap
import com.google.zxing.DecodeHintType
import com.google.zxing.MultiFormatReader
import com.google.zxing.NotFoundException
import com.google.zxing.RGBLuminanceSource
import com.google.zxing.Result as ZXingResult
import com.google.zxing.common.HybridBinarizer
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import java.io.File
import java.util.*
/** EnteQrPlugin */
class EnteQrPlugin: FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private lateinit var channel : MethodChannel
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "ente_qr")
channel.setMethodCallHandler(this)
}
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
when (call.method) {
"getPlatformVersion" -> {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
}
"scanQrFromImage" -> {
val imagePath = call.argument<String>("imagePath")
if (imagePath == null) {
result.success(mapOf(
"success" to false,
"error" to "Image path is required"
))
return
}
try {
val qrResult = scanQrCode(imagePath)
result.success(qrResult)
} catch (e: Exception) {
result.success(mapOf(
"success" to false,
"error" to "Error scanning QR code: ${e.message}"
))
}
}
else -> {
result.notImplemented()
}
}
}
private fun scanQrCode(imagePath: String): Map<String, Any> {
try {
val file = File(imagePath)
if (!file.exists()) {
return mapOf(
"success" to false,
"error" to "Image file not found: $imagePath"
)
}
var bitmap = BitmapFactory.decodeFile(imagePath)
if (bitmap == null) {
return mapOf(
"success" to false,
"error" to "Unable to decode image file"
)
}
// Try multiple times with different image sizes like Aegis does
for (i in 0..2) {
if (i != 0) {
// Resize bitmap for subsequent attempts
val newWidth = bitmap.width / (i * 2)
val newHeight = bitmap.height / (i * 2)
if (newWidth > 0 && newHeight > 0) {
bitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true)
}
}
try {
val width = bitmap.width
val height = bitmap.height
val pixels = IntArray(width * height)
bitmap.getPixels(pixels, 0, width, 0, 0, width, height)
val source = RGBLuminanceSource(width, height, pixels)
val binaryBitmap = BinaryBitmap(HybridBinarizer(source))
val reader = MultiFormatReader()
val hints = HashMap<DecodeHintType, Any>()
hints[DecodeHintType.POSSIBLE_FORMATS] = listOf(BarcodeFormat.QR_CODE)
hints[DecodeHintType.TRY_HARDER] = true
hints[DecodeHintType.ALSO_INVERTED] = true
reader.setHints(hints)
val qrResult: ZXingResult = reader.decode(binaryBitmap)
return mapOf(
"success" to true,
"content" to qrResult.text
)
} catch (e: NotFoundException) {
// Continue to next iteration
continue
}
}
return mapOf(
"success" to false,
"error" to "No QR code found in image"
)
} catch (e: Exception) {
return mapOf(
"success" to false,
"error" to "Error scanning QR code: ${e.message}"
)
}
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
}

View File

@@ -0,0 +1,77 @@
import Flutter
import UIKit
import AVFoundation
public class EnteQrPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "ente_qr", binaryMessenger: registrar.messenger())
let instance = EnteQrPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "getPlatformVersion":
result("iOS " + UIDevice.current.systemVersion)
case "scanQrFromImage":
guard let args = call.arguments as? [String: Any],
let imagePath = args["imagePath"] as? String else {
result([
"success": false,
"error": "Image path is required"
])
return
}
scanQrCode(from: imagePath, result: result)
default:
result(FlutterMethodNotImplemented)
}
}
private func scanQrCode(from imagePath: String, result: @escaping FlutterResult) {
guard let image = UIImage(contentsOfFile: imagePath) else {
result([
"success": false,
"error": "Unable to load image from path: \(imagePath)"
])
return
}
guard let cgImage = image.cgImage else {
result([
"success": false,
"error": "Unable to get CGImage from UIImage"
])
return
}
let detector = CIDetector(ofType: CIDetectorTypeQRCode,
context: nil,
options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])
guard let qrDetector = detector else {
result([
"success": false,
"error": "Unable to create QR code detector"
])
return
}
let ciImage = CIImage(cgImage: cgImage)
let features = qrDetector.features(in: ciImage)
if let qrFeature = features.first as? CIQRCodeFeature,
let messageString = qrFeature.messageString {
result([
"success": true,
"content": messageString
])
} else {
result([
"success": false,
"error": "No QR code found in image"
])
}
}
}

View File

@@ -0,0 +1,23 @@
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint ente_qr.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'ente_qr'
s.version = '0.0.1'
s.summary = 'A QR code reader plugin for Ente.'
s.description = <<-DESC
A QR code reader plugin for Ente.
DESC
s.homepage = 'https://ente.io'
s.license = { :file => '../LICENSE' }
s.author = { 'Ente' => 'team@ente.io' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.platform = :ios, '9.0'
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
s.swift_version = '5.0'
end

View File

@@ -0,0 +1,30 @@
import 'package:ente_qr/ente_qr_platform_interface.dart';
export 'ente_qr_platform_interface.dart' show QrScanResult;
class EnteQr {
Future<String?> getPlatformVersion() {
return EnteQrPlatform.instance.getPlatformVersion();
}
/// Scans a QR code from an image file at the given path.
///
/// [imagePath] - The file path to the image containing the QR code
///
/// Returns a [QrScanResult] containing either the QR code content on success
/// or an error message on failure.
///
/// Example:
/// ```dart
/// final qr = EnteQr();
/// final result = await qr.scanQrFromImage('/path/to/image.jpg');
/// if (result.success) {
/// print('QR Code content: ${result.content}');
/// } else {
/// print('Error: ${result.error}');
/// }
/// ```
Future<QrScanResult> scanQrFromImage(String imagePath) {
return EnteQrPlatform.instance.scanQrFromImage(imagePath);
}
}

View File

@@ -0,0 +1,52 @@
import 'package:ente_qr/ente_qr_platform_interface.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
/// An implementation of [EnteQrPlatform] that uses method channels.
class MethodChannelEnteQr extends EnteQrPlatform {
/// The method channel used to interact with the native platform.
@visibleForTesting
final methodChannel = const MethodChannel('ente_qr');
@override
Future<String?> getPlatformVersion() async {
final version =
await methodChannel.invokeMethod<String>('getPlatformVersion');
return version;
}
@override
Future<QrScanResult> scanQrFromImage(String imagePath) async {
try {
final dynamic result = await methodChannel.invokeMethod(
'scanQrFromImage',
{'imagePath': imagePath},
);
if (result == null) {
return QrScanResult.error('Failed to scan QR code');
}
// Convert to Map<String, dynamic> safely
final Map<String, dynamic> resultMap =
Map<String, dynamic>.from(result as Map);
final bool success = resultMap['success'] as bool? ?? false;
if (success) {
final String? content = resultMap['content'] as String?;
if (content != null && content.isNotEmpty) {
return QrScanResult.success(content);
} else {
return QrScanResult.error('No QR code found in image');
}
} else {
final String? error = resultMap['error'] as String?;
return QrScanResult.error(error ?? 'Unknown error occurred');
}
} on PlatformException catch (e) {
return QrScanResult.error('Platform error: ${e.message}');
} catch (e) {
return QrScanResult.error('Unexpected error: $e');
}
}
}

View File

@@ -0,0 +1,61 @@
import 'package:ente_qr/ente_qr_method_channel.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
/// The result of QR code scanning
class QrScanResult {
final String? content;
final String? error;
final bool success;
const QrScanResult({
this.content,
this.error,
required this.success,
});
factory QrScanResult.success(String content) {
return QrScanResult(
content: content,
success: true,
);
}
factory QrScanResult.error(String error) {
return QrScanResult(
error: error,
success: false,
);
}
}
abstract class EnteQrPlatform extends PlatformInterface {
/// Constructs a EnteQrPlatform.
EnteQrPlatform() : super(token: _token);
static final Object _token = Object();
static EnteQrPlatform _instance = MethodChannelEnteQr();
/// The default instance of [EnteQrPlatform] to use.
///
/// Defaults to [MethodChannelEnteQr].
static EnteQrPlatform get instance => _instance;
/// Platform-specific implementations should set this with their own
/// platform-specific class that extends [EnteQrPlatform] when
/// they register themselves.
static set instance(EnteQrPlatform instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}
Future<String?> getPlatformVersion() {
throw UnimplementedError('platformVersion() has not been implemented.');
}
/// Scans a QR code from an image file at the given path.
/// Returns the QR code content as a string if successful, null otherwise.
Future<QrScanResult> scanQrFromImage(String imagePath) {
throw UnimplementedError('scanQrFromImage() has not been implemented.');
}
}

View File

@@ -0,0 +1,213 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
url: "https://pub.dev"
source: hosted
version: "2.13.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
characters:
dependency: transitive
description:
name: characters
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev"
source: hosted
version: "1.4.0"
clock:
dependency: transitive
description:
name: clock
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
url: "https://pub.dev"
source: hosted
version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev"
source: hosted
version: "1.19.1"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
url: "https://pub.dev"
source: hosted
version: "1.3.3"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
url: "https://pub.dev"
source: hosted
version: "10.0.9"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
url: "https://pub.dev"
source: hosted
version: "3.0.9"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
url: "https://pub.dev"
source: hosted
version: "3.0.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev"
source: hosted
version: "0.12.17"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
url: "https://pub.dev"
source: hosted
version: "1.16.0"
path:
dependency: transitive
description:
name: path
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
url: "https://pub.dev"
source: hosted
version: "1.9.1"
plugin_platform_interface:
dependency: "direct main"
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.8"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
source_span:
dependency: transitive
description:
name: source_span
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
url: "https://pub.dev"
source: hosted
version: "1.10.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
url: "https://pub.dev"
source: hosted
version: "1.12.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
url: "https://pub.dev"
source: hosted
version: "1.4.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
url: "https://pub.dev"
source: hosted
version: "1.2.2"
test_api:
dependency: transitive
description:
name: test_api
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
url: "https://pub.dev"
source: hosted
version: "0.7.4"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
url: "https://pub.dev"
source: hosted
version: "15.0.0"
sdks:
dart: ">=3.7.0-0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"

View File

@@ -0,0 +1,29 @@
name: ente_qr
description: "A QR code reader plugin for Ente."
version: 0.0.1
homepage: https://ente.io
environment:
sdk: '>=3.4.3 <4.0.0'
flutter: '>=3.3.0'
dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.0.2
dev_dependencies:
flutter_lints: ^3.0.0
flutter_test:
sdk: flutter
# The following section is specific to Flutter packages.
flutter:
# This section identifies this Flutter project as a plugin project.
plugin:
platforms:
android:
package: io.ente.auth.ente_qr
pluginClass: EnteQrPlugin
ios:
pluginClass: EnteQrPlugin

View File

@@ -0,0 +1,32 @@
import 'package:ente_qr/ente_qr.dart';
import 'package:ente_qr/ente_qr_method_channel.dart';
import 'package:ente_qr/ente_qr_platform_interface.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
class MockEnteQrPlatform
with MockPlatformInterfaceMixin
implements EnteQrPlatform {
@override
Future<String?> getPlatformVersion() => Future.value('42');
@override
Future<QrScanResult> scanQrFromImage(String imagePath) =>
Future.value(QrScanResult.error('Mock implementation'));
}
void main() {
final EnteQrPlatform initialPlatform = EnteQrPlatform.instance;
test('$MethodChannelEnteQr is the default instance', () {
expect(initialPlatform, isInstanceOf<MethodChannelEnteQr>());
});
test('getPlatformVersion', () async {
final EnteQr enteQrPlugin = EnteQr();
final MockEnteQrPlatform fakePlatform = MockEnteQrPlatform();
EnteQrPlatform.instance = fakePlatform;
expect(await enteQrPlugin.getPlatformVersion(), '42');
});
}

View File

@@ -451,6 +451,13 @@ packages:
relative: true
source: path
version: "1.0.0"
ente_qr:
dependency: "direct main"
description:
path: "plugins/qr"
relative: true
source: path
version: "0.0.1"
ente_strings:
dependency: "direct main"
description:
@@ -466,7 +473,7 @@ packages:
source: path
version: "1.0.0"
ente_utils:
dependency: transitive
dependency: "direct overridden"
description:
path: "../../packages/utils"
relative: true
@@ -532,10 +539,10 @@ packages:
dependency: "direct main"
description:
name: file_picker
sha256: ef9908739bdd9c476353d6adff72e88fd00c625f5b959ae23f7567bd5137db0a
sha256: e7e16c9d15c36330b94ca0e2ad8cb61f93cd5282d0158c09805aed13b5452f22
url: "https://pub.dev"
source: hosted
version: "10.2.0"
version: "10.3.2"
file_saver:
dependency: "direct main"
description:
@@ -951,7 +958,7 @@ packages:
source: hosted
version: "0.1.0"
image:
dependency: transitive
dependency: "direct main"
description:
name: image
sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928"

View File

@@ -1,6 +1,6 @@
name: ente_auth
description: ente two-factor authenticator
version: 4.4.6+446
version: 4.4.7+447
publish_to: none
environment:
@@ -41,6 +41,8 @@ dependencies:
path: ../../packages/logging
ente_network:
path: ../../packages/network
ente_qr:
path: plugins/qr
ente_strings:
path: ../../packages/strings
ente_ui:
@@ -50,7 +52,7 @@ dependencies:
expansion_tile_card: ^3.0.0
ffi: ^2.1.0
figma_squircle: ^0.6.3
file_picker: ^10.2.0
file_picker: ^10.3.2
file_saver: ^0.3.1
fixnum: ^1.1.0
fk_user_agent: # no package updates on pub.dev
@@ -84,6 +86,7 @@ dependencies:
google_nav_bar: ^5.0.5 #supported
gradient_borders: ^1.0.0
http: ^1.1.0
image: ^4.5.4
intl: ^0.20.2
io: ^1.0.4
json_annotation: ^4.5.0

View File

@@ -0,0 +1,22 @@
# melos_managed_dependency_overrides: ente_accounts,ente_base,ente_configuration,ente_events,ente_lock_screen,ente_logging,ente_network,ente_strings,ente_ui,ente_utils
dependency_overrides:
ente_accounts:
path: ../../packages/accounts
ente_base:
path: ../../packages/base
ente_configuration:
path: ../../packages/configuration
ente_events:
path: ../../packages/events
ente_lock_screen:
path: ../../packages/lock_screen
ente_logging:
path: ../../packages/logging
ente_network:
path: ../../packages/network
ente_strings:
path: ../../packages/strings
ente_ui:
path: ../../packages/ui
ente_utils:
path: ../../packages/utils

View File

@@ -1 +1,7 @@
# soon.
# Ente Locker
## TODOs
Refactor and merge
- [ ] Verify correctness for `PackageInfoUtil.getPackageName()` on Linux and Windows
- [ ] Update `file_url.dart` to download only via CF worker when necessary

View File

@@ -1,72 +1 @@
# For more linters, we can check https://dart-lang.github.io/linter/lints/index.html
# or https://pub.dev/packages/lint (Effective dart)
# use "flutter analyze ." or "dart analyze ." for running lint checks
include: package:flutter_lints/flutter.yaml
linter:
rules:
# Ref https://github.com/flutter/packages/blob/master/packages/flutter_lints/lib/flutter.yaml
# Ref https://dart-lang.github.io/linter/lints/
- avoid_print
- avoid_unnecessary_containers
- avoid_web_libraries_in_flutter
- no_logic_in_create_state
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
- prefer_final_locals
- require_trailing_commas
- sized_box_for_whitespace
- use_full_hex_values_for_flutter_colors
- use_key_in_widget_constructors
- cancel_subscriptions
- avoid_empty_else
- exhaustive_cases
# just style suggestions
- sort_pub_dependencies
- use_rethrow_when_possible
- prefer_double_quotes
- directives_ordering
- always_use_package_imports
- sort_child_properties_last
- unawaited_futures
analyzer:
errors:
avoid_empty_else: error
exhaustive_cases: error
curly_braces_in_flow_control_structures: error
directives_ordering: error
require_trailing_commas: error
always_use_package_imports: warning
prefer_final_fields: error
unused_import: error
camel_case_types: error
prefer_is_empty: warning
use_rethrow_when_possible: info
unused_field: warning
use_key_in_widget_constructors: warning
sort_child_properties_last: warning
sort_pub_dependencies: warning
library_private_types_in_public_api: warning
constant_identifier_names: ignore
prefer_const_constructors: warning
prefer_const_declarations: warning
prefer_const_constructors_in_immutables: warning
prefer_final_locals: warning
unnecessary_const: error
cancel_subscriptions: error
unrelated_type_equality_checks: error
unnecessary_cast: info
unawaited_futures: warning # convert to warning after fixing existing issues
invalid_dependency: info
use_build_context_synchronously: ignore # experimental lint, requires many changes
prefer_interpolation_to_compose_strings: ignore # later too many warnings
prefer_double_quotes: ignore # too many warnings
avoid_renaming_method_parameters: ignore # incorrect warnings for `equals` overrides
include: ../../analysis_options.yaml

View File

@@ -8,7 +8,7 @@
<application
android:label="Ente Locker"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
android:icon="@mipmap/icon_blue">
<activity
android:name=".MainActivity"
android:exported="true"
@@ -54,4 +54,5 @@
<data android:mimeType="text/plain"/>
</intent>
</queries>
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
</manifest>

View File

@@ -1,5 +1,6 @@
package io.ente.locker
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity: FlutterActivity()
class MainActivity: FlutterFragmentActivity() {
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#1071ff</color>
</resources>

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -0,0 +1,20 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_34053_111310)">
<path d="M170 66.7593C170 71.8084 169.042 76.732 167.151 81.3933C165.192 86.2233 162.316 90.5536 158.606 94.265L147.36 105.511L151.657 109.806C152.962 111.112 152.26 113.347 150.441 113.671L128.349 117.598C126.785 117.875 125.423 116.513 125.7 114.949L129.628 92.8595C129.952 91.0413 132.187 90.3393 133.492 91.6442L137.12 95.2717L148.366 84.0261C152.978 79.4144 155.519 73.282 155.519 66.7609C155.519 60.2383 152.978 54.105 148.365 49.4941C143.753 44.8815 137.621 42.3422 131.097 42.3422C124.574 42.3422 118.442 44.8815 113.83 49.4941L107.387 55.936C107.383 55.9064 107.378 55.8784 107.373 55.8488L104.299 38.5628C107.848 35.1847 111.936 32.5447 116.463 30.7097C121.123 28.818 126.048 27.8594 131.097 27.8594C136.146 27.8594 141.07 28.818 145.732 30.7089C150.564 32.667 154.894 35.5421 158.606 39.2528C162.317 42.9643 165.192 47.2946 167.151 52.1246C169.041 56.7859 169.999 61.711 170 66.7593Z" fill="#4AAF3C"/>
<path d="M133.814 119.087L105.12 147.779C103.762 149.137 101.92 149.9 99.9998 149.9C98.0791 149.9 96.2375 149.137 94.879 147.779L70.7775 123.678L67.503 126.953C66.1972 128.259 63.9623 127.556 63.6392 125.737L59.7107 103.646C59.4332 102.083 60.7966 100.72 62.3598 100.997L84.4519 104.925C86.2702 105.249 86.9731 107.483 85.6673 108.789L81.0183 113.438L100.001 132.42L124.507 107.914L123.318 114.601C123.053 116.096 123.535 117.63 124.609 118.703C125.684 119.778 127.217 120.259 128.712 119.994L133.814 119.087H133.814Z" fill="#4AAF3C"/>
<path d="M102.359 58.8607L80.2668 54.9325C78.4485 54.6095 77.7456 52.3748 79.0514 51.0692L83.1799 46.9412C79.0498 43.9533 74.1009 42.3406 68.9034 42.3406C62.3808 42.3406 56.2477 44.88 51.6363 49.4925C47.0232 54.1042 44.4828 60.2359 44.4828 66.7585C44.4828 73.2812 47.0232 79.4128 51.6363 84.0246L66.9435 99.3301L62.7415 98.5834C61.2462 98.3179 59.7125 98.8 58.6386 99.8738C57.5647 100.948 57.0825 102.482 57.348 103.977L58.697 111.564L41.3955 94.2635C37.6836 90.552 34.8089 86.2217 32.8499 81.3917C30.9588 76.7312 30 71.8076 30 66.7593C30 61.711 30.9588 56.7867 32.8491 52.1254C34.8081 47.2946 37.6836 42.9643 41.3947 39.2536C45.1057 35.5421 49.4365 32.6678 54.267 30.7097C58.9296 28.818 63.8537 27.8594 68.9034 27.8594C73.953 27.8594 78.8771 28.818 83.5389 30.7081C87.158 32.1753 90.4956 34.1565 93.503 36.6183L97.2157 32.9061C98.5215 31.6004 100.756 32.3032 101.079 34.1214L105.007 56.211C105.286 57.7741 103.922 59.1381 102.359 58.8607Z" fill="#4AAF3C"/>
</g>
<g filter="url(#filter0_f_34053_111310)">
<ellipse cx="102.576" cy="170.536" rx="27.5758" ry="1.59085" fill="#1CA609" fill-opacity="0.5"/>
</g>
<defs>
<filter id="filter0_f_34053_111310" x="70.5" y="164.445" width="64.1515" height="12.1797" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="2.25" result="effect1_foregroundBlur_34053_111310"/>
</filter>
<clipPath id="clip0_34053_111310">
<rect width="140" height="122" fill="white" transform="translate(30 27.8828)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,20 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_34053_111286)">
<path d="M170 66.7593C170 71.8084 169.042 76.732 167.151 81.3933C165.192 86.2233 162.316 90.5536 158.606 94.265L147.36 105.511L151.657 109.806C152.962 111.112 152.26 113.347 150.441 113.671L128.349 117.598C126.785 117.875 125.423 116.513 125.7 114.949L129.628 92.8594C129.952 91.0413 132.187 90.3393 133.492 91.6441L137.12 95.2717L148.366 84.0261C152.978 79.4144 155.519 73.2819 155.519 66.7609C155.519 60.2383 152.978 54.105 148.365 49.4941C143.753 44.8815 137.621 42.3422 131.097 42.3422C124.574 42.3422 118.442 44.8815 113.83 49.4941L107.387 55.936C107.383 55.9064 107.378 55.8784 107.373 55.8488L104.299 38.5628C107.848 35.1847 111.936 32.5447 116.463 30.7097C121.123 28.818 126.048 27.8594 131.097 27.8594C136.146 27.8594 141.07 28.818 145.732 30.7089C150.564 32.667 154.894 35.5421 158.606 39.2528C162.317 42.9643 165.192 47.2946 167.151 52.1246C169.041 56.7859 169.999 61.7102 170 66.7585V66.7593Z" fill="#4AAF3C"/>
<path d="M133.814 119.087L105.12 147.779C103.762 149.137 101.92 149.9 99.9998 149.9C98.0791 149.9 96.2375 149.137 94.879 147.779L70.7775 123.678L67.503 126.953C66.1972 128.259 63.9623 127.556 63.6392 125.737L59.7107 103.646C59.4332 102.083 60.7966 100.72 62.3598 100.997L84.4519 104.925C86.2702 105.249 86.9731 107.483 85.6673 108.789L81.0183 113.438L100.001 132.42L124.507 107.914L123.318 114.601C123.053 116.096 123.535 117.63 124.609 118.703C125.684 119.778 127.217 120.259 128.712 119.994L133.814 119.087H133.814Z" fill="#4AAF3C"/>
<path d="M102.359 58.8607L80.2668 54.9325C78.4485 54.6095 77.7456 52.3748 79.0514 51.0692L83.1799 46.9412C79.0498 43.9533 74.1009 42.3406 68.9034 42.3406C62.3808 42.3406 56.2477 44.88 51.6363 49.4925C47.0232 54.1042 44.4828 60.2359 44.4828 66.7585C44.4828 73.2812 47.0232 79.4128 51.6363 84.0246L66.9435 99.3301L62.7415 98.5834C61.2462 98.3179 59.7125 98.8 58.6386 99.8738C57.5647 100.948 57.0825 102.482 57.348 103.977L58.697 111.564L41.3955 94.2635C37.6836 90.552 34.8089 86.2217 32.8499 81.3917C30.9588 76.7312 30 71.8076 30 66.7593C30 61.711 30.9588 56.7867 32.8491 52.1254C34.8081 47.2946 37.6836 42.9643 41.3947 39.2536C45.1057 35.5421 49.4365 32.6678 54.267 30.7097C58.9296 28.818 63.8537 27.8594 68.9034 27.8594C73.953 27.8594 78.8771 28.818 83.5389 30.7081C87.158 32.1753 90.4957 34.1565 93.503 36.6183L97.2157 32.9061C98.5215 31.6004 100.756 32.3032 101.079 34.1214L105.007 56.211C105.286 57.7741 103.922 59.1373 102.359 58.8599V58.8607Z" fill="#4AAF3C"/>
</g>
<g filter="url(#filter0_f_34053_111286)">
<ellipse cx="101.576" cy="170.536" rx="27.5758" ry="1.59085" fill="#E1E1E1" fill-opacity="0.5"/>
</g>
<defs>
<filter id="filter0_f_34053_111286" x="69.5" y="164.445" width="64.1515" height="12.1797" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="2.25" result="effect1_foregroundBlur_34053_111286"/>
</filter>
<clipPath id="clip0_34053_111286">
<rect width="140" height="122" fill="white" transform="translate(30 27.8828)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@@ -75,9 +75,9 @@ PODS:
- FlutterMacOS
- privacy_screen (0.0.1):
- Flutter
- SDWebImage (5.21.0):
- SDWebImage/Core (= 5.21.0)
- SDWebImage/Core (5.21.0)
- SDWebImage (5.21.1):
- SDWebImage/Core (= 5.21.1)
- SDWebImage/Core (5.21.1)
- Sentry/HybridSDK (8.46.0)
- sentry_flutter (8.14.2):
- Flutter
@@ -188,37 +188,37 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/url_launcher_ios/ios"
SPEC CHECKSUMS:
app_links: f3e17e4ee5e357b39d8b95290a9b2c299fca71c6
cupertino_http: 947a233f40cfea55167a49f2facc18434ea117ba
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
app_links: 76b66b60cc809390ca1ad69bfd66b998d2387ac7
cupertino_http: 94ac07f5ff090b8effa6c5e2c47871d48ab7c86c
device_info_plus: 335f3ce08d2e174b9fdc3db3db0f4e3b1f66bd89
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: b159e0c068aef54932bb15dc9fd1571818edaf49
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_email_sender: e03bdda7637bcd3539bfe718fddd980e9508efaa
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
flutter_local_authentication: 1172a4dd88f6306dadce067454e2c4caf07977bb
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
fluttertoast: 21eecd6935e7064cc1fcb733a4c5a428f3f24f0f
listen_sharing_intent: 74a842adcbcf7bedf7bbc938c749da9155141b9a
local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3
objective_c: 77e887b5ba1827970907e10e832eec1683f3431d
open_file_ios: 461db5853723763573e140de3193656f91990d9e
flutter_email_sender: aa1e9772696691d02cd91fea829856c11efb8e58
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
flutter_local_authentication: 989278c681612f1ee0e36019e149137f114b9d7f
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
listen_sharing_intent: fe0b9a59913cc124dd6cbd55cd9f881de5f75759
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
objective_c: 89e720c30d716b036faf9c9684022048eee1eee2
open_file_ios: 5ff7526df64e4394b4fe207636b67a95e83078bb
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
privacy_screen: 1a131c052ceb3c3659934b003b0d397c2381a24e
SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
privacy_screen: 3159a541f5d3a31bea916cfd4e58f9dc722b3fd4
SDWebImage: f29024626962457f3470184232766516dee8dfea
Sentry: da60d980b197a46db0b35ea12cb8f39af48d8854
sentry_flutter: 2df8b0aab7e4aba81261c230cbea31c82a62dd1b
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sodium_libs: 1faae17af662384acbd13e41867a0008cd2e2318
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
sentry_flutter: 27892878729f42701297c628eb90e7c6529f3684
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sodium_libs: 6c6d0e83f4ee427c6464caa1f1bdc2abf3ca0b7f
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
ua_client_hints: aeabd123262c087f0ce151ef96fa3ab77bfc8b38
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
ua_client_hints: 92fe0d139619b73ec9fcb46cc7e079a26178f586
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
PODFILE CHECKSUM: d2d3220ea22664a259778d9e314054751db31361

View File

@@ -622,7 +622,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = IconBlue;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
@@ -929,7 +929,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = IconBlue;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
@@ -956,7 +956,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = IconBlue;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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