nexus/.planning/phases/26-pwa-performance/26-03-SUMMARY.md
Nexus Dev af182f8dd9 docs(26-03): complete PWA install prompt, offline banner, and message queue plan
- InstallPromptBanner: 7-day cooldown, iOS fallback, beforeinstallprompt CTA
- OfflineBanner: amber theming, queue count, 3s auto-dismiss on reconnect
- useOfflineQueue: IndexedDB nexus-offline/message_queue, flush on online event
- ChatPanel: offline guard in handleSend, OfflineBanner + InstallPromptBanner wired
- Requirements PWA-01, PWA-02, PWA-08 marked complete
2026-04-02 15:08:51 +00:00

6.8 KiB

phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
26-pwa-performance 03 ui
pwa
offline
indexeddb
idb
install-prompt
service-worker
react-hooks
phase provides
26-00 idb dependency installed, pwa.d.ts types, BeforeInstallPromptEvent interface
phase provides
26-02 ChatPanel with MobileChatView mobile/desktop split, useMediaQuery hook
useOnlineStatus hook — reactive navigator.onLine boolean
useInstallPrompt hook — captures beforeinstallprompt, iOS detection, promptInstall()
useOfflineQueue hook — IndexedDB message queue with auto-flush on online event
InstallPromptBanner component — PWA install CTA with iOS fallback and 7-day dismiss cooldown
OfflineBanner component — amber offline status with queued message count
ChatPanel offline integration — enqueues messages when offline via useOfflineQueue
26-04
ChatPanel
MobileChatView
pwa-push-notifications
added patterns
idb@^8.0.3
useOfflineQueue uses openDB with autoIncrement store for message replay
OfflineBanner uses dark: prefix for light/dark amber theme switching
InstallPromptBanner checks localStorage timestamp for 7-day cooldown
handleSend in ChatPanel guards on isOnline before proceeding to network calls
created modified
ui/src/hooks/useOnlineStatus.ts
ui/src/hooks/useInstallPrompt.ts
ui/src/hooks/useOfflineQueue.ts
ui/src/components/InstallPromptBanner.tsx
ui/src/components/OfflineBanner.tsx
ui/src/types/pwa.d.ts
ui/src/components/ChatPanel.tsx
ui/package.json
pnpm-lock.yaml
idb + pwa.d.ts added inline in this plan — parallel 26-00 worktree commits were not on gsd/phase-26-pwa-performance branch
OfflineBanner uses dark: Tailwind prefix for amber light/dark theming — consistent with design system approach
ChatPanel offline guard only enqueues when activeConversationId exists — new conversation creation requires network
useOfflineQueue flush stops on first failure — prevents partial replay; retries on next online event
Offline-first guard at handleSend entry: check isOnline before any network operation
IndexedDB queue pattern: openDB with autoIncrement, getAllKeys/get/delete for sequential flush
PWA-01
PWA-02
PWA-08
5min 2026-04-02

Phase 26 Plan 03: PWA Install Prompt, Offline Banner, and Message Queue Summary

PWA install prompt with iOS fallback, amber offline status banner, and IndexedDB message queue that auto-flushes on reconnection

Performance

  • Duration: ~5 min
  • Started: 2026-04-02T02:15:40Z
  • Completed: 2026-04-02T02:20:35Z
  • Tasks: 2
  • Files modified: 8

Accomplishments

  • Created three production hooks: useOnlineStatus (reactive online state), useInstallPrompt (captures beforeinstallprompt + iOS detection), useOfflineQueue (IndexedDB-backed queue with auto-flush)
  • Built InstallPromptBanner component with 7-day localStorage dismiss cooldown, iOS Share menu instruction text, and "Add to Home Screen" CTA
  • Built OfflineBanner component with amber theming (dark/light), queued message count display, and 3-second auto-dismiss on reconnection
  • Wired ChatPanel to enqueue messages to IndexedDB when offline and display a queued toast notification

Task Commits

  1. Task 1: useOnlineStatus, useInstallPrompt, useOfflineQueue hooks - 2b172bda (feat)
  2. Task 2: InstallPromptBanner, OfflineBanner, ChatPanel wiring - 427e6c80 (feat)

Files Created/Modified

  • ui/src/hooks/useOnlineStatus.ts — Reactive boolean from navigator.onLine with online/offline event listeners
  • ui/src/hooks/useInstallPrompt.ts — Captures beforeinstallprompt, iOS detection via userAgent, promptInstall() callback
  • ui/src/hooks/useOfflineQueue.ts — openDB nexus-offline/message_queue store, enqueue/flush with stop-on-failure strategy
  • ui/src/components/InstallPromptBanner.tsx — Fixed-position banner with 7-day localStorage cooldown and iOS text variant
  • ui/src/components/OfflineBanner.tsx — Fixed top-0 amber banner showing queue count, 3s auto-dismiss on reconnect
  • ui/src/components/ChatPanel.tsx — Added isOnline guard in handleSend, enqueue call, OfflineBanner and InstallPromptBanner renders
  • ui/src/types/pwa.d.ts — BeforeInstallPromptEvent interface with global WindowEventMap extension
  • ui/package.json — Added idb@^8.0.3 dependency

Decisions Made

  • idb and pwa.d.ts were added here as a deviation — the parallel 26-00 worktree commits were not merged into gsd/phase-26-pwa-performance branch
  • Offline guard in handleSend only enqueues when activeConversationId exists — creating a new conversation requires network, so we skip enqueue for that path
  • useOfflineQueue.flush() breaks on first failure — stops partial replay and retries on next online event

Deviations from Plan

Auto-fixed Issues

1. [Rule 3 - Blocking] Added idb dependency and pwa.d.ts that were missing from branch

  • Found during: Task 1 (creating hooks)
  • Issue: The gsd/phase-26-pwa-performance branch was missing the idb package and ui/src/types/pwa.d.ts that were created in a parallel 26-00 worktree but never merged to the main phase branch
  • Fix: Added idb@^8.0.3 to ui/package.json, ran pnpm install, created ui/src/types/pwa.d.ts with BeforeInstallPromptEvent interface
  • Files modified: ui/package.json, pnpm-lock.yaml, ui/src/types/pwa.d.ts
  • Verification: import { openDB } from "idb" compiles without errors
  • Committed in: 2b172bda (Task 1 commit)

Total deviations: 1 auto-fixed (1 blocking) Impact on plan: Required for task completion. No scope creep.

Issues Encountered

  • Pre-existing TypeScript errors in packages/shared (zod module not found) and packages/adapters prevent pnpm --filter @paperclipai/ui build from passing at the workspace level, but tsc -b within the ui directory itself produces zero errors. These are pre-existing issues unrelated to this plan.

User Setup Required

None - no external service configuration required.

Next Phase Readiness

  • PWA install prompt, offline banner, and message queue all functional
  • useOfflineQueue relies on chatApi.postMessage for replay — the flush will restore messages when reconnected
  • Plan 26-04 (push notifications) can build on the same useOnlineStatus pattern

Self-Check: PASSED

  • FOUND: ui/src/hooks/useOnlineStatus.ts
  • FOUND: ui/src/hooks/useInstallPrompt.ts
  • FOUND: ui/src/hooks/useOfflineQueue.ts
  • FOUND: ui/src/components/InstallPromptBanner.tsx
  • FOUND: ui/src/components/OfflineBanner.tsx
  • FOUND: ui/src/types/pwa.d.ts
  • FOUND commit: 2b172bda (Task 1)
  • FOUND commit: 427e6c80 (Task 2)

Phase: 26-pwa-performance Completed: 2026-04-02