Repository navigation
Add the mobile app shell with Inbox, Note and Tasks tabs - #623
Merged
Merged
Conversation
The phone was one route deep. It now has a shell two more screens can live in:
- A bottom TabBar (Inbox /, Note /note, Tasks /tasks) and placeholder
Note and Tasks pages so the routes resolve.
- The pairing gate lifted out of Inbox into MainLayout, so every route is
gated once, the same way, and the tabs are withheld until paired.
- A SyncStatus line in the app bar ("Not paired", "Synced 3m ago",
"Offline - n waiting") read through ISyncStatusSource; SyncStatusTracker
supplies pairing state and the Inbox's last successful load until the
outbox entry supplies queue counts.
- A scoped CaptureDraft so the Inbox's unsent text survives the Router
remounting the page on a tab switch.
- TabBar and SyncStatusLine as library components in a new Shell folder,
with an App shell storybook page.
Also: neither mobile host linked its scoped-CSS bundle, so
MainLayout.razor.css never applied; both now do. The harness phone frame
fits a 375px viewport.
Plan item app-shell of plan mobile-inbox-slice.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Backlog plan item
app-shellof planmobile-inbox-slice. The phone app was one route deep (Inbox). It now has a shell that the Note and Tasks screens can live in:Changes
MainLayout.razorshows aTabBarwith Inbox (/), Note (/note) and Tasks (/tasks). Note and Tasks are placeholder pages (anh1and an empty state) so the routes resolve.Inbox.razorinto a newPairingGatecomponent thatMainLayoutrenders in place of the page while the device is unpaired. Every route is gated once, the same way, and the tabs are hidden until the device is paired. When pairing succeeds, the credential store'sChangedevent puts the page back, so the Inbox loads on its own.SyncStatusin the app bar readsISyncStatusSourceand shows "Not paired", "Synced 3m ago", "Not synced yet" or "Offline — n waiting".SyncStatusTrackersupplies pairing state (fromIDeviceCredentialStore) and the time of the Inbox's last successful load.RecordOffline(waiting)is where the outbox entry of this plan will report queue counts.CaptureDraftis scoped and holds the Inbox's unsent text. The Router remounts pages on navigation, so the old_draftfield lost the text on every tab switch.AddMobileShell()is called by the MAUI head and by the browser harness.TabBar,SyncStatusLineandSyncStatusReadinglive in a newBacklog.UI.Components/Shellfolder, with CSS incomponents.css(48px touch targets; the active tab is marked by weight and a top bar, not colour alone)./app-shell/{Tab}, so the demo tabs are live.StorybookOrderTestsgets theShellchapter.MainLayout.razor.csshas never applied.index.htmlnow linksBacklog.Mobile.styles.cssand the harnessApp.razorlinksBacklog.Mobile.WebHarness.styles.css.width: min(390px, 100%), no padding, andheight: calc(100vh - 2rem).Testing
dotnet build Backlog.sln: 0 errors, MAUI head included. No new warnings in the changed code.dotnet testflapped to "Zero tests ran". 23 projects, 0 failures. ArchitectureTests 173, UI.Components 2397, Desktop.UI 3092, Mobile.UI 39.PairingGateTests(replacesInboxPairingTests; runs on every route),ShellNavigationTestsand libraryShellTests.ShellNavigationTestscovers three tabs with the current one lit, a page per tab, the draft surviving Inbox → Tasks → Inbox, the synced status line, and the tracker's state changes./,/noteand/tasksshows the pairing box and "Not paired", no tab bar, and no horizontal overflow./app-shell: all five stories render. Real touch taps move the URL,aria-currentand the active class, and tabs are 48px tall. No console errors.h1after tab navigation, the draft round trip, "Synced just now", and the tab bar pinned to the bottom of the frame. They need a paired device, and pairing was blocked by the environment: Docker ran out of network subnets, so the Cosmos emulator never started. The draft round trip and the status line are covered by the unit tests above. Focus-on-h1relies on the existingFocusOnNavigate Selector="h1", and every page has oneh1.Related
Plan item
app-shellofmobile-inbox-slice(Backlog entry d5b2199b-bcf7-4d98-9277-2ec2e0f220da). No GitHub issue.Follow-ups
.arc42/05-building-block-view.mdonce this lands.SyncStatusTracker.RecordOffline.Checklist
🤖 Generated with Claude Code