From de276b1fc33eca2a321ce6050c676bda5514552c Mon Sep 17 00:00:00 2001 From: Robin Date: Fri, 13 Dec 2024 15:22:44 -0500 Subject: [PATCH] Annotate the default device with a label --- locales/en/app.json | 1 + src/livekit/MediaDevicesContext.tsx | 7 ++- src/settings/DeviceSelection.module.css | 4 ++ src/settings/DeviceSelection.tsx | 75 +++++++++++++++++-------- 4 files changed, 62 insertions(+), 25 deletions(-) diff --git a/locales/en/app.json b/locales/en/app.json index 8e963ec1..a47e5beb 100644 --- a/locales/en/app.json +++ b/locales/en/app.json @@ -155,6 +155,7 @@ "camera": "Camera", "camera_numbered": "Camera {{n}}", "default": "Default", + "default_named": "Default <2>({{name}})", "microphone": "Microphone", "microphone_numbered": "Microphone {{n}}", "speaker": "Speaker", diff --git a/src/livekit/MediaDevicesContext.tsx b/src/livekit/MediaDevicesContext.tsx index 513e6b2f..82b06bb0 100644 --- a/src/livekit/MediaDevicesContext.tsx +++ b/src/livekit/MediaDevicesContext.tsx @@ -31,7 +31,7 @@ import { export type DeviceLabel = | { type: "name"; name: string } | { type: "number"; number: number } - | { type: "default" }; + | { type: "default"; name: string | null }; export interface MediaDevice { /** @@ -104,7 +104,10 @@ function useMediaDevice( !available.has("") && !available.has("default") ) - available = new Map([["", { type: "default" }], ...available]); + available = new Map([ + ["", { type: "default", name: availableRaw[0]?.label || null }], + ...available, + ]); // Note: creating virtual default input devices would be another problem // entirely, because requesting a media stream from deviceId "" won't // automatically track the default device. diff --git a/src/settings/DeviceSelection.module.css b/src/settings/DeviceSelection.module.css index daa4510e..6686702f 100644 --- a/src/settings/DeviceSelection.module.css +++ b/src/settings/DeviceSelection.module.css @@ -16,3 +16,7 @@ flex-direction: column; gap: var(--cpd-space-4x); } + +.secondary { + color: var(--cpd-color-text-secondary); +} diff --git a/src/settings/DeviceSelection.tsx b/src/settings/DeviceSelection.tsx index 9faa1e82..aebe0aac 100644 --- a/src/settings/DeviceSelection.tsx +++ b/src/settings/DeviceSelection.tsx @@ -5,7 +5,14 @@ SPDX-License-Identifier: AGPL-3.0-only Please see LICENSE in the repository root for full details. */ -import { type ChangeEvent, type FC, useCallback, useId } from "react"; +import { + type ChangeEvent, + type FC, + type ReactElement, + type ReactNode, + useCallback, + useId, +} from "react"; import { Heading, InlineField, @@ -13,7 +20,7 @@ import { RadioControl, Separator, } from "@vector-im/compound-web"; -import { useTranslation } from "react-i18next"; +import { Trans, useTranslation } from "react-i18next"; import { type MediaDevice } from "../livekit/MediaDevicesContext"; import styles from "./DeviceSelection.module.css"; @@ -53,27 +60,49 @@ export const DeviceSelection: FC = ({
- {[...devices.available].map(([id, label]) => ( - - } - > - - - ))} + {[...devices.available].map(([id, label]) => { + let labelText: ReactNode; + switch (label.type) { + case "name": + labelText = label.name; + break; + case "number": + labelText = numberedLabel(label.number); + break; + case "default": + labelText = + label.name === null ? ( + t("settings.devices.default") + ) : ( + + Default{" "} + + ({{ name: label.name } as unknown as ReactElement}) + + + ); + break; + } + + return ( + + } + > + + + ); + })}
);