Nexus Timer 🕰️✨
Nexus Timer is a dynamic multi-player timer designed for games, workshops, or any activity where turns pass sequentially in a circular fashion. It provides a clear visual focus on the current participant and their immediate successor, ensuring everyone stays engaged and aware of who is next. This document serves as a detailed specification for a Progressive Web App (PWA) prototype aimed at game enthusiasts.
Core Concept
Nexus Timer visualizes players in a circular sequence. The Current Player is prominently displayed in the top half of the screen, and the Next Player is in the bottom half. This clear visual pairing indicates the flow of turns, making it perfect for board games, role-playing games, timed presentations, or any scenario needing structured turn management with individual countdowns.
Target Audience
Game enthusiasts who play turn-based games (board games, tabletop RPGs, card games) and need a visually clear and customizable timer solution.
Tech Stack
- HTML5: For structuring the user interface.
- CSS3: For styling and visual presentation, including animations. Consider a CSS framework like Tailwind CSS for rapid prototyping.
- JavaScript: For application logic, timer functionality, and event handling.
- Web Audio API: For audio feedback (ticking sounds, alerts).
- Browser API: For capturing Players' photo.
- Screen Wake Lock API: For preventing of the screen lock in a PWA.
- Local Storage/IndexedDB: For persistent storage of player data, timer states, and settings.
- Service Worker: Essential for PWA functionality (offline access, push notifications - potential future feature).
- Manifest File: Defines the PWA's metadata (name, icons, theme color).
- Web Framework: Use Vue.js
- (Optional) Tailwind CSS: Utility-first CSS framework for rapid UI development.
Hardware Recommendations (Optional Enhancement)
For an enhanced tactile experience, Nexus Timer supports Smart Buttons based on Bluetooth-connected microcontroller (e.g., XIAO nRF52840) implementing HID (Human Interface Device) protocol.
- Buttons: Connect 3 physical buttons, potentially extended (e.g., via 1.5m wires) for easy player access.
- Configuration:
- Player 1's Button: Single Click: Emulates a key press (e.g., 'a'). Configure this as Player 1's "Pass Turn / My Pause" hotkey in the app.
- Player 2's Button: Single Click: Emulates a key press (e.g., 'b'). Configure as Player 2's "Pass Turn / My Pause" hotkey.
- If Player 3 is Game Admin:
- Player 3's Button: Single Click: Emulates a key press (e.g., 'c'). Configure as Player 3's "Pass Turn / My Pause" hotkey.
- Player 3's Button: Double Click: Emulates a key press (e.g., 'x'). Configure as the "Global Run All Timers" hotkey in the app.
- Player 3's Button: Long Press: Emulates a key press (e.g., 's'). Configure as the "Global Stop/Pause All" hotkey in the app.
Key Features
- Circular Player Display:
- Normal Mode (Default): Central focus on the Current Player (top) and Next Player (bottom).
- All Timers Running Mode: List of players with running timers.
- Individual Player Timers:
- Customizable countdown timer (MM:SS) for each player.
- Timers continue into negative time (e.g., -MM:SS) up to a limit (e.g., -59:59).
- Players reaching max negative time are skipped until reset or timer edit.
- Visual feedback: Pulsating effect for active timers (background for positive, text for negative). Skipped players are visually distinct (e.g., greyed out).
- Two Game Modes:
- Normal Mode (Default):
- Only the Current Player's timer runs.
- Pass the turn via Swipe Up on the Next Player's area or the Current Player's "Pass Turn / My Pause" hotkey.
- 3-seconds ticking sound when the timer starts to alert players about the "Pass Turn".
- Tap Current Player's area or use "Global Stop/Pause All" hotkey to pause/resume their timer without passing the turn.
- To pass the turn: Swipe Up on the Next Player's area or have the Current Player press their "Pass Turn / My Pause" hotkey. The current timer pauses, the next player becomes Current, and their timer starts.
- If the current player's timer is paused, and then the turn is passed (via swipe up or hotkey), the next player should become the current player, but their timer should not automatically start. It should remain paused.
- All Timers Running Mode:
- All active player timers run simultaneously.
- Enter by clicking "All Timers Mode" (starts all timers).
- Continuous ticking sound when active.
- Initially, all players are shown in a list with their photo, name and timer value.
- Tapping on a player in the list pauses its timer. Any player can use their "Pass Turn / My Pause" hotkey to pause their own timer.
- Only players with a running timer are shown in the list.
- If all players pause their timers, automatically reverts to Normal Mode.
- Main button: "Stop All Timers" (pauses all, returns to Normal Mode) or "Start All Timers" (resumes all in this mode). Can also be triggered by "Global Stop/Pause All" hotkey.
- Normal Mode (Default):
- Player Management:
- Add, edit, and delete players (2-7 players).
- Use device camera (access via browser API) or default avatars for the player's picture.
- Set initial timer values per player (Default: 60:00).
- Assign unique "Pass Turn / My Pause" hotkeys (single keypresses). E.g.: Use the Player's 1 "single click" action to insert the key.
- Assign the "Global Stop/Pause All" hotkey (single keypresses). E.g.: Use the Player's 3 "long press" action to insert the key.
- Assign the "Run All Timers" hotkey (single keypresses). E.g.: Use the Player's 3 "double click" action to insert the key.
- Re-order players (drag-and-drop planned), reverse, shuffle.
- Intuitive Controls:
- Swipe Up: (On the Next Player's area). Primary gesture for passing turns (Normal Mode).
- On-Screen Taps: (On the Current Player's area). For pausing/resuming timers contextually.
- Audio Feedback:
- Continuous ticking in "All Timers Running Mode" when active.
- Brief 3-second tick when a timer starts in Normal Mode. Cancel the sound when the timer pauses.
- Global mute option.
- Visuals:
- Designed for mobile phone screens (portrait orientation).
- Light/Dark theme options.
- Persistence: Player setups, timer states, and settings are saved locally using browser Local Storage.
- Global Reset: "Reset Game" button restores all timers to initial values and resets game state.
UI/UX Considerations (For AI Generation)
- Minimalist Design: Focus on clarity and ease of use. Avoid clutter.
- Large, Clear Timers: Timers should be easily readable at a glance.
- Color Coding: Use color to indicate timer state (e.g., green for running, red for negative time, grey for skipped).
- Responsive Layout: The UI should adapt to different (mobile phone) screen sizes.
- Touch-Friendly: Buttons and interactive elements should be large enough for easy tapping.
Data Model (For AI Generation)
{
"players": [
{
"id": "1",
"name": "Player 1",
"avatar": null,
"initialTimerSec": 3600,
"currentTimerSec": 3600,
"hotkey": "a",
"isSkipped": false
},
{
"id": "2",
"name": "Player 2",
"avatar": null,
"initialTimerSec": 3600,
"currentTimerSec": 3600,
"hotkey": "b",
"isSkipped": false
}
],
"globalHotkeyStopPause": "s",
"globalHotkeyRunAll": "x",
"currentPlayerIndex": 0,
"gameMode": "normal", // "normal" or "allTimers"
"isMuted": false,
"theme": "dark"
}
Developer Setup
Clone the repository
git clone https://gitea.virtonline.eu/2HoursProject/nexus-timer.git
cd nexus-timer
Run the live update server locally
npm run dev
Modify the app
Make code changes...
Test the PWA locally
Open it in your browser: http://localhost:8080/
Git Pre-Commit Hook
This project uses a Git pre-commit hook to automatically updates the build timestamp placeholder in src/views/InfoView.vue and increments the CACHE_VERSION in public/service-worker.js (it is the indicator for the installed PWA that the new version is available). This ensures that each commit intended for a build/deployment reflects the correct information.
Configure Git to use the local hooks directory
Tell the Git to use the hooks located in the .githooks directory:
git config core.hooksPath .githooks
This step needs to be done once per local clone of the repository. The script scripts/git-hooks/pre-commit.cjs will be executed before every commit.
Commit & Push
Stage changes, commit and push
git add .
git commit -m 'fixed visuals'
git push
Building for the production
On the Server
Navigate to the service directory on the server
cd /virt
Clone the repository
git clone --depth 1 https://gitea.virtonline.eu/2HoursProject/nexus-timer.git
cd nexus-timer
Build the docker image
docker build -t virt-nexus-timer .
Exposing the App Behind Traefik (Reverse Proxy)
Review the provided docker labels and systemd service file
Copy the example label file to its destination
cp docker/traefik.labels labels
View the example service definition:
cat systemd/virt-nexus-timer.service
Create the systemd service
Use the editor to create or overwrite the service:
sudo systemctl edit --force --full virt-nexus-timer.service
Paste the content from systemd/virt-nexus-timer.service, then save and exit.
Enable on system boot and start the service
sudo systemctl enable --now virt-nexus-timer.service
Check the service status
systemctl status virt-nexus-timer.service
View real-time logs
journalctl -fu virt-nexus-timer.service
Test the web application
Verify that the application is accessible via HTTPS:
curl https://nexus-timer.virtonline.eu
Or open it in your browser: https://nexus-timer.virtonline.eu
Release the update
On the Server
Navigate to the app directory on your server
cd /virt/nexus-timer
Pull the changes, build the docker image and restart the service
git pull && docker build -t virt-nexus-timer . && systemctl restart virt-nexus-timer.service
View real-time logs
journalctl -fu virt-nexus-timer.service
The previously installed PWA should update automatically or offer an upgrade