feat: allow clicking keyboard hints throughout (#266)
* allow clicking keyboard hints * Update js/desktop/src/components/key-hint.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * nits --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit was merged in pull request #266.
This commit is contained in:
co-authored by
coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
parent
9fd7e611f3
commit
95f2362947
@@ -2,6 +2,7 @@ import { useCallback, useEffect, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { KeyHint } from '@/components/key-hint';
|
||||
import { updateParticleProperties } from '@/lib/firestore-particles';
|
||||
import { particlePath, toFirestoreDocPath } from '@/lib/particle-path';
|
||||
import type { Particle } from '@/api/types';
|
||||
@@ -63,12 +64,14 @@ export function RenameStreamOverlay({
|
||||
<div className="absolute left-1/2 top-1/2 w-full max-w-sm -translate-x-1/2 -translate-y-1/2 rounded-2xl border border-white/10 bg-white/5 p-6 shadow-2xl backdrop-blur-xl">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h2 className="text-sm font-semibold text-white/70">Rename stream</h2>
|
||||
<span className="text-xs text-white/30">
|
||||
<kbd className="rounded bg-white/10 px-1.5 py-0.5 font-mono text-xs">
|
||||
Esc
|
||||
</kbd>{' '}
|
||||
<KeyHint
|
||||
keys="Esc"
|
||||
onClick={onClose}
|
||||
title="Close (or press Esc)"
|
||||
className="text-xs text-white/30"
|
||||
>
|
||||
to close
|
||||
</span>
|
||||
</KeyHint>
|
||||
</div>
|
||||
|
||||
<Input
|
||||
|
||||
@@ -3,6 +3,7 @@ import { createPortal } from 'react-dom';
|
||||
import { X, UserPlus, Globe, Users, Lock } from 'lucide-react';
|
||||
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
|
||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||
import { KeyHint } from '@/components/key-hint';
|
||||
import {
|
||||
buildCustomVisibility,
|
||||
buildNetworkVisibility,
|
||||
@@ -104,12 +105,14 @@ export function StreamMembersOverlay({
|
||||
{/* Header */}
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h2 className="text-sm font-semibold text-white/70">Members</h2>
|
||||
<span className="text-xs text-white/30">
|
||||
<kbd className="rounded bg-white/10 px-1.5 py-0.5 font-mono text-xs">
|
||||
Esc
|
||||
</kbd>{' '}
|
||||
<KeyHint
|
||||
keys="Esc"
|
||||
onClick={onClose}
|
||||
title="Close (or press Esc)"
|
||||
className="text-xs text-white/30"
|
||||
>
|
||||
to close
|
||||
</span>
|
||||
</KeyHint>
|
||||
</div>
|
||||
|
||||
{/* Visibility */}
|
||||
|
||||
@@ -29,6 +29,7 @@ import { TextParticleView } from '@/features/particles/text-particle-view';
|
||||
import { FallbackParticleView } from '@/features/particles/fallback-particle-view';
|
||||
import { DeletedParticleView } from '@/features/particles/deleted-particle-view';
|
||||
import { VideoAudioToggle } from '@/components/video-audio-toggle';
|
||||
import { KeyHint } from '@/components/key-hint';
|
||||
import { useMediaSettingsStore } from '@/stores/media-settings-store';
|
||||
import {
|
||||
KeybindingsOverlay,
|
||||
@@ -259,12 +260,17 @@ function StreamViewInner({ path, streamParticle }: StreamViewProps) {
|
||||
|
||||
const { fastPlayback } = usePlaybackKeys({ mediaRef });
|
||||
|
||||
const handleExitNavigate = useCallback(() => {
|
||||
navigate(`/${networkId}`);
|
||||
}, [navigate, networkId]);
|
||||
|
||||
useStreamNavigationKeys({
|
||||
next,
|
||||
prev,
|
||||
currentIndex,
|
||||
childrenLength: children.length,
|
||||
mediaRef,
|
||||
onExit: handleExitNavigate,
|
||||
});
|
||||
|
||||
const handleOpenHuddle = useCallback(() => {
|
||||
@@ -325,10 +331,6 @@ function StreamViewInner({ path, streamParticle }: StreamViewProps) {
|
||||
// Always show controls when compose is active or exit countdown is visible
|
||||
const controlsVisible = showControls || composeActive || status === 'ended';
|
||||
|
||||
const handleExitNavigate = useCallback(() => {
|
||||
navigate(`/${networkId}`);
|
||||
}, [navigate, networkId]);
|
||||
|
||||
const exitRemainingMs = useExitCountdown(status, paused, handleExitNavigate);
|
||||
|
||||
// Reset progress when the particle changes.
|
||||
@@ -362,6 +364,8 @@ function StreamViewInner({ path, streamParticle }: StreamViewProps) {
|
||||
<StreamViewControls
|
||||
showEscape
|
||||
onOpenKeybindings={() => setShowKeybindings(true)}
|
||||
onOpenHuddle={handleOpenHuddle}
|
||||
onExit={handleExitNavigate}
|
||||
/>
|
||||
<ComposeOverlay
|
||||
networkId={networkId}
|
||||
@@ -505,6 +509,8 @@ function StreamViewInner({ path, streamParticle }: StreamViewProps) {
|
||||
onlineHumanIds={onlineHumanIds}
|
||||
exitRemainingMs={exitRemainingMs}
|
||||
onOpenKeybindings={() => setShowKeybindings(true)}
|
||||
onOpenHuddle={handleOpenHuddle}
|
||||
onExit={handleExitNavigate}
|
||||
/>
|
||||
|
||||
<KeybindingsOverlay
|
||||
@@ -527,6 +533,8 @@ function BottomBar({
|
||||
onlineHumanIds,
|
||||
exitRemainingMs,
|
||||
onOpenKeybindings,
|
||||
onOpenHuddle,
|
||||
onExit,
|
||||
}: {
|
||||
visible: boolean;
|
||||
total: number;
|
||||
@@ -540,6 +548,8 @@ function BottomBar({
|
||||
onlineHumanIds: Set<string>;
|
||||
exitRemainingMs: number | null;
|
||||
onOpenKeybindings: () => void;
|
||||
onOpenHuddle: () => void;
|
||||
onExit: () => void;
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
@@ -580,6 +590,8 @@ function BottomBar({
|
||||
<StreamViewControls
|
||||
showEscape
|
||||
onOpenKeybindings={onOpenKeybindings}
|
||||
onOpenHuddle={onOpenHuddle}
|
||||
onExit={onExit}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -590,58 +602,54 @@ function BottomBar({
|
||||
function StreamViewControls({
|
||||
showEscape,
|
||||
onOpenKeybindings,
|
||||
onOpenHuddle,
|
||||
onExit,
|
||||
}: {
|
||||
showEscape?: boolean;
|
||||
onOpenKeybindings: () => void;
|
||||
onOpenHuddle: () => void;
|
||||
onExit: () => void;
|
||||
}) {
|
||||
const requestIntent = useComposeIntentStore((s) => s.request);
|
||||
return (
|
||||
<div className="flex items-center gap-4 text-sm text-white/50">
|
||||
{showEscape && (
|
||||
<span>
|
||||
<kbd className="rounded bg-white/10 px-1.5 py-0.5 font-mono text-xs">
|
||||
Esc
|
||||
</kbd>{' '}
|
||||
<KeyHint
|
||||
keys="Esc"
|
||||
onClick={onExit}
|
||||
title="Back to network (or press Esc)"
|
||||
>
|
||||
back
|
||||
</span>
|
||||
</KeyHint>
|
||||
)}
|
||||
<VideoAudioToggle />
|
||||
<button
|
||||
type="button"
|
||||
<KeyHint
|
||||
keys="Hold `"
|
||||
onClick={() => requestIntent('record')}
|
||||
className="cursor-pointer rounded transition-colors hover:text-white/80"
|
||||
title="Reply with a recording (or hold `)"
|
||||
>
|
||||
<kbd className="rounded bg-white/10 px-1.5 py-0.5 font-mono text-xs">
|
||||
Hold `
|
||||
</kbd>{' '}
|
||||
to reply
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
</KeyHint>
|
||||
<KeyHint
|
||||
keys="T"
|
||||
onClick={() => requestIntent('text')}
|
||||
className="cursor-pointer rounded transition-colors hover:text-white/80"
|
||||
title="Reply with text (or press T)"
|
||||
>
|
||||
<kbd className="rounded bg-white/10 px-1.5 py-0.5 font-mono text-xs">
|
||||
T
|
||||
</kbd>{' '}
|
||||
text
|
||||
</button>
|
||||
<span>
|
||||
<kbd className="rounded bg-white/10 px-1.5 py-0.5 font-mono text-xs">
|
||||
H
|
||||
</kbd>{' '}
|
||||
huddle
|
||||
</span>
|
||||
<kbd
|
||||
role="button"
|
||||
onClick={onOpenKeybindings}
|
||||
className="cursor-pointer rounded bg-white/10 px-1.5 py-0.5 font-mono text-xs transition-colors hover:text-white/80"
|
||||
title="Show all shortcuts"
|
||||
</KeyHint>
|
||||
<KeyHint
|
||||
keys="H"
|
||||
onClick={onOpenHuddle}
|
||||
title="Start a huddle (or press H)"
|
||||
>
|
||||
?
|
||||
</kbd>
|
||||
huddle
|
||||
</KeyHint>
|
||||
<KeyHint
|
||||
keys="?"
|
||||
onClick={onOpenKeybindings}
|
||||
title="Show all shortcuts"
|
||||
aria-label="Show keyboard shortcuts"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user