How yasusudas/poptask works
1. Overall shape
- PopTask is a client-only, local-first PWA. There is no backend or account system in this repo; all task/folder/settings data lives in the browser.
- The app is built with React 19 + TypeScript + Vite, and ships as an installable offline-capable web app.
2. Bootstrap and app shell
- index.html and src/main.tsx mount the React app into src/App.tsx.
- src/index.css provides the global styling foundation, while src/components/BottomNav.tsx, Sidebar.tsx, and related shell components adapt the layout to mobile vs. larger screens.
3. Persistent data layer
- Persistence is isolated in src/db/db.ts and src/db/repositories.ts.
- The app uses IndexedDB via Dexie with three repositories: TaskRepository, FolderRepository, and SettingsRepository.
- This layer is the boundary between UI and storage; all task mutations ultimately flow through it.
4. Domain model and state
- Shared shapes live in src/types.ts.
- The domain centers on tasks, one-level folders, and settings, with task status moving through active / completed / trash states.
- The README indicates no sync or server-side reconciliation, so the browser database is the source of truth.
5. Primary user interface
- src/components/TaskForm.tsx, TaskCreateModal.tsx, TaskDetailSheet.tsx, ConfirmDialog.tsx, and ModalSheet.tsx handle task editing and confirmation flows.
- HistoryLists.tsx renders completed and deleted task history, while FolderManageModal.tsx and FolderFilterBar.tsx support folder organization.
- SearchBar.tsx provides partial-match search with a short debounce, and SettingsScreen.tsx contains app-level preferences and maintenance actions.
6. Responsive navigation model
- The app uses two navigation patterns depending on screen size: bottom navigation + FAB on mobile, and sidebar + top-bar style layout on tablet/desktop.
- src/hooks/useMediaQuery.ts is the main responsiveness hook driving that switch.
- This layout choice is an important architectural boundary because the same task data and screens are presented through different shell components.
7. Balloon visualization and task urgency
- src/components/BalloonField.tsx is the visual centerpiece: tasks are rendered as balloons with string, motion, and interaction.
- Pure helper modules in src/lib/size.ts, src/lib/time.ts, src/lib/colors.ts, and src/lib/id.ts compute balloon size, color, identifiers, and time-based presentation rules.
- The README’s “smooth 7-second transition” on due-date changes implies the UI consumes these pure calculations as derived presentation state rather than storing them.
8. Custom physics subsystem
- src/physics/engine.ts is a separate lightweight 2D physics engine used for floating, collision, dragging, and repulsion.
- Keeping physics in its own module makes it reusable and testable, and prevents animation logic from leaking into the React component tree.
- src/physics/engine.test.ts shows this subsystem is explicitly unit-tested.
9. Notifications and lifecycle automation
- src/lib/notifications.ts handles best-effort reminder scheduling and display, including the staged thresholds described in the README.
- Notifications are delivered through the Service Worker where supported, which matters because the app is also a PWA and can surface reminders outside the visible page.
- Trash auto-deletion after 30 days and undo behavior are part of the app’s state transitions and are surfaced through toast/UI flows such as src/components/Toast.tsx.
10. Backup and data portability
- src/lib/backup.ts supports JSON export and full replace import of local data.
- This is a data-boundary feature rather than a UI-only one: it operates on the repositories’ persisted state and can replace the browser’s stored dataset.
- src/lib/backup.test.ts suggests the backup format and import/export behavior are treated as important contract logic.
11. PWA, offline, and update behavior
- The app uses vite-plugin-pwa with Workbox generateSW to pre-cache the application shell.
- This enables offline startup and non-destructive update handling, so the app behaves like an installed local tool rather than a traditional server-backed site.
- public/manifest.webmanifest provides install metadata for the PWA shell.
12. Testing and repo boundaries
- Unit tests cover the pure logic layers: physics, size, time, and backup behavior.
- e2e/app.spec.ts and Playwright configuration validate end-to-end behavior, including offline startup.
- The architecture is intentionally split so that UI, persistence, physics, and pure domain calculations are distinct layers, making the system easier to diagram and reason about.
Main entry points: App.tsx App shell · repositories.ts Repositories · BalloonField.tsx Balloon field · backup.ts Backup
Components 23
UI shell
App entry, responsive navigation, and primary screens
- Main · Bootstraps React into the app
src/main.tsx - App shell · Top-level composition of screens and layout
src/App.tsx - Bottom nav · Mobile navigation and primary actions
src/components/BottomNav.tsx - Sidebar · Larger-screen navigation shell
src/components/Sidebar.tsx - Media query · Switches between mobile and desktop layouts
src/hooks/useMediaQuery.ts - Balloon field · Renders tasks as interactive balloons
src/components/BalloonField.tsx - Create modal · Task creation flow
src/components/TaskCreateModal.tsx - Detail sheet · Task inspection and edit surface
src/components/TaskDetailSheet.tsx - Task form · Shared task editing form
src/components/TaskForm.tsx - History lists · Completed and trash task history
src/components/HistoryLists.tsx - Folder modal · Folder organization and management
src/components/FolderManageModal.tsx - Settings · App preferences and maintenance actions
src/components/SettingsScreen.tsx - Search · Debounced partial-match task search
src/components/SearchBar.tsx
Data layer
IndexedDB persistence and domain shapes
- Dexie DB · Browser database setup
src/db/db.ts - Repositories · Task, folder, and settings persistence APIs
src/db/repositories.ts - Types · Shared task, folder, and settings shapes
src/types.ts
Logic layer
Pure helpers, physics, backup, and notifications
- Backup · JSON export and full-replace import
src/lib/backup.ts - Notifications · Reminder scheduling and display rules
src/lib/notifications.ts - Physics engine · Floating, collision, drag, and repulsion
src/physics/engine.ts - Size rules · Balloon sizing and urgency scaling
src/lib/size.ts - Time rules · Due-date and temporal presentation helpers
src/lib/time.ts
Connections 24
- Main → App shell: mounts · React entry mounts the application shell
- App shell → Media query: responsive · Chooses shell layout by screen size
- App shell → Bottom nav: mobile shell · Mobile navigation and action layer
- App shell → Sidebar: desktop shell · Desktop navigation and layout layer
- App shell → Balloon field: renders · Primary task visualization
- App shell → Create modal: creates · Task creation flow
- App shell → Detail sheet: inspects · Task details and edits
- Detail sheet → Task form: uses · Shares the task editing form
- App shell → History lists: history · Completed and deleted task views
- App shell → Folder modal: folders · Folder organization UI
- App shell → Settings: preferences · Settings and maintenance screen
- App shell → Search: search · Task filtering and lookup
- App shell → Repositories: persists via · All mutations flow through repository APIs
- Repositories → Dexie DB: stores in · Dexie-backed IndexedDB storage
- Repositories → Types: shapes · Repository records follow shared domain types
- Backup → Repositories: exports/imports · Backup operates on persisted browser data
- Notifications → Repositories: reads state · Uses persisted tasks and settings for reminders
- Balloon field → Physics engine: simulates · Uses the custom 2D physics engine
- Balloon field → Size rules: derives size · Computes balloon scale from task state
- Balloon field → Time rules: derives time · Applies time-based presentation rules
- Notifications → Time rules: thresholds · Reminder timing uses temporal rules
- Backup → Types: serializes · Backup format is based on domain data
- Vite PWA → Manifest: installs · PWA build consumes app manifest
- Vite PWA → App shell: packages · Builds the client app for offline use