feat(screens): implement all app screens and navigation flows#51
Conversation
Issue #14 - Complete UI implementation: - Onboarding flow: Welcome, GitHub auth, API keys, Project creation, Completion - Main app tabs: Dashboard, Projects, Agents, Chat, Settings - Project detail screen with tabs for files, commits, tasks, and agents - Agent detail screen with metrics, task history, and controls - Settings sub-screens: Credentials, Editor, Agent behavior - Not found screen for handling invalid routes All screens use the P3 "Warm Technical" design system with organic border-radius styling and ThumbCode brand colors. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughThis PR implements the complete navigation structure and all application screens, including a five-step onboarding flow (welcome, GitHub auth, API keys, project creation, completion), five main tab screens (home, projects, agents, chat, settings), detail screens for projects and agents, and three settings sub-screens. Navigation uses Expo Router with mock data throughout. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Welcome
participant GitHubAuth
participant ApiKeys
participant CreateProject
participant Complete
participant MainApp as MainApp/(tabs)
User->>Welcome: Opens app
Welcome->>User: Display hero & features
User->>Welcome: Tap "Get Started"
Welcome->>GitHubAuth: Navigate to GitHub auth
GitHubAuth->>GitHubAuth: Start Device Flow
GitHubAuth->>User: Display user code
User->>GitHubAuth: Tap "Open GitHub"
GitHubAuth->>GitHubAuth: Poll for authorization
GitHubAuth->>User: Display "Connected!"
User->>GitHubAuth: Tap "Continue"
GitHubAuth->>ApiKeys: Navigate to API keys
ApiKeys->>ApiKeys: User enters API keys
ApiKeys->>ApiKeys: Validate key format (async)
ApiKeys->>User: Display validation status
User->>ApiKeys: Tap "Continue"
ApiKeys->>CreateProject: Navigate to project creation
CreateProject->>CreateProject: Display repo list
User->>CreateProject: Select repo & enter name
CreateProject->>CreateProject: Simulate project creation
User->>CreateProject: Tap "Create Project"
CreateProject->>Complete: Navigate to completion
Complete->>User: Display success badge & summary
User->>Complete: Tap CTA
Complete->>MainApp: Navigate to main app
MainApp->>User: Display home dashboard
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🤖 Fix all issues with AI agents
In `@app/_layout.tsx`:
- Around line 16-52: The onboarding flag is hard-coded to false in
useOnboardingState, so users are always redirected back to onboarding; update
useOnboardingState to read/write a persisted flag (e.g., AsyncStorage or
SecureStore) and initialize setHasCompletedOnboarding from that persisted value,
expose setHasCompletedOnboarding to the onboarding flow, and ensure the
onboarding completion handler calls setHasCompletedOnboarding(true) and persists
the value so RootLayout's redirect logic (segments check + router.replace) can
allow access to the (tabs) route; alternatively add a temporary dev toggle that
flips the persisted flag for testing.
In `@app/`(onboarding)/api-keys.tsx:
- Around line 92-95: The button handler handleContinue currently only routes to
create-project and contains a TODO for persisting keys; implement an async save
flow (e.g., add an exported async function saveApiKeys or saveKeysToSecureStore
and call it from handleContinue) that writes the API keys to a hardware-backed
secure store API (SecureStore/Keychain/Platform-specific secure storage) and
only navigate after successful save, removing the TODO; if you can’t implement
secure persistence now, instead update the UI copy (the text block around lines
123-143 that claims “hardware-backed secure storage”) to remove any promise of
hardware-backed persistence so it accurately reflects current behavior.
In `@app/`(onboarding)/complete.tsx:
- Around line 44-47: The handleGetStarted function currently navigates to
'/(tabs)' without persisting completion; before calling
router.replace('/(tabs)') call the same persistence API used by the root layout
(e.g., the function or method named like markOnboardingComplete,
setOnboardingCompleted, or persistOnboardingState) to record onboarding as
finished; if that API is async await it and handle errors (log or surface) so
navigation only occurs after successful persistence, and then call
router.replace; update handleGetStarted to perform this persistence step using
the exact symbol found in the root layout.
In `@app/`(onboarding)/create-project.tsx:
- Around line 71-79: handleCreate can run twice on rapid taps; add an early
guard that returns immediately if isLoading is true, and ensure you
setIsLoading(true) as the first state change after validating selectedRepo and
projectName so subsequent invocations see the flag; update the handleCreate
function (referencing handleCreate, isLoading, setIsLoading, selectedRepo,
projectName, router) to check if (isLoading) return before proceeding, then
continue with the existing flow and finally setIsLoading(false) after completion
or error.
- Around line 164-177: The "+ Create new repository" Pressable in
create-project.tsx is a dead tap target; either wire it up or render it as
non-pressable until the flow exists—implement an onPress handler (e.g.,
handleCreateRepository or navigateToCreateRepo) on the Pressable that performs
the intended action, or replace the Pressable element that contains the Text "+
Create new repository" with a non-interactive View (keeping the same
styling/className and border radii) until the create-repository flow is
implemented.
In `@app/`(tabs)/index.tsx:
- Around line 221-225: The ProgressBar value calculation using
MOCK_STATS.completedToday and MOCK_STATS.pendingTasks can produce NaN when both
are 0; update the value expression (where ProgressBar is rendered) to compute a
denominator = MOCK_STATS.completedToday + MOCK_STATS.pendingTasks and use a
conditional (e.g., ternary) to return 0 when denominator is 0, otherwise
(MOCK_STATS.completedToday / denominator) * 100 so the component receives 0%
instead of NaN.
In `@app/project/`[id].tsx:
- Around line 93-102: The computation of progress in ProjectDetailScreen can
produce NaN when MOCK_PROJECT.completedTasks and MOCK_PROJECT.pendingTasks are
both 0; change the calculation to guard the denominator by computing a total
(e.g., total = MOCK_PROJECT.completedTasks + MOCK_PROJECT.pendingTasks) and set
progress to (total ? (MOCK_PROJECT.completedTasks / total) * 100 : 0) so
progress falls back to 0 when total is zero.
In `@app/settings/credentials.tsx`:
- Around line 278-294: The current ApiKeyInput onSave handlers unconditionally
call setAnthropicSet(true) / setOpenaiSet(true) even when the key value is
blank; update the handlers so they only mark the key as set when the trimmed
value is non-empty (e.g., onSave={() => { if (anthropicKey.trim())
setAnthropicSet(true) }}) or alternately change ApiKeyInput to pass the current
value into the onSave callback and perform the same trimmed-value guard there;
apply the same fix for anthropicKey/ setAnthropicSet and openaiKey/ setOpenaiSet
to prevent empty keys from being marked as set.
In `@app/settings/editor.tsx`:
- Around line 269-290: The preview is ignoring the theme setting (variable/theme
state named theme) — update the rendering in the component that uses fontSize
and lineNumbers to also derive background and text color class names from theme
(e.g., map "dark" -> bg-charcoal + existing text color tokens, "light" -> a
light bg and darker text classes, "highContrast" -> high-contrast bg/text);
apply those computed classes to the outer View and the inline Text elements
instead of hard-coded classes (where fontSize and lineNumbers are used) and
provide a sensible fallback if theme is undefined.
🧹 Nitpick comments (4)
app/settings/editor.tsx (2)
25-57: Consider adding accessibility labels to interactive elements.The
SettingRowcomponent lacks accessibility attributes. Screen readers won't convey the purpose of the toggle or the navigation chevron. Consider addingaccessibilityLabelto thePressableandaccessibilityLabel/accessibilityRoleto theSwitch.♿ Suggested accessibility improvements
function SettingRow({ title, subtitle, value, onPress, toggle }: SettingRowProps) { return ( <Pressable onPress={onPress} disabled={!onPress && !toggle} className={`py-4 ${onPress ? 'active:bg-neutral-800' : ''}`} + accessibilityRole={toggle ? 'none' : 'button'} + accessibilityLabel={toggle ? undefined : title} > <HStack justify="between" align="center"> <VStack spacing="xs" className="flex-1"> <Text className="text-white">{title}</Text> {subtitle && ( <Text size="sm" className="text-neutral-500"> {subtitle} </Text> )} </VStack> {value && <Text className="text-neutral-400">{value}</Text>} {toggle && ( <Switch value={toggle.value} onValueChange={toggle.onValueChange} trackColor={{ false: '#374151', true: '#0D9488' }} thumbColor={toggle.value ? '#fff' : '#9CA3AF'} + accessibilityLabel={title} /> )} {onPress && !toggle && <Text className="text-neutral-600">›</Text>} </HStack> </Pressable> ); }
126-132: Extract repeated section card styles to a constant.The same border-radius style object is duplicated across all four sections. Consider extracting it to reduce repetition.
♻️ Suggested refactor
export default function EditorSettingsScreen() { const insets = useSafeAreaInsets(); + + const sectionCardStyle = { + borderTopLeftRadius: 14, + borderTopRightRadius: 12, + borderBottomRightRadius: 16, + borderBottomLeftRadius: 10, + overflow: 'hidden' as const, + }; // Editor settings state // ... return ( // ... <VStack spacing="none" className="bg-surface mb-6" - style={{ - borderTopLeftRadius: 14, - borderTopRightRadius: 12, - borderBottomRightRadius: 16, - borderBottomLeftRadius: 10, - overflow: 'hidden', - }} + style={sectionCardStyle} >Also applies to: 181-187, 230-236, 256-262
app/(tabs)/chat.tsx (1)
277-341: Consider deterministic auto-scroll without a fixed timeout.Using a magic delay can be flaky across devices. You can scroll to end when content size changes instead.
♻️ Suggested refactor
- // Scroll to bottom - setTimeout(() => { - flatListRef.current?.scrollToEnd({ animated: true }); - }, 100); + // Scroll to bottom when list content updates<FlatList ref={flatListRef} data={messages} renderItem={({ item }) => <MockMessageBubble message={item} />} keyExtractor={(item) => item.id} + onContentSizeChange={() => flatListRef.current?.scrollToEnd({ animated: true })} contentContainerStyle={{ paddingTop: 16, paddingBottom: showApproval ? 200 : 100, }} showsVerticalScrollIndicator={false} />app/settings/credentials.tsx (1)
195-197: TODO: GitHub OAuth flow still unimplemented.Want me to scaffold the device-flow OAuth wiring or open a tracking issue?
- Add OnboardingContext for persistent onboarding state using AsyncStorage - Fix security copy in api-keys.tsx to not over-promise storage behavior - Add double-submit guard in create-project.tsx - Make "Create new repository" a non-pressable element (coming soon) - Add zero-division guards in index.tsx and project/[id].tsx - Add empty key validation in credentials.tsx - Add theme-aware preview in editor settings Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|




Summary
Closes #14
This PR implements all app screens and navigation flows for ThumbCode, completing the UI layer of the mobile application.
Onboarding Flow (5 screens)
Main App Tabs (5 tabs)
Detail Screens
Settings Sub-screens
Error Handling
Design System Compliance
All screens use:
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.