diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index efdb7cb..5a002b1 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -13,6 +13,7 @@ on: permissions: contents: read pages: write + pull-requests: read id-token: write concurrency: @@ -38,6 +39,17 @@ jobs: uses: actions/configure-pages@v6 - name: Install dependencies run: bun install --frozen-lockfile + - name: Resolve build metadata + env: + BUILD_SHA: ${{ github.event.workflow_run.head_sha || github.sha }} + GH_TOKEN: ${{ github.token }} + run: | + echo "VITE_BUILD_TIMESTAMP=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> "$GITHUB_ENV" + build_pr_url="$(gh api "repos/${GITHUB_REPOSITORY}/commits/${BUILD_SHA}/pulls" --jq '.[0].html_url // empty')" + if [ -z "$build_pr_url" ]; then + build_pr_url="https://github.com/${GITHUB_REPOSITORY}/pulls?q=is%3Apr+is%3Aclosed" + fi + echo "VITE_BUILD_PR_URL=${build_pr_url}" >> "$GITHUB_ENV" - name: Build site run: bun run build - name: Upload site artifact diff --git a/README.md b/README.md index 399eb39..0c5bfd2 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ Bike trainer control web app using Web Bluetooth. Tested with Wahoo KICKR Core 2 ## Features - Welcomes first-time visitors with a concise introduction, open-source and local-data privacy details, a direct source-code link, and an optional “Don't show again” preference stored in the browser; the welcome screen remains available from the Ride Control footer link. -- Manages the smart trainer, heart rate monitor, and both Zwift Click V2 controllers independently from one paired-devices panel, with a blue activity indicator while devices connect and a green indicator once every paired device is ready; keeps the `+` controller above the `−` controller, automatically identifies each physical side, connects both controllers concurrently, routes mirrored Bluetooth notifications only to that side, glows only its row as it is pressed, remembers its identity, and continuously retries saved Click connections after a refresh or controller sleep; stalled attempts can be retried immediately, and Click presses made while this panel is open stay in setup and do not shift the ride. +- Manages the smart trainer, heart rate monitor, and both Zwift Click V2 controllers independently from one paired-devices panel, with blue pulsing dots for controllers awaiting connection and a green indicator once every paired device is ready; keeps the `+` controller above the `−` controller, automatically identifies each physical side, connects both controllers concurrently, routes mirrored Bluetooth notifications only to that side, glows only its row as it is pressed, remembers its identity, continuously retries saved Click connections after a refresh or controller sleep, and keeps the sleeping-controller display stable between retry attempts; stalled attempts can be retried immediately, and Click presses made while this panel is open stay in setup and do not shift the ride. +- Detects browsers outside the currently tested Chrome environment and replaces the pairing controls with a compatibility notice, while showing reconnect-saving guidance alongside the pairing controls only in Chrome. +- Shows each deployment's build time in the viewer's local timezone and links it to the GitHub pull request that produced the build, falling back to the closed pull-request list when no associated PR is available. - Connects to compatible bike trainers and standard Bluetooth heart rate monitors through Web Bluetooth, remembers authorized devices, and automatically reconnects when possible. - Shows live speed, power, cadence, heart rate, elapsed time, distance, and estimated calories, with MPH and KM/H display modes. - Provides direct resistance control with buttons, a slider, and keyboard shortcuts with matching button feedback, shows smoothing progress inside the slider thumb, and records resistance changes alongside the other ride metrics. @@ -40,6 +42,9 @@ directory to GitHub Pages at [ridecontrol.xyz](https://ridecontrol.xyz). ## Automatic reconnect +Ride Control currently tests Web Bluetooth only in desktop Chrome. Bluetooth does not work in +Brave. + Persistent Web Bluetooth permissions are disabled by default in current Chromium builds. To allow the app to reconnect after a page reload: 1. Open `chrome://flags/#enable-web-bluetooth-new-permissions-backend`. diff --git a/src/app.tsx b/src/app.tsx index 3364253..1394a07 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -15,6 +15,7 @@ import { useHeartRateMonitor } from './hooks/use-heart-rate-monitor'; import { useSession } from './hooks/use-session'; import { useTrainer } from './hooks/use-trainer'; import { useZwiftClick } from './hooks/use-zwift-click'; +import { BUILD_PR_URL, BUILD_TIMESTAMP_UTC, formatBuildTimestamp } from './lib/build-info'; import { formatAggregateAverage, formatDuration } from './lib/format'; import { type AppShortcut, appShortcutForKey, gearingKeyboardShortcuts } from './lib/keyboard'; import { @@ -344,7 +345,7 @@ export function App() { const devicesConnecting = [ trainer.connectionBusy, heartRate.busy, - click.busy, + click.reconnecting, click.pairing, ].some(Boolean); let sessionControlLabel = 'Auto paused'; @@ -551,7 +552,7 @@ export function App() { -