Files
AskaEth e28be26ab3 fix: 7 bug fixes + port config with auto-restart
- HTTPException import added (was causing 500 on missing dashboard)
- game_manager.remove_plugin() restored (was AttributeError)
- api.js checks HTTP status codes, fails fast on errors
- sidebar game highlight only matches selected gameId
- scene resize handler uses stored canvas dims (was NaN)
- forwarder socket properly closed on listener stop
- telemetry port: use_unified_port toggle, off = per-game port, auto-restart on switch
2026-07-26 17:23:14 +08:00

55 lines
2.5 KiB
JavaScript

const API = {
_base: '/api',
async _req(method, path, body) {
const opts = { method };
if (body) {
opts.headers = { 'Content-Type': 'application/json' };
opts.body = JSON.stringify(body);
}
const res = await fetch(`${this._base}${path}`, opts);
if (!res.ok) {
const text = await res.text().catch(() => '');
throw new Error(`${method} ${path} ${res.status}: ${text.slice(0, 200)}`);
}
return res.json();
},
async get(path) { return this._req('GET', path); },
async post(path, data) { return this._req('POST', path, data); },
async put(path, data) { return this._req('PUT', path, data); },
async del(path) { return this._req('DELETE', path); },
async getStatus() { return this.get('/status'); },
async getConfig() { return this.get('/config'); },
async updateConfig(data) { return this.put('/config', data); },
async getGames() { return this.get('/games'); },
async getDashboards(category) { return this.get(`/dashboards?category=${category || 'all'}`); },
async getCategories() { return this.get('/dashboards/categories'); },
async getDashboard(id) { return this.get(`/dashboards/${id}`); },
async getDashboardTemplate(id) { return this.get(`/dashboards/${id}/template`); },
async createDashboard(data) { return this.post('/dashboards', data); },
async updateDashboard(id, data) { return this.put(`/dashboards/${id}`, data); },
async deleteDashboard(id) { return this.del(`/dashboards/${id}`); },
async exportDashboard(id) { return this.get(`/dashboards/${id}/export`); },
async getScenes(gameId) { return this.get(`/scenes?game_id=${gameId || ''}`); },
async getScene(id) { return this.get(`/scenes/${id}`); },
async createScene(data) { return this.post('/scenes', data); },
async updateScene(id, data) { return this.put(`/scenes/${id}`, data); },
async deleteScene(id) { return this.del(`/scenes/${id}`); },
async exportScene(id) { return this.get(`/scenes/${id}/export`); },
async startTelemetry() { return this.post('/telemetry/start'); },
async stopTelemetry() { return this.post('/telemetry/stop'); },
async getLatestTelemetry() { return this.get('/telemetry/latest'); },
async removeGamePlugin(id) { return this.del(`/games/${id}`); },
async exportGamePlugin(id) { return this.get(`/games/${id}/export`); },
async reloadGamePlugins() { return this.post('/games/reload'); },
};
window.API = API;