fix: preserve ui state broadcasts in routes
This commit is contained in:
@@ -3,12 +3,40 @@ import express from "express";
|
|||||||
import { AppError } from "../errors";
|
import { AppError } from "../errors";
|
||||||
import { createChildLogger } from "../logger";
|
import { createChildLogger } from "../logger";
|
||||||
import type { VoiceController } from "../voiceController";
|
import type { VoiceController } from "../voiceController";
|
||||||
|
import type { ModerationBroadcaster } from "../moderation/broadcaster";
|
||||||
|
import type { SharedUIState } from "./uiStateRoutes";
|
||||||
|
|
||||||
const logger = createChildLogger("voice-routes");
|
const logger = createChildLogger("voice-routes");
|
||||||
|
|
||||||
export function createVoiceRoutes(voiceController: VoiceController): Router {
|
export interface VoiceRouteOptions {
|
||||||
|
voiceController: VoiceController;
|
||||||
|
patchSharedUIState: (patch: Partial<SharedUIState>) => SharedUIState;
|
||||||
|
broadcaster: ModerationBroadcaster;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createVoiceRoutes(
|
||||||
|
options: VoiceRouteOptions | VoiceController,
|
||||||
|
): Router {
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
// Support both old signature (VoiceController) and new signature (options object)
|
||||||
|
let voiceController: VoiceController;
|
||||||
|
let patchSharedUIState:
|
||||||
|
| ((patch: Partial<SharedUIState>) => SharedUIState)
|
||||||
|
| undefined;
|
||||||
|
let broadcaster: ModerationBroadcaster | undefined;
|
||||||
|
|
||||||
|
if ("connect" in options && "disconnect" in options) {
|
||||||
|
// Old signature: just VoiceController
|
||||||
|
voiceController = options as VoiceController;
|
||||||
|
} else {
|
||||||
|
// New signature: options object
|
||||||
|
const opts = options as VoiceRouteOptions;
|
||||||
|
voiceController = opts.voiceController;
|
||||||
|
patchSharedUIState = opts.patchSharedUIState;
|
||||||
|
broadcaster = opts.broadcaster;
|
||||||
|
}
|
||||||
|
|
||||||
// GET /api/status - Get voice connection status
|
// GET /api/status - Get voice connection status
|
||||||
router.get("/status", (_req, res, next) => {
|
router.get("/status", (_req, res, next) => {
|
||||||
try {
|
try {
|
||||||
@@ -96,6 +124,16 @@ export function createVoiceRoutes(voiceController: VoiceController): Router {
|
|||||||
logger.info({ guildId, channelId }, "Connecting to voice channel");
|
logger.info({ guildId, channelId }, "Connecting to voice channel");
|
||||||
|
|
||||||
const status = await voiceController.connect(guildId, channelId);
|
const status = await voiceController.connect(guildId, channelId);
|
||||||
|
|
||||||
|
// Update UI state and broadcast to connected clients
|
||||||
|
if (patchSharedUIState && broadcaster) {
|
||||||
|
const updatedState = patchSharedUIState({
|
||||||
|
selectedGuild: guildId,
|
||||||
|
selectedVoiceChannel: channelId,
|
||||||
|
});
|
||||||
|
broadcaster.uiState(updatedState);
|
||||||
|
}
|
||||||
|
|
||||||
res.json(status);
|
res.json(status);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
@@ -108,6 +146,16 @@ export function createVoiceRoutes(voiceController: VoiceController): Router {
|
|||||||
logger.info("Disconnecting from voice channel");
|
logger.info("Disconnecting from voice channel");
|
||||||
|
|
||||||
const status = await voiceController.disconnect();
|
const status = await voiceController.disconnect();
|
||||||
|
|
||||||
|
// Update UI state and broadcast to connected clients
|
||||||
|
if (patchSharedUIState && broadcaster) {
|
||||||
|
const updatedState = patchSharedUIState({
|
||||||
|
selectedGuild: "",
|
||||||
|
selectedVoiceChannel: "",
|
||||||
|
});
|
||||||
|
broadcaster.uiState(updatedState);
|
||||||
|
}
|
||||||
|
|
||||||
res.json(status);
|
res.json(status);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
|
|||||||
@@ -182,7 +182,14 @@ export async function startWebserver(
|
|||||||
"/api",
|
"/api",
|
||||||
createUIStateRoutes({ getSharedUIState, patchSharedUIState }),
|
createUIStateRoutes({ getSharedUIState, patchSharedUIState }),
|
||||||
);
|
);
|
||||||
app.use("/api", createVoiceRoutes(voiceController));
|
app.use(
|
||||||
|
"/api",
|
||||||
|
createVoiceRoutes({
|
||||||
|
voiceController,
|
||||||
|
patchSharedUIState,
|
||||||
|
broadcaster,
|
||||||
|
}),
|
||||||
|
);
|
||||||
app.use("/api", createMessageRoutes());
|
app.use("/api", createMessageRoutes());
|
||||||
app.use("/api", createAnalysisRoutes());
|
app.use("/api", createAnalysisRoutes());
|
||||||
app.use("/api", createSyncRoutes(_client));
|
app.use("/api", createSyncRoutes(_client));
|
||||||
@@ -197,7 +204,7 @@ export async function startWebserver(
|
|||||||
const header = Buffer.alloc(4);
|
const header = Buffer.alloc(4);
|
||||||
header.writeInt32LE(hash, 0);
|
header.writeInt32LE(hash, 0);
|
||||||
const packet = Buffer.concat([header, chunk]);
|
const packet = Buffer.concat([header, chunk]);
|
||||||
for (const client of broadcaster.getClients?.() || []) {
|
for (const client of broadcaster.getClients()) {
|
||||||
if (client.readyState === 1) client.send(packet);
|
if (client.readyState === 1) client.send(packet);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user