diff --git a/src/i18n/locales/en/common.json b/src/i18n/locales/en/common.json
index 42341541..c661e479 100644
--- a/src/i18n/locales/en/common.json
+++ b/src/i18n/locales/en/common.json
@@ -1,7 +1,18 @@
{
- "app": {
- "name": "Recordly",
- "editorTitle": "Recordly Editor",
- "subtitle": "Screen recording and editing"
- }
-}
\ No newline at end of file
+ "app": {
+ "name": "Recordly",
+ "editorTitle": "Recordly Editor",
+ "subtitle": "Screen recording and editing"
+ },
+ "actions": {
+ "cancel": "Cancel",
+ "save": "Save",
+ "delete": "Delete",
+ "done": "Done"
+ },
+ "errors": {
+ "invalidFileType": "Invalid file type",
+ "failedToUploadImage": "Failed to upload image",
+ "fileReadError": "There was an error reading the file."
+ }
+}
diff --git a/src/i18n/locales/en/dialogs.json b/src/i18n/locales/en/dialogs.json
index 9e26dfee..0fa405e0 100644
--- a/src/i18n/locales/en/dialogs.json
+++ b/src/i18n/locales/en/dialogs.json
@@ -1 +1,61 @@
-{}
\ No newline at end of file
+{
+ "export": {
+ "pleaseTryAgain": "Please try again",
+ "compilingGifProgress": "Compiling GIF... {{progress}}%",
+ "compilingGifWait": "Compiling GIF... This may take a while",
+ "takeMoment": "This may take a moment...",
+ "exportFailed": "Export Failed",
+ "compilingGifTitle": "Compiling GIF",
+ "exportingFormat": "Exporting {{format}}",
+ "exportComplete": "Export Complete",
+ "formatReady": "Your {{format}} is ready",
+ "showInFolder": "Show in Folder",
+ "compiling": "Compiling",
+ "renderingFrames": "Rendering Frames",
+ "processing": "Processing...",
+ "status": "Status",
+ "format": "Format",
+ "compilingStatus": "Compiling...",
+ "frames": "Frames",
+ "cancelExport": "Cancel Export",
+ "savedSuccess": "{{format}} saved successfully!"
+ },
+ "addFont": {
+ "title": "Add Google Font",
+ "heading": "Add Google Font",
+ "description": "Add a custom font from Google Fonts to use in your annotations.",
+ "urlLabel": "Google Fonts Import URL",
+ "urlPlaceholder": "https://fonts.googleapis.com/css2?family=Roboto&display=swap",
+ "urlHelp": "Get this from Google Fonts: Select a font → Click \"Get font\" → Copy the @import URL",
+ "nameLabel": "Display Name",
+ "namePlaceholder": "My Custom Font",
+ "nameHelp": "This is how the font will appear in the font selector",
+ "adding": "Adding...",
+ "addFont": "Add Font",
+ "enterUrl": "Please enter a Google Fonts import URL",
+ "invalidUrl": "Please enter a valid Google Fonts URL",
+ "enterName": "Please enter a font name",
+ "extractFailed": "Could not extract font family from URL",
+ "addSuccess": "Font \"{{name}}\" added successfully",
+ "addFailed": "Failed to add font",
+ "loadTimeout": "Font took too long to load. Please check the URL and try again.",
+ "loadFailed": "The font could not be loaded. Please verify the Google Fonts URL is correct."
+ },
+ "shortcutsConfig": {
+ "title": "Keyboard Shortcuts",
+ "configurable": "Configurable",
+ "fixed": "Fixed",
+ "pressEscToCancel": "Press Esc to cancel",
+ "clickToChange": "Click to change",
+ "pressAKey": "Press a key…",
+ "alreadyUsedBy": "Already used by {{action}}",
+ "swap": "Swap",
+ "reserved": "This shortcut is reserved for \"{{label}}\" and cannot be reassigned.",
+ "saved": "Keyboard shortcuts saved",
+ "resetNotice": "Reset to default shortcuts — click Save to apply",
+ "instructions": "Click a shortcut then press the new key combination. Press Esc to cancel.",
+ "resetToDefaults": "Reset to defaults",
+ "cancel": "Cancel",
+ "save": "Save"
+ }
+}
diff --git a/src/i18n/locales/en/editor.json b/src/i18n/locales/en/editor.json
index 9e26dfee..4cb31ab3 100644
--- a/src/i18n/locales/en/editor.json
+++ b/src/i18n/locales/en/editor.json
@@ -1 +1,91 @@
-{}
\ No newline at end of file
+{
+ "playback": {
+ "play": "Play",
+ "pause": "Pause"
+ },
+ "annotations": {
+ "settings": "Annotation Settings",
+ "active": "Active",
+ "text": "Text",
+ "image": "Image",
+ "arrow": "Arrow",
+ "textContent": "Text Content",
+ "textPlaceholder": "Enter your text...",
+ "fontStyle": "Font Style",
+ "selectStyle": "Select style",
+ "size": "Size",
+ "toggleBold": "Toggle bold",
+ "toggleItalic": "Toggle italic",
+ "toggleUnderline": "Toggle underline",
+ "alignLeft": "Align left",
+ "alignCenter": "Align center",
+ "alignRight": "Align right",
+ "textColor": "Text Color",
+ "background": "Background",
+ "none": "None",
+ "clearBackground": "Clear Background",
+ "uploadImage": "Upload Image",
+ "supportedFormats": "Supported formats: JPG, PNG, GIF, WebP",
+ "arrowDirection": "Arrow Direction",
+ "strokeWidth": "Stroke Width: {{width}}px",
+ "arrowColor": "Arrow Color",
+ "deleteAnnotation": "Delete Annotation",
+ "shortcutsAndTips": "Shortcuts & Tips",
+ "tipSelectAnnotation": "Move playhead to overlapping annotation section and select an item.",
+ "tipCycleForward": "Use Tab to cycle through overlapping items.",
+ "tipCycleBackward": "Use Shift+Tab to cycle backwards.",
+ "imageUploadSuccess": "Image uploaded successfully!",
+ "imageUploadError": "Please upload a JPG, PNG, GIF, or WebP image file."
+ },
+ "fontStyles": {
+ "classic": "Classic",
+ "editor": "Editor",
+ "strong": "Strong",
+ "typewriter": "Typewriter",
+ "deco": "Deco",
+ "simple": "Simple",
+ "modern": "Modern",
+ "clean": "Clean"
+ },
+ "format": {
+ "mp4Video": "MP4 Video",
+ "mp4Description": "High quality video file",
+ "gifAnimation": "GIF Animation",
+ "gifDescription": "Animated image for sharing"
+ },
+ "gifOptions": {
+ "frameRate": "Frame Rate",
+ "outputSize": "Output Size",
+ "outputDimensions": "Output: {{width}} × {{height}}px",
+ "loopAnimation": "Loop Animation",
+ "loopDescription": "GIF will play continuously"
+ },
+ "tutorial": {
+ "howTrimmingWorks": "How trimming works",
+ "title": "How Trimming Works",
+ "understanding": "Understanding how to cut out unwanted parts of your video.",
+ "descriptionP1": "The Trim tool works by defining the segments you want to",
+ "descriptionRemove": "remove",
+ "descriptionP2": "from your video.",
+ "descriptionP3": "Any part of the timeline that is covered by a red trim segment will be cut out when you export.",
+ "visualExample": "Visual Example",
+ "removed": "REMOVED",
+ "kept": "Kept",
+ "finalVideo": "Final Video",
+ "part": "Part {{number}}",
+ "addTrimStep": "1. Add Trim",
+ "addTrimDesc": "Press T or click the scissors icon to mark a section for removal.",
+ "adjustStep": "2. Adjust",
+ "adjustDesc": "Drag the edges of the red region to cover exactly what you want to cut out."
+ },
+ "keyboardShortcuts": {
+ "title": "Keyboard Shortcuts",
+ "customizeTooltip": "Customize shortcuts",
+ "customize": "Customize",
+ "panTimeline": "Pan Timeline",
+ "zoomTimeline": "Zoom Timeline",
+ "cycleAnnotations": "Cycle Annotations",
+ "tab": "Tab"
+ },
+ "openRecordingsFolder": "Open recordings folder"
+}
diff --git a/src/i18n/locales/en/launch.json b/src/i18n/locales/en/launch.json
index 9e26dfee..4829693f 100644
--- a/src/i18n/locales/en/launch.json
+++ b/src/i18n/locales/en/launch.json
@@ -1 +1,36 @@
-{}
\ No newline at end of file
+{
+ "recording": {
+ "disableSystemAudio": "Disable system audio",
+ "enableSystemAudio": "Enable system audio",
+ "disableMicrophone": "Disable microphone",
+ "enableMicrophone": "Enable microphone",
+ "record": "Record",
+ "recordingFolder": "Recording folder: {{path}}",
+ "chooseRecordingsFolder": "Choose recordings folder",
+ "folderPath": "Path: /{{name}}/",
+ "openVideoFile": "Open video file",
+ "openProject": "Open project",
+ "hideHud": "Hide HUD",
+ "closeApp": "Close App"
+ },
+ "sourceSelector": {
+ "loadingSources": "Loading sources...",
+ "screens": "Screens",
+ "windows": "Windows",
+ "windowsNote": "Only visible (non-minimized) windows can be recorded.",
+ "windowPlaceholder": "Window",
+ "cancel": "Cancel",
+ "share": "Share"
+ },
+ "permissions": {
+ "screenRecordingNeeded": "Recordly needs Screen Recording permission before you start. System Settings has been opened. After enabling it, quit and reopen Recordly.",
+ "screenRecordingMissing": "Screen Recording permission is still missing. System Settings has been opened again. Enable it, then quit and reopen Recordly before recording.",
+ "accessibilityNeeded": "Recordly also needs Accessibility permission for cursor tracking. System Settings has been opened. After enabling it, quit and reopen Recordly.",
+ "accessibilityMissing": "Accessibility permission is still missing. System Settings has been opened again. Enable it, then quit and reopen Recordly before recording.",
+ "selectSource": "Please select a source to record",
+ "systemAudioUnavailable": "System audio is not available for this source. Recording will continue without system audio.",
+ "microphoneDenied": "Microphone access was denied. Recording will continue without microphone audio.",
+ "failedToStart": "Failed to start recording: {{error}}",
+ "failedToStartGeneric": "Failed to start recording"
+ }
+}
diff --git a/src/i18n/locales/en/settings.json b/src/i18n/locales/en/settings.json
index 9e26dfee..2405ce5f 100644
--- a/src/i18n/locales/en/settings.json
+++ b/src/i18n/locales/en/settings.json
@@ -1 +1,60 @@
-{}
\ No newline at end of file
+{
+ "zoom": {
+ "level": "Zoom Level",
+ "selectRegion": "Select a zoom region to adjust",
+ "deleteZoom": "Delete Zoom"
+ },
+ "trim": {
+ "deleteRegion": "Delete Trim Region"
+ },
+ "speed": {
+ "playbackSpeed": "Playback Speed",
+ "selectRegion": "Select a speed region to adjust",
+ "deleteRegion": "Delete Speed Region"
+ },
+ "effects": {
+ "title": "Video Effects",
+ "showCursor": "Show Cursor",
+ "loopCursor": "Loop cursor",
+ "backgroundBlur": "Background Blur",
+ "zoomMotionBlur": "Zoom Motion Blur",
+ "connectZooms": "Connect Zooms",
+ "cursorSize": "Cursor Size",
+ "cursorSmoothing": "Cursor Smoothing",
+ "off": "Off",
+ "cursorMotionBlur": "Cursor Motion Blur",
+ "cursorClickBounce": "Cursor Click Bounce",
+ "shadow": "Shadow",
+ "roundness": "Roundness",
+ "padding": "Padding"
+ },
+ "crop": {
+ "title": "Crop Video",
+ "instruction": "Drag on each side to adjust the crop area"
+ },
+ "background": {
+ "title": "Background",
+ "image": "Image",
+ "color": "Color",
+ "gradient": "Gradient",
+ "uploadCustom": "Upload Custom",
+ "uploadSuccess": "Custom image uploaded successfully!",
+ "uploadError": "Please upload a JPG or JPEG image file."
+ },
+ "export": {
+ "mp4": "MP4",
+ "gif": "GIF",
+ "quality": {
+ "low": "Low",
+ "medium": "Medium",
+ "high": "High"
+ },
+ "loop": "Loop",
+ "outputDimensions": "Output: {{dimensions}}px",
+ "loadProject": "Load Project",
+ "saveProject": "Save Project",
+ "exportVideo": "Export {{format}}",
+ "reportBug": "Report Bug",
+ "starOnGithub": "Star on GitHub"
+ }
+}
diff --git a/src/i18n/locales/en/shortcuts.json b/src/i18n/locales/en/shortcuts.json
index 9e26dfee..dd789d98 100644
--- a/src/i18n/locales/en/shortcuts.json
+++ b/src/i18n/locales/en/shortcuts.json
@@ -1 +1,16 @@
-{}
\ No newline at end of file
+{
+ "actions": {
+ "addZoom": "Add Zoom",
+ "addTrim": "Add Trim",
+ "addSpeed": "Add Speed",
+ "addAnnotation": "Add Annotation",
+ "addKeyframe": "Add Keyframe",
+ "deleteSelected": "Delete Selected",
+ "playPause": "Play / Pause",
+ "cycleForward": "Cycle Annotations Forward",
+ "cycleBackward": "Cycle Annotations Backward",
+ "deleteSelectedAlt": "Delete Selected (alt)",
+ "panTimeline": "Pan Timeline",
+ "zoomTimeline": "Zoom Timeline"
+ }
+}
diff --git a/src/i18n/locales/en/timeline.json b/src/i18n/locales/en/timeline.json
index 9e26dfee..23be3abb 100644
--- a/src/i18n/locales/en/timeline.json
+++ b/src/i18n/locales/en/timeline.json
@@ -1 +1,38 @@
-{}
\ No newline at end of file
+{
+ "zoom": {
+ "cannotPlace": "Cannot place zoom here",
+ "existsOrNoSpace": "Zoom already exists at this location or not enough space available.",
+ "suggestHandlerUnavailable": "Zoom suggestion handler unavailable",
+ "noTelemetry": "No cursor telemetry available",
+ "recordFirst": "Record a screencast first to generate cursor-based suggestions.",
+ "noUsableTelemetry": "No usable cursor telemetry",
+ "notEnoughMovement": "The recording does not include enough cursor movement data.",
+ "noInteractionMoments": "No clear interaction moments found",
+ "tryRecording": "Try a recording with pauses or clicks around important actions.",
+ "noAutoZoomSlots": "No auto-zoom slots available",
+ "dwellPointsOverlap": "Detected dwell points overlap existing zoom regions.",
+ "addedSuggestions": "Added {{count}} interaction-based zoom suggestion(s)",
+ "label": "Zoom {{index}}",
+ "addZoom": "Add Zoom (Z)",
+ "suggestZooms": "Suggest Zooms from Cursor"
+ },
+ "trim": {
+ "cannotPlace": "Cannot place trim here",
+ "existsOrNoSpace": "Trim already exists at this location or not enough space available.",
+ "label": "Trim {{index}}",
+ "addTrim": "Add Trim (T)"
+ },
+ "speed": {
+ "cannotPlace": "Cannot place speed here",
+ "existsOrNoSpace": "Speed region already exists at this location or not enough space available.",
+ "label": "Speed"
+ },
+ "annotation": {
+ "label": "Annotation",
+ "image": "Image",
+ "addAnnotation": "Add Annotation (A)"
+ },
+ "addSpeed": "Add Speed (S)",
+ "resizeLeft": "Resize left",
+ "resizeRight": "Resize right"
+}
diff --git a/src/i18n/locales/es/common.json b/src/i18n/locales/es/common.json
index f5f8d728..92020782 100644
--- a/src/i18n/locales/es/common.json
+++ b/src/i18n/locales/es/common.json
@@ -1,7 +1,18 @@
{
- "app": {
- "name": "Recordly",
- "editorTitle": "Editor de Recordly",
- "subtitle": "Grabacion de pantalla y edicion"
- }
-}
\ No newline at end of file
+ "app": {
+ "name": "Recordly",
+ "editorTitle": "Editor de Recordly",
+ "subtitle": "Grabación de pantalla y edición"
+ },
+ "actions": {
+ "cancel": "Cancelar",
+ "save": "Guardar",
+ "delete": "Eliminar",
+ "done": "Hecho"
+ },
+ "errors": {
+ "invalidFileType": "Tipo de archivo inválido",
+ "failedToUploadImage": "Error al subir la imagen",
+ "fileReadError": "Hubo un error al leer el archivo."
+ }
+}
diff --git a/src/i18n/locales/es/dialogs.json b/src/i18n/locales/es/dialogs.json
index 9e26dfee..283682b5 100644
--- a/src/i18n/locales/es/dialogs.json
+++ b/src/i18n/locales/es/dialogs.json
@@ -1 +1,61 @@
-{}
\ No newline at end of file
+{
+ "export": {
+ "pleaseTryAgain": "Por favor inténtalo de nuevo",
+ "compilingGifProgress": "Compilando GIF... {{progress}}%",
+ "compilingGifWait": "Compilando GIF... Esto puede tardar un momento",
+ "takeMoment": "Esto puede tardar un momento...",
+ "exportFailed": "Error en la exportación",
+ "compilingGifTitle": "Compilando GIF",
+ "exportingFormat": "Exportando {{format}}",
+ "exportComplete": "Exportación completada",
+ "formatReady": "Tu {{format}} está listo",
+ "showInFolder": "Mostrar en carpeta",
+ "compiling": "Compilando",
+ "renderingFrames": "Renderizando cuadros",
+ "processing": "Procesando...",
+ "status": "Estado",
+ "format": "Formato",
+ "compilingStatus": "Compilando...",
+ "frames": "Cuadros",
+ "cancelExport": "Cancelar exportación",
+ "savedSuccess": "¡{{format}} guardado exitosamente!"
+ },
+ "addFont": {
+ "title": "Agregar fuente de Google",
+ "heading": "Agregar fuente de Google",
+ "description": "Agrega una fuente personalizada de Google Fonts para usar en tus anotaciones.",
+ "urlLabel": "URL de importación de Google Fonts",
+ "urlPlaceholder": "https://fonts.googleapis.com/css2?family=Roboto&display=swap",
+ "urlHelp": "Obtén esto de Google Fonts: Selecciona una fuente → Haz clic en \"Obtener fuente\" → Copia la URL de @import",
+ "nameLabel": "Nombre para mostrar",
+ "namePlaceholder": "Mi fuente personalizada",
+ "nameHelp": "Así aparecerá la fuente en el selector de fuentes",
+ "adding": "Agregando...",
+ "addFont": "Agregar fuente",
+ "enterUrl": "Por favor ingresa una URL de importación de Google Fonts",
+ "invalidUrl": "Por favor ingresa una URL válida de Google Fonts",
+ "enterName": "Por favor ingresa un nombre de fuente",
+ "extractFailed": "No se pudo extraer el nombre de la familia de fuentes de la URL",
+ "addSuccess": "Fuente \"{{name}}\" agregada exitosamente",
+ "addFailed": "Error al agregar la fuente",
+ "loadTimeout": "La fuente tardó demasiado en cargar. Por favor verifica la URL e inténtalo de nuevo.",
+ "loadFailed": "No se pudo cargar la fuente. Por favor verifica que la URL de Google Fonts sea correcta."
+ },
+ "shortcutsConfig": {
+ "title": "Atajos de teclado",
+ "configurable": "Configurable",
+ "fixed": "Fijo",
+ "pressEscToCancel": "Presiona Esc para cancelar",
+ "clickToChange": "Haz clic para cambiar",
+ "pressAKey": "Presiona una tecla…",
+ "alreadyUsedBy": "Ya está en uso por {{action}}",
+ "swap": "Intercambiar",
+ "reserved": "Este atajo está reservado para \"{{label}}\" y no se puede reasignar.",
+ "saved": "Atajos de teclado guardados",
+ "resetNotice": "Restablecer a atajos predeterminados — haz clic en Guardar para aplicar",
+ "instructions": "Haz clic en un atajo y luego presiona la nueva combinación de teclas. Presiona Esc para cancelar.",
+ "resetToDefaults": "Restablecer valores predeterminados",
+ "cancel": "Cancelar",
+ "save": "Guardar"
+ }
+}
diff --git a/src/i18n/locales/es/editor.json b/src/i18n/locales/es/editor.json
index 9e26dfee..32d71924 100644
--- a/src/i18n/locales/es/editor.json
+++ b/src/i18n/locales/es/editor.json
@@ -1 +1,91 @@
-{}
\ No newline at end of file
+{
+ "playback": {
+ "play": "Reproducir",
+ "pause": "Pausar"
+ },
+ "annotations": {
+ "settings": "Configuración de anotaciones",
+ "active": "Activo",
+ "text": "Texto",
+ "image": "Imagen",
+ "arrow": "Flecha",
+ "textContent": "Contenido de texto",
+ "textPlaceholder": "Ingresa tu texto...",
+ "fontStyle": "Estilo de fuente",
+ "selectStyle": "Seleccionar estilo",
+ "size": "Tamaño",
+ "toggleBold": "Alternar negrita",
+ "toggleItalic": "Alternar cursiva",
+ "toggleUnderline": "Alternar subrayado",
+ "alignLeft": "Alinear a la izquierda",
+ "alignCenter": "Alinear al centro",
+ "alignRight": "Alinear a la derecha",
+ "textColor": "Color de texto",
+ "background": "Fondo",
+ "none": "Ninguno",
+ "clearBackground": "Borrar fondo",
+ "uploadImage": "Subir imagen",
+ "supportedFormats": "Formatos compatibles: JPG, PNG, GIF, WebP",
+ "arrowDirection": "Dirección de flecha",
+ "strokeWidth": "Ancho de trazo: {{width}}px",
+ "arrowColor": "Color de flecha",
+ "deleteAnnotation": "Eliminar anotación",
+ "shortcutsAndTips": "Atajos y consejos",
+ "tipSelectAnnotation": "Mueve el cabezal de reproducción a la sección de anotación superpuesta y selecciona un elemento.",
+ "tipCycleForward": "Usa Tab para recorrer los elementos superpuestos.",
+ "tipCycleBackward": "Usa Shift+Tab para recorrer hacia atrás.",
+ "imageUploadSuccess": "¡Imagen subida exitosamente!",
+ "imageUploadError": "Por favor sube un archivo de imagen JPG, PNG, GIF o WebP."
+ },
+ "fontStyles": {
+ "classic": "Clásico",
+ "editor": "Editor",
+ "strong": "Fuerte",
+ "typewriter": "Máquina de escribir",
+ "deco": "Deco",
+ "simple": "Simple",
+ "modern": "Moderno",
+ "clean": "Limpio"
+ },
+ "format": {
+ "mp4Video": "Video MP4",
+ "mp4Description": "Archivo de video de alta calidad",
+ "gifAnimation": "Animación GIF",
+ "gifDescription": "Imagen animada para compartir"
+ },
+ "gifOptions": {
+ "frameRate": "Velocidad de cuadros",
+ "outputSize": "Tamaño de salida",
+ "outputDimensions": "Salida: {{width}} × {{height}}px",
+ "loopAnimation": "Animación en bucle",
+ "loopDescription": "El GIF se reproducirá continuamente"
+ },
+ "tutorial": {
+ "howTrimmingWorks": "Cómo funciona el recorte",
+ "title": "Cómo Funciona el Recorte",
+ "understanding": "Comprende cómo eliminar las partes no deseadas de tu video.",
+ "descriptionP1": "La herramienta de recorte funciona definiendo los segmentos que deseas",
+ "descriptionRemove": "eliminar",
+ "descriptionP2": "de tu video.",
+ "descriptionP3": "Cualquier parte de la línea de tiempo cubierta por un segmento de recorte rojo será eliminada al exportar.",
+ "visualExample": "Ejemplo visual",
+ "removed": "ELIMINADO",
+ "kept": "Conservado",
+ "finalVideo": "Video final",
+ "part": "Parte {{number}}",
+ "addTrimStep": "1. Agregar recorte",
+ "addTrimDesc": "Presiona T o haz clic en el ícono de tijeras para marcar una sección para eliminar.",
+ "adjustStep": "2. Ajustar",
+ "adjustDesc": "Arrastra los bordes de la región roja para cubrir exactamente lo que deseas eliminar."
+ },
+ "keyboardShortcuts": {
+ "title": "Atajos de teclado",
+ "customizeTooltip": "Personalizar atajos",
+ "customize": "Personalizar",
+ "panTimeline": "Desplazar línea de tiempo",
+ "zoomTimeline": "Zoom en línea de tiempo",
+ "cycleAnnotations": "Recorrer anotaciones",
+ "tab": "Tab"
+ },
+ "openRecordingsFolder": "Abrir carpeta de grabaciones"
+}
diff --git a/src/i18n/locales/es/launch.json b/src/i18n/locales/es/launch.json
index 9e26dfee..5fd0e6db 100644
--- a/src/i18n/locales/es/launch.json
+++ b/src/i18n/locales/es/launch.json
@@ -1 +1,36 @@
-{}
\ No newline at end of file
+{
+ "recording": {
+ "disableSystemAudio": "Desactivar audio del sistema",
+ "enableSystemAudio": "Activar audio del sistema",
+ "disableMicrophone": "Desactivar micrófono",
+ "enableMicrophone": "Activar micrófono",
+ "record": "Grabar",
+ "recordingFolder": "Carpeta de grabaciones: {{path}}",
+ "chooseRecordingsFolder": "Elegir carpeta de grabaciones",
+ "folderPath": "Ruta: /{{name}}/",
+ "openVideoFile": "Abrir archivo de video",
+ "openProject": "Abrir proyecto",
+ "hideHud": "Ocultar HUD",
+ "closeApp": "Cerrar aplicación"
+ },
+ "sourceSelector": {
+ "loadingSources": "Cargando fuentes...",
+ "screens": "Pantallas",
+ "windows": "Ventanas",
+ "windowsNote": "Solo se pueden grabar las ventanas visibles (no minimizadas).",
+ "windowPlaceholder": "Ventana",
+ "cancel": "Cancelar",
+ "share": "Compartir"
+ },
+ "permissions": {
+ "screenRecordingNeeded": "Recordly needs Screen Recording permission before you start. System Settings has been opened. After enabling it, quit and reopen Recordly.",
+ "screenRecordingMissing": "Screen Recording permission is still missing. System Settings has been opened again. Enable it, then quit and reopen Recordly before recording.",
+ "accessibilityNeeded": "Recordly also needs Accessibility permission for cursor tracking. System Settings has been opened. After enabling it, quit and reopen Recordly.",
+ "accessibilityMissing": "Accessibility permission is still missing. System Settings has been opened again. Enable it, then quit and reopen Recordly before recording.",
+ "selectSource": "Por favor selecciona una fuente para grabar",
+ "systemAudioUnavailable": "El audio del sistema no está disponible para esta fuente. La grabación continuará sin audio del sistema.",
+ "microphoneDenied": "Se denegó el acceso al micrófono. La grabación continuará sin audio del micrófono.",
+ "failedToStart": "Error al iniciar la grabación: {{error}}",
+ "failedToStartGeneric": "Error al iniciar la grabación"
+ }
+}
diff --git a/src/i18n/locales/es/settings.json b/src/i18n/locales/es/settings.json
index 9e26dfee..7b3a1379 100644
--- a/src/i18n/locales/es/settings.json
+++ b/src/i18n/locales/es/settings.json
@@ -1 +1,60 @@
-{}
\ No newline at end of file
+{
+ "zoom": {
+ "level": "Nivel de zoom",
+ "selectRegion": "Selecciona una región de zoom para ajustar",
+ "deleteZoom": "Eliminar zoom"
+ },
+ "trim": {
+ "deleteRegion": "Eliminar región de recorte"
+ },
+ "speed": {
+ "playbackSpeed": "Velocidad de reproducción",
+ "selectRegion": "Selecciona una región de velocidad para ajustar",
+ "deleteRegion": "Eliminar región de velocidad"
+ },
+ "effects": {
+ "title": "Efectos de video",
+ "showCursor": "Mostrar cursor",
+ "loopCursor": "Cursor en bucle",
+ "backgroundBlur": "Desenfoque de fondo",
+ "zoomMotionBlur": "Desenfoque de movimiento del zoom",
+ "connectZooms": "Conectar zooms",
+ "cursorSize": "Tamaño del cursor",
+ "cursorSmoothing": "Suavizado del cursor",
+ "off": "Desactivado",
+ "cursorMotionBlur": "Desenfoque de movimiento del cursor",
+ "cursorClickBounce": "Rebote de clic del cursor",
+ "shadow": "Sombra",
+ "roundness": "Redondez",
+ "padding": "Relleno"
+ },
+ "crop": {
+ "title": "Recortar video",
+ "instruction": "Arrastra cada lado para ajustar el área de recorte"
+ },
+ "background": {
+ "title": "Fondo",
+ "image": "Imagen",
+ "color": "Color",
+ "gradient": "Degradado",
+ "uploadCustom": "Subir personalizado",
+ "uploadSuccess": "¡Imagen personalizada subida exitosamente!",
+ "uploadError": "Por favor sube un archivo de imagen JPG o JPEG."
+ },
+ "export": {
+ "mp4": "MP4",
+ "gif": "GIF",
+ "quality": {
+ "low": "Baja",
+ "medium": "Media",
+ "high": "Alta"
+ },
+ "loop": "Bucle",
+ "outputDimensions": "Salida: {{dimensions}}px",
+ "loadProject": "Cargar proyecto",
+ "saveProject": "Guardar proyecto",
+ "exportVideo": "Exportar {{format}}",
+ "reportBug": "Reportar error",
+ "starOnGithub": "Estrella en GitHub"
+ }
+}
diff --git a/src/i18n/locales/es/shortcuts.json b/src/i18n/locales/es/shortcuts.json
index 9e26dfee..28b42cbc 100644
--- a/src/i18n/locales/es/shortcuts.json
+++ b/src/i18n/locales/es/shortcuts.json
@@ -1 +1,16 @@
-{}
\ No newline at end of file
+{
+ "actions": {
+ "addZoom": "Agregar Zoom",
+ "addTrim": "Agregar Recorte",
+ "addSpeed": "Agregar Velocidad",
+ "addAnnotation": "Agregar Anotación",
+ "addKeyframe": "Agregar Fotograma clave",
+ "deleteSelected": "Eliminar seleccionado",
+ "playPause": "Reproducir / Pausar",
+ "cycleForward": "Recorrer anotaciones hacia adelante",
+ "cycleBackward": "Recorrer anotaciones hacia atrás",
+ "deleteSelectedAlt": "Eliminar seleccionado (alt)",
+ "panTimeline": "Desplazar línea de tiempo",
+ "zoomTimeline": "Zoom en línea de tiempo"
+ }
+}
diff --git a/src/i18n/locales/es/timeline.json b/src/i18n/locales/es/timeline.json
index 9e26dfee..ed948860 100644
--- a/src/i18n/locales/es/timeline.json
+++ b/src/i18n/locales/es/timeline.json
@@ -1 +1,38 @@
-{}
\ No newline at end of file
+{
+ "zoom": {
+ "cannotPlace": "No se puede colocar zoom aquí",
+ "existsOrNoSpace": "Ya existe un zoom en esta ubicación o no hay suficiente espacio.",
+ "suggestHandlerUnavailable": "Manejador de sugerencias de zoom no disponible",
+ "noTelemetry": "No hay telemetría de cursor disponible",
+ "recordFirst": "Graba una captura de pantalla primero para generar sugerencias basadas en el cursor.",
+ "noUsableTelemetry": "No hay telemetría de cursor utilizable",
+ "notEnoughMovement": "La grabación no incluye suficientes datos de movimiento del cursor.",
+ "noInteractionMoments": "No se encontraron momentos de interacción claros",
+ "tryRecording": "Intenta una grabación con pausas o clics alrededor de acciones importantes.",
+ "noAutoZoomSlots": "No hay espacios de auto-zoom disponibles",
+ "dwellPointsOverlap": "Los puntos de permanencia detectados se superponen con regiones de zoom existentes.",
+ "addedSuggestions": "Se agregaron {{count}} sugerencia(s) de zoom basadas en interacción",
+ "label": "Zoom {{index}}",
+ "addZoom": "Agregar Zoom (Z)",
+ "suggestZooms": "Sugerir zooms desde cursor"
+ },
+ "trim": {
+ "cannotPlace": "No se puede colocar recorte aquí",
+ "existsOrNoSpace": "Ya existe un recorte en esta ubicación o no hay suficiente espacio.",
+ "label": "Recorte {{index}}",
+ "addTrim": "Agregar Recorte (T)"
+ },
+ "speed": {
+ "cannotPlace": "No se puede colocar velocidad aquí",
+ "existsOrNoSpace": "Ya existe una región de velocidad en esta ubicación o no hay suficiente espacio.",
+ "label": "Velocidad"
+ },
+ "annotation": {
+ "label": "Anotación",
+ "image": "Imagen",
+ "addAnnotation": "Agregar Anotación (A)"
+ },
+ "addSpeed": "Agregar Velocidad (S)",
+ "resizeLeft": "Redimensionar izquierda",
+ "resizeRight": "Redimensionar derecha"
+}
diff --git a/src/i18n/locales/zh-CN/common.json b/src/i18n/locales/zh-CN/common.json
index 0967ef42..bee0c88b 100644
--- a/src/i18n/locales/zh-CN/common.json
+++ b/src/i18n/locales/zh-CN/common.json
@@ -1 +1,18 @@
-{}
+{
+ "app": {
+ "name": "Recordly",
+ "editorTitle": "Recordly 编辑器",
+ "subtitle": "屏幕录制与编辑"
+ },
+ "actions": {
+ "cancel": "取消",
+ "save": "保存",
+ "delete": "删除",
+ "done": "完成"
+ },
+ "errors": {
+ "invalidFileType": "无效的文件类型",
+ "failedToUploadImage": "上传图片失败",
+ "fileReadError": "读取文件时出错。"
+ }
+}
diff --git a/src/i18n/locales/zh-CN/dialogs.json b/src/i18n/locales/zh-CN/dialogs.json
index 0967ef42..a1749127 100644
--- a/src/i18n/locales/zh-CN/dialogs.json
+++ b/src/i18n/locales/zh-CN/dialogs.json
@@ -1 +1,61 @@
-{}
+{
+ "export": {
+ "pleaseTryAgain": "请重试",
+ "compilingGifProgress": "正在编译 GIF... {{progress}}%",
+ "compilingGifWait": "正在编译 GIF... 这可能需要一些时间",
+ "takeMoment": "这可能需要一点时间...",
+ "exportFailed": "导出失败",
+ "compilingGifTitle": "正在编译 GIF",
+ "exportingFormat": "正在导出 {{format}}",
+ "exportComplete": "导出完成",
+ "formatReady": "您的 {{format}} 已准备就绪",
+ "showInFolder": "在文件夹中显示",
+ "compiling": "正在编译",
+ "renderingFrames": "正在渲染帧",
+ "processing": "正在处理...",
+ "status": "状态",
+ "format": "格式",
+ "compilingStatus": "正在编译...",
+ "frames": "帧",
+ "cancelExport": "取消导出",
+ "savedSuccess": "{{format}} 保存成功!"
+ },
+ "addFont": {
+ "title": "添加 Google 字体",
+ "heading": "添加 Google 字体",
+ "description": "从 Google Fonts 添加自定义字体用于注释。",
+ "urlLabel": "Google Fonts 导入 URL",
+ "urlPlaceholder": "https://fonts.googleapis.com/css2?family=Roboto&display=swap",
+ "urlHelp": "从 Google Fonts 获取:选择字体 → 点击「获取字体」→ 复制 @import URL",
+ "nameLabel": "显示名称",
+ "namePlaceholder": "我的自定义字体",
+ "nameHelp": "此名称将显示在字体选择器中",
+ "adding": "正在添加...",
+ "addFont": "添加字体",
+ "enterUrl": "请输入 Google Fonts 导入 URL",
+ "invalidUrl": "请输入有效的 Google Fonts URL",
+ "enterName": "请输入字体名称",
+ "extractFailed": "无法从 URL 提取字体系列名称",
+ "addSuccess": "字体 \"{{name}}\" 添加成功",
+ "addFailed": "添加字体失败",
+ "loadTimeout": "字体加载超时。请检查 URL 后重试。",
+ "loadFailed": "无法加载字体。请确认 Google Fonts URL 是否正确。"
+ },
+ "shortcutsConfig": {
+ "title": "键盘快捷键",
+ "configurable": "可配置",
+ "fixed": "固定",
+ "pressEscToCancel": "按 Esc 取消",
+ "clickToChange": "点击以更改",
+ "pressAKey": "按下按键…",
+ "alreadyUsedBy": "已被 {{action}} 使用",
+ "swap": "交换",
+ "reserved": "此快捷键已保留给 \"{{label}}\",无法重新分配。",
+ "saved": "键盘快捷键已保存",
+ "resetNotice": "已重置为默认快捷键 - 点击保存以应用",
+ "instructions": "点击快捷键后按下新的组合键。按 Esc 取消。",
+ "resetToDefaults": "重置为默认",
+ "cancel": "取消",
+ "save": "保存"
+ }
+}
diff --git a/src/i18n/locales/zh-CN/editor.json b/src/i18n/locales/zh-CN/editor.json
index 0967ef42..97358490 100644
--- a/src/i18n/locales/zh-CN/editor.json
+++ b/src/i18n/locales/zh-CN/editor.json
@@ -1 +1,91 @@
-{}
+{
+ "playback": {
+ "play": "播放",
+ "pause": "暂停"
+ },
+ "annotations": {
+ "settings": "注释设置",
+ "active": "活动",
+ "text": "文本",
+ "image": "图片",
+ "arrow": "箭头",
+ "textContent": "文本内容",
+ "textPlaceholder": "输入文本...",
+ "fontStyle": "字体样式",
+ "selectStyle": "选择样式",
+ "size": "大小",
+ "toggleBold": "切换粗体",
+ "toggleItalic": "切换斜体",
+ "toggleUnderline": "切换下划线",
+ "alignLeft": "左对齐",
+ "alignCenter": "居中对齐",
+ "alignRight": "右对齐",
+ "textColor": "文本颜色",
+ "background": "背景",
+ "none": "无",
+ "clearBackground": "清除背景",
+ "uploadImage": "上传图片",
+ "supportedFormats": "支持格式:JPG、PNG、GIF、WebP",
+ "arrowDirection": "箭头方向",
+ "strokeWidth": "描边宽度:{{width}}px",
+ "arrowColor": "箭头颜色",
+ "deleteAnnotation": "删除注释",
+ "shortcutsAndTips": "快捷键与提示",
+ "tipSelectAnnotation": "将播放头移动到注释重叠区域并选择项目。",
+ "tipCycleForward": "使用 Tab 循环切换重叠项目。",
+ "tipCycleBackward": "使用 Shift+Tab 反向循环切换。",
+ "imageUploadSuccess": "图片上传成功!",
+ "imageUploadError": "请上传 JPG、PNG、GIF 或 WebP 图片文件。"
+ },
+ "fontStyles": {
+ "classic": "经典",
+ "editor": "编辑器",
+ "strong": "加粗",
+ "typewriter": "打字机",
+ "deco": "装饰",
+ "simple": "简约",
+ "modern": "现代",
+ "clean": "清爽"
+ },
+ "format": {
+ "mp4Video": "MP4 视频",
+ "mp4Description": "高质量视频文件",
+ "gifAnimation": "GIF 动画",
+ "gifDescription": "可分享的动态图片"
+ },
+ "gifOptions": {
+ "frameRate": "帧率",
+ "outputSize": "输出尺寸",
+ "outputDimensions": "输出:{{width}} × {{height}}px",
+ "loopAnimation": "循环动画",
+ "loopDescription": "GIF 将持续播放"
+ },
+ "tutorial": {
+ "howTrimmingWorks": "修剪的工作方式",
+ "title": "修剪的工作方式",
+ "understanding": "了解如何裁剪视频中不需要的部分。",
+ "descriptionP1": "修剪工具通过定义要",
+ "descriptionRemove": "移除",
+ "descriptionP2": "的片段来工作。",
+ "descriptionP3": "时间线上被红色修剪区域覆盖的部分将在导出时被剪掉。",
+ "visualExample": "视觉示例",
+ "removed": "已移除",
+ "kept": "保留",
+ "finalVideo": "最终视频",
+ "part": "第 {{number}} 部分",
+ "addTrimStep": "1. 添加修剪",
+ "addTrimDesc": "按 T 或点击剪刀图标标记要移除的部分。",
+ "adjustStep": "2. 调整",
+ "adjustDesc": "拖动红色区域的边缘,精确覆盖要剪掉的部分。"
+ },
+ "keyboardShortcuts": {
+ "title": "键盘快捷键",
+ "customizeTooltip": "自定义快捷键",
+ "customize": "自定义",
+ "panTimeline": "平移时间线",
+ "zoomTimeline": "缩放时间线",
+ "cycleAnnotations": "循环切换注释",
+ "tab": "Tab"
+ },
+ "openRecordingsFolder": "打开录制文件夹"
+}
diff --git a/src/i18n/locales/zh-CN/launch.json b/src/i18n/locales/zh-CN/launch.json
index 0967ef42..9ac43f3a 100644
--- a/src/i18n/locales/zh-CN/launch.json
+++ b/src/i18n/locales/zh-CN/launch.json
@@ -1 +1,36 @@
-{}
+{
+ "recording": {
+ "disableSystemAudio": "禁用系统音频",
+ "enableSystemAudio": "启用系统音频",
+ "disableMicrophone": "禁用麦克风",
+ "enableMicrophone": "启用麦克风",
+ "record": "录制",
+ "recordingFolder": "录制文件夹:{{path}}",
+ "chooseRecordingsFolder": "选择录制文件夹",
+ "folderPath": "路径:/{{name}}/",
+ "openVideoFile": "打开视频文件",
+ "openProject": "打开项目",
+ "hideHud": "隐藏 HUD",
+ "closeApp": "关闭应用"
+ },
+ "sourceSelector": {
+ "loadingSources": "正在加载源...",
+ "screens": "屏幕",
+ "windows": "窗口",
+ "windowsNote": "仅可录制可见(非最小化)窗口。",
+ "windowPlaceholder": "窗口",
+ "cancel": "取消",
+ "share": "共享"
+ },
+ "permissions": {
+ "screenRecordingNeeded": "Recordly 需要屏幕录制权限才能开始。系统设置已打开。启用后请退出并重新打开 Recordly。",
+ "screenRecordingMissing": "屏幕录制权限仍然缺失。系统设置已再次打开。请启用权限,然后退出并重新打开 Recordly。",
+ "accessibilityNeeded": "Recordly 还需要辅助功能权限以跟踪光标。系统设置已打开。启用后请退出并重新打开 Recordly。",
+ "accessibilityMissing": "辅助功能权限仍然缺失。系统设置已再次打开。请启用权限,然后退出并重新打开 Recordly。",
+ "selectSource": "请选择要录制的源",
+ "systemAudioUnavailable": "此源不支持系统音频。将继续录制但不包含系统音频。",
+ "microphoneDenied": "麦克风访问被拒绝。将继续录制但不包含麦克风音频。",
+ "failedToStart": "录制启动失败:{{error}}",
+ "failedToStartGeneric": "录制启动失败"
+ }
+}
diff --git a/src/i18n/locales/zh-CN/settings.json b/src/i18n/locales/zh-CN/settings.json
index 0967ef42..46106e60 100644
--- a/src/i18n/locales/zh-CN/settings.json
+++ b/src/i18n/locales/zh-CN/settings.json
@@ -1 +1,60 @@
-{}
+{
+ "zoom": {
+ "level": "缩放级别",
+ "selectRegion": "选择缩放区域以调整",
+ "deleteZoom": "删除缩放"
+ },
+ "trim": {
+ "deleteRegion": "删除修剪区域"
+ },
+ "speed": {
+ "playbackSpeed": "播放速度",
+ "selectRegion": "选择变速区域以调整",
+ "deleteRegion": "删除变速区域"
+ },
+ "effects": {
+ "title": "视频效果",
+ "showCursor": "显示光标",
+ "loopCursor": "循环光标",
+ "backgroundBlur": "背景模糊",
+ "zoomMotionBlur": "缩放运动模糊",
+ "connectZooms": "连接缩放",
+ "cursorSize": "光标大小",
+ "cursorSmoothing": "光标平滑",
+ "off": "关",
+ "cursorMotionBlur": "光标运动模糊",
+ "cursorClickBounce": "光标点击弹跳",
+ "shadow": "阴影",
+ "roundness": "圆角",
+ "padding": "内边距"
+ },
+ "crop": {
+ "title": "裁剪视频",
+ "instruction": "拖动各边以调整裁剪区域"
+ },
+ "background": {
+ "title": "背景",
+ "image": "图片",
+ "color": "颜色",
+ "gradient": "渐变",
+ "uploadCustom": "上传自定义",
+ "uploadSuccess": "自定义图片上传成功!",
+ "uploadError": "请上传 JPG 或 JPEG 图片文件。"
+ },
+ "export": {
+ "mp4": "MP4",
+ "gif": "GIF",
+ "quality": {
+ "low": "低",
+ "medium": "中",
+ "high": "高"
+ },
+ "loop": "循环",
+ "outputDimensions": "输出:{{dimensions}}px",
+ "loadProject": "加载项目",
+ "saveProject": "保存项目",
+ "exportVideo": "导出{{format}}",
+ "reportBug": "报告问题",
+ "starOnGithub": "在 GitHub 上加星"
+ }
+}
diff --git a/src/i18n/locales/zh-CN/shortcuts.json b/src/i18n/locales/zh-CN/shortcuts.json
index 0967ef42..9e3f599b 100644
--- a/src/i18n/locales/zh-CN/shortcuts.json
+++ b/src/i18n/locales/zh-CN/shortcuts.json
@@ -1 +1,16 @@
-{}
+{
+ "actions": {
+ "addZoom": "添加缩放",
+ "addTrim": "添加修剪",
+ "addSpeed": "添加变速",
+ "addAnnotation": "添加注释",
+ "addKeyframe": "添加关键帧",
+ "deleteSelected": "删除选中",
+ "playPause": "播放 / 暂停",
+ "cycleForward": "向前循环切换注释",
+ "cycleBackward": "向后循环切换注释",
+ "deleteSelectedAlt": "删除选中(替代)",
+ "panTimeline": "平移时间线",
+ "zoomTimeline": "缩放时间线"
+ }
+}
diff --git a/src/i18n/locales/zh-CN/timeline.json b/src/i18n/locales/zh-CN/timeline.json
index 0967ef42..53e1054d 100644
--- a/src/i18n/locales/zh-CN/timeline.json
+++ b/src/i18n/locales/zh-CN/timeline.json
@@ -1 +1,38 @@
-{}
+{
+ "zoom": {
+ "cannotPlace": "无法在此处放置缩放",
+ "existsOrNoSpace": "此位置已存在缩放或空间不足。",
+ "suggestHandlerUnavailable": "缩放建议处理不可用",
+ "noTelemetry": "无光标遥测数据",
+ "recordFirst": "请先录制屏幕以生成基于光标的建议。",
+ "noUsableTelemetry": "无可用的光标遥测数据",
+ "notEnoughMovement": "录制中未包含足够的光标移动数据。",
+ "noInteractionMoments": "未找到明显的交互时刻",
+ "tryRecording": "尝试在关键操作附近有停顿或点击的录制。",
+ "noAutoZoomSlots": "没有可用的自动缩放位置",
+ "dwellPointsOverlap": "检测到的停留点与现有缩放区域重叠。",
+ "addedSuggestions": "已添加 {{count}} 个基于交互的缩放建议",
+ "label": "缩放 {{index}}",
+ "addZoom": "添加缩放 (Z)",
+ "suggestZooms": "从光标建议缩放"
+ },
+ "trim": {
+ "cannotPlace": "无法在此处放置修剪",
+ "existsOrNoSpace": "此位置已存在修剪或空间不足。",
+ "label": "修剪 {{index}}",
+ "addTrim": "添加修剪 (T)"
+ },
+ "speed": {
+ "cannotPlace": "无法在此处放置变速",
+ "existsOrNoSpace": "此位置已存在变速区域或空间不足。",
+ "label": "变速"
+ },
+ "annotation": {
+ "label": "注释",
+ "image": "图片",
+ "addAnnotation": "添加注释 (A)"
+ },
+ "addSpeed": "添加变速 (S)",
+ "resizeLeft": "向左调整",
+ "resizeRight": "向右调整"
+}