2024-11-19 17:18:36 -05:00
|
|
|
/*
|
|
|
|
|
Copyright 2024 New Vector Ltd.
|
|
|
|
|
|
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
Please see LICENSE in the repository root for full details.
|
|
|
|
|
*/
|
|
|
|
|
|
2024-12-11 09:27:55 +00:00
|
|
|
import { type ChangeEvent, type FC, useCallback, useId } from "react";
|
2024-11-19 17:18:36 -05:00
|
|
|
import {
|
|
|
|
|
Heading,
|
|
|
|
|
InlineField,
|
|
|
|
|
Label,
|
|
|
|
|
RadioControl,
|
|
|
|
|
Separator,
|
|
|
|
|
} from "@vector-im/compound-web";
|
2024-11-21 14:43:30 -05:00
|
|
|
import { useTranslation } from "react-i18next";
|
2024-11-19 17:18:36 -05:00
|
|
|
|
2024-12-11 09:27:55 +00:00
|
|
|
import { type MediaDevice } from "../livekit/MediaDevicesContext";
|
2024-11-19 17:18:36 -05:00
|
|
|
import styles from "./DeviceSelection.module.css";
|
|
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
devices: MediaDevice;
|
2024-11-21 14:43:30 -05:00
|
|
|
title: string;
|
|
|
|
|
numberedLabel: (number: number) => string;
|
2024-11-19 17:18:36 -05:00
|
|
|
}
|
|
|
|
|
|
2024-11-21 14:43:30 -05:00
|
|
|
export const DeviceSelection: FC<Props> = ({
|
|
|
|
|
devices,
|
|
|
|
|
title,
|
|
|
|
|
numberedLabel,
|
|
|
|
|
}) => {
|
|
|
|
|
const { t } = useTranslation();
|
2024-11-19 17:18:36 -05:00
|
|
|
const groupId = useId();
|
|
|
|
|
const onChange = useCallback(
|
|
|
|
|
(e: ChangeEvent<HTMLInputElement>) => {
|
|
|
|
|
devices.select(e.target.value);
|
|
|
|
|
},
|
|
|
|
|
[devices],
|
|
|
|
|
);
|
|
|
|
|
|
2024-11-21 14:43:30 -05:00
|
|
|
if (devices.available.size == 0) return null;
|
2024-11-19 17:18:36 -05:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className={styles.selection}>
|
|
|
|
|
<Heading
|
|
|
|
|
type="body"
|
|
|
|
|
weight="semibold"
|
|
|
|
|
size="sm"
|
|
|
|
|
as="h4"
|
|
|
|
|
className={styles.title}
|
|
|
|
|
>
|
2024-11-21 14:43:30 -05:00
|
|
|
{title}
|
2024-11-19 17:18:36 -05:00
|
|
|
</Heading>
|
|
|
|
|
<Separator className={styles.separator} />
|
|
|
|
|
<div className={styles.options}>
|
2024-11-21 14:43:30 -05:00
|
|
|
{[...devices.available].map(([id, label]) => (
|
2024-11-19 17:18:36 -05:00
|
|
|
<InlineField
|
2024-11-21 14:43:30 -05:00
|
|
|
key={id}
|
2024-11-19 17:18:36 -05:00
|
|
|
name={groupId}
|
|
|
|
|
control={
|
|
|
|
|
<RadioControl
|
2024-11-21 14:43:30 -05:00
|
|
|
checked={id === devices.selectedId}
|
2024-11-19 17:18:36 -05:00
|
|
|
onChange={onChange}
|
2024-11-21 14:43:30 -05:00
|
|
|
value={id}
|
2024-11-19 17:18:36 -05:00
|
|
|
/>
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
<Label>
|
2024-11-21 14:43:30 -05:00
|
|
|
{label.type === "name"
|
|
|
|
|
? label.name
|
|
|
|
|
: label.type === "number"
|
|
|
|
|
? numberedLabel(label.number)
|
|
|
|
|
: t("settings.devices.default")}
|
2024-11-19 17:18:36 -05:00
|
|
|
</Label>
|
|
|
|
|
</InlineField>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|