Skip to content

feat(mobile): phone shell, step 4 (reading drawer, app bridge), tabs and chips, three phone fixes - #6895

Draft
tsahimatsliah wants to merge 10 commits into
mainfrom
claude/mobile-step4
Draft

tsahimatsliah wants to merge 10 commits into
mainfrom
claude/mobile-step4

Conversation

@tsahimatsliah

@tsahimatsliah tsahimatsliah commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Step 4 of the phone shell plan (Storybook, Mobile UX / 10. The build): 4.1 the reading drawer and 4.2 the bridge behaviours. Steps 0 to 3 are on main (#6765, #6767, #6801, #6813, #6826, #6852, #6855).

The native half is dailydotdev/ios claude/reading-drawer. Every message here is silent until a wrapper registers its handler, so the mobile web and today's app builds are unchanged.

4.1 The reading drawer (chapter 6b)

Inside the app, Read keeps the member on the post. The app opens the article behind the web view, and the post page sinks into a drawer at the bottom, as X does.

  • Built on scroll. The drawer is the post page itself, under a see-through band. Its four heights (bar, card, post, full) are scroll positions, so pulling the drawer up is scrolling the post.
  • The capsule stays where it stands. Close, the domain with the page menu (back, forward, copy link, open in browser) and reload ride 10px above the drawer.
  • Reading folds the drawer. Reading down the article folds the title line away; a nudge up brings it back. A tap on the title or on the dimmed article moves between card and post.
  • Back closes the drawer before it leaves the post. The drawer owns one history entry, so this covers the top bar's back, Android back and Escape. The router never sees that entry.
  • Touches above the drawer go to the article, except over our own sheets, menus, dialogs and toasts.
  • Opt-out. "Open links in the app" in Appearance is a client-only flag, shown only inside an app that supports reading. When off, Read opens the link as before.

4.2 Bridge behaviours (chapter 8)

  • Haptics: a light impact on a tab change, an upvote and a bookmark, and a success one when the streak goes up. iOS uses the handler; the Android app uses navigator.vibrate.
  • Pull to refresh: the wrappers call window.dailyNative.refresh(), which refetches what is on screen and answers when done, instead of reloading the page.
  • Status bar: light over a cover page.
  • Reduce Transparency: the floating material turns solid. The app mirrors the setting as a class; browsers answer the media query.
  • Android back contract: window.dailyNative.back() closes the drawer or the top sheet first and reports whether it used the press. nav-state tells the wrapper where the page is. Android has no bridge yet; DailyAndroid is the contract it will implement.

useBookmarkPost gained three type fixes the strict check asks for once the file is touched. They change no behaviour.

Measuring it

Chapter 6b's metric is the share of article opens that end with a reaction or a return to the post.

  • open reading drawer fires when Read opens the drawer.
  • close reading drawer fires when it closes, with duration_ms (the time on the article) and closed_by: close, back, link or leave.
  • Every event the post page logs while the drawer is open carries reading_drawer: true, so an upvote, bookmark or comment made while reading can be told apart from one made on the post.

The domain capsule above the drawer now takes the domain's width instead of filling the row.

Also in this PR: three small phone fixes

These were separate PRs (#6897, #6898, #6902), folded in so there is one web PR to review.

  • Read no longer throws. A Read click from a post page threw an uncaught reading 'pages' error when a cached feed had never loaded; those feeds are skipped (useOnPostClick, with a spec).
  • Back after saving an edit. Saving a post edited from its own post page now steps back to that post, instead of leaving the history as post, post (posts/[id]/edit.tsx, previousShellPath in shellNav, with a spec).
  • New squad explains itself on phones. The one-line explanation is back under the top bar on /squads/new; the title and the illustration stay desktop-only.

Also in this PR: tabs and chips on every phone row

Tabs switch to content that is different altogether; chips narrow the list the page already holds (Storybook chapter 4h). Phones only; tablet and desktop keep their navbars and buttons (checked at 768 and 1280px).

  • Tabs (ShellRow + Segments): a 48px row with a hairline, 15px labels, bold when lit and medium otherwise. Every label reserves its bold width, so lighting a tab never moves the row (label positions measured identical before and after a switch). A 32 × 3px bar slides to the tapped tab. Equal widths while every tab fits, scroll otherwise.
  • Tab with more choices: the lit tab shows a 12px chevron after its label (hung in the tab's padding, so nothing moves); a tap on the lit tab opens its sheet. Happening now's sheet holds its channels; For you's and each custom feed's sheet holds the order (Recommended, By date, when sorting is on) and Feed settings, with the You drawer's filter icon.
  • Home row: no filter icon or sort menu any more (Feed settings stays in the You drawer). The plus for a new custom feed is a plain borderless button (38px target) pinned at the row's right; the tabs scroll under it and fade over their last 24px.
  • Chips (ShellRow kind={ShellRowKind.Chips} + Chips): the Small button's shape, 32px with 10px corners, 14px medium, in a 48px row. Notifications and the Squads directory.
  • Rows that drew their own buttons on phones now follow the rule: Messages (Chats, Requests) and Tools are tabs, Achievements' filters are chips.

Verified

  • The iOS simulator, with the app built from claude/reading-drawer against this branch:
    • Read from the button and from the image;
    • the card, the fold while reading down and the unfold on a nudge up;
    • the title tap to the post and the tap on the dimmed article back to the card;
    • a drag down settling on the card, and pulling up past the top to the post page with its top bar;
    • Read again sinking the post back down;
    • the top bar's back and the close button both returning to the post as it was;
    • the page menu and its close.
  • Pull to refresh: the app called the web layer and got true back, with no page reload.
  • Not seen yet: haptics (the simulator has no Taptic Engine) and the Android side (there is no Android wrapper build).
  • Specs for the bridge messages with a fake handler, and for the drawer with a fake bridge: opens instead of following the link, shows the reported page, back closes it first, and Read stays a plain link without the bridge.
  • Strict type check on changed files, the webapp type check, shared 525 suites and webapp 82 suites all pass.

🤖 Generated with Claude Code

Preview domain

https://claude-mobile-step4.preview.app.daily.dev

4.1, the reading drawer (chapter 6b). Inside a wrapper that can show an
article, Read keeps the member on the post: the wrapper opens the page
behind this web view and the post page sinks into a drawer at the bottom.
The drawer is the document itself, a transparent band above it, so its
heights (bar, card, post, full) are scroll positions and pulling it up is
scrolling the post. The capsule stays where it stands; the controls (close,
the domain with the page menu, reload) ride 10px above the drawer. Reading
down the article folds the title line, a nudge up brings it back. The
drawer owns one history entry, so back (the block's button, the Android
key) closes it before it leaves the post. The wrapper hands touches above
the drawer to the article, except over our own sheets and toasts. Without
the bridge, or with "Open links in the app" off (Appearance, client-only
flag), Read opens the link as before.

4.2, the bridge behaviours (chapter 8): a light impact on a tab change, an
upvote and a bookmark, a success one when the streak goes up (the iOS
handler, navigator.vibrate in the Android app); the wrappers' pull to
refresh refetches what is on screen through window.dailyNative.refresh
instead of reloading; the status bar turns light over a cover; Reduce
Transparency turns the floating material solid; window.dailyNative.back
closes the drawer or the top sheet first, the Android back contract.

Every message is silent until a wrapper registers its handler, so the
mobile web and today's app builds are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
daily-webapp Ready Ready Preview Oct 16, 2026 7:40am UTC
storybook Ready Ready Preview Oct 16, 2026 7:40am UTC

Request Review

It filled the row between close and reload whatever the domain; it now
takes the domain's width, centred between the two squares, and a long
domain still truncates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Chapter 6b's metric is the share of article opens that end with a reaction
or a return to the post. The drawer now logs `open reading drawer` and
`close reading drawer` (with duration_ms, the time on the article, and
closed_by: close, back, link or leave), and every event the post page logs
while the drawer is open carries reading_drawer: true, so an upvote, a
bookmark or a comment made while reading is told apart from one on the post.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tsahimatsliah and others added 3 commits October 14, 2026 15:09
On a Read click outside a feed, useOnPostClick marks the post read in
every cached list feed. A feed query that is in the cache without data
(never fetched, or failed) has no pages, so findIndexOfPostInData threw
"Cannot read properties of undefined (reading 'pages')" as an uncaught
promise rejection on every Read from a post page. Those feeds are skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…wice

The phone edit page replaced itself with the post permalink after a save,
so an edit opened from the post page left the history as post, post: one
back press showed the same post again. When the entry before the editor is
this post, saving now steps back to it, as closing without saving already
does; opened from anywhere else, a save still lands on the post.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Step 3 hid the whole header block of /squads/new below tablet, so a phone
opened straight on "Squad details" with no word on what a squad is. The
explanation is back on phones, one line on the 16px gutter under the top
bar; the title stays desktop-only (the bar already says "New squad") and
so does the illustration, which pushed the form below the fold. Desktop
and tablet are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tsahimatsliah tsahimatsliah changed the title feat(mobile): phone shell, step 4: the reading drawer and the wrappers' bridge feat(mobile): phone shell, step 4 (reading drawer, app bridge) and three phone fixes Oct 14, 2026
Tabs switch to content that is different altogether; chips narrow the list
the page already holds (Tsahi, 16 Oct; Storybook chapter 4h).

Tabs: a 48px row edge to edge with a hairline, 15px labels, bold when lit
and medium otherwise. Every label reserves its bold width, so lighting a
tab never moves the row. One 32 x 3px bar, centred under the lit label,
slides to the tapped tab. A tab takes an equal share while every tab fits
and its own width once they do not, so the row scrolls instead of
truncating. A tab with more choices (Happening now) shows a 12px chevron
whether lit or not; a tap on the lit tab opens its sheet.

Chips: the Small button's shape, 32px with 10px corners and 14px medium
text, in a 48px row; lit filled, others on the float surface.

Rows that drew their own buttons on phones follow the rule too: Messages
(Chats, Requests) and Tools are tabs, Achievements' filters are chips.
Tablet and desktop keep their navbars and buttons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tsahimatsliah tsahimatsliah changed the title feat(mobile): phone shell, step 4 (reading drawer, app bridge) and three phone fixes feat(mobile): phone shell, step 4 (reading drawer, app bridge), tabs and chips, three phone fixes Oct 16, 2026
…s edge

The phone Home row had a filter icon and a sort menu beside the tabs, and
the new-feed plus sat in the tab list. Feed settings already lives in the
You drawer, so the row keeps tabs only: a tap on the lit For you (or a lit
custom feed) opens a sheet with the order (Recommended, By date, when
sorting is on and the feed can be sorted) and Edit feed, like Happening
now's channels.

Row items now carry their own `menu`, replacing Segments' menu/onMenu
props, so any tab can own a sheet. The plus is a square button pinned at
the right; the tabs scroll under it and fade over their last 24px so a
cut label reads as more to scroll.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…me row

The feed sheet's link reads Feed settings with the filter icon, the same
name and icon the You drawer uses for the same page. The new-feed plus
drops the floating square's material, which read as one of the top
header's buttons; it keeps the 38px target and sits in the tabs row in
the unlit tab color.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A chevron on every tab with a sheet made the row busy and, on Home, cut
Following short. Only the lit tab carries it now, since that is the tab a
tap opens the sheet from. It hangs in the tab's side padding instead of
widening the label, so lighting a tab still moves nothing (label offsets
measured identical across a switch) and the bar centers on the text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch was successfully deployed

3 active (1 outdated) deployments
Preview – daily-webapp — 60eebf3f Deployed Oct 16, 2026 by vercel[bot]
Preview – storybook — 60eebf3f Deployed Oct 16, 2026 by vercel[bot]
Preview — 5cd7b084 Deployed Oct 14, 2026 by vercel[bot]
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.

1 participant