Improving the structure

This commit is contained in:
2026-01-06 18:37:51 +01:00
parent f6ce39a40b
commit acb62df859
4 changed files with 53 additions and 24 deletions
+2 -12
View File
@@ -1,10 +1,9 @@
"use client"; "use client";
import { ScrollArea } from "../ui/scroll-area"; import { ScrollArea } from "../ui/scroll-area";
import { Server, Channel } from "@/types/types"; import { Channel } from "@/types/types";
import { Card } from "../ui/card"; import { Card } from "../ui/card";
import { HashIcon, PhoneOff, Volume2Icon } from "lucide-react"; import { HashIcon, Volume2Icon } from "lucide-react";
import App from "@/types/app"; import App from "@/types/app";
import { Button } from "../ui/button";
export function ChannelIcon({ kind }: { kind: "text" | "voice" }) { export function ChannelIcon({ kind }: { kind: "text" | "voice" }) {
switch (kind) { switch (kind) {
@@ -50,15 +49,6 @@ export default function SidebarChannels({ app }: { app: App }) {
))} ))}
</div> </div>
</ScrollArea> </ScrollArea>
<footer className="mt-auto mx-3 mb-2 h-10">
<Button
variant="ghost"
className="text-destructive hover:bg-destructive/20 hover:text-destructive"
>
<PhoneOff />
</Button>
</footer>
</div> </div>
); );
} }
+1 -1
View File
@@ -54,7 +54,7 @@ export default function ChannelView({
}} }}
sendVoice={(data) => { sendVoice={(data) => {
while (!serverRef.current || serverRef.current?.CONNECTING) {} while (!serverRef.current || serverRef.current?.CONNECTING) {}
sendVoice(serverRef.current, 0, data); sendVoice(serverRef.current, data);
}} }}
indicators={indicators.filter( indicators={indicators.filter(
(indicator) => (indicator) =>
+48 -3
View File
@@ -5,27 +5,72 @@ import { ClientMessage, IndicatorContext } from "@/types/protocol";
import { Message } from "@/types/types"; import { Message } from "@/types/types";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { startMic } from "@/lib/audio"; import { startMic } from "@/lib/audio";
import { Button } from "../ui/button";
import {
ChevronLeftIcon,
PhoneCall,
PhoneOff,
Volume2Icon,
} from "lucide-react";
export default function VoiceBox({ export default function VoiceBox({
sendVoice, sendVoice,
app,
channelName,
}: { }: {
app: App; app: App;
sendRequest: (req: ClientMessage) => void; sendRequest: (req: ClientMessage) => void;
channelName?: string; channelName?: string;
channelIcon?: string;
messages: Message[]; messages: Message[];
indicators: IndicatorContext[]; indicators: IndicatorContext[];
sendVoice: (data: Int16Array) => void; sendVoice: (data: Int16Array) => void;
}) { }) {
const [voiceConn, setVoiceConn] = useState(false);
useEffect(() => { useEffect(() => {
if (!voiceConn) return;
const stop = startMic(sendVoice); const stop = startMic(sendVoice);
return () => { return () => {
stop.then((s) => s()); stop.then((s) => s());
}; };
}, []); }, [voiceConn]);
return ( return (
<div className="h-svh w-full max-h-svh flex flex-col pb-5 pl-5 gap-5" /> <div className="h-svh w-full max-h-svh flex flex-col pb-5 pl-5 pr-5 gap-5">
{channelName && (
<header className="h-12 py-4 flex items-center border-b text-sm font-semibold w-full">
<span
onClick={() => app.setSidebarOpen(true)}
className="cursor-pointer flex gap-2"
>
<ChevronLeftIcon className="w-5 h-5 my-auto md:hidden" />
<Volume2Icon className="w-4 h-4 my-auto" />
{channelName}
</span>
</header>
)}
{voiceConn ? (
<div className="h-full w-full">
<footer className="mt-auto h-max">
<Button
variant="ghost"
className="text-destructive hover:bg-destructive/20 hover:text-destructive"
onClick={() => setVoiceConn(false)}
>
<PhoneOff />
</Button>
</footer>
</div>
) : (
<Button
className="w-max mx-auto my-auto h-max bg-transparent text-chart-2 border border-chart-2 hover:bg-chart-2/20"
onClick={() => setVoiceConn(true)}
>
Join <PhoneCall />
</Button>
)}
</div>
); );
} }
+2 -8
View File
@@ -62,14 +62,8 @@ function float32ToPCM16(float32: Float32Array): Int16Array {
return pcm16; return pcm16;
} }
export function sendVoice(ws: WebSocket, voiceId: number, pcm: Int16Array) { export function sendVoice(ws: WebSocket, pcm: Int16Array) {
const buffer = new ArrayBuffer(2 + pcm.byteLength); ws.send(new Uint8Array(pcm.buffer, pcm.byteOffset, pcm.byteLength));
const view = new DataView(buffer);
view.setUint16(0, voiceId, true); // little endian
new Uint8Array(buffer, 2).set(new Uint8Array(pcm.buffer));
ws.send(buffer);
} }
let ctx: AudioContext | null = null; let ctx: AudioContext | null = null;