Improved vc ui and possibly fixed #41
This commit is contained in:
@@ -66,6 +66,8 @@ export default function AppLayout({
|
|||||||
[undefined, undefined]
|
[undefined, undefined]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => app.setSidebarOpen(!isMobile), [isMobile]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-svh md:h-screen">
|
<div className="flex h-svh md:h-screen">
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -392,9 +392,9 @@ export default function MessageBox({
|
|||||||
)}
|
)}
|
||||||
<div className="mt-auto flex flex-col-reverse overflow-y-scroll">
|
<div className="mt-auto flex flex-col-reverse overflow-y-scroll">
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{messages.toReversed().map((msg) => (
|
{messages.toReversed().map((msg, i) => (
|
||||||
<motion.div
|
<motion.div
|
||||||
key={msg.id}
|
key={i}
|
||||||
initial={{ opacity: 0, scale: 0.95 }}
|
initial={{ opacity: 0, scale: 0.95 }}
|
||||||
animate={{ opacity: 1, scale: 1 }}
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
exit={{
|
exit={{
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export default function VoiceBox({
|
|||||||
if (!app.profile) return;
|
if (!app.profile) return;
|
||||||
|
|
||||||
const stop = startMic((data) => {
|
const stop = startMic((data) => {
|
||||||
if (rms(data) > 0.02) {
|
if (rms(data) > 0.005) {
|
||||||
sendVoice(data);
|
sendVoice(data);
|
||||||
|
|
||||||
if (!app.profile) return;
|
if (!app.profile) return;
|
||||||
@@ -54,14 +54,14 @@ export default function VoiceBox({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const inv = setInterval(() => {
|
const inv = setInterval(() => {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const TIMEOUT = 500;
|
const TIMEOUT = 800;
|
||||||
|
|
||||||
app.setSpeaking((prev) =>
|
app.setSpeaking((prev) =>
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
Object.entries(prev).filter(([_, ts]) => now - ts < TIMEOUT)
|
Object.entries(prev).filter(([_, ts]) => now - ts < TIMEOUT)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}, 250);
|
}, 200);
|
||||||
|
|
||||||
return () => clearInterval(inv);
|
return () => clearInterval(inv);
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import App from "@/types/app";
|
import App from "@/types/app";
|
||||||
import { VoiceTile, VoiceUser } from "./VoiceTile";
|
import { VoiceTile, VoiceUser } from "./VoiceTile";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
export default function VoiceGrid({
|
export default function VoiceGrid({
|
||||||
app,
|
app,
|
||||||
@@ -11,13 +12,12 @@ export default function VoiceGrid({
|
|||||||
return (
|
return (
|
||||||
<div className="h-full overflow-y-auto p-4">
|
<div className="h-full overflow-y-auto p-4">
|
||||||
<div
|
<div
|
||||||
className="
|
className={cn(
|
||||||
grid gap-4
|
"grid gap-4 grid-cols-1",
|
||||||
grid-cols-1
|
app.sidebarOpen
|
||||||
sm:grid-cols-2
|
? "min-[930px]:grid-cols-2 min-[1200px]:grid-cols-3 min-[1600px]:grid-cols-4"
|
||||||
md:grid-cols-3
|
: "min-[560px]:grid-cols-2 min-[1200px]:grid-cols-3 min-[1600px]:grid-cols-4"
|
||||||
lg:grid-cols-4
|
)}
|
||||||
"
|
|
||||||
>
|
>
|
||||||
{users.map((user) => (
|
{users.map((user) => (
|
||||||
<VoiceTile key={user.id} user={user} app={app} />
|
<VoiceTile key={user.id} user={user} app={app} />
|
||||||
|
|||||||
@@ -12,13 +12,11 @@ export function VoiceTile({ user, app }: { app: App; user: VoiceUser }) {
|
|||||||
<div
|
<div
|
||||||
className={`
|
className={`
|
||||||
relative flex flex-col items-center justify-center
|
relative flex flex-col items-center justify-center
|
||||||
aspect-square rounded-xl
|
aspect-[16/9] rounded-xl
|
||||||
bg-muted/40
|
bg-muted/40
|
||||||
transition-all
|
transition-all
|
||||||
${
|
${
|
||||||
user.speaking
|
user.speaking ? "border-4 border-green-500" : "border-1 border-border"
|
||||||
? "ring-4 ring-green-500 animate-pulse"
|
|
||||||
: "ring-1 ring-border"
|
|
||||||
}
|
}
|
||||||
${user.muted ? "opacity-50" : ""}
|
${user.muted ? "opacity-50" : ""}
|
||||||
`}
|
`}
|
||||||
@@ -40,11 +38,6 @@ export function VoiceTile({ user, app }: { app: App; user: VoiceUser }) {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Speaking indicator */}
|
|
||||||
{user.speaking && (
|
|
||||||
<div className="absolute bottom-3 text-xs text-green-400">Speaking</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ export async function startMic(onAudio: (data: Int16Array) => void) {
|
|||||||
chunk.set(buffer.splice(0, buffer.length));
|
chunk.set(buffer.splice(0, buffer.length));
|
||||||
}
|
}
|
||||||
onAudio(chunk);
|
onAudio(chunk);
|
||||||
}, 500);
|
}, 800);
|
||||||
|
|
||||||
// Return cleanup function
|
// Return cleanup function
|
||||||
return () => {
|
return () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user