diff --git a/public/locales/en-GB/app.json b/public/locales/en-GB/app.json
index 809f5e4a..fe52c85f 100644
--- a/public/locales/en-GB/app.json
+++ b/public/locales/en-GB/app.json
@@ -16,13 +16,12 @@
"<0>Why not finish by setting up a password to keep your account?0><1>You'll be able to keep your name and set an avatar for use on future calls1>": "<0>Why not finish by setting up a password to keep your account?0><1>You'll be able to keep your name and set an avatar for use on future calls1>",
"Accept camera/microphone permissions to join the call.": "Accept camera/microphone permissions to join the call.",
"Accept microphone permissions to join the call.": "Accept microphone permissions to join the call.",
- "Advanced": "Advanced",
- "Allow analytics": "Allow analytics",
"Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log.": "Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log.",
"Audio": "Audio",
"Avatar": "Avatar",
"By clicking \"Go\", you agree to our <2>Terms and conditions2>": "By clicking \"Go\", you agree to our <2>Terms and conditions2>",
"By clicking \"Join call now\", you agree to our <2>Terms and conditions2>": "By clicking \"Join call now\", you agree to our <2>Terms and conditions2>",
+ "By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our ": "By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our ",
"Call link copied": "Call link copied",
"Call type menu": "Call type menu",
"Camera": "Camera",
@@ -41,10 +40,12 @@
"Description (optional)": "Description (optional)",
"Details": "Details",
"Developer": "Developer",
+ "Developer Settings": "Developer Settings",
"Display name": "Display name",
"Download debug logs": "Download debug logs",
"Element Call Home": "Element Call Home",
"Exit full screen": "Exit full screen",
+ "Expose developer settings in the settings window.": "Expose developer settings in the settings window.",
"Fetching group call timed out.": "Fetching group call timed out.",
"Freedom": "Freedom",
"Full screen": "Full screen",
@@ -84,6 +85,7 @@
"Press and hold spacebar to talk over {{name}}": "Press and hold spacebar to talk over {{name}}",
"Press and hold to talk": "Press and hold to talk",
"Press and hold to talk over {{name}}": "Press and hold to talk over {{name}}",
+ "Privacy Policy": "Privacy Policy",
"Profile": "Profile",
"Recaptcha dismissed": "Recaptcha dismissed",
"Recaptcha not loaded": "Recaptcha not loaded",
@@ -120,7 +122,6 @@
"This feature is only supported on Firefox.": "This feature is only supported on Firefox.",
"This site is protected by ReCAPTCHA and the Google <2>Privacy Policy2> and <6>Terms of Service6> apply.<9>9>By clicking \"Register\", you agree to our <12>Terms and conditions12>": "This site is protected by ReCAPTCHA and the Google <2>Privacy Policy2> and <6>Terms of Service6> apply.<9>9>By clicking \"Register\", you agree to our <12>Terms and conditions12>",
"This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)": "This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)",
- "This will send anonymised data (such as the duration of a call and the number of participants) to the Element Call team to help us optimise the application based on how it is used.": "This will send anonymised data (such as the duration of a call and the number of participants) to the Element Call team to help us optimise the application based on how it is used.",
"Turn off camera": "Turn off camera",
"Turn on camera": "Turn on camera",
"Unmute microphone": "Unmute microphone",
diff --git a/src/ClientContext.tsx b/src/ClientContext.tsx
index fa83f5d9..46dfe5a5 100644
--- a/src/ClientContext.tsx
+++ b/src/ClientContext.tsx
@@ -36,7 +36,10 @@ import {
fallbackICEServerAllowed,
} from "./matrix-utils";
import { widget } from "./widget";
-import { PosthogAnalytics, RegistrationType } from "./PosthogAnalytics";
+import {
+ PosthogAnalytics,
+ RegistrationType,
+} from "./analytics/PosthogAnalytics";
import { translatedError } from "./TranslatedError";
import { useEventTarget } from "./useEvents";
import { Config } from "./config/Config";
diff --git a/src/analytics/AnalyticsOptInDescription.tsx b/src/analytics/AnalyticsOptInDescription.tsx
new file mode 100644
index 00000000..46727f5f
--- /dev/null
+++ b/src/analytics/AnalyticsOptInDescription.tsx
@@ -0,0 +1,20 @@
+import { t } from "i18next";
+import React from "react";
+
+import { Link } from "../typography/Typography";
+
+export const optInDescription: () => JSX.Element = () => {
+ return (
+ <>
+ <>
+ {t(
+ "By ticking this box you consent to the collection of anonymous data, which we use to improve your experience. You can find more information about which data we track in our "
+ )}
+ >
+
+ <>{t("Privacy Policy")}>
+
+ .
+ >
+ );
+};
diff --git a/src/PosthogAnalytics.ts b/src/analytics/PosthogAnalytics.ts
similarity index 98%
rename from src/PosthogAnalytics.ts
rename to src/analytics/PosthogAnalytics.ts
index 4e91a6d6..e2e8fdae 100644
--- a/src/PosthogAnalytics.ts
+++ b/src/analytics/PosthogAnalytics.ts
@@ -19,8 +19,8 @@ import { logger } from "matrix-js-sdk/src/logger";
import { MatrixClient } from "matrix-js-sdk";
import { Buffer } from "buffer";
-import { widget } from "./widget";
-import { getSetting, setSetting, settingsBus } from "./settings/useSetting";
+import { widget } from "../widget";
+import { getSetting, setSetting, settingsBus } from "../settings/useSetting";
import {
CallEndedTracker,
CallStartedTracker,
@@ -30,8 +30,8 @@ import {
MuteMicrophoneTracker,
UndecryptableToDeviceEventTracker,
} from "./PosthogEvents";
-import { Config } from "./config/Config";
-import { getUrlParams } from "./UrlParams";
+import { Config } from "../config/Config";
+import { getUrlParams } from "../UrlParams";
/* Posthog analytics tracking.
*
diff --git a/src/PosthogEvents.ts b/src/analytics/PosthogEvents.ts
similarity index 100%
rename from src/PosthogEvents.ts
rename to src/analytics/PosthogEvents.ts
diff --git a/src/auth/LoginPage.tsx b/src/auth/LoginPage.tsx
index 88296db4..20f6e00b 100644
--- a/src/auth/LoginPage.tsx
+++ b/src/auth/LoginPage.tsx
@@ -25,7 +25,7 @@ import { Button } from "../button";
import styles from "./LoginPage.module.css";
import { useInteractiveLogin } from "./useInteractiveLogin";
import { usePageTitle } from "../usePageTitle";
-import { PosthogAnalytics } from "../PosthogAnalytics";
+import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
import { Config } from "../config/Config";
export const LoginPage: FC = () => {
diff --git a/src/auth/RegisterPage.tsx b/src/auth/RegisterPage.tsx
index f5025b88..0464266e 100644
--- a/src/auth/RegisterPage.tsx
+++ b/src/auth/RegisterPage.tsx
@@ -38,7 +38,7 @@ import { LoadingView } from "../FullScreenView";
import { useRecaptcha } from "./useRecaptcha";
import { Caption, Link } from "../typography/Typography";
import { usePageTitle } from "../usePageTitle";
-import { PosthogAnalytics } from "../PosthogAnalytics";
+import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
import { Config } from "../config/Config";
export const RegisterPage: FC = () => {
diff --git a/src/home/RegisteredView.tsx b/src/home/RegisteredView.tsx
index b08f22a6..a6278c2e 100644
--- a/src/home/RegisteredView.tsx
+++ b/src/home/RegisteredView.tsx
@@ -42,6 +42,8 @@ import { JoinExistingCallModal } from "./JoinExistingCallModal";
import { Title } from "../typography/Typography";
import { Form } from "../form/Form";
import { CallType, CallTypeDropdown } from "./CallTypeDropdown";
+import { useOptInAnalytics } from "../settings/useSetting";
+import { optInDescription } from "../analytics/AnalyticsOptInDescription";
interface Props {
client: MatrixClient;
@@ -52,6 +54,7 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) {
const [callType, setCallType] = useState(CallType.Video);
const [loading, setLoading] = useState(false);
const [error, setError] = useState();
+ const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics();
const history = useHistory();
const { t } = useTranslation();
const { modalState, modalProps } = useModalTriggerState();
@@ -141,6 +144,15 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) {
{loading ? t("Loading…") : t("Go")}
+ ) =>
+ setOptInAnalytics(event.target.checked)
+ }
+ />
{error && (
diff --git a/src/home/UnauthenticatedView.tsx b/src/home/UnauthenticatedView.tsx
index 826468b2..6339e42d 100644
--- a/src/home/UnauthenticatedView.tsx
+++ b/src/home/UnauthenticatedView.tsx
@@ -39,12 +39,15 @@ import { CallType, CallTypeDropdown } from "./CallTypeDropdown";
import styles from "./UnauthenticatedView.module.css";
import commonStyles from "./common.module.css";
import { generateRandomName } from "../auth/generateRandomName";
+import { useOptInAnalytics } from "../settings/useSetting";
+import { optInDescription } from "../analytics/AnalyticsOptInDescription";
export const UnauthenticatedView: FC = () => {
const { setClient } = useClient();
const [callType, setCallType] = useState(CallType.Video);
const [loading, setLoading] = useState(false);
const [error, setError] = useState();
+ const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics();
const [privacyPolicyUrl, recaptchaKey, register] =
useInteractiveRegistration();
const { execute, reset, recaptchaId } = useRecaptcha(recaptchaKey);
@@ -152,6 +155,15 @@ export const UnauthenticatedView: FC = () => {
autoComplete="off"
/>
+ ) =>
+ setOptInAnalytics(event.target.checked)
+ }
+ />
By clicking "Go", you agree to our{" "}
diff --git a/src/input/Input.module.css b/src/input/Input.module.css
index 60b69936..2420cc43 100644
--- a/src/input/Input.module.css
+++ b/src/input/Input.module.css
@@ -209,3 +209,7 @@ limitations under the License.
margin-left: 26px;
width: 100%; /* Ensure that it breaks onto the next row */
}
+
+.description.noLabel {
+ margin-top: -20px; /* Ensures that there is no weired spacing if the checkbox doesn't have a label */
+}
diff --git a/src/input/Input.tsx b/src/input/Input.tsx
index bfc17d74..afecd6ae 100644
--- a/src/input/Input.tsx
+++ b/src/input/Input.tsx
@@ -55,14 +55,14 @@ export function Field({ children, className }: FieldProps): JSX.Element {
}
interface InputFieldProps {
- label: string;
+ label?: string;
type: string;
prefix?: string;
suffix?: string;
id?: string;
checked?: boolean;
className?: string;
- description?: string;
+ description?: string | ReactNode;
disabled?: boolean;
required?: boolean;
// this is a hack. Those variables should be part of `HTMLAttributes | HTMLAttributes`
@@ -140,7 +140,14 @@ export const InputField = forwardRef<
{suffix && {suffix}}
{description && (
-
+
{description}
)}
diff --git a/src/room/GroupCallInspector.tsx b/src/room/GroupCallInspector.tsx
index 73b2a000..648a0a1f 100644
--- a/src/room/GroupCallInspector.tsx
+++ b/src/room/GroupCallInspector.tsx
@@ -35,7 +35,7 @@ import { CallEvent } from "matrix-js-sdk/src/webrtc/call";
import styles from "./GroupCallInspector.module.css";
import { SelectInput } from "../input/SelectInput";
-import { PosthogAnalytics } from "../PosthogAnalytics";
+import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
interface InspectorContextState {
eventsByUserId?: { [userId: string]: SequenceDiagramMatrixEvent[] };
diff --git a/src/room/GroupCallView.tsx b/src/room/GroupCallView.tsx
index 8867ed4d..7af31d63 100644
--- a/src/room/GroupCallView.tsx
+++ b/src/room/GroupCallView.tsx
@@ -32,7 +32,7 @@ import { CallEndedView } from "./CallEndedView";
import { useRoomAvatar } from "./useRoomAvatar";
import { useSentryGroupCallHandler } from "./useSentryGroupCallHandler";
import { useLocationNavigation } from "../useLocationNavigation";
-import { PosthogAnalytics } from "../PosthogAnalytics";
+import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
import { useMediaHandler } from "../settings/useMediaHandler";
import { findDeviceByName, getDevices } from "../media-utils";
diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx
index 17a0fde4..48b1cbf1 100644
--- a/src/room/InCallView.tsx
+++ b/src/room/InCallView.tsx
@@ -63,7 +63,7 @@ import {
import { useModalTriggerState } from "../Modal";
import { useAudioContext } from "../video-grid/useMediaStream";
import { useFullscreen } from "../video-grid/useFullscreen";
-import { PosthogAnalytics } from "../PosthogAnalytics";
+import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
import { widget, ElementWidgetActions } from "../widget";
import { useJoinRule } from "./useJoinRule";
import { useUrlParams } from "../UrlParams";
diff --git a/src/room/useGroupCall.ts b/src/room/useGroupCall.ts
index 9d509872..37484b43 100644
--- a/src/room/useGroupCall.ts
+++ b/src/room/useGroupCall.ts
@@ -29,7 +29,7 @@ import { useTranslation } from "react-i18next";
import { IWidgetApiRequest } from "matrix-widget-api";
import { usePageUnload } from "./usePageUnload";
-import { PosthogAnalytics } from "../PosthogAnalytics";
+import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
import { TranslatedError, translatedError } from "../TranslatedError";
import { ElementWidgetActions, ScreenshareStartData, widget } from "../widget";
diff --git a/src/settings/SettingsModal.module.css b/src/settings/SettingsModal.module.css
index 7eb39159..9b4951b4 100644
--- a/src/settings/SettingsModal.module.css
+++ b/src/settings/SettingsModal.module.css
@@ -26,3 +26,12 @@ limitations under the License.
.fieldRowText {
margin-bottom: 0;
}
+
+/*
+This style guarantees a fixed width of the tab bar in the settings window.
+The "Developer" item in the tab bar can be toggled.
+Without a defined width activating the developer tab makes the tab container jump to the right.
+*/
+.tabLabel {
+ width: 80px;
+}
diff --git a/src/settings/SettingsModal.tsx b/src/settings/SettingsModal.tsx
index 244d1d15..90a1cb5f 100644
--- a/src/settings/SettingsModal.tsx
+++ b/src/settings/SettingsModal.tsx
@@ -34,11 +34,13 @@ import {
useOptInAnalytics,
canEnableSpatialAudio,
useNewGrid,
+ useDeveloperSettingsTab,
} from "./useSetting";
import { FieldRow, InputField } from "../input/Input";
import { Button } from "../button";
import { useDownloadDebugLog } from "./submit-rageshake";
import { Body } from "../typography/Typography";
+import { optInDescription } from "../analytics/AnalyticsOptInDescription";
interface Props {
isOpen: boolean;
@@ -62,6 +64,8 @@ export const SettingsModal = (props: Props) => {
const [spatialAudio, setSpatialAudio] = useSpatialAudio();
const [showInspector, setShowInspector] = useShowInspector();
const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics();
+ const [developerSettingsTab, setDeveloperSettingsTab] =
+ useDeveloperSettingsTab();
const [keyboardShortcuts, setKeyboardShortcuts] = useKeyboardShortcuts();
const [newGrid, setNewGrid] = useNewGrid();
@@ -80,7 +84,7 @@ export const SettingsModal = (props: Props) => {
title={
<>
- {t("Audio")}
+ {t("Audio")}
>
}
>
@@ -158,24 +162,11 @@ export const SettingsModal = (props: Props) => {
title={
<>
- {t("Advanced")}
+ {t("More")}
>
}
>
-
- ) =>
- setOptInAnalytics(event.target.checked)
- }
- />
-
+