docs(launcher): add Call to Play specification and design reference
Extend the launcher design specification and prototype reference with the "Call to Play" multiplayer coordination feature and clean up top-bar chrome. Key additions and changes: - Spec & Roadmap: Document Call to Play mechanics in SPEC.md, including Play Now / Scheduled call flavors, 15-minute check-in windows, top-bar button with active count badge, quick-bar ticker stack above grid, overlay modal, and per-call group chat. Update design/README.md. - Components & Logic: Add calltoplay.jsx and ctp-chat.jsx components for call creation, status progression, and chat. Extend data.jsx with a mock peer roster (PEERS) and helper functions for peer install count tracking. - Top-bar Cleanup: Move game-folder configuration from top bar into Settings -> Library, freeing top-bar space for the Call to Play action button. - Styling & Layout: Add CTP quick-bar, ticker, badge, card, and chat styles to styles.css, and integrate CTP components into launcher.jsx, components.jsx, and SoftLAN Launcher.html. Test Plan: - `git diff --cached --check` -- passed (no trailing whitespace or conflict markers) - `cargo check --workspace` -- passed cleanly - Manual review of staged diff across 9 design/launcher files -- confirmed clean staging
This commit is contained in:
@@ -203,7 +203,37 @@ const STORAGE = {
|
||||
total: 512,
|
||||
};
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────
|
||||
// LAN roster (mock) — used by the peer-install indicator and by the
|
||||
// Call to Play feature to simulate other people in the room.
|
||||
// ────────────────────────────────────────────────────────────────────
|
||||
const PEERS = [
|
||||
'shadowfox', 'pixelqueen', 'kbmaster', 'nullptr', 'wavedash',
|
||||
'crit_happens', 'afk_andy', 'lowping_larry', 'gg_val', 'ctrlaltdave',
|
||||
];
|
||||
|
||||
const hashStr = (s) => [...String(s)].reduce((a, c) => a + c.charCodeAt(0), 0);
|
||||
|
||||
// Deterministic-but-varied subset of PEERS who "have this game installed" —
|
||||
// stable per game id so the same game always shows the same roster/count.
|
||||
function installedPeersFor(game) {
|
||||
const h = hashStr(game.id);
|
||||
const count = 1 + (h % PEERS.length); // 1..PEERS.length
|
||||
const scored = PEERS.map((p, i) => ({ p, s: (h * 7 + i * 13 + hashStr(p)) % 97 }));
|
||||
scored.sort((a, b) => a.s - b.s);
|
||||
return scored.slice(0, count).map(x => x.p);
|
||||
}
|
||||
|
||||
// "2–16" / "1-8" → 16 / 8. Falls back to 8 if unparsable.
|
||||
function parseMaxPlayers(playersStr) {
|
||||
const m = String(playersStr).match(/(\d+)\s*$/);
|
||||
return m ? parseInt(m[1], 10) : 8;
|
||||
}
|
||||
|
||||
window.GAMES = GAMES;
|
||||
window.PEERS = PEERS;
|
||||
window.installedPeersFor = installedPeersFor;
|
||||
window.parseMaxPlayers = parseMaxPlayers;
|
||||
window.STATE_META = STATE_META;
|
||||
window.ACTION_FOR_STATE = ACTION_FOR_STATE;
|
||||
window.countByFilter = countByFilter;
|
||||
|
||||
Reference in New Issue
Block a user