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:
saopig1andClaude Opus 4.6 committed 2026-04-10 17:16:29 +08:00
1 parent d5d6abeb1e
commit 6e828b9c2d
6 files changed
+161 -22

No files matched your search

+6 -1
View File
@@ -1,4 +1,5 @@
import crypto from "node:crypto";
import { EventEmitter } from "node:events";
import {
BotInstance,
type BotInstanceOptions,
@@ -28,7 +29,7 @@ export interface CreateBotParams {
serverPassword?: string;
}
export class BotManager {
export class BotManager extends EventEmitter {
private bots = new Map<string, BotInstance>();
private neteaseProvider: MusicProvider;
private qqProvider: MusicProvider;
@@ -46,6 +47,7 @@ export class BotManager {
config: BotConfig,
logger: Logger
) {
super();
this.neteaseProvider = neteaseProvider;
this.qqProvider = qqProvider;
this.bilibiliProvider = bilibiliProvider;
@@ -82,6 +84,7 @@ export class BotManager {
});
this.bots.set(id, bot);
this.emit("botInstance", bot);
this.database.saveBotInstance({
id,
@@ -179,6 +182,7 @@ export class BotManager {
logger: this.logger,
});
this.bots.set(id, bot);
this.emit("botInstance", bot);
await bot.connect();
// Mark as autoStart so it reconnects on Docker restart, and persist identity
this.database.saveBotInstance({ ...saved, autoStart: true });
@@ -229,6 +233,7 @@ export class BotManager {
});
this.bots.set(saved.id, bot);
this.emit("botInstance", bot);
// Only auto-connect bots that have autoStart enabled
if (saved.autoStart) {