feat: connect WS events to mascot expression triggers
Add MascotExpressionSync component to dashboard layout that listens for message_created (flagged/warn triggers surprise expression) and voice_active_user (triggers listening expression) events. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1c6f98117a
commit
94f8903b24
@@ -1,16 +1,15 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||||
import { Suspense } from "react";
|
import { Suspense, useEffect, useState } from "react";
|
||||||
import { TopNav } from "@/components/layout/top-nav";
|
import { TopNav } from "@/components/layout/top-nav";
|
||||||
import { MobileNav } from "@/components/layout/mobile-nav";
|
import { MobileNav } from "@/components/layout/mobile-nav";
|
||||||
import { WsProvider } from "@/lib/ws/context";
|
import { WsProvider, useWebSocket } from "@/lib/ws/context";
|
||||||
import { MascotProvider } from "@/components/mascot/mascot-context";
|
import { MascotProvider, useMascot } from "@/components/mascot/mascot-context";
|
||||||
import { MascotContainer } from "@/components/mascot/mascot-container";
|
import { MascotContainer } from "@/components/mascot/mascot-container";
|
||||||
import { MiniPlayer } from "@/components/media/mini-player";
|
import { MiniPlayer } from "@/components/media/mini-player";
|
||||||
import { MediaPlayerProvider } from "@/lib/hooks/use-media-player";
|
import { MediaPlayerProvider } from "@/lib/hooks/use-media-player";
|
||||||
import { HiddenSidebar } from "@/components/layout/hidden-sidebar";
|
import { HiddenSidebar } from "@/components/layout/hidden-sidebar";
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
@@ -22,6 +21,31 @@ const queryClient = new QueryClient({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function MascotExpressionSync() {
|
||||||
|
const ws = useWebSocket();
|
||||||
|
const { setExpression } = useMascot();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const unsub1 = ws.on("message_created", (data: any) => {
|
||||||
|
if (data.ai_status === "flagged" || data.ai_status === "warn") {
|
||||||
|
setExpression("surprise");
|
||||||
|
setTimeout(() => setExpression("idle"), 2000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const unsub2 = ws.on("voice_active_user", () => {
|
||||||
|
setExpression("listening");
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
unsub1();
|
||||||
|
unsub2();
|
||||||
|
};
|
||||||
|
}, [ws, setExpression]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
export default function DashboardLayout({
|
export default function DashboardLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
@@ -34,6 +58,7 @@ export default function DashboardLayout({
|
|||||||
<WsProvider>
|
<WsProvider>
|
||||||
<MediaPlayerProvider>
|
<MediaPlayerProvider>
|
||||||
<MascotProvider>
|
<MascotProvider>
|
||||||
|
<MascotExpressionSync />
|
||||||
<div className="min-h-screen bg-canvas">
|
<div className="min-h-screen bg-canvas">
|
||||||
<TopNav />
|
<TopNav />
|
||||||
<HiddenSidebar guildId={guildId} onGuildChange={(g) => setGuildId(g ?? "")} />
|
<HiddenSidebar guildId={guildId} onGuildChange={(g) => setGuildId(g ?? "")} />
|
||||||
|
|||||||
Reference in New Issue
Block a user