Conversation
非 macOS 平台或啟動階段 app.dock 可能不存在,加上 optional chaining 避免崩潰。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
新增 Expo/RN app 骨架與 epub.js WebView reader,翻頁方式從滑動改為點擊畫面左右 1/3 區塊(蓋在 #viewer 上層的最外層文件 tap zone),避開先前滑動手勢與未來劃詞註記手勢 的衝突,也修正舊版點擊翻頁因 iframe 內部座標系失準導致的失效問題。 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: 35 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 ignored due to path filters (1)
📒 Files selected for processing (9)
📝 WalkthroughWalkthroughThis PR bootstraps a new Expo/React Native mobile app (TravelInTime) with tab navigation, an AsyncStorage-backed EPUB library, a WebView-based epub.js reader with a build script generating READER_HTML, project config files (app.json, eas.json, tsconfig, gitignore, license), documentation, and a minor Electron Dock icon safety fix. ChangesMobile App Bootstrap
Estimated code review effort: 3 (Moderate) | ~30 minutes Electron Dock Icon Fix
Sequence Diagram(s)sequenceDiagram
participant ReaderScreen
participant WebView as WebView (READER_HTML)
participant Library as library.ts
ReaderScreen->>WebView: post "ready" listener setup
WebView-->>ReaderScreen: { type: "ready" }
ReaderScreen->>Library: getBookBase64, loadReadingCfi
ReaderScreen->>WebView: post { type: "load", base64, cfi }
WebView->>WebView: loadBook(base64, cfi) via epub.js
WebView-->>ReaderScreen: { type: "relocated", cfi, page }
ReaderScreen->>Library: saveReadingCfi, updateProgress
Related issues: None found. Related PRs: None found. Suggested labels: mobile, enhancement, documentation Suggested reviewers: None found. 🐰
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 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: 8
🧹 Nitpick comments (3)
mobile/lib/library.ts (1)
39-48: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winUnsynchronized read-modify-write on the shared meta array.
loadMeta()/saveMeta()is used byaddBook,removeBook,touchBook, andupdateProgressas a read-then-overwrite pattern with no locking. If two of these fire close together (e.g.,touchBookon focus whileupdateProgress/saveReadingCfifire from readerrelocatedevents, permobile/app/reader/[id].tsx), the second write can silently clobber the first based on a stale read, losing a progress or lastOpenedAt update.Consider serializing writes through an in-memory mutex/queue (or a single "apply(fn)" helper that always re-reads inside a critical section) to make these mutations atomic.
Also applies to: 85-104
🤖 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/lib/library.ts` around lines 39 - 48, The shared meta updates in loadMeta/saveMeta are vulnerable to lost writes because addBook, removeBook, touchBook, and updateProgress do read-modify-write without serialization. Add a single atomic update path in library.ts, such as an in-memory mutex/queue or an apply(fn) helper that re-reads inside a critical section, and route those mutators through it so concurrent calls cannot overwrite each other with stale BookRecord data.mobile/app/reader/[id].tsx (1)
18-22: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate message-contract type.
OutboundMessagehere is a copy of the type defined inmobile/reader-web/index.ts(lines 9-13). Keeping the WebView message contract in two independently-maintained files risks silent drift (e.g., one side adds/renames a field and the other isn't updated, with no compiler error since matching is structural).Consider extracting
InboundMessage/OutboundMessageinto a shared module (e.g.mobile/lib/readerMessages.ts) imported by bothreader-web/index.tsand this screen.🤖 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/reader/`[id].tsx around lines 18 - 22, The OutboundMessage contract is duplicated between this screen and reader-web/index.ts, which can drift silently. Move InboundMessage/OutboundMessage into a shared module such as a readerMessages file and import the types from there in both the WebView screen and the web entrypoint. Keep the message-shape definitions centralized so any future field changes are made once and reused consistently.mobile/scripts/build-reader-html.js (1)
20-48: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winUnescaped
</script>in bundled JS can break the generated HTML.
bundleJsis interpolated raw into<script>${bundleJs}</script>. If the minified bundle (or any transitive dependency like epub.js) ever contains the literal substring</script>, it will prematurely close the tag and corrupt the generated HTML, silently breaking the reader.🛡️ Proposed fix: escape closing script tags
-<script>${bundleJs}</script> +<script>${bundleJs.replace(/<\/script/gi, '<\\/script')}</script>🤖 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/scripts/build-reader-html.js` around lines 20 - 48, The inline bundle injection in build-reader-html.js can be broken by a literal closing script tag inside bundleJs. Update the HTML assembly around the <script>${bundleJs}</script> block to safely escape any </script> sequences before interpolation so the generated document cannot be prematurely terminated. Keep the fix localized to the html template construction in build-reader-html.js and ensure the resulting bundle still loads normally in the reader.
🤖 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 22-39: Add error handling around the async library calls in
handleAddBook and handleDeleteBook in index.tsx, since addBook() and
removeBook() can reject and currently fail silently. Wrap the await calls in
try/catch (including the Alert.alert onPress callback), and on failure show a
user-facing alert or message while keeping refresh() only on success.
In `@mobile/app/reader/`[id].tsx:
- Around line 99-101: The icon-only back control in the reader screen lacks
accessibility metadata, so update the Pressable used with handleBack to expose
an accessibility role and a descriptive label. Add the appropriate accessibility
props directly on the Pressable in the [id] reader component so screen readers
announce it as a back button instead of an unlabeled glyph.
- Around line 107-117: The Reader WebView currently allows top-level navigation
from EPUB content, so add an onShouldStartLoadWithRequest guard to the WebView
in [id].tsx that permits the local READER_HTML and iframe/local resource loads
but blocks any non-local top-frame request. Update the reader message/link
handling around handleMessage so external URLs are intercepted and opened with
Linking.openURL instead of allowing the WebView to navigate there.
In `@mobile/lib/library.ts`:
- Around line 52-78: In addBook, the EPUB file copy is started without waiting
for it to finish, so metadata can be saved before the file actually exists.
Update the addBook flow to await picked.copy(destination) before building the
BookRecord and calling saveMeta, and make sure any copy failure prevents
persisting the new record.
In `@mobile/package.json`:
- Around line 5-20: The mobile package is missing the web runtime dependencies
needed by the existing web entrypoint and web script. Update the dependencies
block in mobile/package.json to include react-dom and react-native-web alongside
the Expo/React Native packages, using versions compatible with the current Expo
57 stack, so the web target can resolve expo-router/entry correctly.
In `@mobile/reader-web/index.ts`:
- Around line 41-71: The navigation lock in turnPage/lockNav can remain active
at book boundaries because rendition.prev()/rendition.next() may resolve without
firing relocated, leaving navBusy true until the 1500ms fallback. Update
turnPage to unlock on promise settlement as well as on relocated, using the
existing unlockNav and unlockNavSoon helpers so boundary taps do not get
swallowed; keep the current navBusy guard and ensure any successful or no-op
navigation clears the lock promptly.
In `@RN_SETUP_GUIDE.md`:
- Around line 63-68: The bootstrap install step in RN_SETUP_GUIDE.md is missing
dependencies that later setup assumes are already present. Update the expo
install command in the initial mobile setup to include expo-constants and
expo-linking alongside expo-router, expo-dev-client,
react-native-safe-area-context, and react-native-screens, or separate them into
a clearly labeled install step so the guide stays consistent.
- Around line 34-50: Section 2 is out of sync with the current mobile baseline
and should be updated or explicitly marked as historical context. In
RN_SETUP_GUIDE.md, revise the version block and the Expo docs reference to match
the active mobile/ baseline used elsewhere (Expo SDK 57 / RN 0.86), or clearly
label the current table as legacy SelfMap versions. Keep the guidance aligned
with the surrounding setup instructions and the relevant version symbols (expo,
expo-router, react-native, typescript) so readers do not follow stale baselines.
---
Nitpick comments:
In `@mobile/app/reader/`[id].tsx:
- Around line 18-22: The OutboundMessage contract is duplicated between this
screen and reader-web/index.ts, which can drift silently. Move
InboundMessage/OutboundMessage into a shared module such as a readerMessages
file and import the types from there in both the WebView screen and the web
entrypoint. Keep the message-shape definitions centralized so any future field
changes are made once and reused consistently.
In `@mobile/lib/library.ts`:
- Around line 39-48: The shared meta updates in loadMeta/saveMeta are vulnerable
to lost writes because addBook, removeBook, touchBook, and updateProgress do
read-modify-write without serialization. Add a single atomic update path in
library.ts, such as an in-memory mutex/queue or an apply(fn) helper that
re-reads inside a critical section, and route those mutators through it so
concurrent calls cannot overwrite each other with stale BookRecord data.
In `@mobile/scripts/build-reader-html.js`:
- Around line 20-48: The inline bundle injection in build-reader-html.js can be
broken by a literal closing script tag inside bundleJs. Update the HTML assembly
around the <script>${bundleJs}</script> block to safely escape any </script>
sequences before interpolation so the generated document cannot be prematurely
terminated. Keep the fix localized to the html template construction in
build-reader-html.js and ensure the resulting bundle still loads normally in the
reader.
🪄 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: a965a16f-49ba-4acb-8873-9f63df3f4831
⛔ Files ignored due to path filters (7)
mobile/assets/android-icon-background.pngis excluded by!**/*.pngmobile/assets/android-icon-foreground.pngis excluded by!**/*.pngmobile/assets/android-icon-monochrome.pngis excluded by!**/*.pngmobile/assets/favicon.pngis excluded by!**/*.pngmobile/assets/icon.pngis excluded by!**/*.pngmobile/assets/splash-icon.pngis excluded by!**/*.pngmobile/yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (19)
RN_SETUP_GUIDE.mdelectron/main.tsmobile/.gitignoremobile/AGENTS.mdmobile/CLAUDE.mdmobile/LICENSEmobile/app.jsonmobile/app/(tabs)/_layout.tsxmobile/app/(tabs)/index.tsxmobile/app/(tabs)/settings.tsxmobile/app/_layout.tsxmobile/app/reader/[id].tsxmobile/eas.jsonmobile/lib/library.tsmobile/lib/readerHtml.generated.tsmobile/package.jsonmobile/reader-web/index.tsmobile/scripts/build-reader-html.jsmobile/tsconfig.json
- 書櫃頁 addBook/removeBook 加上錯誤處理與提示 - 閱讀頁返回鍵補上無障礙標籤,WebView 加上導航守衛避免被導離 - library.ts 的 addBook 等待檔案複製完成,並將 meta 讀寫改為排隊序列化避免併發覆蓋 - reader-web 翻頁鎖在 promise resolve 時也會解鎖,避免邊界翻頁卡住 - 抽出共用的 readerMessages 型別、跳脫 bundle 內的 </script> - 補上 web 版所需的 react-dom/react-native-web 依賴 - RN_SETUP_GUIDE.md 補齊安裝指令並標註版本章節為舊版參考 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Summary by CodeRabbit
New Features
Bug Fixes
Documentation