Skip to content

feat(mobile): give the mobile shell a bottom tab bar - #557

Merged
mudream4869 merged 3 commits into
devfrom
claude/notion-link-review-600l9g
Aug 29, 2026
Merged

feat(mobile): give the mobile shell a bottom tab bar#557
mudream4869 merged 3 commits into
devfrom
claude/notion-link-review-600l9g

Conversation

@mudream4869

Copy link
Copy Markdown
Member

What & why

Ticket: 手機導覽是桌面側邊欄塞進抽屜,切頁要兩次點擊 (PlainShelf 工作項目)

The mobile shell reused MainLayout's off-canvas drawer as its only navigation, so every page switch cost two taps and a full-screen scrim, and the drawer rendered a shrunk copy of the desktop information architecture — whose maintenance/admin sections are empty on the read-only Android client.

The ticket was blocked on a product decision (is Android a primary reading device?). That was resolved: yes → walk A (bottom tab bar + drawer kept only for the folder tree).

Changes

  • New MobileTabBar.vue — a bottom tab bar for the four frequent destinations, reachable in one tap:
    • 書庫 /books · 最近閱讀 /read-history · 下載 /downloads · 設定 /settings
    • Library uses prefix-match active state (covers book detail); the leaf routes use exact match.
    • It's a shared component that imports nothing mobile-only, so it clears check-boundaries; MainLayout gates it on isMobileRuntime() — the same signal the shell itself uses, and the one under which the Downloads destination exists. A narrow desktop browser keeps the existing drawer.
  • MainLayout.vue — renders the tab bar on the mobile runtime, adds bottom padding so content clears the fixed bar, and hides the drawer's now-redundant nav sections there (Recently read, Downloads, Logs, Settings). The drawer keeps shelf switching, Home, and the folder tree.
  • Icon + i18n — added a library icon (tabler/books) and layout.library / layout.tabNavLabel labels in both en and zh-Hant.

Scope notes

  • Desktop/web navigation is unchanged: every drawer trim is gated on isMobileRuntime().
  • Home (/home) stays reachable from the drawer, per the ticket's "fold dashboard into the drawer".

Checks

  • npm --prefix frontend test — 1292 passed (incl. new MobileTabBar.test.ts)
  • npm --prefix frontend run build (vue-tsc + vite) — clean
  • npm --prefix frontend run check-boundaries — OK (3 rules)
  • npm --prefix frontend run check-licenses — OK
  • e2e (not a CI gate; run locally against the preinstalled Chromium): mobile-read-only, sidebar-rail, sidebar-foldable, mobile-downloads, mobile-shelves, mobile-download-badge-layout, read-history, locale, settings-tabs — 34 passed. Added a tab-bar assertion to mobile-read-only.spec.ts (Downloads stays a single link, now via the tab).

🤖 Generated with Claude Code

https://claude.ai/code/session_01K5wyZmR7Uw8Cw47atghjnK


Generated by Claude Code

The mobile shell shared MainLayout's off-canvas drawer as its only
navigation, so every page switch cost two taps and a full-screen scrim,
and the drawer showed a shrunk copy of the desktop information
architecture whose maintenance/admin sections are empty on the read-only
Android client.

Add a mobile-runtime-only bottom tab bar for the four frequent
destinations — Library, Recently read, Downloads, Settings — reachable in
one tap. The drawer stays for shelf switching, Home, and the folder tree;
its now-redundant nav sections (Recently read, Downloads, Logs, Settings)
are hidden on the mobile runtime.

The tab bar is a shared component that imports nothing mobile-only, so it
clears the module-boundary check while MainLayout gates it on
isMobileRuntime() — the same signal the shell itself uses, and the one
under which the Downloads destination exists.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5wyZmR7Uw8Cw47atghjnK

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 00f8c1d070

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread frontend/src/components/MobileTabBar.vue Outdated
claude added 2 commits August 29, 2026 05:25
`library` (/books) and `book-detail` (/books/:id) are sibling route
records, so RouterLink's record-based active matching lit the Library tab
on neither. Compute the tab's active state from the current path instead,
so it owns the whole /books subtree (list, a book, the maintenance
filters that redirect into it) while the leaf tabs match their own path
only. The unit test now drives a real memory router with the same sibling
shape rather than a RouterLink stub, which is what let the bug through.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5wyZmR7Uw8Cw47atghjnK
The new fixed bottom tab bar sat on top of the mobile multi-select
"Download to device" action bar (both fixed at the bottom edge), so its
button's taps were intercepted and mobile-multiselect e2e timed out.

Reserve the bar's height as a shared --mobile-tab-bar-height token and
offset the selection action bar above it. The action bar only renders on
the mobile runtime — the same condition under which the tab bar exists —
so the offset always clears it. MainLayout's page padding uses the same
token instead of a hard-coded height.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5wyZmR7Uw8Cw47atghjnK
@mudream4869
mudream4869 merged commit 35b1fa6 into dev Aug 29, 2026
5 checks passed
@mudream4869
mudream4869 deleted the claude/notion-link-review-600l9g branch August 29, 2026 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants