ui/onboarding/BatteryOptimizationScreen.kt (the "Get mail the instant it arrives" opt-in step)
currently guides the user with text only: onboarding_battery_guidance = "On the next screen,
open Battery and choose 'Unrestricted'." The user then taps "Take me there," which — per #150 —
deep-links only to the app's general info page (ACTION_APPLICATION_DETAILS_SETTINGS), not
directly to the Battery sub-screen, and #150 itself notes there's no single OEM-universal intent
that lands precisely there (Samsung/other skins diverge from stock Android). So today's flow drops
the user into an unfamiliar system screen with only a sentence of text to go on, and that text
isn't visible anymore once they've navigated away from LibreMail into Settings.
A short help animation shown on this screen — before the user leaves the app — would reinforce
the "tap Battery → tap Unrestricted" path far better than static text, and is a natural complement
to #150 rather than a replacement for it: however good the deep link gets, it can't guarantee
landing on the exact right screen on every OEM, so an in-app visual walkthrough of the general
navigation pattern still carries value.
No animation infrastructure exists anywhere in this codebase yet (no Lottie or similar dependency,
no AnimatedVectorDrawable usage, no Compose animation-driven illustrations) — this would be the
first of its kind, so the implementation approach is worth deciding deliberately rather than
defaulting to whatever's fastest to hack in.
Scope
Design a short (~2-4s), looping visual showing the navigation path: tapping into "Battery"
then choosing "Unrestricted." Keep it generic/illustrative rather than a screen recording
of one specific OEM's actual settings UI — the real destination screen varies by
manufacturer (per #150), so a literal recording would look wrong (or go stale) on many
devices; a stylized mock is more honest about being a general guide.
Pick an implementation approach and record the reasoning, consistent with this repo's
existing preference for minimizing new dependencies (see #36's decision write-up for the
pattern): a native AnimatedVectorDrawable or a Compose-driven illustration (built from
vector assets + rememberInfiniteTransition/AnimatedContent) needs no new dependency; a
library like Lottie (Apache-2.0, GPL/F-Droid/Play-compatible if it comes to that) is the
fallback if the native approach can't reasonably produce the desired animation.
Place the animation on BatteryOptimizationScreen.kt, above or alongside the existing
guidance text and before the "Take me there" / "Not now" buttons, so the user sees it while
still in LibreMail — not after they've already navigated away.
Respect reduced-motion: check the system's "Remove animations" accessibility setting
(Settings.Global.ANIMATOR_DURATION_SCALE / AccessibilityManager equivalent) and fall back
to a static illustration or the current text-only guidance when it's on.
Keep the existing text guidance too (or an equivalent content description) so TalkBack users
get the same information — the animation should be additive, not a replacement for an
accessible fallback.
Acceptance criteria
The battery opt-in onboarding screen shows a short looping animation illustrating the
"Battery → Unrestricted" navigation path before the user is sent to system settings.
The existing "Take me there" / "Not now" flow and re-check-on-resume behavior
(BatteryOptimizationScreen's LifecycleEventEffect(ON_RESUME)) are unchanged.
Users with system reduced-motion enabled, or using TalkBack, get an equivalent non-animated
guidance path.
Complements #150 (battery settings deep link) — this ticket is about in-app guidance regardless
of how precisely the deep link itself lands.
## Context
`ui/onboarding/BatteryOptimizationScreen.kt` (the "Get mail the instant it arrives" opt-in step)
currently guides the user with text only: `onboarding_battery_guidance` = "On the next screen,
open Battery and choose 'Unrestricted'." The user then taps "Take me there," which — per #150 —
deep-links only to the app's general info page (`ACTION_APPLICATION_DETAILS_SETTINGS`), not
directly to the Battery sub-screen, and #150 itself notes there's no single OEM-universal intent
that lands precisely there (Samsung/other skins diverge from stock Android). So today's flow drops
the user into an unfamiliar system screen with only a sentence of text to go on, and that text
isn't visible anymore once they've navigated away from LibreMail into Settings.
A short help animation shown on this screen — before the user leaves the app — would reinforce
the "tap Battery → tap Unrestricted" path far better than static text, and is a natural complement
to #150 rather than a replacement for it: however good the deep link gets, it can't guarantee
landing on the exact right screen on every OEM, so an in-app visual walkthrough of the general
navigation pattern still carries value.
No animation infrastructure exists anywhere in this codebase yet (no Lottie or similar dependency,
no `AnimatedVectorDrawable` usage, no Compose animation-driven illustrations) — this would be the
first of its kind, so the implementation approach is worth deciding deliberately rather than
defaulting to whatever's fastest to hack in.
## Scope
- [ ] Design a short (~2-4s), looping visual showing the navigation path: tapping into "Battery"
then choosing "Unrestricted." Keep it **generic/illustrative** rather than a screen recording
of one specific OEM's actual settings UI — the real destination screen varies by
manufacturer (per #150), so a literal recording would look wrong (or go stale) on many
devices; a stylized mock is more honest about being a general guide.
- [ ] Pick an implementation approach and record the reasoning, consistent with this repo's
existing preference for minimizing new dependencies (see #36's decision write-up for the
pattern): a native `AnimatedVectorDrawable` or a Compose-driven illustration (built from
vector assets + `rememberInfiniteTransition`/`AnimatedContent`) needs no new dependency; a
library like Lottie (Apache-2.0, GPL/F-Droid/Play-compatible if it comes to that) is the
fallback if the native approach can't reasonably produce the desired animation.
- [ ] Place the animation on `BatteryOptimizationScreen.kt`, above or alongside the existing
guidance text and before the "Take me there" / "Not now" buttons, so the user sees it while
still in LibreMail — not after they've already navigated away.
- [ ] Respect reduced-motion: check the system's "Remove animations" accessibility setting
(`Settings.Global.ANIMATOR_DURATION_SCALE` / `AccessibilityManager` equivalent) and fall back
to a static illustration or the current text-only guidance when it's on.
- [ ] Keep the existing text guidance too (or an equivalent content description) so TalkBack users
get the same information — the animation should be additive, not a replacement for an
accessible fallback.
## Acceptance criteria
- The battery opt-in onboarding screen shows a short looping animation illustrating the
"Battery → Unrestricted" navigation path before the user is sent to system settings.
- The existing "Take me there" / "Not now" flow and re-check-on-resume behavior
(`BatteryOptimizationScreen`'s `LifecycleEventEffect(ON_RESUME)`) are unchanged.
- Users with system reduced-motion enabled, or using TalkBack, get an equivalent non-animated
guidance path.
## Relevant files
- `ui/onboarding/BatteryOptimizationScreen.kt`, `res/values/strings.xml`
(`onboarding_battery_*` block).
## Dependencies
Complements #150 (battery settings deep link) — this ticket is about in-app guidance regardless
of how precisely the deep link itself lands.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Context
ui/onboarding/BatteryOptimizationScreen.kt(the "Get mail the instant it arrives" opt-in step)currently guides the user with text only:
onboarding_battery_guidance= "On the next screen,open Battery and choose 'Unrestricted'." The user then taps "Take me there," which — per #150 —
deep-links only to the app's general info page (
ACTION_APPLICATION_DETAILS_SETTINGS), notdirectly to the Battery sub-screen, and #150 itself notes there's no single OEM-universal intent
that lands precisely there (Samsung/other skins diverge from stock Android). So today's flow drops
the user into an unfamiliar system screen with only a sentence of text to go on, and that text
isn't visible anymore once they've navigated away from LibreMail into Settings.
A short help animation shown on this screen — before the user leaves the app — would reinforce
the "tap Battery → tap Unrestricted" path far better than static text, and is a natural complement
to #150 rather than a replacement for it: however good the deep link gets, it can't guarantee
landing on the exact right screen on every OEM, so an in-app visual walkthrough of the general
navigation pattern still carries value.
No animation infrastructure exists anywhere in this codebase yet (no Lottie or similar dependency,
no
AnimatedVectorDrawableusage, no Compose animation-driven illustrations) — this would be thefirst of its kind, so the implementation approach is worth deciding deliberately rather than
defaulting to whatever's fastest to hack in.
Scope
then choosing "Unrestricted." Keep it generic/illustrative rather than a screen recording
of one specific OEM's actual settings UI — the real destination screen varies by
manufacturer (per #150), so a literal recording would look wrong (or go stale) on many
devices; a stylized mock is more honest about being a general guide.
existing preference for minimizing new dependencies (see #36's decision write-up for the
pattern): a native
AnimatedVectorDrawableor a Compose-driven illustration (built fromvector assets +
rememberInfiniteTransition/AnimatedContent) needs no new dependency; alibrary like Lottie (Apache-2.0, GPL/F-Droid/Play-compatible if it comes to that) is the
fallback if the native approach can't reasonably produce the desired animation.
BatteryOptimizationScreen.kt, above or alongside the existingguidance text and before the "Take me there" / "Not now" buttons, so the user sees it while
still in LibreMail — not after they've already navigated away.
(
Settings.Global.ANIMATOR_DURATION_SCALE/AccessibilityManagerequivalent) and fall backto a static illustration or the current text-only guidance when it's on.
get the same information — the animation should be additive, not a replacement for an
accessible fallback.
Acceptance criteria
"Battery → Unrestricted" navigation path before the user is sent to system settings.
(
BatteryOptimizationScreen'sLifecycleEventEffect(ON_RESUME)) are unchanged.guidance path.
Relevant files
ui/onboarding/BatteryOptimizationScreen.kt,res/values/strings.xml(
onboarding_battery_*block).Dependencies
Complements #150 (battery settings deep link) — this ticket is about in-app guidance regardless
of how precisely the deep link itself lands.