-
-
Notifications
You must be signed in to change notification settings - Fork 50
RC1 for 0.18.0: Eny Integration #641
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR prepares the 0.18.0 release candidate by adding an “Eny” receipt-scanning integration (including UI flows, deep-linking, and persistence), plus associated widget/layout updates and build system bumps.
Changes:
- Add Eny integration: connect flow via deep links, receipt upload/polling, and UI for scanning and preferences.
- Introduce camera-based capture + desktop drop-zone for receipt images and new external toast plumbing.
- Update transaction button model/order to include the Eny action; extend home-screen widgets to support more actions.
Reviewed changes
Copilot reviewed 82 out of 86 changed files in this pull request and generated 22 comments.
Show a summary per file
| File | Description |
|---|---|
| pubspec.yaml | Bump app version; add camera and lottie deps; update icons package. |
| pubspec.lock | Lock new deps (camera*, lottie). |
| lib/widgets/sheets/select_flow_icon_sheet/select_char_flow_icon_sheet.dart | Remove TODO comment. |
| lib/widgets/scaffold_actions.dart | Platform-specific bottom padding adjustment. |
| lib/widgets/integrations/eny_page/eny_privacy_notice.dart | New privacy notice UI for Eny data sharing. |
| lib/widgets/integrations/eny_page/eny_error_sheet.dart | New sheet for invalid Eny credentials. |
| lib/widgets/image_drop_zone.dart | New desktop drag-and-drop image picker UI. |
| lib/widgets/home/preferences/button_order_preferences/transaction_type_button.dart | Switch button type model to FlowButtonType. |
| lib/widgets/home/navbar/new_transaction_button.dart | Build pie menu based on preferences + Eny connection state. |
| lib/widgets/general/markdown_view.dart | Add divider embed builder support for Quill. |
| lib/widgets/general/button.dart | Refactor Row content layout for leading/trailing. |
| lib/widgets/external_toasts_handler.dart | New widget to display toasts emitted outside UI contexts. |
| lib/widgets/camera_page_base/overlay_button.dart | New reusable overlay button for camera UI. |
| lib/widgets/camera_page_base.dart | New camera preview base widget with flash handling. |
| lib/widgets/animated_eny_logo.dart | New Eny logo widget using Lottie + network fallback. |
| lib/widgets/account_card.dart | Change account edit navigation path. |
| lib/utils/pick_file.dart | Add limit param to multi-media picker. |
| lib/utils/loose_parsers.dart | New “loose” parsers for dynamic payloads. |
| lib/utils/flutter_quill/divider_embed_builder.dart | New Quill embed builder for dividers. |
| lib/services/user_preferences.dart | Add scan preference; migrate transaction button order to FlowButtonType. |
| lib/services/navigation.dart | Handle Eny deep link route (integrate/eny). |
| lib/services/local_auth.dart | Add fallback localizedReason for biometrics prompt. |
| lib/services/integrations/eny.dart | New Eny integration service: connect, upload, poll, import transactions. |
| lib/services/file_attachment.dart | Remove TODO comment. |
| lib/services/external_toasts.dart | New service emitting toast events via stream. |
| lib/services/categories.dart | Add frecency-sorted category retrieval for Eny payloads. |
| lib/services/camera.dart | New camera initialization service wrapper. |
| lib/routes/utils/edit_markdown_page.dart | Add divider embed builder to editor; minor formatting. |
| lib/routes/transaction_page.dart | Display Eny attribution; track whether transaction imported from Eny. |
| lib/routes/preferences_page.dart | Add “Integrations” section with Eny entry. |
| lib/routes/preferences/integrations/eny_preferences_page.dart | New Eny preferences page (connect state, credits, scan behavior). |
| lib/routes/preferences/button_order_preferences_page.dart | Update reorder UI/logic for new button types and Eny availability. |
| lib/routes/integrations/eny_page.dart | New Eny scan page using camera/gallery/drop zone. |
| lib/routes/integrate/integrate_eny_page.dart | New Eny connect flow page (from deep link). |
| lib/routes/home_page.dart | Route Eny action; wrap app with ExternalToastsHandler. |
| lib/routes.dart | Add routes for Eny pages; redirect type=eny new-transaction links. |
| lib/prefs/local_preferences.dart | Initialize new Eny local preferences. |
| lib/prefs/eny_preferences.dart | New Eny local preferences (api key/email/pending receipts). |
| lib/objectbox/objectbox.g.dart | Add new createTransactionsPerItemInScans property to model. |
| lib/objectbox/objectbox-model.json | Mirror ObjectBox model update. |
| lib/objectbox/actions.dart | Extend programmable-object save to support tags/extensions. |
| lib/main.dart | Remove unused URI subscription cleanup. |
| lib/graceful_migrations.dart | Migrate transaction button order to FlowButtonType. |
| lib/entity/user_preferences.g.dart | Serialize/deserialize new scan preference. |
| lib/entity/user_preferences.dart | Add new preference field + update button order logic. |
| lib/entity/transaction/wrapper.dart | Add Eny extension accessor. |
| lib/entity/transaction/extensions/default/eny_receipt.g.dart | Generated JSON serialization for Eny receipt extension. |
| lib/entity/transaction/extensions/default/eny_receipt.dart | New Eny receipt transaction extension. |
| lib/data/transaction_programmable_object.dart | Add Eny JSON import support; use loose parsers. |
| lib/data/transaction_multi_programmable_object.dart | Add multi-transaction import from Eny items. |
| lib/data/setup/default_categories.dart | Fix “stationery” localization key. |
| lib/data/flow_button_type.dart | New enum for transaction/new-action buttons incl. Eny. |
| lib/constants.dart | Add Eny URLs and logo animation URLs. |
| ios/Runner/Info.plist | Add microphone usage description. |
| ios/Podfile.lock | Add camera plugin pod. |
| assets/l10n/en.json | Add Eny strings + drop-zone strings + stationery key + external transaction strings. |
| assets/l10n/mn_MN.json | Same: Eny + drop-zone + stationery + external transaction strings. |
| assets/l10n/ru_RU.json | Same: Eny + drop-zone + stationery. |
| assets/l10n/uk_UA.json | Same: Eny + drop-zone + stationery. |
| assets/l10n/tr_TR.json | Same: Eny + drop-zone + stationery. |
| assets/l10n/it_IT.json | Same: Eny + drop-zone + stationery. |
| assets/l10n/fr_FR.json | Same: Eny + drop-zone + stationery. |
| assets/l10n/es_ES.json | Same: Eny + drop-zone + stationery. |
| assets/l10n/de_DE.json | Same: Eny + drop-zone + stationery. |
| assets/l10n/cs_CZ.json | Same: Eny + drop-zone + stationery. |
| assets/l10n/ar.json | Same: Eny + drop-zone + stationery. |
| android/settings.gradle.kts | Bump Android Gradle Plugin version. |
| android/gradle/wrapper/gradle-wrapper.properties | Bump Gradle wrapper version. |
| android/gradle.properties | Add/adjust Android Gradle properties for new tooling. |
| android/app/src/main/res/xml/two_entry_widget_info.xml | Update widget provider sizing + metadata. |
| android/app/src/main/res/xml/two_entry_last_widget_info.xml | Add new “Two Actions (Last)” widget provider. |
| android/app/src/main/res/xml/four_entry_widget_info.xml | Add new “Four Actions” widget provider. |
| android/app/src/main/res/drawable/camera.xml | Add camera vector icon for widgets. |
| android/app/src/main/kotlin/mn/flow/flow/glance/TwoEntryLastReceiver.kt | New receiver for new widget variant. |
| android/app/src/main/kotlin/mn/flow/flow/glance/TwoEntryLast.kt | New widget variant showing last two actions. |
| android/app/src/main/kotlin/mn/flow/flow/glance/TwoEntry.kt | Refactor to share widget rendering utilities. |
| android/app/src/main/kotlin/mn/flow/flow/glance/FourEntryReceiver.kt | New receiver for 2x2 widget. |
| android/app/src/main/kotlin/mn/flow/flow/glance/FourEntry.kt | New 2x2 widget for up to 4 actions. |
| android/app/src/main/kotlin/mn/flow/flow/FlowWidgetUtils.kt | Shared widget button-order + rendering logic. |
| android/app/src/main/AndroidManifest.xml | Register new widget receivers. |
| android/app/proguard-rules.pro | Add proguard rules for picker/Gson-related keep rules. |
| android/app/build.gradle.kts | Update NDK version; adjust debug ObjectBox browser dep. |
| CHANGELOG.md | Add 0.18.0 “Eny scan receipts (beta)” entry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 84 out of 88 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Future<void> resolveProcessedReceipt() async { | ||
| try { | ||
| final List<String>? items = EnyLocalPreferences().pendingReceipts.get(); | ||
| if (items == null || items.isEmpty) { | ||
| _log.finer("No pending receipts to resolve"); | ||
| return; | ||
| } | ||
|
|
||
| if (_currentConcurrentRequests >= _maxConcurrentRequests) { | ||
| _log.fine( | ||
| "Max concurrent requests reached ($_currentConcurrentRequests), delaying...", | ||
| ); | ||
| return; | ||
| } | ||
|
|
||
| await Future.wait( | ||
| items.take(_maxConcurrentRequests - _currentConcurrentRequests).map(( | ||
| id, | ||
| ) { | ||
| _currentConcurrentRequests += 1; | ||
| return _resolveProcessedReceipt(id).whenComplete(() { | ||
| _currentConcurrentRequests -= 1; | ||
| }); | ||
| }), | ||
| ); | ||
|
|
||
| await Future.delayed(const Duration(seconds: 3)); | ||
|
|
||
| return await resolveProcessedReceipt(); | ||
| } catch (e) { |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resolveProcessedReceipt uses async recursion (return await resolveProcessedReceipt()) which can grow the call stack over time. Also, when _currentConcurrentRequests >= _maxConcurrentRequests it returns without scheduling another attempt, which can leave pending receipts stuck. Prefer a loop/timer-based worker and ensure you reschedule when at the concurrency limit.
No description provided.