diff --git a/src/app/app.ts b/src/app/app.ts
index 5ca3c46..a5abb25 100644
--- a/src/app/app.ts
+++ b/src/app/app.ts
@@ -170,6 +170,8 @@ export default class Enclave
{
if (!server || channel.kind !== "voice") return;
+ if (server.voiceChannelId) this.leaveVoice();
+
server.voiceJoin = (pin, channelId) => {
invoke("connect_to_vc", {
hostname: server.hostname,
@@ -177,14 +179,12 @@ export default class Enclave
{
sharedSecret: server.websocket?.sharedSecret,
})
.then(() => {
- server.isInVoiceChat = true;
server.voiceChannelId = channelId;
this.forceRender();
})
.catch(console.error);
};
- server.isInVoiceChat = true;
server.voiceChannelId = channel.id;
server.websocket?.send({ method: "JoinVoice", channel_id: channel.id });
@@ -195,12 +195,11 @@ export default class Enclave
{
public leaveVoice() {
const server = this.server;
- if (!server || !server.isInVoiceChat) return;
+ if (!server || !server.voiceChannelId) return;
server.websocket?.send({ method: "LeaveVoice" });
invoke("disconnect_from_vc").catch(console.error);
- server.isInVoiceChat = false;
server.voiceChannelId = undefined;
server.voiceChatSpeakers = {};
diff --git a/src/app/server.ts b/src/app/server.ts
index ca67ec3..4b27b4c 100644
--- a/src/app/server.ts
+++ b/src/app/server.ts
@@ -37,7 +37,6 @@ export default class EnclaveServer {
public voiceJoin?: (pin: bigint, channelId: string) => void;
public voiceChatUsers: Record;
public voiceChatSpeakers: Record;
- public isInVoiceChat: boolean;
public voiceChannelId?: string;
public constructor(hostname: string, isSecure: boolean) {
@@ -47,7 +46,6 @@ export default class EnclaveServer {
this.users = {};
this.voiceChatUsers = {};
this.voiceChatSpeakers = {};
- this.isInVoiceChat = false;
}
public disconnect() {
diff --git a/src/app/ws.ts b/src/app/ws.ts
index f3f2f9c..5e3e3b0 100644
--- a/src/app/ws.ts
+++ b/src/app/ws.ts
@@ -17,7 +17,6 @@ export default class EnclaveWebSocket {
onOpenQueue: Array<() => void>;
private sendCounter = 0n;
- private recvCounter = 0n;
public sharedSecret: Uint8Array | null = null;
private readonly handshakeReady: Promise;
@@ -78,14 +77,6 @@ export default class EnclaveWebSocket {
return nonce;
}
- private nextRecvNonce(): Uint8Array {
- const nonce = new Uint8Array(12);
- const view = new DataView(nonce.buffer);
- view.setBigUint64(0, this.recvCounter, false);
- this.recvCounter += 1n;
- return nonce;
- }
-
private encrypt(plaintext: Uint8Array): Uint8Array {
if (!this.sharedSecret) throw new Error("Handshake not complete");
diff --git a/src/components/page/channel/VoiceChannel.tsx b/src/components/page/channel/VoiceChannel.tsx
index 2fe0fc1..9ff1d54 100644
--- a/src/components/page/channel/VoiceChannel.tsx
+++ b/src/components/page/channel/VoiceChannel.tsx
@@ -1,8 +1,9 @@
import Enclave from "@/app/app";
import { ChannelPageProps } from "../PageView";
-import { useEffect } from "react";
import { cn } from "@/lib/utils";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
+import { Button } from "@/components/ui/button";
+import { Phone, Volume2 } from "lucide-react";
export default function VoiceChannel({
appRef,
@@ -11,23 +12,15 @@ export default function VoiceChannel({
}) {
const channel = appRef.current?.page?.channel;
- useEffect(() => {
- if (!channel || channel.kind !== "voice") return;
-
- const server = appRef.current?.server;
-
- if (!server || server.voiceChannelId === channel.id) return;
-
- appRef.current?.joinVoice(channel);
- }, [channel?.id]);
-
if (!channel) return null;
- const speakers =
- appRef.current?.server?.voiceChatSpeakers &&
- Object.keys(appRef.current?.server?.voiceChatSpeakers);
+ const server = appRef.current?.server;
+ const isConnected = server?.voiceChannelId === channel.id;
- const users = appRef.current?.server?.voiceChatUsers[channel.id];
+ const speakers =
+ server?.voiceChatSpeakers && Object.keys(server.voiceChatSpeakers);
+
+ const users = server?.voiceChatUsers[channel.id];
const usersLength = users?.length || 0;
// Dynamic grid column layout based on user count
@@ -45,63 +38,104 @@ export default function VoiceChannel({
return "h-14 w-14 text-lg";
};
+ const handleJoinVoice = () => {
+ appRef.current?.joinVoice(channel);
+ };
+
return (
-