Add poker admin tablet app files
This commit is contained in:
parent
f75abe564d
commit
2b80a789d0
2 changed files with 661 additions and 0 deletions
108
scripts/poker-admin-tablet.js
Normal file
108
scripts/poker-admin-tablet.js
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
(function() {
|
||||
var APP_NAME = "POKER ADMIN";
|
||||
var APP_URL = "https://wizards.cyou/tablet/poker-admin.html";
|
||||
var APP_ICON = "https://wizards.cyou/tablet/poker-admin-icon.svg";
|
||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
var button = tablet.addButton({
|
||||
text: APP_NAME,
|
||||
icon: APP_ICON
|
||||
});
|
||||
|
||||
var webEventHandler = function(data) {
|
||||
try {
|
||||
var msg = JSON.parse(data);
|
||||
if (msg.type === "ready") {
|
||||
var username = AccountServices.username || "";
|
||||
tablet.emitScriptEvent(JSON.stringify({
|
||||
type: "init",
|
||||
username: username,
|
||||
position: MyAvatar.position,
|
||||
rotation: MyAvatar.orientation,
|
||||
}));
|
||||
} else if (msg.type === "getPosition") {
|
||||
// Tablet can request a fresh position snapshot any time
|
||||
tablet.emitScriptEvent(JSON.stringify({
|
||||
type: "position",
|
||||
position: MyAvatar.position,
|
||||
rotation: MyAvatar.orientation,
|
||||
}));
|
||||
} else if (msg.type === "spawnSeats") {
|
||||
// HTML side has confirmed table created, now spawn seat pads in world
|
||||
spawnSeatPads(msg.tableEntityID, msg.pokerID, msg.seatCount,
|
||||
msg.position, msg.rotation);
|
||||
}
|
||||
} catch(e) {
|
||||
print("[pokerAdmin] web event error: " + e);
|
||||
}
|
||||
};
|
||||
|
||||
function spawnSeatPads(tableEntityID, pokerID, seatCount, position, rotation) {
|
||||
var constants = Script.require(Script.resolvePath("poker_constants.js"));
|
||||
var layout = constants.POKER_SEATS[seatCount];
|
||||
if (!layout) {
|
||||
print("[pokerAdmin] no layout for seatCount=" + seatCount);
|
||||
return;
|
||||
}
|
||||
|
||||
// Spawn the table model entity first
|
||||
var tableID = Entities.addEntity({
|
||||
type: "Model",
|
||||
name: "poker_table_" + pokerID,
|
||||
modelURL: constants.POKER_TABLE_MODEL_URL,
|
||||
position: position,
|
||||
rotation: rotation,
|
||||
dimensions: { x: 3.0, y: 1.0, z: 3.0 },
|
||||
userData: JSON.stringify({
|
||||
pokerID: pokerID,
|
||||
seatCount: seatCount,
|
||||
}),
|
||||
grabbable: false,
|
||||
});
|
||||
|
||||
print("[pokerAdmin] spawned table entity " + tableID);
|
||||
|
||||
// Spawn a seat pad for each seat
|
||||
for (var i = 0; i < seatCount; i++) {
|
||||
var seat = layout[i];
|
||||
var worldOffset = Vec3.multiplyQbyV(rotation, seat.offset);
|
||||
var seatPos = Vec3.sum(position, worldOffset);
|
||||
var seatRot = Quat.fromPitchYawRollDegrees(0, seat.yaw, 0);
|
||||
|
||||
Entities.addEntity({
|
||||
type: "Image",
|
||||
name: "poker_seat_" + pokerID + "_" + i,
|
||||
imageURL: constants.POKER_SEAT_PAD.imageURL,
|
||||
dimensions: constants.POKER_SEAT_PAD.dimensions,
|
||||
alpha: constants.POKER_SEAT_PAD.alpha,
|
||||
position: seatPos,
|
||||
rotation: seatRot,
|
||||
script: "https://wizards.cyou/scripts/poker_sit.js",
|
||||
userData: JSON.stringify({
|
||||
tableID: tableID,
|
||||
pokerID: pokerID,
|
||||
seatIndex: i,
|
||||
}),
|
||||
triggerable: true,
|
||||
grabbable: false,
|
||||
ignorePickIntersection: false,
|
||||
});
|
||||
|
||||
print("[pokerAdmin] spawned seat " + i + " for table " + pokerID);
|
||||
}
|
||||
|
||||
tablet.emitScriptEvent(JSON.stringify({
|
||||
type: "spawnComplete",
|
||||
tableEntityID: tableID,
|
||||
}));
|
||||
}
|
||||
|
||||
button.clicked.connect(function() {
|
||||
tablet.gotoWebScreen(APP_URL);
|
||||
tablet.webEventReceived.connect(webEventHandler);
|
||||
});
|
||||
|
||||
Script.scriptEnding.connect(function() {
|
||||
tablet.removeButton(button);
|
||||
tablet.webEventReceived.disconnect(webEventHandler);
|
||||
});
|
||||
})();
|
||||
553
scripts/poker-admin.html
Normal file
553
scripts/poker-admin.html
Normal file
|
|
@ -0,0 +1,553 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>POKER ADMIN</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Cinzel:wght@400;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--bg: #0e0e1a;
|
||||
--panel: #13132a;
|
||||
--border: #2a2a4a;
|
||||
--gold: #ffd700;
|
||||
--gold-dim: #a08800;
|
||||
--text: #c8c8e0;
|
||||
--muted: #555570;
|
||||
--red: #ff4444;
|
||||
--green: #44cc88;
|
||||
--mono: 'Share Tech Mono', monospace;
|
||||
--serif: 'Cinzel', serif;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font-family: var(--mono);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
body::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background-image:
|
||||
linear-gradient(var(--border) 1px, transparent 1px),
|
||||
linear-gradient(90deg, var(--border) 1px, transparent 1px);
|
||||
background-size: 40px 40px;
|
||||
opacity: 0.25;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
background: var(--bg);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding: 12px 16px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.app-title {
|
||||
font-family: var(--serif);
|
||||
font-size: 13px;
|
||||
letter-spacing: 4px;
|
||||
color: var(--gold);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.user-badge {
|
||||
font-size: 9px;
|
||||
color: var(--muted);
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
#status-bar {
|
||||
font-size: 9px;
|
||||
color: var(--muted);
|
||||
text-align: center;
|
||||
padding: 4px 16px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
letter-spacing: 1px;
|
||||
min-height: 20px;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
#status-bar.error { color: var(--red); }
|
||||
#status-bar.ok { color: var(--green); }
|
||||
|
||||
/* ── tabs ── */
|
||||
.tabs {
|
||||
display: flex;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.tab {
|
||||
flex: 1;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-bottom: 2px solid transparent;
|
||||
color: var(--muted);
|
||||
font-family: var(--mono);
|
||||
font-size: 9px;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
transition: color 0.15s, border-color 0.15s;
|
||||
}
|
||||
|
||||
.tab:hover { color: var(--text); }
|
||||
.tab.active {
|
||||
color: var(--gold);
|
||||
border-bottom-color: var(--gold);
|
||||
}
|
||||
|
||||
/* ── panels ── */
|
||||
.panel {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
gap: 12px;
|
||||
}
|
||||
.panel.active { display: flex; }
|
||||
|
||||
/* ── form elements ── */
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.field label {
|
||||
font-size: 9px;
|
||||
color: var(--muted);
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.field input {
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
font-family: var(--mono);
|
||||
font-size: 12px;
|
||||
padding: 8px 10px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s;
|
||||
}
|
||||
|
||||
.field input:focus { border-color: var(--gold-dim); }
|
||||
|
||||
.field-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background: transparent;
|
||||
border: 1px solid var(--gold-dim);
|
||||
color: var(--gold);
|
||||
font-family: var(--mono);
|
||||
font-size: 10px;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s, border-color 0.15s;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn:hover { background: rgba(255,215,0,0.08); border-color: var(--gold); }
|
||||
.btn.danger {
|
||||
border-color: #662222;
|
||||
color: var(--red);
|
||||
}
|
||||
.btn.danger:hover { background: rgba(255,68,68,0.08); border-color: var(--red); }
|
||||
.btn:disabled { opacity: 0.4; cursor: default; }
|
||||
|
||||
/* ── table list ── */
|
||||
.table-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.table-card {
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--border);
|
||||
padding: 10px 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.table-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.table-name {
|
||||
font-family: var(--serif);
|
||||
font-size: 11px;
|
||||
color: #e8e8ff;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.table-id {
|
||||
font-size: 8px;
|
||||
color: var(--muted);
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.table-meta {
|
||||
font-size: 9px;
|
||||
color: var(--muted);
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.table-meta span { color: var(--gold-dim); }
|
||||
|
||||
.table-actions {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.table-actions .btn {
|
||||
font-size: 8px;
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
font-family: var(--serif);
|
||||
font-size: 9px;
|
||||
letter-spacing: 3px;
|
||||
color: var(--muted);
|
||||
text-transform: uppercase;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: var(--border);
|
||||
}
|
||||
|
||||
#no-tables {
|
||||
font-size: 10px;
|
||||
color: var(--muted);
|
||||
text-align: center;
|
||||
padding: 24px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<div class="app-title">POKER ADMIN</div>
|
||||
<div class="user-badge" id="user-badge">—</div>
|
||||
</header>
|
||||
|
||||
<div id="status-bar">Initialising...</div>
|
||||
|
||||
<div class="tabs">
|
||||
<button class="tab active" onclick="switchTab('create')">Create</button>
|
||||
<button class="tab" onclick="switchTab('manage')">Manage</button>
|
||||
</div>
|
||||
|
||||
<!-- ── Create Tab ── -->
|
||||
<div class="panel active" id="tab-create">
|
||||
<div class="section-header">New Table</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Table ID (slug)</label>
|
||||
<input type="text" id="f-id" placeholder="main" value="main">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Display Name</label>
|
||||
<input type="text" id="f-name" placeholder="Main Table">
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label>Seat Count</label>
|
||||
<input type="number" id="f-seats" value="7" min="2" max="9">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Turn Timer (s)</label>
|
||||
<input type="number" id="f-timer" value="30" min="10" max="120">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label>Small Blind</label>
|
||||
<input type="number" id="f-sb" value="5" min="1">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Big Blind</label>
|
||||
<input type="number" id="f-bb" value="10" min="2">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label>Min Buy-in</label>
|
||||
<input type="number" id="f-minbuy" value="100" min="1">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Max Buy-in</label>
|
||||
<input type="number" id="f-maxbuy" value="1000" min="1">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<button class="btn" id="btn-create" onclick="createTable()">Spawn Table at Avatar Position</button>
|
||||
</div>
|
||||
|
||||
<!-- ── Manage Tab ── -->
|
||||
<div class="panel" id="tab-manage">
|
||||
<div class="section-header">Tables</div>
|
||||
<div class="table-list" id="table-list">
|
||||
<div id="no-tables">Loading...</div>
|
||||
</div>
|
||||
<button class="btn" onclick="loadTables()" style="margin-top:auto">Refresh</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var API_BASE = "https://wizards.cyou/api";
|
||||
var POKER_BASE = "https://wizards.cyou/poker";
|
||||
|
||||
var state = {
|
||||
username: null,
|
||||
token: null,
|
||||
position: null,
|
||||
rotation: null,
|
||||
};
|
||||
|
||||
// ── tabs ─────────────────────────────────────────────────────
|
||||
|
||||
function switchTab(name) {
|
||||
document.querySelectorAll(".tab").forEach(function(t) { t.classList.remove("active"); });
|
||||
document.querySelectorAll(".panel").forEach(function(p) { p.classList.remove("active"); });
|
||||
document.querySelector("[onclick=\"switchTab('" + name + "')\"]").classList.add("active");
|
||||
document.getElementById("tab-" + name).classList.add("active");
|
||||
if (name === "manage") loadTables();
|
||||
}
|
||||
|
||||
// ── status ───────────────────────────────────────────────────
|
||||
|
||||
function setStatus(msg, cls) {
|
||||
var el = document.getElementById("status-bar");
|
||||
el.textContent = msg;
|
||||
el.className = cls || "";
|
||||
}
|
||||
|
||||
// ── session ──────────────────────────────────────────────────
|
||||
|
||||
function ensureSession(cb) {
|
||||
if (state.token) { cb(null, state.token); return; }
|
||||
fetch(API_BASE + "/session", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ username: state.username }),
|
||||
})
|
||||
.then(function(r) {
|
||||
if (!r.ok) throw new Error("Session failed (" + r.status + ")");
|
||||
return r.json();
|
||||
})
|
||||
.then(function(d) {
|
||||
state.token = d.token;
|
||||
cb(null, state.token);
|
||||
})
|
||||
.catch(function(e) { cb(e.message); });
|
||||
}
|
||||
|
||||
// ── create table ─────────────────────────────────────────────
|
||||
|
||||
function createTable() {
|
||||
var id = document.getElementById("f-id").value.trim();
|
||||
var name = document.getElementById("f-name").value.trim();
|
||||
var seats = parseInt(document.getElementById("f-seats").value);
|
||||
var timer = parseInt(document.getElementById("f-timer").value);
|
||||
var sb = parseInt(document.getElementById("f-sb").value);
|
||||
var bb = parseInt(document.getElementById("f-bb").value);
|
||||
var minbuy = parseInt(document.getElementById("f-minbuy").value);
|
||||
var maxbuy = parseInt(document.getElementById("f-maxbuy").value);
|
||||
|
||||
if (!id || !name) { setStatus("ID and Name are required", "error"); return; }
|
||||
if (bb !== sb * 2) { setStatus("Big blind must be exactly 2x small blind", "error"); return; }
|
||||
if (minbuy < bb * 10) { setStatus("Min buy-in must be at least 10x big blind (" + (bb*10) + ")", "error"); return; }
|
||||
if (maxbuy < minbuy) { setStatus("Max buy-in must be >= min buy-in", "error"); return; }
|
||||
|
||||
var btn = document.getElementById("btn-create");
|
||||
btn.disabled = true;
|
||||
setStatus("Getting session...");
|
||||
|
||||
ensureSession(function(err) {
|
||||
if (err) { setStatus(err, "error"); btn.disabled = false; return; }
|
||||
|
||||
// Request a fresh position snapshot from the tablet script
|
||||
setStatus("Fetching avatar position...");
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: "getPosition" }));
|
||||
|
||||
// Store config to use once position arrives
|
||||
state.pendingCreate = {
|
||||
id: id, name: name, seatCount: seats, turnTimer: timer,
|
||||
smallBlind: sb, bigBlind: bb, minBuyin: minbuy, maxBuyin: maxbuy,
|
||||
};
|
||||
btn.disabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
function doCreateTable(cfg, position, rotation) {
|
||||
var btn = document.getElementById("btn-create");
|
||||
btn.disabled = true;
|
||||
setStatus("Creating table...");
|
||||
|
||||
fetch(POKER_BASE + "/admin/tables", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": "Bearer " + state.token,
|
||||
},
|
||||
body: JSON.stringify(cfg),
|
||||
})
|
||||
.then(function(r) {
|
||||
if (!r.ok) return r.json().then(function(e) { throw new Error(e.error || r.status); });
|
||||
return r.json();
|
||||
})
|
||||
.then(function(d) {
|
||||
setStatus("Table created! Spawning entities...", "ok");
|
||||
// Tell the tablet script to spawn the in-world entities
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "spawnSeats",
|
||||
pokerID: cfg.id,
|
||||
seatCount: cfg.seatCount,
|
||||
position: position,
|
||||
rotation: rotation,
|
||||
}));
|
||||
})
|
||||
.catch(function(e) {
|
||||
setStatus(e.message, "error");
|
||||
btn.disabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
// ── manage tables ─────────────────────────────────────────────
|
||||
|
||||
function loadTables() {
|
||||
setStatus("Loading tables...");
|
||||
fetch(POKER_BASE + "/tables")
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(d) {
|
||||
renderTables(d.tables || []);
|
||||
setStatus(d.tables.length + " table(s) loaded", "ok");
|
||||
})
|
||||
.catch(function() { setStatus("Could not load tables", "error"); });
|
||||
}
|
||||
|
||||
function renderTables(tables) {
|
||||
var list = document.getElementById("table-list");
|
||||
if (tables.length === 0) {
|
||||
list.innerHTML = '<div id="no-tables">No tables yet</div>';
|
||||
return;
|
||||
}
|
||||
list.innerHTML = "";
|
||||
tables.forEach(function(t) {
|
||||
var cfg = t.config || t;
|
||||
var card = document.createElement("div");
|
||||
card.className = "table-card";
|
||||
card.innerHTML =
|
||||
'<div class="table-card-header">' +
|
||||
'<div class="table-name">' + cfg.name + '</div>' +
|
||||
'<div class="table-id">' + cfg.id + '</div>' +
|
||||
'</div>' +
|
||||
'<div class="table-meta">' +
|
||||
'<span>' + cfg.seatCount + '</span> seats · ' +
|
||||
'blinds <span>' + cfg.smallBlind + '/' + cfg.bigBlind + '</span> · ' +
|
||||
'buy-in <span>' + cfg.minBuyin + '–' + cfg.maxBuyin + '</span>' +
|
||||
'</div>' +
|
||||
'<div class="table-actions">' +
|
||||
'<button class="btn danger" onclick="deleteTable(\'' + cfg.id + '\')">Delete</button>' +
|
||||
'</div>';
|
||||
list.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteTable(id) {
|
||||
if (!confirm("Delete table " + id + "? Seated players will be refunded.")) return;
|
||||
|
||||
ensureSession(function(err) {
|
||||
if (err) { setStatus(err, "error"); return; }
|
||||
setStatus("Deleting " + id + "...");
|
||||
fetch(POKER_BASE + "/admin/tables/" + id, {
|
||||
method: "DELETE",
|
||||
headers: { "Authorization": "Bearer " + state.token },
|
||||
})
|
||||
.then(function(r) {
|
||||
if (!r.ok) return r.json().then(function(e) { throw new Error(e.error || r.status); });
|
||||
return r.json();
|
||||
})
|
||||
.then(function() {
|
||||
setStatus("Table " + id + " deleted", "ok");
|
||||
loadTables();
|
||||
})
|
||||
.catch(function(e) { setStatus(e.message, "error"); });
|
||||
});
|
||||
}
|
||||
|
||||
// ── EventBridge ──────────────────────────────────────────────
|
||||
|
||||
function init() {
|
||||
if (typeof EventBridge !== "undefined") {
|
||||
EventBridge.scriptEventReceived.connect(function(data) {
|
||||
try {
|
||||
var msg = JSON.parse(data);
|
||||
if (msg.type === "init") {
|
||||
state.username = msg.username;
|
||||
state.position = msg.position;
|
||||
state.rotation = msg.rotation;
|
||||
document.getElementById("user-badge").textContent = msg.username || "unknown";
|
||||
setStatus("Ready");
|
||||
if (msg.username !== "nak") {
|
||||
setStatus("Admin access required", "error");
|
||||
document.getElementById("btn-create").disabled = true;
|
||||
}
|
||||
} else if (msg.type === "position") {
|
||||
state.position = msg.position;
|
||||
state.rotation = msg.rotation;
|
||||
if (state.pendingCreate) {
|
||||
var cfg = state.pendingCreate;
|
||||
state.pendingCreate = null;
|
||||
doCreateTable(cfg, state.position, state.rotation);
|
||||
}
|
||||
} else if (msg.type === "spawnComplete") {
|
||||
setStatus("Table and seats spawned!", "ok");
|
||||
document.getElementById("btn-create").disabled = false;
|
||||
}
|
||||
} catch(e) {
|
||||
print("poker-admin event error: " + e);
|
||||
}
|
||||
});
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: "ready" }));
|
||||
} else {
|
||||
setStatus("EventBridge not available (dev mode)", "error");
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = init;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Reference in a new issue