```
move "{{count, number}}_one" "participant_count_one"
move "{{count, number}}_other" "participant_count_other"
move "{{count}} stars_one" "star_rating_input_label_one"
move "{{count}} stars_other" "star_rating_input_label_other"
move "{{displayName}} is presenting" "video_tile.presenter_label"
move "{{displayName}}, your call has ended." "call_ended_view.headline"
move "<0></0><1></1>You may withdraw consent by unchecking this box. If you are currently in a call, this setting will take effect at the end of the call." "settings.opt_in_description"
move "<0>Already have an account?</0><1><0>Log in</0> Or <2>Access as a guest</2></1>" "register_auth_links"
move "<0>Create an account</0> Or <2>Access as a guest</2>" "login_auth_links"
move "<0>Oops, something's gone wrong.</0>" "full_screen_view_h1"
move "<0>Submitting debug logs will help us track down the problem.</0>" "full_screen_view_description"
move "<0>Thanks for your feedback!</0>" "call_ended_view.feedback_done"
move "<0>We'd love to hear your feedback so we can improve your experience.</0>" "call_ended_view.feedback_prompt"
move "<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 calls</1>" "call_ended_view.create_account_prompt"
move "Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log." "rageshake_request_modal.body"
move "Back to recents" "lobby.leave_button"
move "By participating in this beta, you consent to the collection of anonymous data, which we use to improve the product. You can find more information about which data we track in our <2>Privacy Policy</2> and our <5>Cookie Policy</5>." "analytics_notice"
move "Call not found" "group_call_loader_failed_heading"
move "Calls are now end-to-end encrypted and need to be created from the home page. This helps make sure everyone's using the same encryption key." "group_call_loader_failed_text"
move "Confirm password" "register_confirm_password_label"
move "Connectivity to the server has been lost." "disconnected_banner"
move "Continue in browser" "app_selection_modal.continue_in_browser"
move "Create account" "call_ended_view.create_account_button"
move "Debug log request" "rageshake_request_modal.title"
move "Developer" "settings.developer_tab_title"
move "Developer Settings" "settings.developer_settings_label"
move "Element Call Home" "header_label"
move "End call" "hangup_button_label"
move "Full screen" "fullscreen_button_label"
move "Exit full screen" "exit_fullscreen_button_label"
move "Expose developer settings in the settings window." "settings.developer_settings_label_description"
move "Feedback" "settings.feedback_tab_title"
move "Grid" "layout_grid_label"
move "Spotlight" "layout_spotlight_label"
move "How did it go?" "call_ended_view.survey_prompt"
move "If you are experiencing issues or simply would like to provide some feedback, please send us a short description below." "settings.feedback_tab_body"
move "Include debug logs" "settings.feedback_tab_send_logs_label"
move "Invite to this call" "invite_modal.title"
move "Join call" "lobby.join_button"
move "Join call now" "room_auth_view_join_button"
move "Join existing call?" "join_existing_call_modal.title"
move "Link copied to clipboard" "invite_modal.link_copied_toast"
move "Local volume" "local_volume_label"
move "Logging in…" "logging_in"
move "Login" "login_title"
move "Login to your account" "unauthenticated_view_login_button"
move "Microphone off" "microphone_off"
move "Microphone on" "microphone_on"
move "More" "settings.more_tab_title"
move "Mute microphone" "mute_microphone_button_label"
move "Name of call" "call_name"
move "Not now, return to home screen" "call_ended_view.not_now_button"
move "Open in the app" "app_selection_modal.open_in_app"
move "Not registered yet? <2>Create an account</2>" "unauthenticated_view_body"
move "Participants" "header_participants_label"
move "Passwords must match" "register.passwords_must_match"
move "Ready to join?" "app_selection_modal.text"
move "Recaptcha dismissed" "recaptcha_dismissed"
move "Recaptcha not loaded" "recaptcha_not_loaded"
move "Reconnect" "call_ended_view.reconnect_button"
move "Registering…" "register.registering"
move "Retry sending logs" "rageshake_button_error_caption"
move "Return to home screen" "return_home_button"
move "Select an option" "select_input_unset_button"
move "Select app" "app_selection_modal.title"
move "Send debug logs" "rageshake_send_logs"
move "Sending debug logs…" "rageshake_sending_logs"
move "Sending…" "rageshake_sending"
move "Share screen" "screenshare_button_label"
move "Sharing screen" "stop_screenshare_button_label"
move "Show connection stats" "settings.show_connection_stats_label"
move "Speaker" "settings.speaker_device_selection_label"
move "Start new call" "start_new_call"
move "Start video" "start_video_button_label"
move "Stop video" "stop_video_button_label"
move "Submit feedback" "settings.feedback_tab_h4"
move "Submitting…" "submitting"
move "Thanks, we received your feedback!" "settings.feedback_tab_thank_you"
move "Thanks!" "rageshake_sent"
move "This application has been opened in another tab." "application_opened_another_tab"
move "This call already exists, would you like to join?" "join_existing_call_modal.text"
move "Unmute microphone" "unmute_microphone_button_label"
move "Version: {{version}}" "version"
move "Waiting for other participants…" "waiting_for_participants"
move "Yes, join call" "join_existing_call_modal.join_button"
move "You" "video_tile.sfu_participant_local"
move "You were disconnected from the call" "call_ended_view.body"
move "Your feedback" "settings.feedback_tab_description_label"
move "Your web browser does not support media end-to-end encryption. Supported Browsers are Chrome, Safari, Firefox >=117" "browser_media_e2ee_unsupported"
move "By clicking \"Go\", you agree to our <2>End User Licensing Agreement (EULA)</2>" "unauthenticated_view_eula_caption"
move "By clicking \"Join call now\", you agree to our <2>End User Licensing Agreement (EULA)</2>" "room_auth_view_eula_caption"
move "This site is protected by ReCAPTCHA and the Google <2>Privacy Policy</2> and <6>Terms of Service</6> apply.<9></9>By clicking \"Register\", you agree to our <12>End User Licensing Agreement (EULA)</12>" "register.recaptcha_caption"
```
This commit is contained in:
@@ -257,9 +257,7 @@ export const ClientProvider: FC<Props> = ({ children }) => {
|
||||
"message",
|
||||
useCallback(() => {
|
||||
initClientState?.client.stopClient();
|
||||
setAlreadyOpenedErr(
|
||||
translatedError("This application has been opened in another tab.", t),
|
||||
);
|
||||
setAlreadyOpenedErr(translatedError("application_opened_another_tab", t));
|
||||
}, [initClientState?.client, setAlreadyOpenedErr, t]),
|
||||
);
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ export const DisconnectedBanner: FC<Props> = ({
|
||||
{shouldShowBanner && (
|
||||
<div className={classNames(styles.banner, className)} {...rest}>
|
||||
{children}
|
||||
{t("Connectivity to the server has been lost.")}
|
||||
{t("disconnected_banner")}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -85,7 +85,7 @@ export const ErrorView: FC<ErrorViewProps> = ({ error }) => {
|
||||
className={styles.homeLink}
|
||||
onPress={onReload}
|
||||
>
|
||||
{t("Return to home screen")}
|
||||
{t("return_home_button")}
|
||||
</Button>
|
||||
) : (
|
||||
<LinkButton
|
||||
@@ -94,7 +94,7 @@ export const ErrorView: FC<ErrorViewProps> = ({ error }) => {
|
||||
className={styles.homeLink}
|
||||
to="/"
|
||||
>
|
||||
{t("Return to home screen")}
|
||||
{t("return_home_button")}
|
||||
</LinkButton>
|
||||
)}
|
||||
</FullScreenView>
|
||||
@@ -110,11 +110,11 @@ export const CrashView: FC = () => {
|
||||
|
||||
return (
|
||||
<FullScreenView>
|
||||
<Trans>
|
||||
<Trans i18nKey="full_screen_view_h1">
|
||||
<h1>Oops, something's gone wrong.</h1>
|
||||
</Trans>
|
||||
{Config.get().rageshake?.submit_url && (
|
||||
<Trans>
|
||||
<Trans i18nKey="full_screen_view_description">
|
||||
<p>Submitting debug logs will help us track down the problem.</p>
|
||||
</Trans>
|
||||
)}
|
||||
@@ -126,7 +126,7 @@ export const CrashView: FC = () => {
|
||||
className={styles.wideButton}
|
||||
onPress={onReload}
|
||||
>
|
||||
{t("Return to home screen")}
|
||||
{t("return_home_button")}
|
||||
</Button>
|
||||
</FullScreenView>
|
||||
);
|
||||
|
||||
@@ -105,7 +105,7 @@ export const HeaderLogo: FC<HeaderLogoProps> = ({ className }) => {
|
||||
<Link
|
||||
className={classNames(styles.headerLogo, className)}
|
||||
to="/"
|
||||
aria-label={t("Element Call Home")}
|
||||
aria-label={t("header_label")}
|
||||
>
|
||||
<Logo />
|
||||
</Link>
|
||||
@@ -155,10 +155,10 @@ export const RoomHeaderInfo: FC<RoomHeaderInfoProps> = ({
|
||||
<UserProfileIcon
|
||||
width={20}
|
||||
height={20}
|
||||
aria-label={t("Participants")}
|
||||
aria-label={t("header_participants_label")}
|
||||
/>
|
||||
<Text as="span" size="sm" weight="medium">
|
||||
{t("{{count, number}}", { count: participantCount })}
|
||||
{t("participant_count", { count: participantCount })}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -20,7 +20,7 @@ import { Trans } from "react-i18next";
|
||||
import { Link } from "../typography/Typography";
|
||||
|
||||
export const AnalyticsNotice: FC = () => (
|
||||
<Trans>
|
||||
<Trans i18nKey="analytics_notice">
|
||||
By participating in this beta, you consent to the collection of anonymous
|
||||
data, which we use to improve the product. You can find more information
|
||||
about which data we track in our{" "}
|
||||
|
||||
@@ -30,7 +30,7 @@ import { Config } from "../config/Config";
|
||||
|
||||
export const LoginPage: FC = () => {
|
||||
const { t } = useTranslation();
|
||||
usePageTitle(t("Login"));
|
||||
usePageTitle(t("login_title"));
|
||||
|
||||
const { setClient } = useClient();
|
||||
const login = useInteractiveLogin();
|
||||
@@ -126,7 +126,7 @@ export const LoginPage: FC = () => {
|
||||
disabled={loading}
|
||||
data-testid="login_login"
|
||||
>
|
||||
{loading ? t("Logging in…") : t("Login")}
|
||||
{loading ? t("logging_in") : t("login_title")}
|
||||
</Button>
|
||||
</FieldRow>
|
||||
</form>
|
||||
@@ -134,7 +134,7 @@ export const LoginPage: FC = () => {
|
||||
<div className={styles.authLinks}>
|
||||
<p>Not registered yet?</p>
|
||||
<p>
|
||||
<Trans>
|
||||
<Trans i18nKey="login_auth_links">
|
||||
<Link to="/register">Create an account</Link>
|
||||
{" Or "}
|
||||
<Link to="/">Access as a guest</Link>
|
||||
|
||||
@@ -44,7 +44,7 @@ import { Config } from "../config/Config";
|
||||
|
||||
export const RegisterPage: FC = () => {
|
||||
const { t } = useTranslation();
|
||||
usePageTitle(("action.register"));
|
||||
usePageTitle(t("action.register"));
|
||||
|
||||
const { loading, authenticated, passwordlessUser, client, setClient } =
|
||||
useClientLegacy();
|
||||
@@ -140,7 +140,9 @@ export const RegisterPage: FC = () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (password && passwordConfirmation && password !== passwordConfirmation) {
|
||||
confirmPasswordRef.current?.setCustomValidity(t("Passwords must match"));
|
||||
confirmPasswordRef.current?.setCustomValidity(
|
||||
t("register.passwords_must_match"),
|
||||
);
|
||||
} else {
|
||||
confirmPasswordRef.current?.setCustomValidity("");
|
||||
}
|
||||
@@ -202,14 +204,14 @@ export const RegisterPage: FC = () => {
|
||||
setPasswordConfirmation(e.target.value)
|
||||
}
|
||||
value={passwordConfirmation}
|
||||
placeholder={t("Confirm password")}
|
||||
label={t("Confirm password")}
|
||||
placeholder={t("register_confirm_password_label")}
|
||||
label={t("register_confirm_password_label")}
|
||||
ref={confirmPasswordRef}
|
||||
data-testid="register_confirm_password"
|
||||
/>
|
||||
</FieldRow>
|
||||
<Caption>
|
||||
<Trans>
|
||||
<Trans i18nKey="recaptcha_caption">
|
||||
This site is protected by ReCAPTCHA and the Google{" "}
|
||||
<Link href="https://www.google.com/policies/privacy/">
|
||||
Privacy Policy
|
||||
@@ -237,14 +239,16 @@ export const RegisterPage: FC = () => {
|
||||
disabled={registering}
|
||||
data-testid="register_register"
|
||||
>
|
||||
{registering ? t("Registering…") : ("action.register")}
|
||||
{registering
|
||||
? t("register.registering")
|
||||
: t("action.register")}
|
||||
</Button>
|
||||
</FieldRow>
|
||||
<div id={recaptchaId} />
|
||||
</form>
|
||||
</div>
|
||||
<div className={styles.authLinks}>
|
||||
<Trans>
|
||||
<Trans i18nKey="register_auth_links">
|
||||
<p>Already have an account?</p>
|
||||
<p>
|
||||
<Link to="/login">Log in</Link>
|
||||
|
||||
@@ -80,14 +80,14 @@ export function useRecaptcha(sitekey?: string): {
|
||||
|
||||
if (!window.grecaptcha) {
|
||||
logger.log("Recaptcha not loaded");
|
||||
return Promise.reject(translatedError("Recaptcha not loaded", t));
|
||||
return Promise.reject(translatedError("recaptcha_not_loaded", t));
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const observer = new MutationObserver((mutationsList) => {
|
||||
for (const item of mutationsList) {
|
||||
if ((item.target as HTMLElement)?.style?.visibility !== "visible") {
|
||||
reject(translatedError("Recaptcha dismissed", t));
|
||||
reject(translatedError("recaptcha_dismissed", t));
|
||||
observer.disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ export const MicButton: FC<{
|
||||
}> = ({ muted, ...rest }) => {
|
||||
const { t } = useTranslation();
|
||||
const Icon = muted ? MicOffSolidIcon : MicOnSolidIcon;
|
||||
const label = muted ? t("Unmute microphone") : t("Mute microphone");
|
||||
const label = muted ? t("unmute_microphone_button_label") : t("mute_microphone_button_label");
|
||||
|
||||
return (
|
||||
<Tooltip label={label}>
|
||||
@@ -160,7 +160,7 @@ export const VideoButton: FC<{
|
||||
}> = ({ muted, ...rest }) => {
|
||||
const { t } = useTranslation();
|
||||
const Icon = muted ? VideoCallOffSolidIcon : VideoCallSolidIcon;
|
||||
const label = muted ? t("Start video") : t("Stop video");
|
||||
const label = muted ? t("start_video_button_label") : t("stop_video_button_label");
|
||||
|
||||
return (
|
||||
<Tooltip label={label}>
|
||||
@@ -178,7 +178,7 @@ export const ScreenshareButton: FC<{
|
||||
[index: string]: unknown;
|
||||
}> = ({ enabled, className, ...rest }) => {
|
||||
const { t } = useTranslation();
|
||||
const label = enabled ? t("Sharing screen") : t("Share screen");
|
||||
const label = enabled ? t("stop_screenshare_button_label") : t("screenshare_button_label");
|
||||
|
||||
return (
|
||||
<Tooltip label={label}>
|
||||
@@ -197,13 +197,13 @@ export const HangupButton: FC<{
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Tooltip label={t("End call")}>
|
||||
<Tooltip label={t("hangup_button_label")}>
|
||||
<Button
|
||||
variant="toolbar"
|
||||
className={classNames(styles.hangupButton, className)}
|
||||
{...rest}
|
||||
>
|
||||
<EndCallIcon aria-label={t("End call")} />
|
||||
<EndCallIcon aria-label={t("hangup_button_label")} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
@@ -236,9 +236,9 @@ export const AudioButton: FC<AudioButtonProps> = ({ volume, ...rest }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Tooltip label={t("Local volume")}>
|
||||
<Tooltip label={t("local_volume_label")}>
|
||||
<Button variant="icon" {...rest}>
|
||||
<VolumeIcon volume={volume} aria-label={t("Local volume")} />
|
||||
<VolumeIcon volume={volume} aria-label={t("local_volume_label")} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
@@ -254,7 +254,7 @@ export const FullscreenButton: FC<FullscreenButtonProps> = ({
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const Icon = fullscreen ? FullscreenExit : Fullscreen;
|
||||
const label = fullscreen ? t("Exit full screen") : t("Full screen");
|
||||
const label = fullscreen ? t("exit_fullscreen_button_label") : t("fullscreen_button_label");
|
||||
|
||||
return (
|
||||
<Tooltip label={label}>
|
||||
|
||||
@@ -37,12 +37,12 @@ export const JoinExistingCallModal: FC<Props> = ({
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Modal title={t("Join existing call?")} open={open} onDismiss={onDismiss}>
|
||||
<p>{t("This call already exists, would you like to join?")}</p>
|
||||
<Modal title={t("join_existing_call_modal.title")} open={open} onDismiss={onDismiss}>
|
||||
<p>{t("join_existing_call_modal.text")}</p>
|
||||
<FieldRow rightAlign className={styles.buttons}>
|
||||
<Button onPress={onDismiss}>{t("action.no")}</Button>
|
||||
<Button onPress={onJoin} data-testid="home_joinExistingRoom">
|
||||
{t("Yes, join call")}
|
||||
{t("join_existing_call_modal.join_button")}
|
||||
</Button>
|
||||
</FieldRow>
|
||||
</Modal>
|
||||
|
||||
@@ -125,15 +125,15 @@ export const RegisteredView: FC<Props> = ({ client }) => {
|
||||
<main className={commonStyles.main}>
|
||||
<HeaderLogo className={commonStyles.logo} />
|
||||
<Heading size="lg" weight="semibold">
|
||||
{t("Start new call")}
|
||||
{t("start_new_call")}
|
||||
</Heading>
|
||||
<Form className={styles.form} onSubmit={onSubmit}>
|
||||
<FieldRow className={styles.fieldRow}>
|
||||
<InputField
|
||||
id="callName"
|
||||
name="callName"
|
||||
label={t("Name of call")}
|
||||
placeholder={t("Name of call")}
|
||||
label={t("call_name")}
|
||||
placeholder={t("call_name")}
|
||||
type="text"
|
||||
required
|
||||
autoComplete="off"
|
||||
|
||||
@@ -158,15 +158,15 @@ export const UnauthenticatedView: FC = () => {
|
||||
<main className={commonStyles.main}>
|
||||
<HeaderLogo className={commonStyles.logo} />
|
||||
<Heading size="lg" weight="semibold">
|
||||
{t("Start new call")}
|
||||
{t("start_new_call")}
|
||||
</Heading>
|
||||
<Form className={styles.form} onSubmit={onSubmit}>
|
||||
<FieldRow>
|
||||
<InputField
|
||||
id="callName"
|
||||
name="callName"
|
||||
label={t("Name of call")}
|
||||
placeholder={t("Name of call")}
|
||||
label={t("call_name")}
|
||||
placeholder={t("call_name")}
|
||||
type="text"
|
||||
required
|
||||
autoComplete="off"
|
||||
@@ -191,7 +191,7 @@ export const UnauthenticatedView: FC = () => {
|
||||
</Caption>
|
||||
)}
|
||||
<Caption className={styles.notice}>
|
||||
<Trans>
|
||||
<Trans i18nKey="unauthenticated_view_eula_caption">
|
||||
By clicking "Go", you agree to our{" "}
|
||||
<Link href={Config.get().eula}>
|
||||
End User Licensing Agreement (EULA)
|
||||
@@ -217,11 +217,11 @@ export const UnauthenticatedView: FC = () => {
|
||||
<footer className={styles.footer}>
|
||||
<Body className={styles.mobileLoginLink}>
|
||||
<Link color="primary" to="/login" data-testid="home_login">
|
||||
{t("Login to your account")}
|
||||
{t("unauthenticated_view_login_button")}
|
||||
</Link>
|
||||
</Body>
|
||||
<Body>
|
||||
<Trans>
|
||||
<Trans i18nKey="unauthenticated_view_body">
|
||||
Not registered yet?{" "}
|
||||
<Link color="primary" to="/register" data-testid="home_register">
|
||||
Create an account
|
||||
|
||||
@@ -58,7 +58,7 @@ export function SelectInput(props: Props): JSX.Element {
|
||||
<span {...valueProps} className={styles.selectedItem}>
|
||||
{state.selectedItem
|
||||
? state.selectedItem.rendered
|
||||
: t("Select an option")}
|
||||
: t("select_input_unset_button")}
|
||||
</span>
|
||||
<ArrowDownIcon />
|
||||
</button>
|
||||
|
||||
@@ -62,7 +62,7 @@ export function StarRatingInput({
|
||||
id={"starInvisibleLabel" + String(index)}
|
||||
htmlFor={"starInput" + String(index)}
|
||||
>
|
||||
{t("{{count}} stars", {
|
||||
{t("star_rating_input_label", {
|
||||
count: index,
|
||||
})}
|
||||
</label>
|
||||
|
||||
@@ -76,15 +76,15 @@ export const AppSelectionModal: FC<Props> = ({ roomId }) => {
|
||||
}, [roomId, roomSharedKey]);
|
||||
|
||||
return (
|
||||
<Modal className={styles.modal} title={t("Select app")} open={open}>
|
||||
<Modal className={styles.modal} title={t("app_selection_modal.title")} open={open}>
|
||||
<Text size="md" weight="semibold">
|
||||
{t("Ready to join?")}
|
||||
{t("app_selection_modal.text")}
|
||||
</Text>
|
||||
<Button kind="secondary" onClick={onBrowserClick}>
|
||||
{t("Continue in browser")}
|
||||
{t("app_selection_modal.continue_in_browser")}
|
||||
</Button>
|
||||
<Button as="a" href={appUrl} Icon={PopOutIcon}>
|
||||
{t("Open in the app")}
|
||||
{t("app_selection_modal.open_in_app")}
|
||||
</Button>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@@ -88,7 +88,7 @@ export const CallEndedView: FC<Props> = ({
|
||||
|
||||
const createAccountDialog = isPasswordlessUser && (
|
||||
<div className={styles.callEndedContent}>
|
||||
<Trans>
|
||||
<Trans i18nKey="call_ended_view.create_account_prompt">
|
||||
<p>Why not finish by setting up a password to keep your account?</p>
|
||||
<p>
|
||||
You'll be able to keep your name and set an avatar for use on future
|
||||
@@ -101,14 +101,14 @@ export const CallEndedView: FC<Props> = ({
|
||||
variant="default"
|
||||
to="/register"
|
||||
>
|
||||
{t("Create account")}
|
||||
{t("call_ended_view.create_account_button")}
|
||||
</LinkButton>
|
||||
</div>
|
||||
);
|
||||
|
||||
const qualitySurveyDialog = (
|
||||
<div className={styles.callEndedContent}>
|
||||
<Trans>
|
||||
<Trans i18nKey="call_ended_view.feedback_prompt">
|
||||
<p>
|
||||
We'd love to hear your feedback so we can improve your experience.
|
||||
</p>
|
||||
@@ -122,14 +122,14 @@ export const CallEndedView: FC<Props> = ({
|
||||
className={feedbackStyle.feedback}
|
||||
id="feedbackText"
|
||||
name="feedbackText"
|
||||
label={t("Your feedback")}
|
||||
placeholder={t("Your feedback")}
|
||||
label={t("settings.feedback_tab_description_label")}
|
||||
placeholder={t("settings.feedback_tab_description_label")}
|
||||
type="textarea"
|
||||
/>
|
||||
</FieldRow>{" "}
|
||||
<FieldRow>
|
||||
{submitDone ? (
|
||||
<Trans>
|
||||
<Trans i18nKey="call_ended_view.feedback_done">
|
||||
<p>Thanks for your feedback!</p>
|
||||
</Trans>
|
||||
) : (
|
||||
@@ -140,7 +140,7 @@ export const CallEndedView: FC<Props> = ({
|
||||
variant="default"
|
||||
data-testid="home_go"
|
||||
>
|
||||
{submitting ? t("Submitting…") : ("action.submit")}
|
||||
{submitting ? t("submitting") : t("action.submit")}
|
||||
</Button>
|
||||
)}
|
||||
</FieldRow>
|
||||
@@ -154,11 +154,13 @@ export const CallEndedView: FC<Props> = ({
|
||||
<>
|
||||
<main className={styles.main}>
|
||||
<Headline className={styles.headline}>
|
||||
<Trans>You were disconnected from the call</Trans>
|
||||
<Trans i18nKey="call_ended_view.body">
|
||||
You were disconnected from the call
|
||||
</Trans>
|
||||
</Headline>
|
||||
<div className={styles.disconnectedButtons}>
|
||||
<Button size="lg" variant="default" onClick={reconnect}>
|
||||
{t("Reconnect")}
|
||||
{t("call_ended_view.reconnect_button")}
|
||||
</Button>
|
||||
<div className={styles.rageshakeButton}>
|
||||
<RageshakeButton description="***Call disconnected***" />
|
||||
@@ -168,7 +170,7 @@ export const CallEndedView: FC<Props> = ({
|
||||
{!confineToRoom && (
|
||||
<Body className={styles.footer}>
|
||||
<Link color="primary" to="/">
|
||||
{t("Return to home screen")}
|
||||
{t("return_home_button")}
|
||||
</Link>
|
||||
</Body>
|
||||
)}
|
||||
@@ -180,14 +182,14 @@ export const CallEndedView: FC<Props> = ({
|
||||
<main className={styles.main}>
|
||||
<Headline className={styles.headline}>
|
||||
{surveySubmitted
|
||||
? t("{{displayName}}, your call has ended.", {
|
||||
? t("call_ended_view.headline", {
|
||||
displayName,
|
||||
})
|
||||
: t("{{displayName}}, your call has ended.", {
|
||||
: t("call_ended_view.headline", {
|
||||
displayName,
|
||||
}) +
|
||||
"\n" +
|
||||
t("How did it go?")}
|
||||
t("call_ended_view.survey_prompt")}
|
||||
</Headline>
|
||||
{(!surveySubmitted || confineToRoom) &&
|
||||
PosthogAnalytics.instance.isEnabled()
|
||||
@@ -197,7 +199,7 @@ export const CallEndedView: FC<Props> = ({
|
||||
{!confineToRoom && (
|
||||
<Body className={styles.footer}>
|
||||
<Link color="primary" to="/">
|
||||
{t("Not now, return to home screen")}
|
||||
{t("call_ended_view.not_now_button")}
|
||||
</Link>
|
||||
</Body>
|
||||
)}
|
||||
|
||||
@@ -63,12 +63,8 @@ export function GroupCallLoader({
|
||||
if ((groupCallState.error as MatrixError).errcode === "M_NOT_FOUND") {
|
||||
return (
|
||||
<FullScreenView>
|
||||
<Heading>{t("Call not found")}</Heading>
|
||||
<Text>
|
||||
{t(
|
||||
"Calls are now end-to-end encrypted and need to be created from the home page. This helps make sure everyone's using the same encryption key.",
|
||||
)}
|
||||
</Text>
|
||||
<Heading>{t("group_call_loader_failed_heading")}</Heading>
|
||||
<Text>{t("group_call_loader_failed_text")}</Text>
|
||||
{/* XXX: A 'create it for me' button would be the obvious UX here. Two screens already have
|
||||
dupes of this flow, let's make a common component and put it here. */}
|
||||
<Link href="/" onClick={onHomeClick}>
|
||||
|
||||
@@ -303,11 +303,7 @@ export const GroupCallView: FC<Props> = ({
|
||||
return (
|
||||
<FullScreenView>
|
||||
<Heading>Incompatible Browser</Heading>
|
||||
<Text>
|
||||
{t(
|
||||
"Your web browser does not support media end-to-end encryption. Supported Browsers are Chrome, Safari, Firefox >=117",
|
||||
)}
|
||||
</Text>
|
||||
<Text>{t("browser_media_e2ee_unsupported")}</Text>
|
||||
<Link href="/" onClick={onHomeClick}>
|
||||
{t("common.home")}
|
||||
</Link>
|
||||
|
||||
@@ -276,7 +276,7 @@ export const InCallView: FC<InCallViewProps> = ({
|
||||
if (items.length === 0) {
|
||||
return (
|
||||
<div className={styles.centerMessage}>
|
||||
<p>{t("Waiting for other participants…")}</p>
|
||||
<p>{t("waiting_for_participants")}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ export const InviteModal: FC<Props> = ({ room, open, onDismiss }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal title={t("Invite to this call")} open={open} onDismiss={onDismiss}>
|
||||
<Modal title={t("invite_modal.title")} open={open} onDismiss={onDismiss}>
|
||||
<Text className={styles.url} size="sm" weight="semibold">
|
||||
{url}
|
||||
</Text>
|
||||
@@ -77,7 +77,7 @@ export const InviteModal: FC<Props> = ({ room, open, onDismiss }) => {
|
||||
autoDismiss={2000}
|
||||
Icon={CheckIcon}
|
||||
>
|
||||
{t("Link copied to clipboard")}
|
||||
{t("invite_modal.link_copied_toast")}
|
||||
</Toast>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -52,9 +52,9 @@ export const LayoutToggle: FC<Props> = ({ layout, setLayout, className }) => {
|
||||
checked={layout === "spotlight"}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<Tooltip label={t("Spotlight")}>
|
||||
<Tooltip label={t("layout_spotlight_label")}>
|
||||
<label htmlFor={spotlightId}>
|
||||
<SpotlightIcon aria-label={t("Spotlight")} />
|
||||
<SpotlightIcon aria-label={t("layout_spotlight_label")} />
|
||||
</label>
|
||||
</Tooltip>
|
||||
<input
|
||||
@@ -65,9 +65,9 @@ export const LayoutToggle: FC<Props> = ({ layout, setLayout, className }) => {
|
||||
checked={layout === "grid"}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<Tooltip label={t("Grid")}>
|
||||
<Tooltip label={t("layout_grid_label")}>
|
||||
<label htmlFor={gridId}>
|
||||
<GridIcon aria-label={t("Grid")} />
|
||||
<GridIcon aria-label={t("layout_grid_label")} />
|
||||
</label>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
@@ -87,7 +87,7 @@ export const LobbyView: FC<Props> = ({
|
||||
const recentsButtonInFooter = useMediaQuery("(max-height: 500px)");
|
||||
const recentsButton = !confineToRoom && (
|
||||
<Link className={styles.recents} href="#" onClick={onLeaveClick}>
|
||||
{t("Back to recents")}
|
||||
{t("lobby.leave_button")}
|
||||
</Link>
|
||||
);
|
||||
|
||||
@@ -120,7 +120,7 @@ export const LobbyView: FC<Props> = ({
|
||||
onClick={onEnter}
|
||||
data-testid="lobby_joinCall"
|
||||
>
|
||||
{t("Join call")}
|
||||
{t("lobby.join_button")}
|
||||
</Button>
|
||||
</VideoPreview>
|
||||
{!recentsButtonInFooter && recentsButton}
|
||||
|
||||
@@ -44,12 +44,8 @@ export const RageshakeRequestModal: FC<Props> = ({
|
||||
}, [sent, onDismiss]);
|
||||
|
||||
return (
|
||||
<Modal title={t("Debug log request")} open={open} onDismiss={onDismiss}>
|
||||
<Body>
|
||||
{t(
|
||||
"Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log.",
|
||||
)}
|
||||
</Body>
|
||||
<Modal title={t("rageshake_request_modal.title")} open={open} onDismiss={onDismiss}>
|
||||
<Body>{t("rageshake_request_modal.body")}</Body>
|
||||
<FieldRow>
|
||||
<Button
|
||||
onPress={(): void =>
|
||||
@@ -61,7 +57,7 @@ export const RageshakeRequestModal: FC<Props> = ({
|
||||
}
|
||||
disabled={sending}
|
||||
>
|
||||
{sending ? t("Sending debug logs…") : t("Send debug logs")}
|
||||
{sending ? t("rageshake_sending_logs") : t("rageshake_send_logs")}
|
||||
</Button>
|
||||
</FieldRow>
|
||||
{error && (
|
||||
|
||||
@@ -70,7 +70,9 @@ export const RoomAuthView: FC = () => {
|
||||
</Header>
|
||||
<div className={styles.container}>
|
||||
<main className={styles.main}>
|
||||
<Headline className={styles.headline}>{t("Join call")}</Headline>
|
||||
<Headline className={styles.headline}>
|
||||
{t("lobby.join_button")}
|
||||
</Headline>
|
||||
<Form className={styles.form} onSubmit={onSubmit}>
|
||||
<FieldRow>
|
||||
<InputField
|
||||
@@ -85,7 +87,7 @@ export const RoomAuthView: FC = () => {
|
||||
/>
|
||||
</FieldRow>
|
||||
<Caption>
|
||||
<Trans>
|
||||
<Trans i18nKey="room_auth_view_eula_caption">
|
||||
By clicking "Join call now", you agree to our{" "}
|
||||
<Link href={Config.get().eula}>
|
||||
End User Licensing Agreement (EULA)
|
||||
@@ -103,13 +105,13 @@ export const RoomAuthView: FC = () => {
|
||||
disabled={loading}
|
||||
data-testid="joincall_joincall"
|
||||
>
|
||||
{loading ? t("common.loading") : t("Join call now")}
|
||||
{loading ? t("common.loading") : t("room_auth_view_join_button")}
|
||||
</Button>
|
||||
<div id={recaptchaId} />
|
||||
</Form>
|
||||
</main>
|
||||
<Body className={styles.footer}>
|
||||
<Trans>
|
||||
<Trans i18nKey="unauthenticated_view_body">
|
||||
Not registered yet?{" "}
|
||||
<Link
|
||||
color="primary"
|
||||
|
||||
@@ -62,32 +62,28 @@ export const FeedbackSettingsTab: FC<Props> = ({ roomId }) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h4 className={styles.label}>{t("Submit feedback")}</h4>
|
||||
<Body>
|
||||
{t(
|
||||
"If you are experiencing issues or simply would like to provide some feedback, please send us a short description below.",
|
||||
)}
|
||||
</Body>
|
||||
<h4 className={styles.label}>{t("settings.feedback_tab_h4")}</h4>
|
||||
<Body>{t("settings.feedback_tab_body")}</Body>
|
||||
<form onSubmit={onSubmitFeedback}>
|
||||
<FieldRow>
|
||||
<InputField
|
||||
className={feedbackStyles.feedback}
|
||||
id="description"
|
||||
name="description"
|
||||
label={t("Your feedback")}
|
||||
placeholder={t("Your feedback")}
|
||||
label={t("settings.feedback_tab_description_label")}
|
||||
placeholder={t("settings.feedback_tab_description_label")}
|
||||
type="textarea"
|
||||
disabled={sending || sent}
|
||||
/>
|
||||
</FieldRow>
|
||||
{sent ? (
|
||||
<Body> {t("Thanks, we received your feedback!")}</Body>
|
||||
<Body> {t("settings.feedback_tab_thank_you")}</Body>
|
||||
) : (
|
||||
<FieldRow>
|
||||
<InputField
|
||||
id="sendLogs"
|
||||
name="sendLogs"
|
||||
label={t("Include debug logs")}
|
||||
label={t("settings.feedback_tab_send_logs_label")}
|
||||
type="checkbox"
|
||||
defaultChecked
|
||||
/>
|
||||
@@ -97,7 +93,7 @@ export const FeedbackSettingsTab: FC<Props> = ({ roomId }) => {
|
||||
</FieldRow>
|
||||
)}
|
||||
<Button type="submit" disabled={sending}>
|
||||
{sending ? t("Submitting…") : ("action.submit")}
|
||||
{sending ? t("submitting") : "action.submit"}
|
||||
</Button>
|
||||
</FieldRow>
|
||||
)}
|
||||
|
||||
@@ -41,13 +41,13 @@ export const RageshakeButton: FC<Props> = ({ description }) => {
|
||||
|
||||
let logsComponent: JSX.Element | null = null;
|
||||
if (sending) {
|
||||
logsComponent = <span>{t("Sending…")}</span>;
|
||||
logsComponent = <span>{t("rageshake_sending")}</span>;
|
||||
} else if (sent) {
|
||||
logsComponent = <div>{t("Thanks!")}</div>;
|
||||
logsComponent = <div>{t("rageshake_sent")}</div>;
|
||||
} else {
|
||||
let caption = t("Send debug logs");
|
||||
let caption = t("rageshake_send_logs");
|
||||
if (error) {
|
||||
caption = t("Retry sending logs");
|
||||
caption = t("rageshake_button_error_caption");
|
||||
}
|
||||
|
||||
logsComponent = (
|
||||
|
||||
@@ -103,7 +103,7 @@ export const SettingsModal: FC<Props> = (props) => {
|
||||
|
||||
const optInDescription = (
|
||||
<Caption>
|
||||
<Trans>
|
||||
<Trans i18nKey="settings.opt_in_description">
|
||||
<AnalyticsNotice />
|
||||
<br />
|
||||
You may withdraw consent by unchecking this box. If you are currently in
|
||||
@@ -127,7 +127,10 @@ export const SettingsModal: FC<Props> = (props) => {
|
||||
>
|
||||
{generateDeviceSelection(devices.audioInput, t("common.microphone"))}
|
||||
{!isFirefox() &&
|
||||
generateDeviceSelection(devices.audioOutput, t("Speaker"))}
|
||||
generateDeviceSelection(
|
||||
devices.audioOutput,
|
||||
t("settings.speaker_device_selection_label"),
|
||||
)}
|
||||
</TabItem>
|
||||
);
|
||||
|
||||
@@ -165,7 +168,7 @@ export const SettingsModal: FC<Props> = (props) => {
|
||||
title={
|
||||
<>
|
||||
<FeedbackIcon width={16} height={16} />
|
||||
<span>{t("Feedback")}</span>
|
||||
<span>{t("settings.feedback_tab_title")}</span>
|
||||
</>
|
||||
}
|
||||
>
|
||||
@@ -179,7 +182,7 @@ export const SettingsModal: FC<Props> = (props) => {
|
||||
title={
|
||||
<>
|
||||
<OverflowIcon width={16} height={16} />
|
||||
<span>{t("More")}</span>
|
||||
<span>{t("settings.more_tab_title")}</span>
|
||||
</>
|
||||
}
|
||||
>
|
||||
@@ -190,8 +193,8 @@ export const SettingsModal: FC<Props> = (props) => {
|
||||
id="developerSettingsTab"
|
||||
type="checkbox"
|
||||
checked={developerSettingsTab}
|
||||
label={t("Developer Settings")}
|
||||
description={t("Expose developer settings in the settings window.")}
|
||||
label={t("settings.developer_settings_label")}
|
||||
description={t("settings.developer_settings_label_description")}
|
||||
onChange={(event: ChangeEvent<HTMLInputElement>): void =>
|
||||
setDeveloperSettingsTab(event.target.checked)
|
||||
}
|
||||
@@ -218,13 +221,13 @@ export const SettingsModal: FC<Props> = (props) => {
|
||||
title={
|
||||
<>
|
||||
<DeveloperIcon width={16} height={16} />
|
||||
<span>{t("Developer")}</span>
|
||||
<span>{t("settings.developer_tab_title")}</span>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<FieldRow>
|
||||
<Body className={styles.fieldRowText}>
|
||||
{t("Version: {{version}}", {
|
||||
{t("version", {
|
||||
version: import.meta.env.VITE_APP_VERSION || "dev",
|
||||
})}
|
||||
</Body>
|
||||
@@ -233,7 +236,7 @@ export const SettingsModal: FC<Props> = (props) => {
|
||||
<InputField
|
||||
id="showConnectionStats"
|
||||
name="connection-stats"
|
||||
label={t("Show connection stats")}
|
||||
label={t("settings.show_connection_stats_label")}
|
||||
type="checkbox"
|
||||
checked={showConnectionStats}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>): void =>
|
||||
|
||||
@@ -193,18 +193,18 @@ export const VideoTile = forwardRef<HTMLDivElement, Props>(
|
||||
)}
|
||||
{content === TileContent.ScreenShare ? (
|
||||
<div className={styles.presenterLabel}>
|
||||
<span>{t("{{displayName}} is presenting", { displayName })}</span>
|
||||
<span>{t("video_tile.presenter_label", { displayName })}</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.nameTag}>
|
||||
<MicIcon
|
||||
width={20}
|
||||
height={20}
|
||||
aria-label={muted ? t("Microphone off") : t("Microphone on")}
|
||||
aria-label={muted ? t("microphone_off") : t("microphone_on")}
|
||||
data-muted={muted}
|
||||
/>
|
||||
<Text as="span" size="sm" weight="medium">
|
||||
{sfuParticipant.isLocal ? t("You") : displayName}
|
||||
{sfuParticipant.isLocal ? t("video_tile.sfu_participant_local") : displayName}
|
||||
</Text>
|
||||
{showConnectionStats && (
|
||||
<ConnectionQualityIndicator participant={sfuParticipant} />
|
||||
|
||||
@@ -82,7 +82,7 @@ export const VideoTileSettingsModal: FC<Props> = ({
|
||||
return (
|
||||
<Modal
|
||||
className={styles.videoTileSettingsModal}
|
||||
title={t("Local volume")}
|
||||
title={t("local_volume_label")}
|
||||
open={open}
|
||||
onDismiss={onDismiss}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user