Join on click and speaking on server channel list
This commit is contained in:
@@ -1,9 +1,8 @@
|
|||||||
import Enclave from "@/app/app";
|
import Enclave from "@/app/app";
|
||||||
import { ChannelPageProps } from "../PageView";
|
import { ChannelPageProps } from "../PageView";
|
||||||
|
import { useEffect } from "react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Phone } from "lucide-react";
|
|
||||||
|
|
||||||
export default function VoiceChannel({
|
export default function VoiceChannel({
|
||||||
appRef,
|
appRef,
|
||||||
@@ -11,11 +10,18 @@ export default function VoiceChannel({
|
|||||||
appRef: React.RefObject<Enclave<ChannelPageProps> | null>;
|
appRef: React.RefObject<Enclave<ChannelPageProps> | null>;
|
||||||
}) {
|
}) {
|
||||||
const channel = appRef.current?.page?.channel;
|
const channel = appRef.current?.page?.channel;
|
||||||
if (!channel) return null;
|
|
||||||
|
|
||||||
const isConnected =
|
useEffect(() => {
|
||||||
appRef.current?.server?.isInVoiceChat &&
|
if (!channel || channel.kind !== "voice") return;
|
||||||
appRef.current.server.voiceChannelId === channel.id;
|
|
||||||
|
const server = appRef.current?.server;
|
||||||
|
|
||||||
|
if (!server || server.voiceChannelId === channel.id) return;
|
||||||
|
|
||||||
|
appRef.current?.joinVoice(channel);
|
||||||
|
}, [channel?.id]);
|
||||||
|
|
||||||
|
if (!channel) return null;
|
||||||
|
|
||||||
const speakers =
|
const speakers =
|
||||||
appRef.current?.server?.voiceChatSpeakers &&
|
appRef.current?.server?.voiceChatSpeakers &&
|
||||||
@@ -96,20 +102,6 @@ export default function VoiceChannel({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Bottom Control Bar */}
|
|
||||||
{!isConnected && (
|
|
||||||
<footer className="flex items-center justify-center px-4 py-2 border-t border-border/40 bg-card/50 rounded-xl mx-2">
|
|
||||||
<Button
|
|
||||||
variant="default"
|
|
||||||
onClick={() => appRef.current?.joinVoice(channel)}
|
|
||||||
className="flex items-center gap-2 font-medium px-6 bg-emerald-600 hover:bg-emerald-700 text-white"
|
|
||||||
>
|
|
||||||
<Phone className="w-4 h-4" />
|
|
||||||
Join Voice
|
|
||||||
</Button>
|
|
||||||
</footer>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -68,9 +68,19 @@ export function RenderFeatures({
|
|||||||
const user = appRef.current?.server?.users[pubkey];
|
const user = appRef.current?.server?.users[pubkey];
|
||||||
if (!user) return null;
|
if (!user) return null;
|
||||||
|
|
||||||
|
const isSpeaking =
|
||||||
|
appRef.current?.server?.voiceChatSpeakers[pubkey];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={pubkey} className="flex flex-row items-center gap-2">
|
<div key={pubkey} className="flex flex-row items-center gap-2">
|
||||||
<Avatar className="h-7 w-7">
|
<Avatar
|
||||||
|
className={cn(
|
||||||
|
"h-7 w-7",
|
||||||
|
isSpeaking
|
||||||
|
? "ring-2 ring-emerald-500 shadow-[0_0_15px_rgba(16,185,129,0.25)] bg-card"
|
||||||
|
: "ring-1 ring-border/60 hover:ring-border",
|
||||||
|
)}
|
||||||
|
>
|
||||||
<AvatarImage src={user.avatar} />
|
<AvatarImage src={user.avatar} />
|
||||||
<AvatarFallback>
|
<AvatarFallback>
|
||||||
{user?.displayName.slice(0, 1).toUpperCase() ||
|
{user?.displayName.slice(0, 1).toUpperCase() ||
|
||||||
|
|||||||
@@ -99,4 +99,4 @@ export default function StatusCard({
|
|||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user