44 lines
1.8 KiB
TypeScript
44 lines
1.8 KiB
TypeScript
|
|
import { useEffect } from 'react';
|
||
|
|
import { useAtomValue } from 'jotai';
|
||
|
|
import { callEmbedAtom } from '../state/callEmbed';
|
||
|
|
import { useCallControlState } from '../plugins/call';
|
||
|
|
import { invokeTauri, useTauriEvent } from './useTauri';
|
||
|
|
|
||
|
|
type ThumbbarAction = { action: 'mute' | 'deafen' | 'end' };
|
||
|
|
|
||
|
|
/**
|
||
|
|
* P5-44 — Taskbar thumbnail toolbar (call controls). While a call is active,
|
||
|
|
* mirrors the mic/sound state onto the native `set_thumbbar` command (three
|
||
|
|
* Mute / Deafen / End-Call buttons on the Windows taskbar thumbnail toolbar) and
|
||
|
|
* hides them when the call ends. Thumb-button clicks come back as the
|
||
|
|
* `thumbbar-action` event and drive the real call controls. No-op in the browser.
|
||
|
|
*/
|
||
|
|
export function useTauriThumbbar(): void {
|
||
|
|
const callEmbed = useAtomValue(callEmbedAtom);
|
||
|
|
const { microphone, sound } = useCallControlState(callEmbed?.control);
|
||
|
|
|
||
|
|
const active = callEmbed !== undefined;
|
||
|
|
// Muted / deafened only make sense while a call is active; report false
|
||
|
|
// otherwise so the buttons render in a sane (hidden) state.
|
||
|
|
const muted = active && !microphone;
|
||
|
|
const deafened = active && !sound;
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
invokeTauri('set_thumbbar', { active, muted, deafened });
|
||
|
|
}, [active, muted, deafened]);
|
||
|
|
|
||
|
|
useTauriEvent<ThumbbarAction>('thumbbar-action', ({ action }) => {
|
||
|
|
if (!callEmbed) return;
|
||
|
|
if (action === 'mute') {
|
||
|
|
// toggleMicrophone flips the mic; `microphone === false` means muted.
|
||
|
|
callEmbed.control.toggleMicrophone();
|
||
|
|
} else if (action === 'deafen') {
|
||
|
|
// toggleSound flips local audio; `sound === false` means deafened. It also
|
||
|
|
// mutes the mic while deafened, matching the in-app Deafen control.
|
||
|
|
callEmbed.control.toggleSound();
|
||
|
|
} else if (action === 'end') {
|
||
|
|
callEmbed.hangup();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|