Redesign onboarding intro as a swipeable carousel with progress indicator - #45
Merged
Conversation
…ogress indicator Splits the single long intro page into 4 focused slides (welcome, record, browse, export) navigable via swipe or Next/Skip, and adds a page indicator to the bottom of every setup page (intro slides, orientation, resolution, duration) tracking progress across the whole onboarding flow. TODO: improve onboarding flow - make beautiful, split across multiple pages, add page indicator at the bottom of each page so the user can see how far they are Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
|
App apk at:
|
…r icon Image()/painterResource() can't parse the <adaptive-icon> XML that R.mipmap.ic_launcher_round resolves to on API 26+, which crashed the setup flow right after granting permissions. Use the existing "play" vector icon for the welcome slide instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
# Conflicts: # TODO.md
# Conflicts: # TODO.md
…nto per-permission pages Reorders the first-run flow so the onboarding intro slides play before permissions are requested, then presents each required permission as its own swipeable page styled like the intro slides (icon badge, title, description, grant status), gated behind granting rather than free swipe. Returning users who complete setup but later revoke a permission still see the lightweight standalone re-request screen, now sharing the same styled page component. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
… swipe Each permission page now watches its own grant state and moves on automatically (after a brief pause to show the "Granted" indicator) rather than requiring a manual continue tap; the last page auto-continues out of the permission flow once everything is granted, or routes back to whatever is still missing if the user swiped past it. Removes the back chevron from the intro and permission pages, since swiping now covers backward navigation within them. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
Removes the Skip button from the intro, and merges intro, permissions, orientation, resolution and duration into a single HorizontalPager so the entire onboarding flow is one continuous swipe, with no back buttons anywhere in it. Pages beyond the first ungranted permission aren't revealed yet, so users still can't swipe past a permission without granting it - and the camera- dependent setup steps that follow permissions stay unreachable until every permission is granted, preventing a crash from missing camera access. Also fixes the auto-continue effect getting stuck mid-transition: it was keyed on the pager's continuously-updating currentPage, so its own animateScrollToPage call (or the user's drag) would cancel and restart it mid-flight. It's now keyed on settledPage, which only changes once the pager is actually at rest, so each transition fires exactly once. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
…uto-advance - Removes the (now pointless, back-button-less) black toolbar from every onboarding page. - The page indicator and primary action button now live once, outside the HorizontalPager, staying static while only the page content swipes. Each page reports its current action (label/enabled/onClick) up via a new PagerAction, since pages like Resolution have local, dynamic enabled-state (camera readiness) that can't be computed from the router. - Fixes auto-advance firing every time an already-granted permission page is revisited (e.g. by swiping back to it): it now only fires once per permission, tracked via a remembered set of already-advanced permissions. Applies to both the onboarding flow and the standalone permission re-request screen shown to returning users after a permission is revoked. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
Compose can keep the outgoing and incoming page composed simultaneously during a swipe transition, so whichever page's reported action landed last was shown - sometimes the previous page's action (e.g. "Next" while sat on an ungranted permission page), which then silently failed since that page wasn't revealed yet. Each reported action is now tagged with the page it came from, and only displayed when it matches the currently active page, so a stale report from a page just swiped away from can never end up shown (and clicked) on the wrong page. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
…the router HorizontalPager composes its pages via subcomposition, deferred to the layout pass - on a different schedule to the pager's surrounding composable. Relying on a value reported from inside a subcomposed page (via SideEffect) to drive rendering outside the pager was unreliable: the button could be missing, stale, or briefly showing the wrong page's action. The router now computes the current page's action directly from state it already owns (view models, permission grants), the same reliable pattern the page indicator already used successfully. Orientation and duration's view models are hoisted to the router so it can read/act on them synchronously. Resolution is a deliberate exception: its "Next" button's enabled state depends on local, asynchronously loaded camera readiness that only that page's composable knows about, so it keeps its own internal button as it did before this "move outside the pager" work began, rather than trying to report that state out. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
Permission pages no longer auto-advance once granted - the button simply becomes "Next" (or "Continue" on the standalone permission screen's last page), requiring an explicit tap like every other page in the flow. Restyles the orientation, resolution, and video duration pages to match the onboarding/permission pages' visual language: a new shared SetupStepHeader (icon badge, title, description) sits above each page's interactive content, replacing the old plain text headers. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
…boarding style - Redesigns SingleOptionSelector (orientation) and IntPicker (duration) as soft, accent-colored controls (sliding pill segmented control, circular stepper buttons) matching the onboarding's visual language. - Resolution page now uses the same static "Next" button and page indicator as every other onboarding page, outside the swipeable content: its camera-loading state is hoisted into the router so the button's readiness can be computed the same reliable way as the rest. - Removes the < / > buttons next to the resolution text and replaces them with floating glass buttons on the left/right edges of the video preview itself. - Fixes swiping over the camera preview doing nothing: CameraInput always installed a pinch-zoom gesture handler that consumed single-finger pan gestures too, even when zoom was disabled, silently swallowing the pager's swipe. It's now only installed when zoom is actually enabled. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
Replaces the floating buttons over the camera feed with a row layout: chevron, then the preview filling the remaining horizontal space with weight(1f), then chevron - so the preview no longer spans the full width of the screen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
Duration (the page after resolution) is no longer revealed in the pager until a valid resolution is selected - consistent with how permission pages already gate the pages that follow them. The resolution page's "Next" button is now always enabled to match; tapping it before a resolution is ready is a no-op rather than being visibly disabled. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
…eady - Restores the visible disabled state on the resolution page's "Next" button when no valid resolution is selected, alongside the existing swipe/reveal gating. - Adds a new final "You're all set!" page after video duration, shown right before the user enters the app. Its button reads "Get started" and is what actually completes setup now, rather than duration's own Next button. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
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.
Summary
Implements the following TODO item:
PageIndicator(dots) to the bottom of every page in the onboarding flow — the 4 intro slides plus the orientation, resolution, and video-duration steps — so the dots track a single continuous progress through the whole flow (7 pages total).GenericToolbarwith an optional trailingendContentslot (used for the intro's "Skip" action), backwards compatible with all existing callers.SetupIntroBulletcomponent.TODO.md.Test plan
./gradlew compileDebugKotlin— builds successfully./gradlew assembleDebug— builds successfully./gradlew test— unit tests pass🤖 Generated with Claude Code
https://claude.ai/code/session_014hM6AmSVVvZKXHdG27prwm
Generated by Claude Code