Merge remote-tracking branch 'upstream/livekit' into SimonBrandner/feat/e2ee

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Šimon Brandner
2023-07-25 16:00:12 +02:00
54 changed files with 1117 additions and 864 deletions

View File

@@ -77,7 +77,7 @@ export function ProfileSettingsTab({ client }: Props) {
return (
<form onChange={onFormChange} ref={formRef} className={styles.content}>
<FieldRow className={styles.avatarFieldRow}>
{avatarUrl && displayName && (
{displayName && (
<AvatarInputField
id="avatar"
name="avatar"

View File

@@ -0,0 +1,21 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.rageshakeControl {
height: 50px;
text-align: center;
vertical-align: middle;
}

View File

@@ -0,0 +1,67 @@
/*
Copyright 2023 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { useTranslation } from "react-i18next";
import { useCallback } from "react";
import { Button } from "../button";
import { Config } from "../config/Config";
import styles from "./RageshakeButton.module.css";
import { useSubmitRageshake } from "./submit-rageshake";
interface Props {
description: string;
}
export const RageshakeButton = ({ description }: Props) => {
const { submitRageshake, sending, sent, error } = useSubmitRageshake();
const { t } = useTranslation();
const sendDebugLogs = useCallback(() => {
submitRageshake({
description,
sendLogs: true,
});
}, [submitRageshake, description]);
if (!Config.get().rageshake?.submit_url) return null;
let logsComponent: JSX.Element | null = null;
if (sending) {
logsComponent = <span>{t("Sending…")}</span>;
} else if (sent) {
logsComponent = <div>{t("Thanks!")}</div>;
} else {
let caption = t("Send debug logs");
if (error) {
caption = t("Retry sending logs");
}
logsComponent = (
<Button
size="lg"
variant="default"
onPress={sendDebugLogs}
className={styles.wideButton}
disabled={sending}
>
{caption}
</Button>
);
}
return <div className={styles.rageshakeControl}>{logsComponent}</div>;
};

View File

@@ -120,7 +120,7 @@ export const SettingsModal = (props: Props) => {
const devices = props.mediaDevicesSwitcher;
const tabs = [
const audioTab = (
<TabItem
key="audio"
title={
@@ -132,7 +132,10 @@ export const SettingsModal = (props: Props) => {
>
{devices && generateDeviceSelection(devices.audioIn, t("Microphone"))}
{devices && generateDeviceSelection(devices.audioOut, t("Speaker"))}
</TabItem>,
</TabItem>
);
const videoTab = (
<TabItem
key="video"
title={
@@ -143,7 +146,24 @@ export const SettingsModal = (props: Props) => {
}
>
{devices && generateDeviceSelection(devices.videoIn, t("Camera"))}
</TabItem>,
</TabItem>
);
const profileTab = (
<TabItem
key="profile"
title={
<>
<UserIcon width={15} height={15} />
<span>{t("Profile")}</span>
</>
}
>
<ProfileSettingsTab client={props.client} />
</TabItem>
);
const feedbackTab = (
<TabItem
key="feedback"
title={
@@ -154,7 +174,10 @@ export const SettingsModal = (props: Props) => {
}
>
<FeedbackSettingsTab roomId={props.roomId} />
</TabItem>,
</TabItem>
);
const moreTab = (
<TabItem
key="more"
title={
@@ -190,85 +213,73 @@ export const SettingsModal = (props: Props) => {
}}
/>
</FieldRow>
</TabItem>,
];
</TabItem>
);
if (!isEmbedded) {
tabs.push(
<TabItem
key="profile"
title={
<>
<UserIcon width={15} height={15} />
<span>{t("Profile")}</span>
</>
}
>
<ProfileSettingsTab client={props.client} />
</TabItem>
);
}
const developerTab = (
<TabItem
key="developer"
title={
<>
<DeveloperIcon width={16} height={16} />
<span>{t("Developer")}</span>
</>
}
>
<FieldRow>
<Body className={styles.fieldRowText}>
{t("Version: {{version}}", {
version: import.meta.env.VITE_APP_VERSION || "dev",
})}
</Body>
</FieldRow>
<FieldRow>
<InputField
id="showInspector"
name="inspector"
label={t("Show call inspector")}
type="checkbox"
checked={showInspector}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setShowInspector(e.target.checked)
}
/>
</FieldRow>
<FieldRow>
<InputField
id="showConnectionStats"
name="connection-stats"
label={t("Show connection stats")}
type="checkbox"
checked={showConnectionStats}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setShowConnectionStats(e.target.checked)
}
/>
</FieldRow>
<FieldRow>
<InputField
id="enableE2EE"
name="end-to-end-encryption"
label={t("Enable end-to-end encryption (password protected calls)")}
type="checkbox"
checked={enableE2EE}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setEnableE2EE(e.target.checked)
}
/>
</FieldRow>
<FieldRow>
<Button onPress={downloadDebugLog}>{t("Download debug logs")}</Button>
</FieldRow>
</TabItem>
);
if (developerSettingsTab) {
tabs.push(
<TabItem
key="developer"
title={
<>
<DeveloperIcon width={16} height={16} />
<span>{t("Developer")}</span>
</>
}
>
<FieldRow>
<Body className={styles.fieldRowText}>
{t("Version: {{version}}", {
version: import.meta.env.VITE_APP_VERSION || "dev",
})}
</Body>
</FieldRow>
<FieldRow>
<InputField
id="showInspector"
name="inspector"
label={t("Show call inspector")}
type="checkbox"
checked={showInspector}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setShowInspector(e.target.checked)
}
/>
</FieldRow>
<FieldRow>
<InputField
id="showConnectionStats"
name="connection-stats"
label={t("Show connection stats")}
type="checkbox"
checked={showConnectionStats}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setShowConnectionStats(e.target.checked)
}
/>
</FieldRow>
<FieldRow>
<InputField
id="enableE2EE"
name="end-to-end-encryption"
label={t("Enable end-to-end encryption (password protected calls)")}
type="checkbox"
checked={enableE2EE}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setEnableE2EE(e.target.checked)
}
/>
</FieldRow>
<FieldRow>
<Button onPress={downloadDebugLog}>{t("Download debug logs")}</Button>
</FieldRow>
</TabItem>
);
}
const tabs: JSX.Element[] = [];
if (devices) tabs.push(audioTab, videoTab);
if (!isEmbedded) tabs.push(profileTab);
tabs.push(feedbackTab, moreTab);
if (developerSettingsTab) tabs.push(developerTab);
return (
<Modal