mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
fix(ws): re-attach stateChange listeners when bot instance is replaced
startBot creates a fresh BotInstance but the WS layer keyed its listener map by bot.id, so ensureAllBotsAttached skipped the new object and stateChange events were never broadcast — the player bar only appeared after a manual refresh. BotManager now extends EventEmitter and emits "botInstance" whenever a new bot object is created; websocket.ts stores the bot reference, detaches on replacement, and subscribes to the event for immediate wiring. Also enlarges the bot selector (padding 10×20, font 16, min-height 44, bigger dot/chevron/state icons, wider name) and adds Playwright repro scripts for the player bar bug and navbar sizing check. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
d5d6abeb1e
commit
6e828b9c2d
6 files changed
+161
-22
No files matched your search
+27
-12
@@ -10,8 +10,9 @@ export function setupWebSocket(
|
||||
): () => void {
|
||||
const clients = new Set<WebSocket>();
|
||||
|
||||
/** Track which bots already have listeners attached */
|
||||
/** Track which bot instances have listeners attached (keyed by id, storing ref) */
|
||||
const attachedBots = new Map<string, {
|
||||
bot: BotInstance;
|
||||
stateChange: () => void;
|
||||
connected: () => void;
|
||||
disconnected: () => void;
|
||||
@@ -48,8 +49,22 @@ export function setupWebSocket(
|
||||
}
|
||||
};
|
||||
|
||||
function detachBotListener(id: string): void {
|
||||
const existing = attachedBots.get(id);
|
||||
if (!existing) return;
|
||||
existing.bot.removeListener("stateChange", existing.stateChange);
|
||||
existing.bot.removeListener("connected", existing.connected);
|
||||
existing.bot.removeListener("disconnected", existing.disconnected);
|
||||
attachedBots.delete(id);
|
||||
}
|
||||
|
||||
function attachBotListener(bot: BotInstance): void {
|
||||
if (attachedBots.has(bot.id)) return;
|
||||
const existing = attachedBots.get(bot.id);
|
||||
if (existing) {
|
||||
if (existing.bot === bot) return; // already attached to this instance
|
||||
// Bot instance was replaced (e.g. startBot re-created it) — re-attach
|
||||
detachBotListener(bot.id);
|
||||
}
|
||||
|
||||
const onStateChange = () => {
|
||||
broadcast({
|
||||
@@ -81,6 +96,7 @@ export function setupWebSocket(
|
||||
bot.on("disconnected", onDisconnected);
|
||||
|
||||
attachedBots.set(bot.id, {
|
||||
bot,
|
||||
stateChange: onStateChange,
|
||||
connected: onConnected,
|
||||
disconnected: onDisconnected,
|
||||
@@ -94,21 +110,20 @@ export function setupWebSocket(
|
||||
}
|
||||
}
|
||||
|
||||
// Check for newly added bots periodically
|
||||
// React immediately when a bot instance is created or replaced
|
||||
const onBotInstance = (bot: BotInstance) => attachBotListener(bot);
|
||||
botManager.on("botInstance", onBotInstance);
|
||||
|
||||
// Safety net: periodically re-check in case any bot was missed
|
||||
const intervalId = setInterval(ensureAllBotsAttached, 5000);
|
||||
ensureAllBotsAttached();
|
||||
|
||||
return () => {
|
||||
clearInterval(intervalId);
|
||||
// Clean up named listeners
|
||||
for (const bot of botManager.getAllBots()) {
|
||||
const listeners = attachedBots.get(bot.id);
|
||||
if (listeners) {
|
||||
bot.removeListener("stateChange", listeners.stateChange);
|
||||
bot.removeListener("connected", listeners.connected);
|
||||
bot.removeListener("disconnected", listeners.disconnected);
|
||||
}
|
||||
botManager.removeListener("botInstance", onBotInstance);
|
||||
// Clean up all attached listeners (detach from stored bot refs, not live map)
|
||||
for (const id of Array.from(attachedBots.keys())) {
|
||||
detachBotListener(id);
|
||||
}
|
||||
attachedBots.clear();
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user