fix: localize cloud dialogs and correct editor controls

This commit is contained in:
webadderall
2026-09-21 20:33:13 +10:00
parent 5c04751ea8
commit ab7fd8baea
18 changed files with 558 additions and 66 deletions
+37 -26
View File
@@ -1,3 +1,4 @@
import { useI18n } from "@/contexts/I18nContext";
import { GoogleLogo, SignOut, XLogo } from "@phosphor-icons/react";
import type { User } from "@supabase/supabase-js";
import { type FormEvent, useEffect, useState } from "react";
@@ -32,16 +33,20 @@ type Props = {
onAuthenticated: () => void;
};
function friendlyAuthError(error: unknown, action: string): string {
function friendlyAuthError(
error: unknown,
action: string,
t: ReturnType<typeof useI18n>["t"],
): string {
const message = error instanceof Error ? error.message : String(error);
if (/unsupported provider|provider is not enabled/i.test(message)) {
if (action === "google") {
return "Google sign-in isn't enabled yet. Use email for now, or ask your Recordly administrator to connect Google.";
return t("editor.cloud.googleUnavailable");
}
if (action === "x") {
return "X sign-in isn't enabled yet. Use email for now, or ask your Recordly administrator to connect X.";
return t("editor.cloud.xUnavailable");
}
return "This sign-in method isn't enabled for Recordly yet. Use email for now.";
return t("editor.cloud.providerUnavailable");
}
return message;
}
@@ -55,16 +60,19 @@ export function RecordlySignInDialog({
callbackError,
onAuthenticated,
}: Props) {
const { t } = useI18n();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [busy, setBusy] = useState<string>();
const [message, setMessage] = useState<string>();
const [resetSent, setResetSent] = useState(false);
useEffect(() => {
if (!open) {
setPassword("");
setBusy(undefined);
setMessage(undefined);
setResetSent(false);
}
}, [open]);
@@ -75,10 +83,11 @@ export function RecordlySignInDialog({
const run = async (label: string, action: () => Promise<unknown>) => {
setBusy(label);
setMessage(undefined);
setResetSent(false);
try {
await action();
} catch (error) {
setMessage(friendlyAuthError(error, label));
setMessage(friendlyAuthError(error, label, t));
} finally {
setBusy(undefined);
}
@@ -95,12 +104,13 @@ export function RecordlySignInDialog({
const forgotPassword = () => {
if (!email.trim()) {
setMessage("Enter your email address first.");
setMessage(t("editor.cloud.enterEmail"));
return;
}
void run("reset", async () => {
await sendPasswordReset(email.trim());
setMessage("Password reset email sent.");
setMessage(t("editor.cloud.resetSent"));
setResetSent(true);
});
};
@@ -110,17 +120,19 @@ export function RecordlySignInDialog({
<Modal.Backdrop>
<Modal.Container size="sm" placement="center">
<Modal.Dialog>
<Modal.CloseTrigger aria-label="Close" />
<Modal.CloseTrigger aria-label={t("common.actions.close")} />
<Modal.Header>
<Modal.Heading>
{user ? "Your Recordly account" : "Sign into Recordly"}
{user
? t("editor.cloud.accountHeading")
: t("editor.cloud.signInHeading")}
</Modal.Heading>
<Description>
{user
? user.email
: reason === "share"
? "Sign in to publish this video and manage its shared link."
: "Access your recordings and shared links."}
? t("editor.cloud.signInShareDescription")
: t("editor.cloud.signInDescription")}
</Description>
</Modal.Header>
<Modal.Body className="flex flex-col gap-4">
@@ -132,7 +144,9 @@ export function RecordlySignInDialog({
onPress={() => void run("signout", signOutRecordly)}
>
<SignOut className="size-4" />
{busy === "signout" ? "Signing out…" : "Sign out"}
{busy === "signout"
? t("editor.cloud.signingOut")
: t("editor.cloud.signOut")}
</Button>
) : (
<>
@@ -161,7 +175,9 @@ export function RecordlySignInDialog({
</div>
<div className="my-1 flex items-center gap-3">
<Separator className="flex-1" />
<span className="text-xs text-muted">or</span>
<span className="text-xs text-muted">
{t("editor.cloud.or")}
</span>
<Separator className="flex-1" />
</div>
<Form className="flex flex-col gap-4" onSubmit={submitEmail}>
@@ -173,7 +189,7 @@ export function RecordlySignInDialog({
isRequired
isDisabled={Boolean(busy)}
>
<Label>Email</Label>
<Label>{t("editor.cloud.email")}</Label>
<Input
placeholder="you@example.com"
autoComplete="email"
@@ -188,7 +204,7 @@ export function RecordlySignInDialog({
isRequired
isDisabled={Boolean(busy)}
>
<Label>Password</Label>
<Label>{t("editor.cloud.password")}</Label>
<Input autoComplete="current-password" />
<FieldError />
</TextField>
@@ -199,26 +215,22 @@ export function RecordlySignInDialog({
isDisabled={disabled}
onPress={forgotPassword}
>
Forgot password?
{t("editor.cloud.forgotPassword")}
</Button>
<Button
type="submit"
className="w-full"
isDisabled={disabled}
>
{busy === "email" ? "Signing in…" : "Sign in"}
{busy === "email"
? t("editor.cloud.signingIn")
: t("editor.cloud.signIn")}
</Button>
</Form>
</>
)}
{message || callbackError ? (
<Alert
status={
message === "Password reset email sent."
? "success"
: "danger"
}
>
<Alert status={resetSent && !callbackError ? "success" : "danger"}>
<Alert.Indicator />
<Alert.Content>
<Alert.Description>
@@ -231,8 +243,7 @@ export function RecordlySignInDialog({
{!configured && !user && (
<Modal.Footer>
<Description role="status" className="min-w-0 flex-1">
Cloud sign-in isn’t available in this build yet. You can still
save videos to your computer.
{t("editor.cloud.unavailable")}
</Description>
</Modal.Footer>
)}
@@ -196,6 +196,6 @@
}
.micSelect option {
background-color: #1a1a22;
background-color: var(--surface);
color: var(--foreground);
}
@@ -1,3 +1,4 @@
import { useI18n } from "@/contexts/I18nContext";
import { Check, CloudArrowUp, Copy, ShareNetwork } from "@phosphor-icons/react";
import { useCallback, useEffect, useRef, useState } from "react";
import { toast } from "@/components/ui/toast";
@@ -35,6 +36,7 @@ export function CloudShareButton({
hideTrigger = false,
authToken,
}: Props) {
const { t } = useI18n();
const [internalOpen, setInternalOpen] = useState(false);
const open = controlledOpen ?? internalOpen;
const setOpen = useCallback(
@@ -96,7 +98,7 @@ export function CloudShareButton({
setError(undefined);
setShareUrl(undefined);
try {
if (!authToken) throw new Error("Sign in to Recordly before creating a shared link.");
if (!authToken) throw new Error(t("editor.cloud.signInRequired"));
let resolvedFilePath = filePath ?? preparedFileRef.current;
if (!resolvedFilePath) {
resolvedFilePath = await prepareFile?.();
@@ -105,8 +107,7 @@ export function CloudShareButton({
void window.electronAPI.discardExportedTemp(resolvedFilePath);
return;
}
if (!resolvedFilePath)
throw new Error("Could not prepare the current edit for sharing.");
if (!resolvedFilePath) throw new Error(t("editor.cloud.prepareFailed"));
preparedFileRef.current = resolvedFilePath;
}
const nextUploadId = crypto.randomUUID();
@@ -121,12 +122,12 @@ export function CloudShareButton({
uploadId: nextUploadId,
});
if (!result.success || !result.shareUrl) {
if (!result.canceled) setError(result.error || "Cloud upload failed.");
if (!result.canceled) setError(result.error || t("editor.cloud.uploadFailed"));
return;
}
setProgress(100);
setShareUrl(result.shareUrl);
toast.success("Share link created");
toast.success(t("editor.cloud.linkCreated"));
} catch (cause) {
setError(cause instanceof Error ? cause.message : String(cause));
} finally {
@@ -134,7 +135,7 @@ export function CloudShareButton({
setPhase("idle");
setUploadId(undefined);
}
}, [authToken, filePath, notes, prepareFile, projectTitle]);
}, [authToken, filePath, notes, prepareFile, projectTitle, t]);
const handleCancel = useCallback(async () => {
cancelRequestedRef.current = true;
@@ -144,10 +145,15 @@ export function CloudShareButton({
const copyShareUrl = useCallback(async () => {
if (!shareUrl) return;
await navigator.clipboard.writeText(shareUrl);
setCopied(true);
toast.success("Link copied");
}, [shareUrl]);
try {
await navigator.clipboard.writeText(shareUrl);
setCopied(true);
toast.success(t("editor.cloud.linkCopied"));
} catch {
setCopied(false);
toast.error(t("editor.cloud.copyFailed"));
}
}, [shareUrl, t]);
return (
<>
@@ -158,27 +164,26 @@ export function CloudShareButton({
onClick={() => setOpen(true)}
disabled={!filePath && !prepareFile}
className="inline-flex h-11 flex-1 items-center justify-center gap-2 rounded-lg border-foreground/10 bg-foreground/5 px-3 text-foreground hover:bg-foreground/10 disabled:opacity-40"
title="Create a shareable link"
title={t("editor.cloud.createLinkTitle")}
>
<ShareNetwork className="h-4 w-4" />
<span className="text-sm font-semibold tracking-tight">Create link</span>
<span className="text-sm font-semibold tracking-tight">
{t("editor.cloud.createLink")}
</span>
</Button>
)}
<Dialog open={open} onOpenChange={handleOpenChange}>
<DialogContent className="max-w-md border-foreground/10 bg-editor-dialog text-foreground">
<DialogHeader>
<DialogTitle>Share to the cloud</DialogTitle>
<DialogDescription>
Publish the current edit to a Recordly viewing and feedback page. No
download is required. Shared videos are prepared at up to 1080p.
</DialogDescription>
<DialogTitle>{t("editor.cloud.heading")}</DialogTitle>
<DialogDescription>{t("editor.cloud.description")}</DialogDescription>
</DialogHeader>
{shareUrl ? (
<div className="space-y-4">
<div className="flex items-center gap-2 rounded-lg border border-emerald-500/20 bg-emerald-500/10 p-3 text-sm text-emerald-400">
<Check className="h-5 w-5 shrink-0" />
Your video is ready to share.
{t("editor.cloud.ready")}
</div>
<div className="flex gap-2">
<Input value={shareUrl} readOnly className="min-w-0" />
@@ -188,7 +193,7 @@ export function CloudShareButton({
) : (
<Copy className="h-4 w-4" />
)}
{copied ? "Copied" : "Copy"}
{copied ? t("editor.cloud.copied") : t("editor.cloud.copy")}
</Button>
</div>
<Button
@@ -197,16 +202,16 @@ export function CloudShareButton({
onClick={() => void window.electronAPI.openExternalUrl(shareUrl)}
className="w-full"
>
Open share page
{t("editor.cloud.openPage")}
</Button>
</div>
) : (
<div className="space-y-4">
<div className="space-y-2">
<Label htmlFor="cloud-share-notes">Notes</Label>
<Label htmlFor="cloud-share-notes">{t("editor.cloud.notes")}</Label>
<textarea
id="cloud-share-notes"
placeholder="Add context, instructions, or a short summary for viewers…"
placeholder={t("editor.cloud.notesPlaceholder")}
value={notes}
onChange={(event) =>
setNotes(event.target.value.slice(0, 2000))
@@ -228,8 +233,8 @@ export function CloudShareButton({
</div>
<p className="text-xs text-muted-foreground">
{phase === "preparing"
? "Preparing the current edit…"
: `Uploading… ${progress}%`}
? t("editor.cloud.preparing")
: t("editor.cloud.uploading", undefined, { progress })}
</p>
</div>
) : null}
@@ -241,12 +246,12 @@ export function CloudShareButton({
variant="outline"
onClick={() => void handleCancel()}
>
Cancel
{t("common.actions.cancel")}
</Button>
) : (
<Button type="button" onClick={() => void handleUpload()}>
<CloudArrowUp className="h-4 w-4" />
Publish and create link
{t("editor.cloud.publish")}
</Button>
)}
</div>
@@ -301,7 +301,7 @@ export function EditorExportMenu(props: Props) {
onClick={handleExportDropdownClose}
className="h-8 flex-1 text-xs"
>
Done
{t("editor.cloud.done")}
</Button>
</div>
</Card>
@@ -350,7 +350,7 @@ export function EditorExportMenu(props: Props) {
}}
>
<CloudArrowUp className="size-4" />
Create share link
{t("editor.cloud.createShareLink")}
</Button>
</div>
</>
@@ -377,9 +377,9 @@ export function EditorShell(props: Props) {
aria-live="polite"
>
<div className="rounded-xl border border-separator bg-background p-6 text-center">
<p className="font-medium">Adding video…</p>
<p className="font-medium">{t("editor.cloud.addingVideo")}</p>
<p className="mt-2 text-sm text-muted-foreground">
Preparing footage and audio for your timeline.
{t("editor.cloud.preparingFootage")}
</p>
<Button
className="mt-4"
@@ -6,7 +6,15 @@ import {
Gear,
FrameCorners,
} from "@phosphor-icons/react";
import { ToggleButtonGroup, ToggleButton, Tooltip, Card, Switch, Label } from "@heroui/react";
import {
ToggleButtonGroup,
ToggleButton,
Button,
Tooltip,
Card,
Switch,
Label,
} from "@heroui/react";
import type { ComponentProps, ReactNode } from "react";
import { useMemo, useState } from "react";
import type { useI18n } from "@/contexts/I18nContext";
@@ -93,7 +101,7 @@ export function EditorSidebar({
))}
</ToggleButtonGroup>
<Tooltip>
<ToggleButton
<Button
variant="ghost"
isIconOnly
className="mt-auto"
@@ -101,7 +109,7 @@ export function EditorSidebar({
onPress={onAccountClick}
>
<UserCircle className="size-5" />
</ToggleButton>
</Button>
<Tooltip.Content placement="right">Account</Tooltip.Content>
</Tooltip>
</nav>
@@ -343,13 +343,8 @@
/* Caption previews share the filmstrip, with enough contrast over any footage. */
.glassCaption.embeddedCaption,
:global(:root:not(.dark)) .glassCaption.embeddedCaption {
background: rgba(0, 0, 0, 0.72);
border-color: rgba(255, 255, 255, 0.25);
border-radius: 4px;
}
.glassCaption.embeddedCaption.selected {
box-shadow: inset 0 0 0 1px var(--accent);
}
/* Caption selection uses the same primary blue as the editor controls. */
.glassCaption.selected,
@@ -360,7 +355,7 @@
box-shadow: inset 0 0 0 1.5px var(--accent);
}
/* Compact caption lane above the filmstrip. */
/* Compact caption lane inside the filmstrip. */
.glassCaption,
.glassCaption.embeddedCaption,
:global(:root:not(.dark)) .glassCaption,
+43
View File
@@ -1,4 +1,47 @@
{
"cloud": {
"signInRequired": "Melde dich bei Recordly an, bevor du einen Freigabelink erstellst.",
"prepareFailed": "Der aktuelle Schnitt konnte nicht zum Teilen vorbereitet werden.",
"uploadFailed": "Cloud-Upload fehlgeschlagen.",
"linkCreated": "Freigabelink erstellt",
"linkCopied": "Link kopiert",
"copyFailed": "Link konnte nicht kopiert werden. Wähle ihn aus und kopiere ihn manuell.",
"copied": "Kopiert",
"copy": "Kopieren",
"preparing": "Aktueller Schnitt wird vorbereitet…",
"createLink": "Link erstellen",
"heading": "In der Cloud teilen",
"ready": "Dein Video kann jetzt geteilt werden.",
"openPage": "Freigabeseite öffnen",
"notes": "Notizen",
"publish": "Veröffentlichen und Link erstellen",
"createLinkTitle": "Einen Freigabelink erstellen",
"notesPlaceholder": "Füge Kontext, Anweisungen oder eine kurze Zusammenfassung für Zuschauer hinzu…",
"description": "Veröffentliche den aktuellen Schnitt auf einer Recordly-Seite zum Ansehen und Kommentieren. Ein Download ist nicht nötig. Videos werden mit bis zu 1080p vorbereitet.",
"uploading": "Wird hochgeladen… {progress}%",
"googleUnavailable": "Die Google-Anmeldung ist noch nicht aktiviert. Nutze E-Mail oder bitte deinen Recordly-Administrator, Google zu verbinden.",
"xUnavailable": "Die X-Anmeldung ist noch nicht aktiviert. Nutze E-Mail oder bitte deinen Recordly-Administrator, X zu verbinden.",
"providerUnavailable": "Diese Anmeldemethode ist noch nicht aktiviert. Nutze vorerst E-Mail.",
"enterEmail": "Gib zuerst deine E-Mail-Adresse ein.",
"resetSent": "E-Mail zum Zurücksetzen des Passworts gesendet.",
"accountHeading": "Dein Recordly-Konto",
"signInHeading": "Bei Recordly anmelden",
"signInShareDescription": "Melde dich an, um dieses Video zu veröffentlichen und seinen Freigabelink zu verwalten.",
"signInDescription": "Greife auf deine Aufnahmen und Freigabelinks zu.",
"signingOut": "Abmeldung läuft…",
"signOut": "Abmelden",
"signingIn": "Anmeldung läuft…",
"signIn": "Anmelden",
"or": "oder",
"email": "E-Mail",
"password": "Passwort",
"forgotPassword": "Passwort vergessen?",
"unavailable": "Die Cloud-Anmeldung ist in dieser Version noch nicht verfügbar. Du kannst Videos weiterhin auf deinem Computer speichern.",
"createShareLink": "Freigabelink erstellen",
"done": "Fertig",
"addingVideo": "Video wird hinzugefügt…",
"preparingFootage": "Video und Audio werden für die Zeitleiste vorbereitet."
},
"library": {
"videos": "Videos"
},
+43
View File
@@ -1,4 +1,47 @@
{
"cloud": {
"signInRequired": "Sign in to Recordly before creating a shared link.",
"prepareFailed": "Could not prepare the current edit for sharing.",
"uploadFailed": "Cloud upload failed.",
"linkCreated": "Share link created",
"linkCopied": "Link copied",
"copyFailed": "Could not copy link. Select and copy it manually.",
"copied": "Copied",
"copy": "Copy",
"preparing": "Preparing the current edit…",
"createLink": "Create link",
"heading": "Share to the cloud",
"ready": "Your video is ready to share.",
"openPage": "Open share page",
"notes": "Notes",
"publish": "Publish and create link",
"createLinkTitle": "Create a shareable link",
"notesPlaceholder": "Add context, instructions, or a short summary for viewers…",
"description": "Publish the current edit to a Recordly viewing and feedback page. No download is required. Shared videos are prepared at up to 1080p.",
"uploading": "Uploading… {progress}%",
"googleUnavailable": "Google sign-in isn't enabled yet. Use email for now, or ask your Recordly administrator to connect Google.",
"xUnavailable": "X sign-in isn't enabled yet. Use email for now, or ask your Recordly administrator to connect X.",
"providerUnavailable": "This sign-in method isn't enabled for Recordly yet. Use email for now.",
"enterEmail": "Enter your email address first.",
"resetSent": "Password reset email sent.",
"accountHeading": "Your Recordly account",
"signInHeading": "Sign into Recordly",
"signInShareDescription": "Sign in to publish this video and manage its shared link.",
"signInDescription": "Access your recordings and shared links.",
"signingOut": "Signing out…",
"signOut": "Sign out",
"signingIn": "Signing in…",
"signIn": "Sign in",
"or": "or",
"email": "Email",
"password": "Password",
"forgotPassword": "Forgot password?",
"unavailable": "Cloud sign-in isn’t available in this build yet. You can still save videos to your computer.",
"createShareLink": "Create share link",
"done": "Done",
"addingVideo": "Adding video…",
"preparingFootage": "Preparing footage and audio for your timeline."
},
"library": {
"videos": "Videos"
},
+43
View File
@@ -1,4 +1,47 @@
{
"cloud": {
"signInRequired": "Inicia sesión en Recordly antes de crear un enlace compartido.",
"prepareFailed": "No se pudo preparar la edición actual para compartirla.",
"uploadFailed": "Error al subir a la nube.",
"linkCreated": "Enlace creado",
"linkCopied": "Enlace copiado",
"copyFailed": "No se pudo copiar el enlace. Selecciónalo y cópialo manualmente.",
"copied": "Copiado",
"copy": "Copiar",
"preparing": "Preparando la edición actual…",
"createLink": "Crear enlace",
"heading": "Compartir en la nube",
"ready": "Tu vídeo está listo para compartir.",
"openPage": "Abrir página compartida",
"notes": "Notas",
"publish": "Publicar y crear enlace",
"createLinkTitle": "Crear un enlace para compartir",
"notesPlaceholder": "Añade contexto, instrucciones o un breve resumen para los espectadores…",
"description": "Publica la edición actual en una página de Recordly para verla y comentarla. No es necesario descargarla. Los vídeos se preparan con una resolución de hasta 1080p.",
"uploading": "Subiendo… {progress}%",
"googleUnavailable": "El inicio de sesión con Google aún no está habilitado. Usa el correo o pide al administrador de Recordly que conecte Google.",
"xUnavailable": "El inicio de sesión con X aún no está habilitado. Usa el correo o pide al administrador de Recordly que conecte X.",
"providerUnavailable": "Este método de inicio de sesión aún no está habilitado. Usa el correo.",
"enterEmail": "Introduce primero tu dirección de correo.",
"resetSent": "Correo para restablecer la contraseña enviado.",
"accountHeading": "Tu cuenta de Recordly",
"signInHeading": "Iniciar sesión en Recordly",
"signInShareDescription": "Inicia sesión para publicar este vídeo y gestionar su enlace compartido.",
"signInDescription": "Accede a tus grabaciones y enlaces compartidos.",
"signingOut": "Cerrando sesión…",
"signOut": "Cerrar sesión",
"signingIn": "Iniciando sesión…",
"signIn": "Iniciar sesión",
"or": "o",
"email": "Correo electrónico",
"password": "Contraseña",
"forgotPassword": "¿Olvidaste la contraseña?",
"unavailable": "El inicio de sesión en la nube aún no está disponible en esta versión. Puedes guardar vídeos en tu ordenador.",
"createShareLink": "Crear enlace compartido",
"done": "Listo",
"addingVideo": "Añadiendo vídeo…",
"preparingFootage": "Preparando vídeo y audio para la línea de tiempo."
},
"library": {
"videos": "Vídeos"
},
+43
View File
@@ -1,4 +1,47 @@
{
"cloud": {
"signInRequired": "Connectez-vous à Recordly avant de créer un lien de partage.",
"prepareFailed": "Impossible de préparer le montage actuel pour le partage.",
"uploadFailed": "Échec de l’envoi dans le cloud.",
"linkCreated": "Lien de partage créé",
"linkCopied": "Lien copié",
"copyFailed": "Impossible de copier le lien. Sélectionnez-le et copiez-le manuellement.",
"copied": "Copié",
"copy": "Copier",
"preparing": "Préparation du montage actuel…",
"createLink": "Créer un lien",
"heading": "Partager dans le cloud",
"ready": "Votre vidéo est prête à être partagée.",
"openPage": "Ouvrir la page de partage",
"notes": "Notes",
"publish": "Publier et créer un lien",
"createLinkTitle": "Créer un lien de partage",
"notesPlaceholder": "Ajoutez du contexte, des instructions ou un bref résumé pour les spectateurs…",
"description": "Publiez le montage actuel sur une page Recordly de visionnage et de commentaires. Aucun téléchargement n’est nécessaire. Les vidéos sont préparées jusqu’en 1080p.",
"uploading": "Envoi… {progress}%",
"googleUnavailable": "La connexion Google n’est pas encore activée. Utilisez votre e-mail ou demandez à votre administrateur Recordly de connecter Google.",
"xUnavailable": "La connexion X n’est pas encore activée. Utilisez votre e-mail ou demandez à votre administrateur Recordly de connecter X.",
"providerUnavailable": "Ce mode de connexion n’est pas encore activé. Utilisez votre e-mail.",
"enterEmail": "Saisissez d’abord votre adresse e-mail.",
"resetSent": "E-mail de réinitialisation du mot de passe envoyé.",
"accountHeading": "Votre compte Recordly",
"signInHeading": "Se connecter à Recordly",
"signInShareDescription": "Connectez-vous pour publier cette vidéo et gérer son lien de partage.",
"signInDescription": "Accédez à vos enregistrements et liens partagés.",
"signingOut": "Déconnexion…",
"signOut": "Se déconnecter",
"signingIn": "Connexion…",
"signIn": "Se connecter",
"or": "ou",
"email": "E-mail",
"password": "Mot de passe",
"forgotPassword": "Mot de passe oublié ?",
"unavailable": "La connexion au cloud n’est pas encore disponible dans cette version. Vous pouvez toujours enregistrer des vidéos sur votre ordinateur.",
"createShareLink": "Créer un lien de partage",
"done": "Terminé",
"addingVideo": "Ajout de la vidéo…",
"preparingFootage": "Préparation de la vidéo et de l’audio pour la timeline."
},
"library": {
"videos": "Vidéos"
},
+43
View File
@@ -1,4 +1,47 @@
{
"cloud": {
"signInRequired": "Accedi a Recordly prima di creare un link condiviso.",
"prepareFailed": "Impossibile preparare il montaggio attuale per la condivisione.",
"uploadFailed": "Caricamento sul cloud non riuscito.",
"linkCreated": "Link di condivisione creato",
"linkCopied": "Link copiato",
"copyFailed": "Impossibile copiare il link. Selezionalo e copialo manualmente.",
"copied": "Copiato",
"copy": "Copia",
"preparing": "Preparazione del montaggio attuale…",
"createLink": "Crea link",
"heading": "Condividi sul cloud",
"ready": "Il video è pronto per la condivisione.",
"openPage": "Apri pagina condivisa",
"notes": "Note",
"publish": "Pubblica e crea link",
"createLinkTitle": "Crea un link condivisibile",
"notesPlaceholder": "Aggiungi contesto, istruzioni o un breve riepilogo per gli spettatori…",
"description": "Pubblica il montaggio attuale su una pagina Recordly per visualizzarlo e commentarlo. Non è necessario scaricarlo. I video vengono preparati fino a 1080p.",
"uploading": "Caricamento… {progress}%",
"googleUnavailable": "L’accesso con Google non è ancora abilitato. Usa l’e-mail o chiedi all’amministratore di Recordly di collegare Google.",
"xUnavailable": "L’accesso con X non è ancora abilitato. Usa l’e-mail o chiedi all’amministratore di Recordly di collegare X.",
"providerUnavailable": "Questo metodo di accesso non è ancora abilitato. Usa l’e-mail.",
"enterEmail": "Inserisci prima il tuo indirizzo e-mail.",
"resetSent": "E-mail per reimpostare la password inviata.",
"accountHeading": "Il tuo account Recordly",
"signInHeading": "Accedi a Recordly",
"signInShareDescription": "Accedi per pubblicare questo video e gestirne il link condiviso.",
"signInDescription": "Accedi alle tue registrazioni e ai link condivisi.",
"signingOut": "Disconnessione…",
"signOut": "Esci",
"signingIn": "Accesso…",
"signIn": "Accedi",
"or": "oppure",
"email": "E-mail",
"password": "Password",
"forgotPassword": "Password dimenticata?",
"unavailable": "L’accesso al cloud non è ancora disponibile in questa versione. Puoi comunque salvare i video sul computer.",
"createShareLink": "Crea link di condivisione",
"done": "Fine",
"addingVideo": "Aggiunta del video…",
"preparingFootage": "Preparazione di video e audio per la timeline."
},
"library": {
"videos": "Video"
},
+43
View File
@@ -1,4 +1,47 @@
{
"cloud": {
"signInRequired": "공유 링크를 만들기 전에 Recordly에 로그인하세요.",
"prepareFailed": "현재 편집본을 공유할 준비를 하지 못했습니다.",
"uploadFailed": "클라우드 업로드에 실패했습니다.",
"linkCreated": "공유 링크가 생성되었습니다",
"linkCopied": "링크가 복사되었습니다",
"copyFailed": "링크를 복사하지 못했습니다. 직접 선택하여 복사하세요.",
"copied": "복사됨",
"copy": "복사",
"preparing": "현재 편집본 준비 중…",
"createLink": "링크 만들기",
"heading": "클라우드에 공유",
"ready": "동영상을 공유할 준비가 되었습니다.",
"openPage": "공유 페이지 열기",
"notes": "메모",
"publish": "게시하고 링크 만들기",
"createLinkTitle": "공유 가능한 링크 만들기",
"notesPlaceholder": "시청자를 위한 설명, 안내 또는 간단한 요약을 추가하세요…",
"description": "현재 편집본을 Recordly 시청 및 피드백 페이지에 게시합니다. 다운로드할 필요가 없습니다. 공유 동영상은 최대 1080p로 준비됩니다.",
"uploading": "업로드 중… {progress}%",
"googleUnavailable": "Google 로그인이 아직 활성화되지 않았습니다. 이메일을 사용하거나 Recordly 관리자에게 Google 연결을 요청하세요.",
"xUnavailable": "X 로그인이 아직 활성화되지 않았습니다. 이메일을 사용하거나 Recordly 관리자에게 X 연결을 요청하세요.",
"providerUnavailable": "이 로그인 방식은 아직 활성화되지 않았습니다. 이메일을 사용하세요.",
"enterEmail": "먼저 이메일 주소를 입력하세요.",
"resetSent": "비밀번호 재설정 이메일을 보냈습니다.",
"accountHeading": "내 Recordly 계정",
"signInHeading": "Recordly에 로그인",
"signInShareDescription": "이 동영상을 게시하고 공유 링크를 관리하려면 로그인하세요.",
"signInDescription": "녹화 및 공유 링크에 접근하세요.",
"signingOut": "로그아웃 중…",
"signOut": "로그아웃",
"signingIn": "로그인 중…",
"signIn": "로그인",
"or": "또는",
"email": "이메일",
"password": "비밀번호",
"forgotPassword": "비밀번호를 잊으셨나요?",
"unavailable": "이 버전에서는 아직 클라우드 로그인을 사용할 수 없습니다. 동영상은 계속 컴퓨터에 저장할 수 있습니다.",
"createShareLink": "공유 링크 만들기",
"done": "완료",
"addingVideo": "동영상 추가 중…",
"preparingFootage": "타임라인에 사용할 영상과 오디오를 준비하고 있습니다."
},
"library": {
"videos": "동영상"
},
+43
View File
@@ -1,4 +1,47 @@
{
"cloud": {
"signInRequired": "Meld je aan bij Recordly voordat je een deellink maakt.",
"prepareFailed": "De huidige montage kon niet worden voorbereid om te delen.",
"uploadFailed": "Uploaden naar de cloud mislukt.",
"linkCreated": "Deellink gemaakt",
"linkCopied": "Link gekopieerd",
"copyFailed": "De link kon niet worden gekopieerd. Selecteer en kopieer deze handmatig.",
"copied": "Gekopieerd",
"copy": "Kopiëren",
"preparing": "Huidige montage voorbereiden…",
"createLink": "Link maken",
"heading": "Delen in de cloud",
"ready": "Je video is klaar om te delen.",
"openPage": "Deelpagina openen",
"notes": "Notities",
"publish": "Publiceren en link maken",
"createLinkTitle": "Een deellink maken",
"notesPlaceholder": "Voeg context, instructies of een korte samenvatting voor kijkers toe…",
"description": "Publiceer de huidige montage op een Recordly-pagina om te bekijken en feedback te geven. Downloaden is niet nodig. Video’s worden voorbereid tot 1080p.",
"uploading": "Uploaden… {progress}%",
"googleUnavailable": "Aanmelden met Google is nog niet ingeschakeld. Gebruik e-mail of vraag je Recordly-beheerder om Google te koppelen.",
"xUnavailable": "Aanmelden met X is nog niet ingeschakeld. Gebruik e-mail of vraag je Recordly-beheerder om X te koppelen.",
"providerUnavailable": "Deze aanmeldmethode is nog niet ingeschakeld. Gebruik voorlopig e-mail.",
"enterEmail": "Voer eerst je e-mailadres in.",
"resetSent": "E-mail om je wachtwoord te herstellen verzonden.",
"accountHeading": "Je Recordly-account",
"signInHeading": "Aanmelden bij Recordly",
"signInShareDescription": "Meld je aan om deze video te publiceren en de deellink te beheren.",
"signInDescription": "Bekijk je opnamen en gedeelde links.",
"signingOut": "Afmelden…",
"signOut": "Afmelden",
"signingIn": "Aanmelden…",
"signIn": "Aanmelden",
"or": "of",
"email": "E-mail",
"password": "Wachtwoord",
"forgotPassword": "Wachtwoord vergeten?",
"unavailable": "Aanmelden bij de cloud is nog niet beschikbaar in deze versie. Je kunt video’s wel op je computer opslaan.",
"createShareLink": "Deellink maken",
"done": "Gereed",
"addingVideo": "Video toevoegen…",
"preparingFootage": "Video en audio voorbereiden voor je tijdlijn."
},
"library": {
"videos": "Video’s"
},
+43
View File
@@ -1,4 +1,47 @@
{
"cloud": {
"signInRequired": "Entre no Recordly antes de criar um link compartilhado.",
"prepareFailed": "Não foi possível preparar a edição atual para compartilhar.",
"uploadFailed": "Falha no envio para a nuvem.",
"linkCreated": "Link de compartilhamento criado",
"linkCopied": "Link copiado",
"copyFailed": "Não foi possível copiar o link. Selecione e copie manualmente.",
"copied": "Copiado",
"copy": "Copiar",
"preparing": "Preparando a edição atual…",
"createLink": "Criar link",
"heading": "Compartilhar na nuvem",
"ready": "Seu vídeo está pronto para compartilhar.",
"openPage": "Abrir página compartilhada",
"notes": "Notas",
"publish": "Publicar e criar link",
"createLinkTitle": "Criar um link compartilhável",
"notesPlaceholder": "Adicione contexto, instruções ou um breve resumo para os espectadores…",
"description": "Publique a edição atual em uma página do Recordly para assistir e comentar. Não é necessário baixar. Os vídeos são preparados em até 1080p.",
"uploading": "Enviando… {progress}%",
"googleUnavailable": "O login com Google ainda não está habilitado. Use e-mail ou peça ao administrador do Recordly para conectar o Google.",
"xUnavailable": "O login com X ainda não está habilitado. Use e-mail ou peça ao administrador do Recordly para conectar o X.",
"providerUnavailable": "Este método de login ainda não está habilitado. Use e-mail por enquanto.",
"enterEmail": "Digite seu endereço de e-mail primeiro.",
"resetSent": "E-mail de redefinição de senha enviado.",
"accountHeading": "Sua conta Recordly",
"signInHeading": "Entrar no Recordly",
"signInShareDescription": "Entre para publicar este vídeo e gerenciar seu link compartilhado.",
"signInDescription": "Acesse suas gravações e links compartilhados.",
"signingOut": "Saindo…",
"signOut": "Sair",
"signingIn": "Entrando…",
"signIn": "Entrar",
"or": "ou",
"email": "E-mail",
"password": "Senha",
"forgotPassword": "Esqueceu a senha?",
"unavailable": "O login na nuvem ainda não está disponível nesta versão. Você ainda pode salvar vídeos no computador.",
"createShareLink": "Criar link compartilhado",
"done": "Concluído",
"addingVideo": "Adicionando vídeo…",
"preparingFootage": "Preparando vídeo e áudio para a linha do tempo."
},
"library": {
"videos": "Vídeos"
},
+43
View File
@@ -1,4 +1,47 @@
{
"cloud": {
"signInRequired": "Войдите в Recordly, прежде чем создавать ссылку для доступа.",
"prepareFailed": "Не удалось подготовить текущий монтаж для публикации.",
"uploadFailed": "Не удалось загрузить в облако.",
"linkCreated": "Ссылка создана",
"linkCopied": "Ссылка скопирована",
"copyFailed": "Не удалось скопировать ссылку. Выделите и скопируйте её вручную.",
"copied": "Скопировано",
"copy": "Копировать",
"preparing": "Подготовка текущего монтажа…",
"createLink": "Создать ссылку",
"heading": "Поделиться в облаке",
"ready": "Видео готово к публикации.",
"openPage": "Открыть страницу видео",
"notes": "Заметки",
"publish": "Опубликовать и создать ссылку",
"createLinkTitle": "Создать ссылку для доступа",
"notesPlaceholder": "Добавьте контекст, инструкции или краткое описание для зрителей…",
"description": "Опубликуйте текущий монтаж на странице Recordly для просмотра и обсуждения. Скачивание не требуется. Видео подготавливается в разрешении до 1080p.",
"uploading": "Загрузка… {progress}%",
"googleUnavailable": "Вход через Google ещё не включён. Используйте почту или попросите администратора Recordly подключить Google.",
"xUnavailable": "Вход через X ещё не включён. Используйте почту или попросите администратора Recordly подключить X.",
"providerUnavailable": "Этот способ входа ещё не включён. Пока используйте почту.",
"enterEmail": "Сначала введите адрес электронной почты.",
"resetSent": "Письмо для сброса пароля отправлено.",
"accountHeading": "Ваш аккаунт Recordly",
"signInHeading": "Войти в Recordly",
"signInShareDescription": "Войдите, чтобы опубликовать видео и управлять ссылкой на него.",
"signInDescription": "Доступ к вашим записям и общим ссылкам.",
"signingOut": "Выход…",
"signOut": "Выйти",
"signingIn": "Вход…",
"signIn": "Войти",
"or": "или",
"email": "Электронная почта",
"password": "Пароль",
"forgotPassword": "Забыли пароль?",
"unavailable": "Вход в облако пока недоступен в этой версии. Вы по-прежнему можете сохранять видео на компьютере.",
"createShareLink": "Создать общую ссылку",
"done": "Готово",
"addingVideo": "Добавление видео…",
"preparingFootage": "Подготовка видео и звука для шкалы времени."
},
"library": {
"videos": "Видео"
},
+43
View File
@@ -1,4 +1,47 @@
{
"cloud": {
"signInRequired": "创建共享链接前,请先登录 Recordly。",
"prepareFailed": "无法准备当前剪辑以供分享。",
"uploadFailed": "云端上传失败。",
"linkCreated": "共享链接已创建",
"linkCopied": "链接已复制",
"copyFailed": "无法复制链接,请选中后手动复制。",
"copied": "已复制",
"copy": "复制",
"preparing": "正在准备当前剪辑…",
"createLink": "创建链接",
"heading": "分享到云端",
"ready": "视频已准备好,可以分享了。",
"openPage": "打开分享页面",
"notes": "备注",
"publish": "发布并创建链接",
"createLinkTitle": "创建可分享的链接",
"notesPlaceholder": "为观看者添加背景信息、说明或简短摘要…",
"description": "将当前剪辑发布到 Recordly 观看和反馈页面,无需下载。分享的视频最高为 1080p。",
"uploading": "正在上传… {progress}%",
"googleUnavailable": "尚未启用 Google 登录。请使用邮箱,或请 Recordly 管理员连接 Google。",
"xUnavailable": "尚未启用 X 登录。请使用邮箱,或请 Recordly 管理员连接 X。",
"providerUnavailable": "尚未启用此登录方式,请先使用邮箱。",
"enterEmail": "请先输入邮箱地址。",
"resetSent": "密码重置邮件已发送。",
"accountHeading": "你的 Recordly 账户",
"signInHeading": "登录 Recordly",
"signInShareDescription": "登录后即可发布此视频并管理共享链接。",
"signInDescription": "访问你的录制内容和共享链接。",
"signingOut": "正在退出…",
"signOut": "退出登录",
"signingIn": "正在登录…",
"signIn": "登录",
"or": "或",
"email": "邮箱",
"password": "密码",
"forgotPassword": "忘记密码?",
"unavailable": "此版本尚不支持云端登录,你仍然可以将视频保存到电脑。",
"createShareLink": "创建共享链接",
"done": "完成",
"addingVideo": "正在添加视频…",
"preparingFootage": "正在为时间轴准备视频和音频。"
},
"library": {
"videos": "视频"
},
+43
View File
@@ -1,4 +1,47 @@
{
"cloud": {
"signInRequired": "建立分享連結前,請先登入 Recordly。",
"prepareFailed": "無法準備目前的剪輯以供分享。",
"uploadFailed": "雲端上傳失敗。",
"linkCreated": "分享連結已建立",
"linkCopied": "連結已複製",
"copyFailed": "無法複製連結,請選取後手動複製。",
"copied": "已複製",
"copy": "複製",
"preparing": "正在準備目前的剪輯…",
"createLink": "建立連結",
"heading": "分享到雲端",
"ready": "影片已準備好,可以分享了。",
"openPage": "開啟分享頁面",
"notes": "備註",
"publish": "發布並建立連結",
"createLinkTitle": "建立可分享的連結",
"notesPlaceholder": "為觀眾新增背景資訊、說明或簡短摘要…",
"description": "將目前的剪輯發布到 Recordly 觀看及回饋頁面,無需下載。分享的影片最高為 1080p。",
"uploading": "正在上傳… {progress}%",
"googleUnavailable": "尚未啟用 Google 登入。請使用電子郵件,或請 Recordly 管理員連結 Google。",
"xUnavailable": "尚未啟用 X 登入。請使用電子郵件,或請 Recordly 管理員連結 X。",
"providerUnavailable": "尚未啟用此登入方式,請先使用電子郵件。",
"enterEmail": "請先輸入電子郵件地址。",
"resetSent": "密碼重設郵件已寄出。",
"accountHeading": "你的 Recordly 帳戶",
"signInHeading": "登入 Recordly",
"signInShareDescription": "登入後即可發布此影片並管理分享連結。",
"signInDescription": "存取你的錄影內容和分享連結。",
"signingOut": "正在登出…",
"signOut": "登出",
"signingIn": "正在登入…",
"signIn": "登入",
"or": "或",
"email": "電子郵件",
"password": "密碼",
"forgotPassword": "忘記密碼?",
"unavailable": "此版本尚不支援雲端登入,你仍可將影片儲存到電腦。",
"createShareLink": "建立分享連結",
"done": "完成",
"addingVideo": "正在新增影片…",
"preparingFootage": "正在為時間軸準備影片與音訊。"
},
"library": {
"videos": "影片"
},