Files
cinny/src/app/hooks/useCallPolicyRevokedToast.ts
T
jaredandClaude Opus 5 34574178a9 feat(calls): toast when a room admin turns off screen sharing / camera mid-call (#223)
Re-measured the revoke on the current stack (guard fix + fork lotus.4): the
SFU drops the sharer's tracks and EC's own button, the captured tracks and our
control bar all follow within ~2-4 s — the 30 s lag is gone. What remained was
that the button simply vanished with no explanation, so a call-lifetime hook
now toasts 'Screen sharing was turned off by a room admin.' (or the camera
variant) when a track ends while the room policy forbids it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-19 01:12:25 -04:00

40 lines
1.6 KiB
TypeScript

import { useEffect, useRef } from 'react';
import { useSetAtom } from 'jotai';
import { CallEmbed, useCallControlState } from '../plugins/call';
import { useRoomCallPolicy } from './useRoomCallPolicy';
import { toastQueueAtom } from '../state/toast';
/**
* [Gitea #223] When a room admin turns Allow Screen Sharing / Allow Camera
* off mid-call, the voice-limit-guard revokes the publish permission and the
* SFU drops our track within seconds — the button just vanishes with no
* explanation. Tell the user why: a track that went away while the room policy
* forbids it was not their doing.
*/
export function useCallPolicyRevokedToast(embed: CallEmbed, joined: boolean): void {
const { screenshare, video } = useCallControlState(embed.control);
const { allowScreenshare, allowCamera } = useRoomCallPolicy(embed.room);
const setToast = useSetAtom(toastQueueAtom);
const prev = useRef({ screenshare, video });
useEffect(() => {
const was = prev.current;
prev.current = { screenshare, video };
if (!joined) return;
const notify = (body: string) =>
setToast({
id: `call-policy-${Date.now()}`,
displayName: 'Lotus Chat',
body,
roomName: embed.room.name ?? 'Voice call',
roomId: embed.roomId,
});
if (was.screenshare && !screenshare && !allowScreenshare) {
notify('Screen sharing was turned off by a room admin.');
}
if (was.video && !video && !allowCamera) {
notify('Your camera was turned off by a room admin.');
}
}, [screenshare, video, allowScreenshare, allowCamera, joined, setToast, embed]);
}