Merge branch 'fkwp/delegation_of_delayed_events' into fkwp/feature_relax_homeserver_offline

This commit is contained in:
fkwp
2026-04-22 21:11:23 +02:00
5 changed files with 264 additions and 176 deletions
+4
View File
@@ -18,3 +18,7 @@ keys:
devkey: secret devkey: secret
room: room:
auto_create: false auto_create: false
webhook:
api_key: devkey
urls:
- https://matrix-rtc.othersite.m.localhost/livekit/jwt/sfu_webhook
+4
View File
@@ -18,3 +18,7 @@ keys:
devkey: secret devkey: secret
room: room:
auto_create: false auto_create: false
webhook:
api_key: devkey
urls:
- https://matrix-rtc.m.localhost/livekit/jwt/sfu_webhook
+8
View File
@@ -62,7 +62,10 @@ services:
- 7882:7882/tcp - 7882:7882/tcp
- 50100-50200:50100-50200/udp - 50100-50200:50100-50200/udp
volumes: volumes:
- ./backend/dev_tls_m.localhost.crt:/local_cert.pem:Z
- ./backend/dev_livekit.yaml:/etc/livekit.yaml:Z - ./backend/dev_livekit.yaml:/etc/livekit.yaml:Z
environment:
- SSL_CERT_FILE=/local_cert.pem
networks: networks:
- ecbackend - ecbackend
@@ -82,7 +85,10 @@ services:
- 17882:17882/tcp - 17882:17882/tcp
- 50300-50400:50300-50400/udp - 50300-50400:50300-50400/udp
volumes: volumes:
- ./backend/dev_tls_m.localhost.crt:/local_cert.pem:Z
- ./backend/dev_livekit-othersite.yaml:/etc/livekit.yaml:Z - ./backend/dev_livekit-othersite.yaml:/etc/livekit.yaml:Z
environment:
- SSL_CERT_FILE=/local_cert.pem
networks: networks:
- ecbackend - ecbackend
@@ -164,6 +170,8 @@ services:
- "8448:8448" - "8448:8448"
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
- "auth-server:127.0.0.1"
- "auth-server-1:127.0.0.1"
depends_on: depends_on:
- synapse - synapse
networks: networks:
+71 -1
View File
@@ -6,7 +6,7 @@ Please see LICENSE in the repository root for full details.
*/ */
import { render } from "@testing-library/react"; import { render } from "@testing-library/react";
import { type FC, useRef } from "react"; import { type FC, useRef, useState } from "react";
import { expect, test, vi } from "vitest"; import { expect, test, vi } from "vitest";
import { Button } from "@vector-im/compound-web"; import { Button } from "@vector-im/compound-web";
import userEvent from "@testing-library/user-event"; import userEvent from "@testing-library/user-event";
@@ -17,6 +17,7 @@ import {
ReactionSet, ReactionSet,
ReactionsRowSize, ReactionsRowSize,
} from "./reactions"; } from "./reactions";
import { type Controls } from "./controls";
// Test Explanation: // Test Explanation:
// - The main objective is to test `useCallViewKeyboardShortcuts`. // - The main objective is to test `useCallViewKeyboardShortcuts`.
@@ -27,6 +28,7 @@ interface TestComponentProps {
onButtonClick?: () => void; onButtonClick?: () => void;
sendReaction?: () => void; sendReaction?: () => void;
toggleHandRaised?: () => void; toggleHandRaised?: () => void;
initialModalOpen?: boolean;
} }
const TestComponent: FC<TestComponentProps> = ({ const TestComponent: FC<TestComponentProps> = ({
@@ -34,7 +36,9 @@ const TestComponent: FC<TestComponentProps> = ({
onButtonClick = (): void => {}, onButtonClick = (): void => {},
sendReaction = (reaction: ReactionOption): void => {}, sendReaction = (reaction: ReactionOption): void => {},
toggleHandRaised = (): void => {}, toggleHandRaised = (): void => {},
initialModalOpen = false,
}) => { }) => {
const [modalOpen, setModalOpen] = useState(initialModalOpen);
const ref = useRef<HTMLDivElement | null>(null); const ref = useRef<HTMLDivElement | null>(null);
useCallViewKeyboardShortcuts( useCallViewKeyboardShortcuts(
ref, ref,
@@ -47,6 +51,19 @@ const TestComponent: FC<TestComponentProps> = ({
return ( return (
<div ref={ref}> <div ref={ref}>
<Button onClick={onButtonClick}>TEST</Button> <Button onClick={onButtonClick}>TEST</Button>
{modalOpen && (
<dialog
open
onKeyDown={(e) => {
if (e.key === "Escape") {
e.preventDefault();
setModalOpen(false);
}
}}
>
<button>InModalButton</button>
</dialog>
)}
</div> </div>
); );
}; };
@@ -118,6 +135,27 @@ test("raised hand can be sent via keyboard presses", async () => {
expect(toggleHandRaised).toHaveBeenCalledOnce(); expect(toggleHandRaised).toHaveBeenCalledOnce();
}); });
test("raised hand cannot be sent via keyboard presses if modal open and focussed", async () => {
const user = userEvent.setup();
const toggleHandRaised = vi.fn();
const { getByRole } = render(
<TestComponent
toggleHandRaised={toggleHandRaised}
initialModalOpen={true}
/>,
);
getByRole("button", { name: "InModalButton" }).focus();
await user.keyboard("h");
expect(toggleHandRaised).not.toHaveBeenCalledOnce();
// once we press esc...
await user.keyboard("[Escape]");
// we can toggle the hand raise...
await user.keyboard("h");
expect(toggleHandRaised).toHaveBeenCalledOnce();
});
test("unmuting happens in place of the default action", async () => { test("unmuting happens in place of the default action", async () => {
const user = userEvent.setup(); const user = userEvent.setup();
const defaultPrevented = vi.fn(); const defaultPrevented = vi.fn();
@@ -138,3 +176,35 @@ test("unmuting happens in place of the default action", async () => {
await user.keyboard("[Space]"); await user.keyboard("[Space]");
expect(defaultPrevented).toBeCalledWith(true); expect(defaultPrevented).toBeCalledWith(true);
}); });
test("escape button triggers the controls back action", async () => {
const user = userEvent.setup();
window.controls = { onBackButtonPressed: vi.fn() } as unknown as Controls;
// In the real application, we mostly just want the spacebar shortcut to avoid
// scrolling the page. But to test that here in JSDOM, we need some kind of
// container element that can be interactive and receive focus / keydown
// events. <video> is kind of a weird choice, but it'll do the job.
render(<TestComponent setAudioEnabled={() => {}} />);
await user.keyboard("[Escape]");
expect(window.controls.onBackButtonPressed).toHaveBeenCalled();
});
test("escape button does not trigger back if sth else is focused", async () => {
const user = userEvent.setup();
window.controls = { onBackButtonPressed: vi.fn() } as unknown as Controls;
const { getByRole } = render(<TestComponent initialModalOpen={true} />);
getByRole("button", { name: "InModalButton" }).focus();
// First Escape: the dialog's onKeyDown intercepts it and closes the modal.
await user.keyboard("[Escape]");
expect(window.controls.onBackButtonPressed).not.toHaveBeenCalled();
// Second Escape: modal is gone, focus has fallen back to document.body,
// which *does* contain the ref div, so the hook fires and back IS triggered.
await user.keyboard("[Escape]");
expect(window.controls.onBackButtonPressed).toHaveBeenCalled();
});
+2
View File
@@ -68,6 +68,8 @@ export function useCallViewKeyboardShortcuts(
} else if (KeyToReactionMap[event.key]) { } else if (KeyToReactionMap[event.key]) {
event.preventDefault(); event.preventDefault();
sendReaction(KeyToReactionMap[event.key]); sendReaction(KeyToReactionMap[event.key]);
} else if (event.key === "Escape") {
window.controls.onBackButtonPressed?.();
} }
}, },
[ [