Repository navigation
feat(mobile): low battery motion mode - #5899
Conversation
Code Review SummaryStatus: 2 Issues Found | Recommendation: Address before merge Executive SummaryRefreshProgress still participates in parent Overview
Issue Details (click to expand)WARNING
Files Reviewed (24 files)
Fix these issues in Kilo Cloud Previous Review Summaries (5 snapshots, latest commit d64b7eb)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit d64b7eb)Status: No Issues Found | Recommendation: Merge Executive SummaryIncremental review of the cross-platform battery policy and i18n key splits at d64b7eb; no new correctness, security, or runtime issues. Files Reviewed (14 files)
Previous review (commit 8467ebf)Status: No Issues Found | Recommendation: Merge Executive SummaryNo incremental code changes since the previous review; HEAD matches the previously reviewed tree after a history rewrite. Files Reviewed (0 files)Previous review (commit 9c86be2)Status: No Issues Found | Recommendation: Merge Files Reviewed (24 files)
Previous review (commit 5cfe2c5)Status: No Issues Found | Recommendation: Merge Files Reviewed (3 files)
Previous review (commit 9e751aa)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (154 files)
Reviewed by grok-4.6 · Input: 409.8K · Output: 26.4K · Cached: 1.2M Review guidance: REVIEW.md from base branch |
9c86be2 to
8467ebf
Compare
cec2ef2 to
6b4eb6c
Compare
d9354de to
d64b7eb
Compare
d64b7eb to
c371a80
Compare
Keep the tab-screen RefreshProgress child on main's marginBottom clearance. Mock motion wrappers in mounted tests that now import expo-battery.
| return ( | ||
| <View | ||
| accessibilityRole={showStaticProgress ? 'progressbar' : undefined} | ||
| className={`${reducedMotion ? 'h-9' : 'h-0'} items-center justify-center`} |
There was a problem hiding this comment.
WARNING: h-0 RefreshProgress still consumes parent gap
The slot stays mounted on every pull-to-refresh TabScreenScrollView / DetailScreenScrollView / CenteredState / list header. h-0 removes height but Yoga still treats the node as a flex item, so contentContainerClassName values like gap-6 (KiloClaw instance list) and gap-4 (Security dashboard) add extra top spacing for all users, not only low-battery mode.
Keep the View mounted for instance identity, but use hidden / display: 'none' when motion is not reduced so the node is skipped in gap.
| className={`${reducedMotion ? 'h-9' : 'h-0'} items-center justify-center`} | |
| className={`${reducedMotion ? 'h-9' : 'hidden'} items-center justify-center`} |
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| <View {...props} className="items-center justify-center" style={style}> | ||
| <Loader2 | ||
| size={indicatorDimension(size)} | ||
| color={!animating && hidesWhenStopped ? 'transparent' : color} |
There was a problem hiding this comment.
WARNING: Reduced-motion spinner has no default color
Native ActivityIndicator supplies a platform gray when color is omitted. The static Loader2 fallback passes color through, and Lucide treats undefined as black/currentColor. Call sites such as file-part-renderer.tsx (dark:bg-neutral-900) and quick-chat-screen.tsx omit color, so the loading affordance disappears on dark surfaces in low-battery mode.
Default to a theme token (for example mutedForeground) when color is unset.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Request
Changelog for users
New sessioninstead ofNew coding task.Changelog for maintainers
MotionProviderwraps the app root and combines the system Reduce Motion setting with an Android-only battery policy: battery level below 20% and unplugged/not-charging forcesreducedMotionon and switches Reanimated's globalReducedMotionConfigtoAlways; otherwise it staysSystem.useMotionPolicy(a thin wrapper overuseReducedMotion) is replaced by a context-backed hook plususeProvidedMotionPolicy; every animation primitive (Skeleton,SpinningIcon,StatusDot, the provisioning avatar pulse, splash overlay, composer, and entrance selectors) now reads the shared policy instead ofuseReducedMotion.activity-indicator,refresh-control, andrefresh-progressprimitives render the static equivalents under reduced motion; all in-appActivityIndicator/RefreshControlimports are routed through them, withRefreshProgressadded as a list header and to scroll containers so the static glyph stays stable.RefreshControlwrapper forcesrefreshingtofalseunder reduced motion (suppressing the native spinner) whileRefreshProgressrenders the static glyph, so pull-to-refresh presentation changes only when motion is reduced.expo-batteryis added as a dependency.canceledflag when the owner detaches mid-refresh, and callers fall back to a second refetch instead of treating a detached owner result as handled; focus/foreground refresh now relies on the live-sync owner rather than separately invalidating the active-sessions query.lib/a11y/motion.tsxand the root_layout.tsxprovider for the policy/threshold logic, and the three newuiprimitives for the static swap; the highest-risk area is the globalReducedMotionConfigmode switch and the native refresh spinner suppression.E2E proof
Recording of the verified flow (waits trimmed)
e3-android-pagination-refresh.mp4.trim.mp4
Follow-ups (not changed here)