| 1 |
1 |
|
# Balanced Breakfast - Mobile Port
|
| 2 |
2 |
|
|
| 3 |
|
- |
Tauri 2 iOS/Android port. CSS-first responsive design with touch gestures. Based on GoingsOn mobile patterns.
|
| 4 |
|
- |
|
| 5 |
|
- |
**What stays the same:**
|
| 6 |
|
- |
- `crates/bb-core/` — orchestrator, plugin manager, unchanged
|
| 7 |
|
- |
- `crates/bb-db/` — SQLite repository, unchanged
|
| 8 |
|
- |
- `crates/bb-interface/` — plugin types, unchanged
|
| 9 |
|
- |
- `crates/bb-feed/` — aggregation, unchanged
|
| 10 |
|
- |
- `src-tauri/src/commands/` — Tauri commands, unchanged
|
| 11 |
|
- |
- `src-tauri/frontend/js/` — all JS modules (minor mobile branches)
|
| 12 |
|
- |
- `BB.api` with `invoke()` — same IPC mechanism
|
| 13 |
|
- |
|
| 14 |
|
- |
**What changes:** CSS responsiveness, new touch/mobile JS modules, bottom tab bar, single-column layout, Tauri mobile config.
|
|
3 |
+ |
Done: Phases 1-5, Phase 6 partial. Active: None. Next: Phase 6 remaining, Phase 7 polish.
|
| 15 |
4 |
|
|
| 16 |
5 |
|
---
|
| 17 |
6 |
|
|
| 18 |
|
- |
## Design: Three-Panel → Single-Column
|
| 19 |
|
- |
|
| 20 |
|
- |
**Desktop:** Sidebar (sources) | Items (list) | Detail (article) — all visible simultaneously.
|
| 21 |
|
- |
|
| 22 |
|
- |
**Mobile (<=768px):** One panel at a time with drill-down navigation.
|
| 23 |
|
- |
|
| 24 |
|
- |
### Bottom Tab Bar
|
| 25 |
|
- |
|
| 26 |
|
- |
| Tab | Default View | Description |
|
| 27 |
|
- |
|-----|-------------|-------------|
|
| 28 |
|
- |
| Feed | Items list (All) | Current feed items, sorted by selected order |
|
| 29 |
|
- |
| Saved | Starred items | Saved/starred articles |
|
| 30 |
|
- |
| Sources | Source list | Feed sources with unread counts, tap to filter |
|
| 31 |
|
- |
| + | Add Feed | Opens add-feed modal |
|
| 32 |
|
- |
| More | Popover | Settings, Sync, OPML, Shortcuts |
|
| 33 |
|
- |
|
| 34 |
|
- |
### Navigation Flow
|
| 35 |
|
- |
|
| 36 |
|
- |
```
|
| 37 |
|
- |
Sources tab → tap source → Feed tab (filtered to that source)
|
| 38 |
|
- |
Feed tab → tap item → Detail view (slides in full-screen)
|
| 39 |
|
- |
Detail view → back button / swipe-right → Items list
|
| 40 |
|
- |
```
|
| 41 |
|
- |
|
| 42 |
|
- |
### Panel Visibility Rules
|
| 43 |
|
- |
|
| 44 |
|
- |
| State | Sidebar | Items | Detail | Tab Bar |
|
| 45 |
|
- |
|-------|---------|-------|--------|---------|
|
| 46 |
|
- |
| Feed tab | hidden | visible | hidden | visible |
|
| 47 |
|
- |
| Saved tab | hidden | visible (starred) | hidden | visible |
|
| 48 |
|
- |
| Sources tab | visible (full-width) | hidden | hidden | visible |
|
| 49 |
|
- |
| Reading article | hidden | hidden | visible | hidden |
|
| 50 |
|
- |
|
| 51 |
|
- |
---
|
| 52 |
|
- |
|
| 53 |
|
- |
## Phase 1: CSS Foundation
|
| 54 |
|
- |
|
| 55 |
|
- |
### Layout
|
| 56 |
|
- |
- [ ] `viewport-fit=cover` meta tag
|
| 57 |
|
- |
- [ ] `@media (max-width: 768px)` master breakpoint (replace existing 768px + 600px rules)
|
| 58 |
|
- |
- [ ] Hide header (`display: none`) — search/sort/actions move to appropriate locations
|
| 59 |
|
- |
- [ ] Body padding: `env(safe-area-inset-top)` top, `calc(52px + env(safe-area-inset-bottom))` bottom
|
| 60 |
|
- |
- [ ] Sidebar: `display: none` by default, full-width when `.mobile-sources-visible`
|
| 61 |
|
- |
- [ ] Items panel: full-width, single column
|
| 62 |
|
- |
- [ ] Detail panel: fixed full-screen overlay when `.mobile-detail-open`
|
| 63 |
|
- |
- [ ] Remove all three-panel flex layout on mobile (`.main` → single column)
|
| 64 |
|
- |
|
| 65 |
|
- |
### Components
|
| 66 |
|
- |
- [ ] Modal → bottom sheet (full-width, rounded top corners, drag handle)
|
| 67 |
|
- |
- [ ] Toasts positioned above tab bar
|
| 68 |
|
- |
- [ ] `@media (hover: none)` disable hover effects on touch devices
|
| 69 |
|
- |
- [ ] Item cards: increase tap target size, larger star button
|
| 70 |
|
- |
- [ ] Source list items: full-width rows, larger tap targets
|
| 71 |
|
- |
|
| 72 |
|
- |
### Mobile Search
|
| 73 |
|
- |
- [ ] Search bar at top of Feed/Saved views (replaces header search)
|
| 74 |
|
- |
- [ ] Sort dropdown integrated into search bar area or as a pill row
|
| 75 |
|
- |
|
| 76 |
|
- |
---
|
| 77 |
|
- |
|
| 78 |
|
- |
## Phase 2: Bottom Tab Bar
|
| 79 |
|
- |
|
| 80 |
|
- |
### HTML
|
| 81 |
|
- |
- [ ] `<nav id="mobile-tab-bar" class="mobile-tab-bar">` before closing `</div>` of `#app`
|
| 82 |
|
- |
- [ ] 5 buttons: Feed, Saved, Sources, +, More
|
| 83 |
|
- |
- [ ] More popover: Settings, Sync, OPML Import/Export, Shortcuts
|
| 84 |
|
- |
|
| 85 |
|
- |
### CSS
|
| 86 |
|
- |
- [ ] Base styles: `display: none`, fixed bottom, z-index 1100, safe-area padding
|
| 87 |
|
- |
- [ ] Show at 768px: `display: flex`
|
| 88 |
|
- |
- [ ] Active tab highlight (accent color)
|
| 89 |
|
- |
- [ ] More popover positioned above tab bar
|
| 90 |
|
- |
|
| 91 |
|
- |
### JS (`navigation.js` — new file)
|
| 92 |
|
- |
- [ ] `initMobileTabBar()` — click handlers for each tab
|
| 93 |
|
- |
- [ ] Feed tab: show items panel, set source filter to current/All
|
| 94 |
|
- |
- [ ] Saved tab: show items panel, filter to starred
|
| 95 |
|
- |
- [ ] Sources tab: show sidebar full-width
|
| 96 |
|
- |
- [ ] + button: open add-feed modal
|
| 97 |
|
- |
- [ ] More button: toggle popover
|
| 98 |
|
- |
- [ ] `updateMobileTabBar(view)` — sync active tab state
|
| 99 |
|
- |
- [ ] Source tap handler: switch to Feed tab filtered to that source
|
| 100 |
|
- |
|
| 101 |
|
- |
---
|
| 102 |
|
- |
|
| 103 |
|
- |
## Phase 3: Detail View Navigation
|
| 104 |
|
- |
|
| 105 |
|
- |
### Back Button
|
| 106 |
|
- |
- [ ] Detail header: add back arrow button (visible only on mobile)
|
| 107 |
|
- |
- [ ] Back button returns to items list, closes detail panel
|
| 108 |
|
- |
- [ ] Update `BB.detail` to track mobile open/close state
|
| 109 |
|
- |
|
| 110 |
|
- |
### Transitions
|
| 111 |
|
- |
- [ ] Detail slides in from right (CSS transform + transition)
|
| 112 |
|
- |
- [ ] Items list slides out left (or stays, detail overlays)
|
| 113 |
|
- |
- [ ] Tab bar hidden when detail is open (full reading experience)
|
| 114 |
|
- |
|
| 115 |
|
- |
### Reader State
|
| 116 |
|
- |
- [ ] `BB.state.mobileDetailOpen` flag
|
| 117 |
|
- |
- [ ] On item select (mobile): set flag, show detail full-screen
|
| 118 |
|
- |
- [ ] On back: clear flag, return to items
|
| 119 |
|
- |
|
| 120 |
|
- |
---
|
| 121 |
|
- |
|
| 122 |
|
- |
## Phase 4: Touch Module (`js/touch.js` — new file)
|
| 123 |
|
- |
|
| 124 |
|
- |
Port from GoingsOn's touch.js, adapted for BB's domain.
|
| 125 |
|
- |
|
| 126 |
|
- |
### Utilities
|
| 127 |
|
- |
- [ ] `isTouchDevice` detection
|
| 128 |
|
- |
- [ ] `addLongPress(element, callback, duration)` — 500ms hold
|
| 129 |
|
- |
- [ ] `addSwipeActions(element, config)` — reveal action behind item
|
| 130 |
|
- |
- [ ] `addPullToRefresh(container, callback)` — pull indicator + callback
|
| 131 |
|
- |
- [ ] `addDragToDismiss(element, onDismiss)` — swipe down to close
|
| 132 |
|
- |
- [ ] All functions return cleanup functions, no-op on non-touch
|
| 133 |
|
- |
|
| 134 |
|
- |
### Mobile Wiring (`js/mobile.js` — new file)
|
| 135 |
|
- |
- [ ] Items: swipe right = toggle star, swipe left = toggle read
|
| 136 |
|
- |
- [ ] Pull-to-refresh on items list → `BB.feeds.refreshAll()`
|
| 137 |
|
- |
- [ ] Pull-to-refresh on sources list → `BB.feeds.refreshAll()`
|
| 138 |
|
- |
- [ ] Long-press on item → show action sheet (star, read/unread, open in browser, save)
|
| 139 |
|
- |
- [ ] Detail view: swipe right → back to items
|
| 140 |
|
- |
- [ ] Modal swipe-to-dismiss wiring
|
| 141 |
|
- |
|
| 142 |
|
- |
---
|
| 143 |
|
- |
|
| 144 |
|
- |
## Phase 5: View Adaptations
|
| 145 |
|
- |
|
| 146 |
|
- |
### Items List (mobile)
|
| 147 |
|
- |
- [ ] Item rows: larger padding, bigger star toggle target
|
| 148 |
|
- |
- [ ] Unread indicator: bold title + accent left border (like GO task priority borders)
|
| 149 |
|
- |
- [ ] Source name badge on items (needed since sidebar isn't visible in Feed tab)
|
| 150 |
|
- |
- [ ] Inline sort pills above items (Newest / Score / Unread / Starred)
|
| 151 |
|
- |
|
| 152 |
|
- |
### Sources List (mobile)
|
| 153 |
|
- |
- [ ] Full-width card layout with unread counts
|
| 154 |
|
- |
- [ ] All/Saved as top sticky rows
|
| 155 |
|
- |
- [ ] Tag filter bar: horizontal scroll pills (like GO pill nav)
|
| 156 |
|
- |
- [ ] Edit/delete actions via long-press action sheet
|
| 157 |
|
- |
|
| 158 |
|
- |
### Detail View (mobile)
|
| 159 |
|
- |
- [ ] Full-screen reader with comfortable margins
|
| 160 |
|
- |
- [ ] Sticky header: back button + title + star + open-in-browser
|
| 161 |
|
- |
- [ ] Safe area padding top and bottom
|
| 162 |
|
- |
- [ ] Article body scrollable with momentum
|
| 163 |
|
- |
|
| 164 |
|
- |
### Keyboard
|
| 165 |
|
- |
- [ ] Disable keyboard shortcuts on touch devices
|
| 166 |
|
- |
|
| 167 |
|
- |
---
|
| 168 |
|
- |
|
| 169 |
|
- |
## Phase 6: Tauri Mobile Build Config
|
| 170 |
|
- |
|
| 171 |
|
- |
### Cargo.toml
|
| 172 |
|
- |
- [ ] Desktop-only deps gated: `tauri-plugin-shell`, `tauri-plugin-notification`, `tauri-plugin-window-state`
|
| 173 |
|
- |
- [ ] `crate-type = ["staticlib", "cdylib", "lib"]` for iOS
|
|
7 |
+ |
## Phase 6: Tauri Mobile Build Config — Remaining
|
| 174 |
8 |
|
- [ ] Platform-conditional `rusqlite` bundled feature for Android
|
| 175 |
|
- |
|
| 176 |
|
- |
### Source Gating
|
| 177 |
|
- |
- [ ] `lib.rs`: mobile entry point (`build_mobile_app()` + `#[cfg(mobile)]`)
|
| 178 |
|
- |
- [ ] Desktop-only plugin init gated in `main.rs`
|
| 179 |
|
- |
- [ ] Desktop-only window commands gated
|
| 180 |
|
- |
|
| 181 |
|
- |
### Capabilities
|
| 182 |
|
- |
- [ ] Split: `default.json` (cross-platform) + `desktop.json` (shell, notifications)
|
| 183 |
|
- |
|
| 184 |
|
- |
### Build & Test
|
|
9 |
+ |
- [ ] Split capabilities: `default.json` (cross-platform) + `desktop.json` (shell, notifications)
|
| 185 |
10 |
|
- [ ] `cargo tauri ios init` → generates `gen/apple/`
|
| 186 |
11 |
|
- [ ] `cargo tauri android init` → generates `gen/android/`
|
| 187 |
12 |
|
- [ ] iOS simulator test
|
| 191 |
16 |
|
---
|
| 192 |
17 |
|
|
| 193 |
18 |
|
## Phase 7: Polish
|
| 194 |
|
- |
|
|
19 |
+ |
- [ ] Inline sort pills above items
|
| 195 |
20 |
|
- [ ] Physical device testing (iOS + Android)
|
| 196 |
21 |
|
- [ ] Safe area insets on various device models
|
| 197 |
22 |
|
- [ ] VoiceOver / TalkBack accessibility
|
| 207 |
32 |
|
| File | Role |
|
| 208 |
33 |
|
|------|------|
|
| 209 |
34 |
|
| `src-tauri/frontend/css/styles.css` | All responsive CSS |
|
| 210 |
|
- |
| `src-tauri/frontend/js/touch.js` | Gesture utilities (new) |
|
| 211 |
|
- |
| `src-tauri/frontend/js/mobile.js` | Mobile interaction wiring (new) |
|
| 212 |
|
- |
| `src-tauri/frontend/js/navigation.js` | Bottom tab bar + view switching (new) |
|
| 213 |
|
- |
| `src-tauri/frontend/js/sources.js` | Source list (mobile adaptations) |
|
| 214 |
|
- |
| `src-tauri/frontend/js/items.js` | Item list (mobile adaptations) |
|
| 215 |
|
- |
| `src-tauri/frontend/js/detail.js` | Detail panel (mobile full-screen) |
|
| 216 |
|
- |
| `src-tauri/frontend/js/components.js` | Action sheets, modal swipe-dismiss |
|
| 217 |
|
- |
| `src-tauri/frontend/js/app.js` | Bootstrap, keyboard gating |
|
| 218 |
|
- |
| `src-tauri/frontend/index.html` | Tab bar HTML, viewport meta |
|
|
35 |
+ |
| `src-tauri/frontend/js/touch.js` | Gesture utilities |
|
|
36 |
+ |
| `src-tauri/frontend/js/mobile.js` | Mobile interaction wiring |
|
|
37 |
+ |
| `src-tauri/frontend/js/navigation.js` | Bottom tab bar + view switching |
|
| 219 |
38 |
|
| `src-tauri/Cargo.toml` | Desktop-only dep gating |
|
| 220 |
39 |
|
| `src-tauri/src/main.rs` | Desktop-only plugin/service gating |
|
| 221 |
|
- |
| `src-tauri/src/lib.rs` | Desktop-only module gating |
|
| 222 |
|
- |
|
| 223 |
|
- |
---
|
| 224 |
|
- |
|
| 225 |
|
- |
## Reference
|
| 226 |
|
- |
|
| 227 |
|
- |
GoingsOn mobile implementation (fully complete):
|
| 228 |
|
- |
- `Apps/goingson/docs/todo/todo_mobile.md` — completed phases 1-6
|
| 229 |
|
- |
- `Apps/goingson/src-tauri/frontend/js/touch.js` — gesture utilities to port
|
| 230 |
|
- |
- `Apps/goingson/src-tauri/frontend/js/mobile.js` — wiring patterns to adapt
|
| 231 |
|
- |
- `Apps/goingson/src-tauri/frontend/js/navigation.js` — tab bar reference
|