Troubleshooting
Relevant source files
The following files were used as context for generating this wiki page:This document provides guidance for diagnosing and resolving common issues encountered during the development, build, and runtime of the Endfield-Pomodoro application. It covers problems related to dependencies, configuration, state persistence, and Progressive Web App (PWA) functionality.
Build and Dependency Issues
Problems in this category typically arise during the pnpm install or pnpm build steps. Ensure your environment meets the project's requirements.
- Environment: Node.js version >= 18 is required.
- Sources: README.md:80-81
- Dependencies: The project uses
pnpmfor package management. Key dependencies are listed inpackage.json.- Sources: package.json:5-10, README.md:83-85
Key Dependencies
| Dependency | Version | Role |
|---|---|---|
react | ^19.2.0 | Core UI library. |
vite | ^7.2.4 | Build tool and development server. |
typescript | ~5.9.3 | Language superset for type safety. |
tailwindcss | ^4.1.17 | Utility-first CSS framework. |
babel-plugin-react-compiler | ^1.0.0 | Automatically optimizes React components. Enabled in vite.config.ts. |
vite-plugin-pwa | ^1.2.0 | Generates the service worker for PWA capabilities. |
Sources: package.json:12-35, vite.config.ts:11-12, README.md:180-186
Build Process Flow
The build process is orchestrated by Vite and configured in vite.config.ts. A failure in the pnpm build command can often be traced back to TypeScript errors or misconfigurations in the Vite plugins.
The following diagram illustrates the high-level build flow.
Sources: package.json:8, vite.config.ts, tsconfig.json
Configuration and State Persistence
User settings, tasks, and timer state are persisted in the browser's localStorage. If settings are not being saved or are resetting on refresh, it's likely an issue with localStorage access or data parsing.
LocalStorage Usage
The application uses specific keys to store data. Any corruption of data under these keys can lead to fallback to default values.
| Key | Component | Purpose |
|---|---|---|
endfield_settings | App.tsx | Stores the main Settings object, including durations, theme, etc. |
endfield_sessions | App.tsx | Stores the number of completed Pomodoro sessions. |
endfield_total_seconds | App.tsx | Stores the total accumulated work time in seconds. |
endfield_current_session_start | App.tsx | Timestamp for when the current work session started, for persistence. |
origin_terminal_tasks | TaskManager.tsx | Stores the list of user-created tasks. |
origin_terminal_timer | Pomodoro.tsx | Persists the current timer state (mode, timeLeft, isActive). |
Sources: src/App.tsx:16,92,100,105,241, src/components/Pomodoro.tsx:29,106, src/components/TaskManager.tsx:11
Settings Loading and Persistence Flow
The App component is responsible for loading settings from localStorage on initial render. If no saved settings are found or if parsing fails, it falls back to DEFAULT_SETTINGS.
This diagram shows the sequence of loading and saving settings.
Sources: src/App.tsx:70-85, 209-215
A common issue is notification permissions. If a user grants permission and later revokes it in browser settings, the app will detect this on the next load and automatically set notificationsEnabled to false.
Sources: src/App.tsx:76-78
Timer and Session Issues
The Pomodoro timer's ability to survive a page refresh is critical. This is handled by the Pomodoro.tsx component, which saves its state to localStorage and attempts to restore it on mount.
Timer State Restoration
On component mount, Pomodoro.tsx reads origin_terminal_timer from localStorage. If the timer was active (isActive: true), it calculates the time elapsed since it was last saved and adjusts the timeLeft accordingly.
Sources: src/components/Pomodoro.tsx:49-93
If the timer appears to reset unexpectedly, check the browser console for errors related to JSON.parse or localStorage quota exceptions. The component is designed to log these errors.
Sources: src/components/Pomodoro.tsx:90-92, 114-118
PWA and Offline Functionality
The application uses vite-plugin-pwa to enable PWA features, including offline caching via a service worker. Issues with offline mode or online music playback can often be traced to the service worker's caching strategy defined in vite.config.ts.
Caching Strategy
The workbox configuration specifies how different resources are handled.
| URL Pattern | Handler | Cache Name | Description |
|---|---|---|---|
**/*.{js,css,html,...} | (Precaching) | workbox-precache | Core application assets are cached on service worker installation. |
/index.html | NetworkFirst | index-html | Always tries to fetch the latest index.html from the network first to ensure app updates. |
https://api.injahow.cn/meting/ | NetworkOnly | - | MetingAPI requests for online music are never cached and always go to the network. |
| Audio/Video requests | NetworkOnly | - | All requests for audio or video files are forced to go to the network. |
Music streaming hostnames (e.g., music.126.net) | NetworkOnly | - | Explicitly prevents caching of music streams from various platforms. |
Google Fonts (fonts.googleapis.com) | CacheFirst | google-fonts-stylesheets | Caches font stylesheets for up to a year. |
Google Fonts (fonts.gstatic.com) | CacheFirst | google-fonts-webfonts | Caches font files for up to a year. |
Sources: vite.config.ts:20-136
Troubleshooting Online Music in PWA
A key design choice is to force all online music-related requests to use the network (NetworkOnly). This is to avoid caching large audio files and to ensure playlist information is up-to-date. If online music is not working while offline, this is expected behavior. The app should display an "OFFLINE" status.
The diagram below shows how the service worker routes requests.
Sources: vite.config.ts:65-135, src/App.tsx:300-303
Internationalization (i18n)
If UI text appears as keys (e.g., APP_TITLE) instead of the translated string, it indicates a problem with the i18n system.
- Translations: All English and Chinese translations are stored in the
translationsobject insrc/utils/i18n.ts. - Language Detection: The default language is determined by the browser's language settings (
navigator.languages). - Usage: The
useTranslationhook provides thetfunction, which retrieves the correct string for the currently selected language.
If a translation is missing for a specific key in the current language, the hook will return the key itself as a fallback. Ensure that any new text has a corresponding entry for both Language.EN and Language.CN.
Sources: src/utils/i18n.ts, src/App.tsx:34-37