Where the host can't delegate the user's click (Firefox, Safari, WebKitGTK), lotus.20 showed EC's own screenshare button floating in the frame's corner, apart from the host's call bar. Now the host keeps its bar button and sends the new toWidget io.lotus.prompt_screenshare; the fork shows a small "Share your screen?" card inside the frame, just above the bar, and its Share button starts the share with the frame's own click. Same two clicks as the host's confirm on Chromium. - The card focuses Share; Cancel and Escape close it; it closes if a share starts some other way or the room's call policy stops allowing sharing, and never opens where the policy forbids it (set_frame_screenshare). - Picture-in-picture (~158 px tall): compact card without the description. - controls_state: frameScreenshare is now always false (the corner button is gone), screensharePrompt says the host should use the prompt, and screensharePromptOpen lets the host stop covering the frame meanwhile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
61 lines
2.3 KiB
TypeScript
61 lines
2.3 KiB
TypeScript
/*
|
|
Copyright 2026 Lotus Guild
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
import { describe, expect, test } from "vitest";
|
|
|
|
import { LOTUS_TO_WIDGET_ACTIONS, LotusWidgetActions } from "./lotusActions";
|
|
|
|
describe("LotusWidgetActions", () => {
|
|
test("every action value is namespaced under io.lotus.*", () => {
|
|
for (const value of Object.values(LotusWidgetActions)) {
|
|
expect(value).toMatch(/^io\.lotus\./);
|
|
}
|
|
});
|
|
|
|
test("LOTUS_TO_WIDGET_ACTIONS contains exactly the toWidget actions", () => {
|
|
// CallState is the only fromWidget action (host <- widget); everything
|
|
// else is toWidget (host -> widget) and must be allow-listed so
|
|
// `initializeWidget` accepts it.
|
|
const expectedToWidget = [
|
|
LotusWidgetActions.FocusParticipant,
|
|
LotusWidgetActions.InjectAudio,
|
|
LotusWidgetActions.SetQuality,
|
|
LotusWidgetActions.Decorations,
|
|
LotusWidgetActions.SetDeafen,
|
|
LotusWidgetActions.SetAudioOutput,
|
|
LotusWidgetActions.SetLayout,
|
|
LotusWidgetActions.OpenSettings,
|
|
LotusWidgetActions.ToggleReactions,
|
|
LotusWidgetActions.SetScreenshare,
|
|
LotusWidgetActions.SetHotkeys,
|
|
LotusWidgetActions.SetFrameScreenshare,
|
|
LotusWidgetActions.PromptScreenshare,
|
|
];
|
|
|
|
expect(new Set(LOTUS_TO_WIDGET_ACTIONS)).toEqual(new Set(expectedToWidget));
|
|
expect(LOTUS_TO_WIDGET_ACTIONS).toHaveLength(expectedToWidget.length);
|
|
});
|
|
|
|
test("LOTUS_TO_WIDGET_ACTIONS excludes the fromWidget actions", () => {
|
|
// CallState, RequestState and DenoiseState are all fromWidget (widget ->
|
|
// host) per their doc comments in lotusActions.ts, so none of them should
|
|
// ever be allow-listed as a toWidget action.
|
|
expect(LOTUS_TO_WIDGET_ACTIONS).not.toContain(LotusWidgetActions.CallState);
|
|
expect(LOTUS_TO_WIDGET_ACTIONS).not.toContain(
|
|
LotusWidgetActions.RequestState,
|
|
);
|
|
expect(LOTUS_TO_WIDGET_ACTIONS).not.toContain(
|
|
LotusWidgetActions.DenoiseState,
|
|
);
|
|
expect(LOTUS_TO_WIDGET_ACTIONS).not.toContain(
|
|
LotusWidgetActions.ControlsState,
|
|
);
|
|
expect(LOTUS_TO_WIDGET_ACTIONS).not.toContain(LotusWidgetActions.MicLevel);
|
|
expect(LOTUS_TO_WIDGET_ACTIONS).not.toContain(LotusWidgetActions.Hotkey);
|
|
});
|
|
});
|