From 3ffaf337014ec10fb786d3b3e6d88fcf12bf8e78 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Mon, 6 Oct 2025 09:45:12 +0100 Subject: [PATCH] Add prefer sticky setting] --- locales/en/app.json | 4 +++ src/rtcSessionHelpers.ts | 3 +- src/settings/DeveloperSettingsTab.tsx | 48 +++++++++++++++++++++++++-- src/settings/settings.ts | 5 +++ 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/locales/en/app.json b/locales/en/app.json index 704f68ac..6aa85c01 100644 --- a/locales/en/app.json +++ b/locales/en/app.json @@ -75,6 +75,10 @@ "multi_sfu": "Multi-SFU media transport", "mute_all_audio": "Mute all audio (participants, reactions, join sounds)", "show_connection_stats": "Show connection statistics", + "prefer_sticky_events": { + "label": "Prefer sticky events", + "description": "Improves reliability of calls (requires homeserver support)" + }, "url_params": "URL parameters", "use_new_membership_manager": "Use the new implementation of the call MembershipManager", "use_to_device_key_transport": "Use to device key transport. This will fallback to room key transport when another call member sent a room key" diff --git a/src/rtcSessionHelpers.ts b/src/rtcSessionHelpers.ts index 3dd7c5f8..b80c8efd 100644 --- a/src/rtcSessionHelpers.ts +++ b/src/rtcSessionHelpers.ts @@ -20,6 +20,7 @@ import { ElementWidgetActions, widget, type WidgetHelpers } from "./widget"; import { MatrixRTCTransportMissingError } from "./utils/errors"; import { getUrlParams } from "./UrlParams"; import { getSFUConfigWithOpenID } from "./livekit/openIDSFU.ts"; +import { preferStickyEvents } from "./settings/settings.ts"; const FOCI_WK_KEY = "org.matrix.msc4143.rtc_foci"; @@ -137,7 +138,7 @@ export async function enterRTCSession( membershipEventExpiryMs: matrixRtcSessionConfig?.membership_event_expiry_ms, useExperimentalToDeviceTransport, - unstableSendStickyEvents: true, + unstableSendStickyEvents: preferStickyEvents.getValue(), }, ); if (widget) { diff --git a/src/settings/DeveloperSettingsTab.tsx b/src/settings/DeveloperSettingsTab.tsx index c24eadc5..6d531e40 100644 --- a/src/settings/DeveloperSettingsTab.tsx +++ b/src/settings/DeveloperSettingsTab.tsx @@ -5,7 +5,14 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { type ChangeEvent, type FC, useCallback, useMemo } from "react"; +import { + type ChangeEvent, + type FC, + useCallback, + useEffect, + useMemo, + useState, +} from "react"; import { useTranslation } from "react-i18next"; import { FieldRow, InputField } from "../input/Input"; @@ -18,11 +25,16 @@ import { multiSfu as multiSfuSetting, muteAllAudio as muteAllAudioSetting, alwaysShowIphoneEarpiece as alwaysShowIphoneEarpieceSetting, + preferStickyEvents as preferStickyEventsSetting, } from "./settings"; -import type { MatrixClient } from "matrix-js-sdk"; +import { + UNSTABLE_MSC4354_STICKY_EVENTS, + type MatrixClient, +} from "matrix-js-sdk"; import type { Room as LivekitRoom } from "livekit-client"; import styles from "./DeveloperSettingsTab.module.css"; import { useUrlParams } from "../UrlParams"; +import { logger } from "matrix-js-sdk/lib/logger"; interface Props { client: MatrixClient; livekitRooms?: { room: LivekitRoom; url: string; isLocal?: boolean }[]; @@ -35,6 +47,22 @@ export const DeveloperSettingsTab: FC = ({ client, livekitRooms }) => { debugTileLayoutSetting, ); + const [stickyEventsSupported, setStickyEventsSupported] = useState(false); + useEffect(() => { + client + .doesServerSupportUnstableFeature(UNSTABLE_MSC4354_STICKY_EVENTS) + .then((result) => { + setStickyEventsSupported(result); + }) + .catch((ex) => { + logger.warn("Failed to check if sticky events are supported", ex); + }); + }, [client]); + + const [preferStickyEvents, setPreferStickyEvents] = useSetting( + preferStickyEventsSetting, + ); + const [showConnectionStats, setShowConnectionStats] = useSetting( showConnectionStatsSetting, ); @@ -121,6 +149,22 @@ export const DeveloperSettingsTab: FC = ({ client, livekitRooms }) => { } /> + + ): void => { + setPreferStickyEvents(event.target.checked); + }, + [setPreferStickyEvents], + )} + /> + ( false, ); +export const preferStickyEvents = new Setting( + "prefer-sticky-events", + false, +); + export const audioInput = new Setting( "audio-input", undefined,