Files
nexus-timer/README.md
2025-05-09 15:04:47 +02:00

10 KiB

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:
    1. Normal Mode (Default): Central focus on the Current Player (top) and Next Player (bottom).
    2. 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:
    1. 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.
    2. 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.
  • 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"
}

Building for the production

Navigate to the projects' 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

Update the app

Make code changes...

Run the live update server locally

npm run dev

Test the PWA locally

Open it in your browser: http://localhost:8080/

When done, do not forget to update the CACHE_VERSION in the service-worker.js. It is the indicator for the PWA that the new version is available.

ver=$(grep -oP "CACHE_VERSION = 'nexus-timer-cache-v\K[0-9]+" public/service-worker.js)
sed -i "s/nexus-timer-cache-v$ver/nexus-timer-cache-v$((ver+1))/" public/service-worker.js

Stage changes, commit and push

git add .
git commit -m 'fixed visuals'
git push

Release the update

Pull the changes on your server

git pull

Build the docker image and restart the service

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