CI / Build & Quality Checks (pull_request) Successful in 3m3s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 11s
CI / Playwright smoke (e2e) (pull_request) Successful in 16m14s
When a room admin turned off Allow Screen Sharing, the sharer got two toasts: the correct "turned off by a room admin" and the fork's "ended" notice, "the shared window was closed", which was wrong. Skip the ended notice while the room policy forbids sharing. Fixes #297 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
64 lines
2.4 KiB
TypeScript
64 lines
2.4 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
import { useSetAtom } from 'jotai';
|
|
import { Icons } from 'folds';
|
|
import { CallEmbed } from '../plugins/call';
|
|
import { toastQueueAtom } from '../state/toast';
|
|
import { useRoomCallPolicy } from './useRoomCallPolicy';
|
|
|
|
export type ScreenshareNoticeKind = 'ended' | 'no-frames' | 'alone';
|
|
|
|
export const describeScreenshareNotice = (kind: ScreenshareNoticeKind): string | undefined => {
|
|
switch (kind) {
|
|
case 'ended':
|
|
return 'Screen sharing stopped — the shared window was closed.';
|
|
case 'no-frames':
|
|
return 'Your screen share is showing nothing — the shared window may be minimised or hidden.';
|
|
case 'alone':
|
|
return "Still sharing? You've been sharing your screen for 30 minutes with nobody else in the call.";
|
|
default:
|
|
return undefined;
|
|
}
|
|
};
|
|
|
|
/** Pure: a policy-forced stop is explained by its own toast (#297). */
|
|
export const shouldShowScreenshareNotice = (
|
|
kind: ScreenshareNoticeKind,
|
|
allowScreenshare: boolean,
|
|
): boolean => !(kind === 'ended' && !allowScreenshare);
|
|
|
|
/**
|
|
* [Gitea EC#39] Toast the fork's io.lotus.screenshare_notice: shared window
|
|
* closed, no frames for a while, or a long share with nobody watching.
|
|
*/
|
|
export function useScreenshareNotices(embed: CallEmbed): void {
|
|
const setToast = useSetAtom(toastQueueAtom);
|
|
// [Gitea #297] When a room admin turns screen sharing off, the share ends
|
|
// and the fork reports `ended` ("the shared window was closed"), which is
|
|
// wrong; useCallPolicyRevokedToast already says what happened.
|
|
const { allowScreenshare } = useRoomCallPolicy(embed.room);
|
|
const allowRef = useRef(allowScreenshare);
|
|
allowRef.current = allowScreenshare;
|
|
useEffect(
|
|
() =>
|
|
embed.listenAction<{ data?: { kind?: ScreenshareNoticeKind } }>(
|
|
'io.lotus.screenshare_notice',
|
|
(evt) => {
|
|
const kind = evt.detail?.data?.kind as ScreenshareNoticeKind;
|
|
if (!shouldShowScreenshareNotice(kind, allowRef.current)) return;
|
|
const body = describeScreenshareNotice(kind);
|
|
if (!body) return;
|
|
setToast({
|
|
id: `screenshare-${evt.detail?.data?.kind}-${Date.now()}`,
|
|
iconSrc: Icons.ScreenShare,
|
|
displayName: 'Screen share',
|
|
body,
|
|
roomName: embed.room.name ?? 'Voice call',
|
|
roomId: embed.roomId,
|
|
sticky: evt.detail?.data?.kind === 'alone',
|
|
});
|
|
},
|
|
),
|
|
[embed, setToast],
|
|
);
|
|
}
|