BikeControl (SwiftControl)
使用 Zwift Click、Zwift Play、Shimano Di2 或任何藍牙控制器,搭配 MyWhoosh、Rouvy、Zwift 等。iOS、Android、Windows、macOS 均可免費試用。
AI 翻译
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Lineups, rotations, and live stat entry for a volleyball coach running the
bench solo. Built to work with zero signal — everything lives on the device,
not a server.
This is a real, runnable project — a Vite + React app, installable as a PWA
(add it to your phone's home screen like a native app). Two things make it
more than a local demo:查看完整 README ↗Lineups, rotations, and live stat entry for a volleyball coach running the bench solo. Built to work with zero signal — everything lives on the device, not a server.
This is a real, runnable project — a Vite + React app, installable as a PWA (add it to your phone's home screen like a native app). Two things make it more than a local demo:
src/firebase.js) means reads come from the local
cache instantly and writes queue up and sync automatically once a
connection comes back — this is what makes it keep working with zero
signal in a gym, not just "usually" work. vite-plugin-pwa handles the
other half: caching the app's own code so it loads with no network at
all after the first visit.The app won't run without this. You need your own free Firebase project; Firebase doesn't come pre-configured because that would mean sharing database credentials in this README.
volley-bandit, and
click through the setup (you can decline Google Analytics, it's not
needed here).</> (web) icon on the
project overview page to register a web app. Give it any nickname —
you don't need Firebase Hosting, just registering the app.firebaseConfig object with values like apiKey,
authDomain, projectId, etc. Copy those into src/firebase.js,
replacing the placeholder values there.Firestore's "test mode" allows anyone with your project's config to read and write to it, for 30 days, after which it locks down by default. For this app to keep working past that window, go to Firestore Database → Rules and set:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
Be clear-eyed about what this means: it makes your Firestore database open to anyone who has your team code (since that's the only thing gating which document someone reads or writes) and technically anyone who found your Firebase project's public config, if they went looking for it and knew to query Firestore directly rather than going through the app. In practice that's an extremely unlikely threat for a personal coaching tool — but it's not the same thing as real access control, and it's worth knowing the difference rather than assuming "rules are set" means "secure." The app's own passcode screen and team code are the real practical gate here; the Firestore rule above is just what lets the app function past the 30-day test-mode window.
npm install
npm run dev
Opens at http://localhost:5173. Hot-reloads as you edit.
Note: the offline service worker only activates in a production build
(npm run build + npm run preview), not in npm run dev. If you want to
actually test offline behavior — turn on airplane mode and confirm it still
loads — do that against the preview build, not the dev server.
npm run build
npm run preview
public/icon-192.png, public/icon-512.png, and public/favicon.svg are
placeholder marks (a simple net-and-ball motif in the app's color scheme).
Swap them for a real team or app logo whenever you want — same filenames,
same sizes, and the manifest in vite.config.js will pick them up
automatically.
This is exactly the kind of project that belongs in a repo:
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/<your-username>/<repo-name>.git
git push -u origin main
GitHub hosts the source — code, history, README. It doesn't run the app by itself. To get an actual URL you can open on your phone, deploy the built site somewhere. A few good, free options:
base path tweak in
vite.config.js if the repo isn't served from the domain root.Once deployed, open the URL on your phone and use "Add to Home Screen" (iOS Safari) or the install prompt (Android Chrome) to install it like a real app.
The first time the app opens on a device with no team linked, it shows a Create/Join screen:
GRF-4X29) and
shows it once — write it down.Every device linked to the same code reads and writes the same Firestore data, live. Two different coaches using this same deployed app each create their own team and never see each other's data — the app-wide passcode (if you've set one) is a separate outer gate that applies before any of this, same as before.
Switch or unlink a device from its team anytime via the "Switch Team" button on the Roster tab.
Carried over from the product spec. The should-haves (rotation/sub undo, editable matches, safer deletion) and this round's four (timeouts, CSV import/export, tap-through navigation, season-to-date stats) are all done as of this version. Multi-device sync — the one item that used to be a bigger, separate undertaking — is now built (see above). What's left is genuinely nice-to-have, not correctness-critical:
None of these block using the app for a real match today.
player-eval/ is a separate Vite + React app in this same repo: post-match
player evaluations (skill ratings, trends, and lineup-aware position
recommendations). It's its own standalone app, but shares this app's
Firebase project and team code, so entering the same code there picks up
this app's roster (and, for its Recommend tab, this app's active lineup)
live — see player-eval/README.md for details.
player-stats/ is a third Vite + React app in this repo, and the only one
players themselves use: one URL for everybody, where a player types the code
her coach gave her (Settings → Player Access) and sees her own season stats
first, then the same numbers match by match, with the team's totals beside
her own.
It reads exactly one document — playerAccess/{code}, a top-level collection
the coach's app writes on Publish — and never touches teams/{code}/…. A
published document deliberately carries no team code, roster, lineups or
other player's line, and a short name ("Joy B.") rather than a full one.
Deploy it as its own Vercel project with root directory player-stats, then
point PLAYER_STATS_URL in src/App.jsx at the deployment. See
player-stats/README.md.