/* Copyright 2022-2024 New Vector Ltd. 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 { useTranslation } from "react-i18next"; import { FieldRow, InputField } from "../input/Input"; import { useSetting, duplicateTiles as duplicateTilesSetting, debugTileLayout as debugTileLayoutSetting, showNonMemberTiles as showNonMemberTilesSetting, showConnectionStats as showConnectionStatsSetting, useNewMembershipManager as useNewMembershipManagerSetting, useExperimentalToDeviceTransport as useExperimentalToDeviceTransportSetting, muteAllAudio as muteAllAudioSetting, alwaysShowIphoneEarpiece as alwaysShowIphoneEarpieceSetting, } from "./settings"; import type { MatrixClient } from "matrix-js-sdk"; import type { Room as LivekitRoom } from "livekit-client"; import styles from "./DeveloperSettingsTab.module.css"; import { useUrlParams } from "../UrlParams"; interface Props { client: MatrixClient; livekitRoom?: LivekitRoom; } export const DeveloperSettingsTab: FC = ({ client, livekitRoom }) => { const { t } = useTranslation(); const [duplicateTiles, setDuplicateTiles] = useSetting(duplicateTilesSetting); const [debugTileLayout, setDebugTileLayout] = useSetting( debugTileLayoutSetting, ); const [showNonMemberTiles, setShowNonMemberTiles] = useSetting( showNonMemberTilesSetting, ); const [showConnectionStats, setShowConnectionStats] = useSetting( showConnectionStatsSetting, ); const [useNewMembershipManager, setNewMembershipManager] = useSetting( useNewMembershipManagerSetting, ); const [alwaysShowIphoneEarpiece, setAlwaysShowIphoneEarpiece] = useSetting( alwaysShowIphoneEarpieceSetting, ); const [ useExperimentalToDeviceTransport, setUseExperimentalToDeviceTransport, ] = useSetting(useExperimentalToDeviceTransportSetting); const [muteAllAudio, setMuteAllAudio] = useSetting(muteAllAudioSetting); const urlParams = useUrlParams(); const sfuUrl = useMemo((): URL | null => { if (livekitRoom?.engine.client.ws?.url) { // strip the URL params const url = new URL(livekitRoom.engine.client.ws.url); url.search = ""; return url; } return null; }, [livekitRoom]); return ( <>

{t("developer_mode.hostname", { hostname: window.location.hostname || "unknown", })}

{t("version", { productName: import.meta.env.VITE_PRODUCT_NAME || "Element Call", version: import.meta.env.VITE_APP_VERSION || "dev", })}

{t("developer_mode.crypto_version", { version: client.getCrypto()?.getVersion() || "unknown", })}

{t("developer_mode.matrix_id", { id: client.getUserId() || "unknown", })}

{t("developer_mode.device_id", { id: client.getDeviceId() || "unknown", })}

): void => { const value = event.target.valueAsNumber; if (value < 0) { return; } setDuplicateTiles(Number.isNaN(value) ? 0 : value); }, [setDuplicateTiles], )} /> ): void => setDebugTileLayout(event.target.checked) } /> ): void => { setShowNonMemberTiles(event.target.checked); }, [setShowNonMemberTiles], )} /> ): void => { setShowConnectionStats(event.target.checked); }, [setShowConnectionStats], )} /> ): void => { setNewMembershipManager(event.target.checked); }, [setNewMembershipManager], )} /> ): void => { setUseExperimentalToDeviceTransport(event.target.checked); }, [setUseExperimentalToDeviceTransport], )} /> ): void => { setMuteAllAudio(event.target.checked); }, [setMuteAllAudio], )} /> {" "} ): void => { setAlwaysShowIphoneEarpiece(event.target.checked); }, [setAlwaysShowIphoneEarpiece], )} />{" "} {livekitRoom ? ( <>

{t("developer_mode.livekit_sfu", { url: sfuUrl?.href || "unknown", })}

{t("developer_mode.livekit_server_info")}

            {livekitRoom.serverInfo
              ? JSON.stringify(livekitRoom.serverInfo, null, 2)
              : "undefined"}
            {livekitRoom.metadata}
          
) : null}

{t("developer_mode.environment_variables")}

{JSON.stringify(import.meta.env, null, 2)}

{t("developer_mode.url_params")}

{JSON.stringify(urlParams, null, 2)}
); };