Testing speaking UI
This commit is contained in:
@@ -4,7 +4,7 @@ import App from "@/types/app";
|
||||
import React from "react";
|
||||
import PluginChannel from "./PluginChannel";
|
||||
import { IndicatorContext } from "@/types/protocol";
|
||||
import VoiceBox from "./VoiceBox";
|
||||
import VoiceBox from "./voice/VoiceBox";
|
||||
import { sendVoice } from "@/lib/audio";
|
||||
|
||||
export default function ChannelView({
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ClientMessage, IndicatorContext } from "@/types/protocol";
|
||||
import { Message } from "@/types/types";
|
||||
import { useEffect, useState } from "react";
|
||||
import { startMic } from "@/lib/audio";
|
||||
import { Button } from "../ui/button";
|
||||
import { Button } from "../../ui/button";
|
||||
import {
|
||||
ChevronLeftIcon,
|
||||
Phone,
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
PhoneOff,
|
||||
Volume2Icon,
|
||||
} from "lucide-react";
|
||||
import VoiceGrid from "./VoiceGrid";
|
||||
|
||||
export default function VoiceBox({
|
||||
sendVoice,
|
||||
@@ -53,7 +54,14 @@ export default function VoiceBox({
|
||||
</span>
|
||||
</header>
|
||||
)}
|
||||
<div className="h-full overflow-y-scroll"></div>
|
||||
<VoiceGrid
|
||||
users={[
|
||||
{ id: "1", name: "Klesty", speaking: true },
|
||||
{ id: "2", name: "Alex", speaking: false },
|
||||
{ id: "3", name: "Mia", speaking: true },
|
||||
{ id: "4", name: "John", speaking: false },
|
||||
]}
|
||||
/>
|
||||
<footer className="mt-auto h-max w-max mx-auto">
|
||||
{voiceConn ? (
|
||||
<Button
|
||||
@@ -0,0 +1,21 @@
|
||||
import { VoiceTile, VoiceUser } from "./VoiceTile";
|
||||
|
||||
export default function VoiceGrid({ users }: { users: VoiceUser[] }) {
|
||||
return (
|
||||
<div className="h-full overflow-y-auto p-4">
|
||||
<div
|
||||
className="
|
||||
grid gap-4
|
||||
grid-cols-1
|
||||
sm:grid-cols-2
|
||||
md:grid-cols-3
|
||||
lg:grid-cols-4
|
||||
"
|
||||
>
|
||||
{users.map((user) => (
|
||||
<VoiceTile key={user.id} user={user} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
export type VoiceUser = {
|
||||
id: string;
|
||||
name: string;
|
||||
speaking: boolean;
|
||||
muted?: boolean;
|
||||
};
|
||||
|
||||
export function VoiceTile({ user }: { user: VoiceUser }) {
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
relative flex flex-col items-center justify-center
|
||||
aspect-square rounded-xl
|
||||
bg-muted/40
|
||||
transition-all
|
||||
${
|
||||
user.speaking
|
||||
? "ring-4 ring-green-500 animate-pulse"
|
||||
: "ring-1 ring-border"
|
||||
}
|
||||
${user.muted ? "opacity-50" : ""}
|
||||
`}
|
||||
>
|
||||
{/* Avatar */}
|
||||
<div
|
||||
className={`
|
||||
h-20 w-20 rounded-full
|
||||
flex items-center justify-center
|
||||
text-2xl font-semibold
|
||||
bg-background
|
||||
`}
|
||||
>
|
||||
{user.name[0].toUpperCase()}
|
||||
</div>
|
||||
|
||||
{/* Name */}
|
||||
<div className="mt-3 text-sm font-medium">{user.name}</div>
|
||||
|
||||
{/* Speaking indicator */}
|
||||
{user.speaking && (
|
||||
<div className="absolute bottom-3 text-xs text-green-400">Speaking</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user