Files
element-call/src/lotus/lotusActions.test.ts
T
Lotus CIandClaude Opus 5.5 bb675fa50e
CI / Build embedded bundle (pull_request) Successful in 3m25s
CI / Publish to Gitea npm registry (pull_request) Skipped
feat(lotus): in-frame "Share your screen?" prompt replaces the corner button (cinny #43)
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
2026-09-27 12:48:12 -04:00

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);
});
});