39 lines
1.5 KiB
TypeScript
39 lines
1.5 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';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* P5-43 — expose the active call to the Windows System Media Transport Controls
|
||
|
|
* (the volume-flyout / media overlay). Mirrors the call-embed atom (undefined =
|
||
|
|
* no active call) and the current mic state onto the native
|
||
|
|
* `set_smtc_call_state` command, and translates SMTC button presses back into
|
||
|
|
* call actions:
|
||
|
|
* - Play/Pause (`smtc-action` → `mute`) toggles the microphone.
|
||
|
|
* - Stop (`smtc-action` → `end`) hangs up the call.
|
||
|
|
* No-op in the browser (the native command and events only fire under Tauri).
|
||
|
|
*/
|
||
|
|
type SmtcAction = { action: 'mute' | 'end' };
|
||
|
|
|
||
|
|
export function useTauriSmtc(): void {
|
||
|
|
const callEmbed = useAtomValue(callEmbedAtom);
|
||
|
|
// `microphone` reflects mic-enabled; muted is its inverse while in a call.
|
||
|
|
const { microphone } = useCallControlState(callEmbed?.control);
|
||
|
|
const active = callEmbed !== undefined;
|
||
|
|
const muted = active && !microphone;
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
invokeTauri('set_smtc_call_state', { active, muted });
|
||
|
|
}, [active, muted]);
|
||
|
|
|
||
|
|
useTauriEvent<SmtcAction>('smtc-action', ({ action }) => {
|
||
|
|
if (!callEmbed) return;
|
||
|
|
if (action === 'mute') {
|
||
|
|
callEmbed.control.toggleMicrophone().catch(() => undefined);
|
||
|
|
} else if (action === 'end') {
|
||
|
|
callEmbed.hangup().catch(() => undefined);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|