A small no-framework PWA with two modes:
- meat cooking timer with minute reminders to flip the meat;
- breathing practice timer with inhale/exhale guidance.
The UI, notifications, and recorded audio prompts support Russian and English.
- Duration from 1 to 120 minutes.
- Number input, range slider, and quick presets: 5, 10, 20, 30, 40, 50, 60 minutes.
- Quick presets are inside a collapsible
Quick choices/Быстрый выборsection so the page stays compact for screen-reader users. - The selected duration is saved locally and restored on the next visit.
- One primary toggle button:
Запуск/ПаузаorLaunch/Pause. - Secondary reset button for clearing the current timer.
- Minute reminders with tones, recorded MP3 voice prompt, and browser notification.
- Completion sound, recorded MP3 prompt, and final notification.
- Optional Wake Lock checkbox to keep the screen on where supported.
- Separate tab for breathing practices.
- Practice duration in minutes, with quick presets in a collapsible section.
- Configurable inhale and exhale durations in seconds.
- Inhale and exhale quick presets include 1, 2, 3, 4, 5, 6, 7, 8, 9, and 10 seconds.
- Practice, inhale, and exhale values are saved locally and restored on the next visit.
- One primary toggle button: launch/pause.
- Calm phase prompts for inhale and exhale.
- Calm minute sound plus recorded minute prompt.
- Completion sound, recorded MP3 prompt, and final notification.
- Installable PWA with manifest and icons.
- Service worker caches the app shell and all MP3 assets for offline use after first load.
- Browser notifications are routed through the service worker.
The app does not depend on Web Speech Synthesis for user-facing voice messages. It plays local MP3 files from:
assets/audio/en/
assets/audio/ru/
Current prompt files per language:
- fixed prompts:
meat-start.mp3,meat-finish.mp3,breath-start.mp3,breath-inhale.mp3,breath-exhale.mp3,breath-finish.mp3 - compatibility minute prompts:
meat-minute.mp3,breath-minute.mp3 - composable minute prompts: elapsed-word files, minute-form files, action files, and
number-1.mp3throughnumber-120.mp3
Minute reminders are assembled from local audio fragments, for example: “Прошло десять минут. Пора перевернуть мясо.” This keeps the app offline-friendly without generating one full sentence per minute/action combination.
Install/use edge-tts, then run:
node scripts/generate-audio.jsThe script writes real MP3 files into assets/audio/{ru,en}/. The runtime app only needs the generated MP3 files, not edge-tts.
meat-timer/
├── assets/audio/en/*.mp3
├── assets/audio/ru/*.mp3
├── scripts/generate-audio.js
├── scripts/smoke-check.js
├── index.html
├── manifest.json
├── sw.js
├── icon-192.png
├── icon-512.png
├── PLAN.md
└── README.md
Because service workers require an HTTP origin, use a local server instead of opening the file directly:
python3 -m http.server 8080Then open:
http://localhost:8080/
Run the static smoke check after UI or service-worker changes:
node scripts/smoke-check.jsThe check parses the inline app script, parses sw.js, and verifies the accessible collapsible preset controls plus saved-setting hooks.
If deploying under a different repository path, update start_url, scope, and icon paths in manifest.json.
- Audio playback requires a user gesture; the launch button provides it.
- Wake Lock is not available in every browser, especially iOS Safari.
- Background timer precision can still be limited by mobile browsers.
- Notifications require browser permission.
Open source - feel free to use and modify as needed.