simple huddle implementation with streams

This commit is contained in:
talksik
2026-04-01 08:50:56 -07:00
parent 0c340199e3
commit daa77c4e27
12 changed files with 252 additions and 65 deletions
@@ -1,5 +1,6 @@
import { Video, Mic, Paperclip } from "lucide-react";
import { useMediaSettingsStore } from "@/stores/media-settings-store";
import { PropsWithChildren } from "react";
interface ControlsIndicatorProps {
type: "reply" | "new";
@@ -12,7 +13,8 @@ export default function ControlsIndicator({
attachmentCount = 0,
showEscape = false,
onOpenAttachments,
}: ControlsIndicatorProps) {
children
}: PropsWithChildren<ControlsIndicatorProps>) {
const recordingMode = useMediaSettingsStore((s) => s.recordingMode);
const setRecordingMode = useMediaSettingsStore((s) => s.setRecordingMode);
@@ -82,6 +84,7 @@ export default function ControlsIndicator({
{attachmentCount} {attachmentCount === 1 ? "attachment" : "attachments"}
</button>
)}
{children}
</div>
);
}
+26 -6
View File
@@ -1,6 +1,7 @@
import { useState, useEffect, useEffectEvent, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { useAuthStore } from "@/stores/auth-store";
import { apiClient } from "@/api/client";
import type { Particle } from "@/api/types";
import { parseParticlePath, type ParticlePath } from "@/lib/particle-path";
import { ComposeOverlay } from "@/features/compose/compose-overlay";
@@ -170,12 +171,20 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
e.preventDefault();
navigate(`/${networkId}`);
break;
case "h": {
e.preventDefault();
const roomId = streamParticle.id;
apiClient.getLivekitToken(roomId).then(({ token, server_url }) => {
window.electronWindow.openHuddle({ token, serverUrl: server_url });
});
break;
}
}
}
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
},
[composeActive, next, prev, navigate, networkId],
[composeActive, next, prev, navigate, networkId, streamParticle.id],
);
// Click-to-navigate: left 30% = prev, right 70% = next
@@ -204,7 +213,14 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
<p className="text-muted-foreground text-sm">
No particles in this stream yet
</p>
<ControlsIndicator type="reply" showEscape={true} />
<ControlsIndicator type="reply" showEscape={true}>
<span>
<kbd className="rounded bg-white/10 px-1.5 py-0.5 font-mono text-xs">
H
</kbd>{" "}
huddle
</span>
</ControlsIndicator>
<ComposeOverlay
networkId={networkId}
targetPath={path}
@@ -299,10 +315,14 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
{/* Bottom-center: controls */}
<div className="absolute inset-x-0 bottom-0 z-10 flex justify-center pb-3">
<ControlsIndicator
showEscape={true}
type="reply"
/>
<ControlsIndicator type="reply" showEscape={true}>
<span>
<kbd className="rounded bg-white/10 px-1.5 py-0.5 font-mono text-xs">
H
</kbd>{" "}
huddle
</span>
</ControlsIndicator>
</div>
</div>
);