Repository navigation
Conversation
…gation_plugin_connection # Conflicts: # app/src/main/java/com/sameerasw/essentials/data/repository/SettingsRepository.kt # app/src/main/java/com/sameerasw/essentials/domain/registry/FeatureRegistry.kt # app/src/main/java/com/sameerasw/essentials/island/service/IslandCoordinator.kt # app/src/main/java/com/sameerasw/essentials/ui/features/display/IslandSettingsUI.kt # app/src/main/java/com/sameerasw/essentials/viewmodels/MainViewModel.kt # app/src/main/res/values/strings.xml
Moves "Delete shared screenshots" onto a new Screenshots page under Security and adds: - a delay after sharing (immediately, 1 hour, 1 day) - auto-clean: every new screenshot is trashed after 1, 7 or 30 days, with a quiet notification offering Keep and Trash now; starred screenshots are kept - a count of cleaned screenshots and the storage saved New screenshots are picked up with a MediaStore ContentObserver and each cleanup is a unique WorkManager job keyed by the media id. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
## Description <!-- Describe what this PR changes and why. If it resolves an issue, link it here: e.g. Closes #123 --> Enable navigation popup on island when any type of navigation. Navigation only accepts ongoing notifications that pass isNavigationNotification. That means the channel ID is in the navigation channel list or contains "navigation", or the category contains "navigation". Maps' Live Update has a progress bar, so it would also qualify for the progress ring. While the island and its Navigation item are on, extractLatestProgressNotification skips navigation notifications, so the progress plugin doesn't show it a second time. Inside the changes a couple of settings can be enabled inside the toggle: <img width="561" height="790" alt="image" src="https://github.com/user-attachments/assets/d47c81a3-3254-49e1-a3c0-a48cc237d727" /> - New instruction: This options ask the user the behaviour of the island when an going change of direction is headed at. By default this expands the island with all info. (the user can set the island to only Line peek the info, or do nothing) - Expand before turn: Kinda self explanatory. - Line peek after expanding: Once the user pass a direction and collapses by default, this renders the island with the line peek info, off by default. This implementation was only tested on a real device and on an emulator with no issues, Waze doesn't create any notification with nav info apart of the only persistent notification to keep the app alive. ## Type of change - [ ] Bug fix - [x] New feature - [ ] UI / visual update - [ ] Performance improvement - [ ] Refactoring / cleanup - [ ] Translations - [ ] Build / CI tooling ## UI changes <!-- Required if this PR changes or adds UI. Please attach screenshots or a screen recording. --> https://github.com/user-attachments/assets/018fc3de-b2fd-4cd4-b60f-df4f1f6749a0 [Screen_recording_20261013_115734.webm](https://github.com/user-attachments/assets/c21fd215-ac12-46c9-9d4e-e265d986fe54) ## Checklist Before submitting, please make sure: - [x] The base branch is set to `develop` (not `main`). - [x] The app builds cleanly locally with `./gradlew assembleDebug`. - [x] Unit tests pass with `./gradlew testDebugUnitTest`. - [x] You tested the changes on a device or emulator (including Shizuku or Root if applicable). - [x] New preferences use `SettingsRepository` for keys and getter/setter methods. - [x] New user-facing settings are registered in `FeatureRegistry.kt` for search indexing. - [x] New UI follows the design system in `ui/core/` (`RoundedCardContainer`, `IconToggleItem`, etc.). - [x] Strings are added to `res/values/strings.xml` and drawables use rounded variants (`R.drawable.rounded_*`).
…proved trash handling
<!-- claude-projects-attribution: {"github_login":"jawzf"} -->
_Requested by **Joe** · [project
thread](https://claude.ai/code/project/chan_01FyKGsodrf7JS5wLrjvnZmV?thread=cmsg_01FyKGsodrf7JS5wLrjvnZmVMzi9Au2zRtq95Xj3iAzWwM)_
## Description
Follow-up to #1380 (merged).
Before: screenshot cleanup was a single "Delete shared screenshots"
toggle that trashed a screenshot right after you shared it.
After: a dedicated Screenshots page under Security with:
- **After sharing**: the existing toggle, plus a delay of Immediately, 1
hour or 1 day before the shared screenshot is trashed.
- **Auto-clean**: trashes every new screenshot after 1, 7 or 30 days.
Each new screenshot gets a quiet, grouped notification with a preview
and Keep / Trash now actions, which times out after an hour. Screenshots
starred in Photos are always kept.
- **Cleaned so far**: how many screenshots were cleaned and the storage
saved.
How: a MediaStore `ContentObserver` in the accessibility service picks
up newly saved screenshots (only ones added in the last minute, with the
last seen id stored so restarts don't re-notify). Each one gets a unique
per-screenshot WorkManager job; Keep cancels it, and Trash now runs it
immediately. Trashing still uses the `IS_TRASHED` update from #1380, so
screenshots stay restorable for 30 days, and starred ones are skipped by
the automatic cleanup. No new permissions.
## Type of change
- [ ] Bug fix
- [x] New feature
- [x] UI / visual update
- [ ] Performance improvement
- [ ] Refactoring / cleanup
- [ ] Translations
- [ ] Build / CI tooling
## UI changes
<img width="1344" height="2992" alt="1_screenshots_page"
src="https://github.com/user-attachments/assets/35693295-c270-4459-9e29-e0981ca9a4d0"
/>
<!-- 1_screenshots_page.png -->
The new Screenshots page.
<!-- 2_auto_clean_notification.png -->
<img width="1344" height="2992" alt="2_auto_clean_notification"
src="https://github.com/user-attachments/assets/9e62eb5f-6c08-46bc-a746-8e1d1d238bbf"
/>
The auto-clean notification with Keep and Trash now.
<!-- 3_share_delay_toast.png -->
<img width="359" height="800" alt="3_share_delay_toast"
src="https://github.com/user-attachments/assets/95e830ca-0b84-463f-831c-69919188289e"
/>
The message shown when a shared screenshot is scheduled for later.
<!-- 4_grouped_notifications.png -->
<img width="1344" height="2992" alt="4_grouped_notifications"
src="https://github.com/user-attachments/assets/e2c568e3-efb6-4889-a508-322cac998923"
/>
Several screenshot notifications grouped together.
## Checklist
Before submitting, please make sure:
- [x] The base branch is set to `develop` (not `main`).
- [x] The app builds cleanly locally with `./gradlew assembleDebug`.
- [x] Unit tests pass with `./gradlew testDebugUnitTest`.
- [x] You tested the changes on a device or emulator (including Shizuku
or Root if applicable).
- [x] New preferences use `SettingsRepository` for keys and
getter/setter methods.
- [x] New user-facing settings are registered in `FeatureRegistry.kt`
for search indexing.
- [x] New UI follows the design system in `ui/core/`
(`RoundedCardContainer`, `IconToggleItem`, etc.).
- [x] Strings are added to `res/values/strings.xml` and drawables use
rounded variants (`R.drawable.rounded_*`).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01CVTvKLdph38zfD5D45PjJh
Each stack's current widget was only kept in memory, so a reboot, app update or killed process sent every stack back to its first widget. Positions are now saved per stack in widget_stack_prefs after an arrow or edge step, when the screen turns off and when the app is moved to the background, and restored (clamped to the hosted widgets) on start. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## Description Follow-up to #1328 (widget stack). Before: each stack's current widget was only kept in memory, so after a reboot, an app update or the process being killed, every stack went back to its first widget. After: a stack comes back showing the widget it was on. How: positions are saved per stack in the existing `widget_stack_prefs` file (`position_<stackWidgetId>`), next to the stack configs, and restored when `StackHost` starts. A small `StackPositions.restore` clamps each saved position to the stack's current widgets and drops positions for stacks that no longer exist. Positions are saved: - right after an arrow or edge step, - when the screen turns off, - when the app is moved to the background (`onTrimMemory`), because a cached app gets frozen and doesn't receive `SCREEN_OFF` until it wakes. They aren't saved on every timer tick, so a running stack doesn't write to disk every few seconds. Removing a stack also removes its saved position. ## Type of change - [ ] Bug fix - [x] New feature - [ ] UI / visual update - [ ] Performance improvement - [ ] Refactoring / cleanup - [ ] Translations - [ ] Build / CI tooling ## UI changes None. ## Checklist - [x] The base branch is set to `develop` (not `main`). - [x] The app builds cleanly locally with `./gradlew assembleDebug`. - [x] Unit tests pass with `./gradlew testDebugUnitTest` (new `StackPositionsTest`, 6 tests). - [x] Tested on the Android 17 emulator: stepped a 3-widget stack to the 2nd widget, rebooted, same widget shown; removed a widget so the saved position was out of range, rebooted, last widget shown without errors; confirmed nothing is written on timer ticks. - [x] Positions stay in `WidgetStackRepository` alongside the stack configs, as the widget stack already stores its data there; no new user-facing preference. - [x] No new settings, so nothing to register in `FeatureRegistry.kt`. - [x] No UI changes. - [x] No new strings or drawables. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Posts a notification with a user-set title, message and label (shown as subtext next to the app name) on its own "Automation notifications" channel. Running the same action again replaces its notification. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ng titles, drop helper text
## Description Adds a **Send notification** action to DIY automations, under System actions next to Wait. Before: automations could only post failure notices; there was no way to show your own message. After: add Send notification to any automation and fill in: - **Title** - **Message** (multi-line) - **Label** (optional): shown next to the app name in the header, e.g. "Essentials • Home". Android always shows the posting app's name there, so the label is set as the notification's subtext. Save stays disabled until there's a title or a message, and blank fields are left off the notification. The action row shows "Send notification · <title>". How: `Action.SendNotification` is a configurable action like `Wait`, saved through the existing `ActionGsonAdapter`. `AutomationNotificationPoster` posts it on a new **Automation notifications** channel, separate from the failure notices so either can be muted on its own. Each action uses its own notification id, so running the same action again replaces its notification while different actions stack. The action needs `POST_NOTIFICATIONS`; the editor shows the existing permission sheet when it's missing, and at run time a missing permission is skipped without a crash. ## Type of change - [ ] Bug fix - [x] New feature - [ ] UI / visual update - [ ] Performance improvement - [ ] Refactoring / cleanup - [ ] Translations - [ ] Build / CI tooling ## UI changes <!-- 1_notification.png --> <img width="1344" height="2992" alt="1_notification" src="https://github.com/user-attachments/assets/3a6cbb20-726f-468a-809b-f482f9b8ca07" /> The posted notification with title, message and label. <!-- 2_two_notifications.png --> <img width="1344" height="2992" alt="2_two_notifications" src="https://github.com/user-attachments/assets/e3e93305-0578-4d04-8897-00dfafbc0f49" /> Two different Send notification actions stack; the one with only a title has no empty lines. ## Checklist - [x] The base branch is set to `develop` (not `main`). - [x] The app builds cleanly locally with `./gradlew assembleDebug` (and `assembleRelease`). - [x] Unit tests pass with `./gradlew testDebugUnitTest` (2 new tests in `ActionListJsonTest`: round trip, and missing fields load as empty). - [x] Tested on the Android 17 emulator: action listed under System; Save disabled when empty; notification shows title, message and "Essentials • <label>"; blank fields omitted; same action twice shows one notification, two actions show two; without notification permission the editor shows the permission sheet and running the automation doesn't crash; actions keep their text after a force-stop. - [x] Reuses `EssentialsBottomSheet`, `RoundedCardContainer` and the existing permission sheet. - [x] New strings are in `strings.xml` (English only). - [x] No new settings, so nothing to register in `FeatureRegistry.kt`. - [x] No new dependencies or permissions in the manifest. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This pull request introduces several new features and improvements, primarily focused on navigation notification support, enhanced screenshot management, and expanded DIY action capabilities. The main changes include adding a new navigation notification data model and parser, extending screenshot cleanup and auto-clean options, introducing a "Send Notification" DIY action, and updating feature and permission registries to reflect these enhancements.
Navigation Notification Support:
NavigationNotificationDatadata class andNavigationParserutility for parsing and handling navigation notifications, including distance parsing and exit action detection.SettingsRepository, such as toggles for showing navigation, navigation-on-new behavior, peek-after-expand, and expand distance. [1] [2]Screenshot Management Enhancements:
DIY Actions:
SendNotificationaction to the DIY actions system, allowing users to configure and trigger notifications with custom titles and bodies. [1] [2]Widget Stack Improvements:
Feature Registry and Search:
These changes collectively enhance the app's capabilities around navigation, screenshots, and user customization, while improving maintainability and discoverability of features.
Type of change