Conversation
依 RN 效能最佳實踐,將不依賴 props/state/theme 的樣式抽到各元件的
StyleSheet.create;隨 theme 顏色、props(如 width)、互動狀態變動的
部分仍用 style={[styles.x, { 動態值 }]} 合併,避免每次 render 產生
新物件、也讓之後套用 React.memo 的清單元件(如 BookCard)能真正生效。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
useBookmarks 原本依賴 setState updater 是否被提前同步執行來讀取新陣列, 在閱讀器頁面頻繁有其他 state 更新時該行為不保證發生,導致存進 AsyncStorage 的是舊值。改成跟 useAnnotations 一致的寫法:直接用當下 state 算出 next 再依序 setBookmarks/saveBookmarks。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Next review available in: 46 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe mobile UI replaces inline React Native styles with local ChangesMobile UI and bookmark changes
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@mobile/app/`(tabs)/index.tsx:
- Around line 189-206: Replace all reviewed inline JSX style props with
className bindings, preserving conditional theme and active-state behavior:
update mobile/app/(tabs)/index.tsx lines 189-206 for the safe-area, title, and
empty-state styles; mobile/app/(tabs)/settings.tsx lines 9-27 for the safe-area,
rows, labels, and switch; mobile/app/reader/[id].tsx lines 127-155 for the
reader header and controls; mobile/components/BookCard.tsx lines 32-44 for cover
and placeholder; mobile/components/ListPanel.tsx lines 118-123 and the remaining
panel controls; mobile/components/SelectionBar.tsx lines 30-44 for the selection
bar and swatches; mobile/components/SettingsPanel.tsx lines 46-60 for
helper-generated and JSX styles; and mobile/components/SortControl.tsx lines
21-30 for sort-control styles. Use the existing stylesheet/extraction classes
rather than introducing new inline objects.
In `@mobile/hooks/reader/useBookmarks.ts`:
- Around line 27-29: Update handleToggleBookmark and handleDeleteBookmark to use
a functional bookmarks state updater or reducer so consecutive calls compose
from the latest state instead of the captured snapshot. Move saveBookmarks out
of both handlers into a synchronization effect or equivalent that persists each
committed final bookmarks state, preserving the existing bookmark mutations and
id association.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 4e88edca-4641-432c-aef2-4c7a958fd3da
📒 Files selected for processing (9)
mobile/app/(tabs)/index.tsxmobile/app/(tabs)/settings.tsxmobile/app/reader/[id].tsxmobile/components/BookCard.tsxmobile/components/ListPanel.tsxmobile/components/SelectionBar.tsxmobile/components/SettingsPanel.tsxmobile/components/SortControl.tsxmobile/hooks/reader/useBookmarks.ts
| <SafeAreaView edges={['top']} style={[styles.safeArea, { backgroundColor: colors.paperBg }]}> | ||
| <View style={styles.header}> | ||
| <Text style={[styles.headerTitle, { color: colors.ink }]}> | ||
| 書櫃 <Text style={[styles.headerCount, { color: colors.ink3 }]}>{books.length} 本</Text> | ||
| </Text> | ||
| <Pressable onPress={handleAddBook} hitSlop={12}> | ||
| <Text style={{ fontSize: 16, color: '#2563eb' }}>+ 加入書籍</Text> | ||
| <Text style={styles.addButtonText}>+ 加入書籍</Text> | ||
| </Pressable> | ||
| </View> | ||
|
|
||
| {books.length > 0 && ( | ||
| <View style={{ paddingHorizontal: 16, paddingBottom: 12 }}> | ||
| <View style={styles.sortWrapper}> | ||
| <SortControl sort={sort} onSortChange={setSort} /> | ||
| </View> | ||
| )} | ||
|
|
||
| {!loading && books.length === 0 ? ( | ||
| <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> | ||
| <View style={styles.emptyState}> |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift
Use className and remove inline style props.
The stylesheet extraction still leaves inline JSX style objects in every reviewed component. Replace these style props with className bindings, including conditional theme and active-state classes.
mobile/app/(tabs)/index.tsx#L189-L206: Replace the safe-area, title, and empty-statestyleprops.mobile/app/(tabs)/settings.tsx#L9-L27: Replace the safe-area, row, label, and switchstyleprops.mobile/app/reader/[id].tsx#L127-L155: Replace the reader header and controlstyleprops.mobile/components/BookCard.tsx#L32-L44: Replace cover and placeholderstyleprops.mobile/components/ListPanel.tsx#L118-L123: Replace table-of-contentsstyleprops and apply the same change to the remaining panel controls.mobile/components/SelectionBar.tsx#L30-L44: Replace selection-bar and color-swatchstyleprops.mobile/components/SettingsPanel.tsx#L46-L60: Replace helper-generated and JSXstyleprops.mobile/components/SortControl.tsx#L21-L30: Replace sort-controlstyleprops.
As per coding guidelines, **/*.tsx: React JSX 頁面/元件中應使用 className 寫法,並避免使用 inline style.
📍 Affects 8 files
mobile/app/(tabs)/index.tsx#L189-L206(this comment)mobile/app/(tabs)/settings.tsx#L9-L27mobile/app/reader/[id].tsx#L127-L155mobile/components/BookCard.tsx#L32-L44mobile/components/ListPanel.tsx#L118-L123mobile/components/SelectionBar.tsx#L30-L44mobile/components/SettingsPanel.tsx#L46-L60mobile/components/SortControl.tsx#L21-L30
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@mobile/app/`(tabs)/index.tsx around lines 189 - 206, Replace all reviewed
inline JSX style props with className bindings, preserving conditional theme and
active-state behavior: update mobile/app/(tabs)/index.tsx lines 189-206 for the
safe-area, title, and empty-state styles; mobile/app/(tabs)/settings.tsx lines
9-27 for the safe-area, rows, labels, and switch; mobile/app/reader/[id].tsx
lines 127-155 for the reader header and controls; mobile/components/BookCard.tsx
lines 32-44 for cover and placeholder; mobile/components/ListPanel.tsx lines
118-123 and the remaining panel controls; mobile/components/SelectionBar.tsx
lines 30-44 for the selection bar and swatches;
mobile/components/SettingsPanel.tsx lines 46-60 for helper-generated and JSX
styles; and mobile/components/SortControl.tsx lines 21-30 for sort-control
styles. Use the existing stylesheet/extraction classes rather than introducing
new inline objects.
Source: Coding guidelines
handleToggleBookmark/handleDeleteBookmark 原本從 closure 裡的 bookmarks 快照算出 next 再同步存檔,連續呼叫(例如書籤清單連點兩個刪除)會用同一份 舊 snapshot,後者蓋掉前者。改成 functional updater 疊加狀態,saveBookmarks 移到跟著已提交 bookmarks state 變化的 effect 裡執行,同時維持前一輪修的 「不讀取 setState updater 尚未執行的舊值」。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Summary by CodeRabbit