Fix formatting and locale config

This commit is contained in:
LorenzoLancia
2026-04-08 20:26:16 +02:00
parent a4f1c6a2ee
commit 5a9c85c345
20 changed files with 1294 additions and 11 deletions
+1248
View File
File diff suppressed because it is too large Load Diff
@@ -53,8 +53,8 @@ export function AnnotationOverlay({
const y = (annotation.position.y / 100) * containerHeight;
const width = (annotation.size.width / 100) * containerWidth;
const height = (annotation.size.height / 100) * containerHeight;
const isSelectedFreehandBlur = false;
const blurShape = annotation.type === "blur" ? annotation.blurData?.shape || "rectangle" : null;
const isSelectedFreehandBlur = isSelected && blurShape === "freehand";
const isDraggingRef = useRef(false);
const isDrawingFreehandRef = useRef(false);
const freehandPointsRef = useRef<Array<{ x: number; y: number }>>([]);
@@ -233,7 +233,7 @@ export function AnnotationOverlay({
);
case "blur": {
const shape = annotation.blurData?.shape === "oval" ? "oval" : "rectangle";
const shape = blurShape || "rectangle";
const blurIntensity = Math.max(
1,
Math.round(annotation.blurData?.intensity ?? DEFAULT_BLUR_INTENSITY),
@@ -276,7 +276,7 @@ export function AnnotationOverlay({
clipPath: isFreehandDrawing ? undefined : clipPath,
WebkitClipPath: isFreehandDrawing ? undefined : clipPath,
};
const isFreehandSelected = isSelected && shape === "freehand";
const isFreehandSelected = isSelectedFreehandBlur;
return (
<div className="w-full h-full relative">
<div
@@ -93,7 +93,9 @@ export function BlurSettingsPanel({
<div className="mt-4 p-3 rounded-lg bg-white/5 border border-white/10">
<div className="flex items-center justify-between mb-2">
<span className="text-xs font-medium text-slate-300">Blur intensity</span>
<span className="text-xs font-medium text-slate-300">
{t("annotation.blurIntensity")}
</span>
<span className="text-[10px] text-slate-400 font-mono">
{Math.round(blurRegion.blurData?.intensity ?? DEFAULT_BLUR_DATA.intensity)}px
</span>
@@ -670,6 +670,7 @@ export default function VideoEditor() {
setSelectedZoomId(null);
setSelectedTrimId(null);
setSelectedAnnotationId(null);
setSelectedSpeedId(null);
}
}, []);
@@ -1408,7 +1408,15 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(
const sorted = [...filtered].sort((a, b) => a.zIndex - b.zIndex);
const handleBlurClick = (clickedId: string) => {
onSelectBlur?.(clickedId);
if (!onSelectBlur) return;
if (clickedId === selectedBlurId && sorted.length > 1) {
const currentIndex = sorted.findIndex((a) => a.id === clickedId);
const nextIndex = (currentIndex + 1) % sorted.length;
onSelectBlur(sorted[nextIndex].id);
} else {
onSelectBlur(clickedId);
}
};
return sorted.map((blurRegion) => (
@@ -34,6 +34,7 @@ import {
} from "./types";
const WALLPAPER_COUNT = 18;
const VALID_BLUR_SHAPES = new Set(["rectangle", "oval", "freehand"] as const);
export const WALLPAPER_PATHS = Array.from(
{ length: WALLPAPER_COUNT },
@@ -259,6 +260,11 @@ export function normalizeProjectEditor(editor: Partial<ProjectEditorState>): Pro
const rawEnd = isFiniteNumber(region.endMs) ? Math.round(region.endMs) : rawStart + 1000;
const startMs = Math.max(0, Math.min(rawStart, rawEnd));
const endMs = Math.max(startMs + 1, rawEnd);
const blurShape =
typeof region.blurData?.shape === "string" &&
VALID_BLUR_SHAPES.has(region.blurData.shape)
? region.blurData.shape
: DEFAULT_BLUR_DATA.shape;
return {
id: region.id,
@@ -319,6 +325,7 @@ export function normalizeProjectEditor(editor: Partial<ProjectEditorState>): Pro
? {
...DEFAULT_BLUR_DATA,
...region.blurData,
shape: blurShape,
intensity: isFiniteNumber(region.blurData.intensity)
? clamp(region.blurData.intensity, MIN_BLUR_INTENSITY, MAX_BLUR_INTENSITY)
: DEFAULT_BLUR_INTENSITY,
@@ -1241,6 +1241,9 @@ export default function TimelineEditor({
if (matchesShortcut(e, keyShortcuts.addAnnotation, isMac)) {
handleAddAnnotation();
}
if (matchesShortcut(e, keyShortcuts.addBlur, isMac)) {
handleAddBlur();
}
if (matchesShortcut(e, keyShortcuts.addSpeed, isMac)) {
handleAddSpeed();
}
+1 -1
View File
@@ -1,5 +1,5 @@
export const DEFAULT_LOCALE = "en" as const;
export const SUPPORTED_LOCALES = ["en", "zh-CN", "es", , "fr", "tr"] as const;
export const SUPPORTED_LOCALES = ["en", "zh-CN", "es", "fr", "tr"] as const;
export const I18N_NAMESPACES = [
"common",
"dialogs",
+1
View File
@@ -119,6 +119,7 @@
"strokeWidth": "Stroke Width: {{width}}px",
"arrowColor": "Arrow Color",
"blurShape": "Blur Shape",
"blurIntensity": "Blur Intensity",
"blurShapeRectangle": "Rectangle",
"blurShapeOval": "Oval",
"blurShapeFreehand": "Freehand",
+1
View File
@@ -18,6 +18,7 @@
"addTrim": "Add Trim",
"addSpeed": "Add Speed",
"addAnnotation": "Add Annotation",
"addBlur": "Add Blur",
"addKeyframe": "Add Keyframe",
"deleteSelected": "Delete Selected",
"playPause": "Play / Pause"
+1
View File
@@ -119,6 +119,7 @@
"strokeWidth": "Grosor del trazo: {{width}}px",
"arrowColor": "Color de la flecha",
"blurShape": "Forma del desenfoque",
"blurIntensity": "Intensidad del desenfoque",
"blurShapeRectangle": "Rectángulo",
"blurShapeOval": "Óvalo",
"blurShapeFreehand": "Mano alzada",
+1
View File
@@ -18,6 +18,7 @@
"addTrim": "Agregar recorte",
"addSpeed": "Agregar velocidad",
"addAnnotation": "Agregar anotación",
"addBlur": "Agregar desenfoque",
"addKeyframe": "Agregar fotograma clave",
"deleteSelected": "Eliminar seleccionado",
"playPause": "Reproducir / Pausar"
+1
View File
@@ -116,6 +116,7 @@
"strokeWidth": "Épaisseur du trait : {{width}}px",
"arrowColor": "Couleur de la flèche",
"blurShape": "Forme du flou",
"blurIntensity": "Intensité du flou",
"blurShapeRectangle": "Rectangle",
"blurShapeOval": "Ovale",
"blurShapeFreehand": "Main levée",
+1
View File
@@ -18,6 +18,7 @@
"addTrim": "Ajouter une coupe",
"addSpeed": "Ajouter une vitesse",
"addAnnotation": "Ajouter une annotation",
"addBlur": "Ajouter un flou",
"addKeyframe": "Ajouter une image-clé",
"deleteSelected": "Supprimer la sélection",
"playPause": "Lecture / Pause"
+1
View File
@@ -116,6 +116,7 @@
"strokeWidth": "Çizgi Kalınlığı: {{width}}px",
"arrowColor": "Ok Rengi",
"blurShape": "Bulanik Sekli",
"blurIntensity": "Bulaniklik Yogunlugu",
"blurShapeRectangle": "Dikdortgen",
"blurShapeOval": "Oval",
"blurShapeFreehand": "Serbest",
+1
View File
@@ -18,6 +18,7 @@
"addTrim": "Kırpma Ekle",
"addSpeed": "Hız Ekle",
"addAnnotation": "Açıklama Ekle",
"addBlur": "Bulanik Ekle",
"addKeyframe": "Anahtar Kare Ekle",
"deleteSelected": "Seçileni Sil",
"playPause": "Oynat / Duraklat"
+1
View File
@@ -119,6 +119,7 @@
"strokeWidth": "描边宽度:{{width}}px",
"arrowColor": "箭头颜色",
"blurShape": "模糊形状",
"blurIntensity": "模糊强度",
"blurShapeRectangle": "矩形",
"blurShapeOval": "椭圆",
"blurShapeFreehand": "自由手绘",
+1
View File
@@ -18,6 +18,7 @@
"addTrim": "添加剪辑",
"addSpeed": "添加速度",
"addAnnotation": "添加标注",
"addBlur": "添加模糊",
"addKeyframe": "添加关键帧",
"deleteSelected": "删除所选",
"playPause": "播放 / 暂停"
+3 -3
View File
@@ -5,14 +5,14 @@
"addTrim": "添加剪辑 (T)",
"addAnnotation": "添加标注 (A)",
"addSpeed": "添加速度 (S)",
"addBlur": "????"
"addBlur": "添加模糊"
},
"hints": {
"pressZoom": "按 Z 添加缩放",
"pressTrim": "按 T 添加剪辑",
"pressAnnotation": "按 A 添加标注",
"pressSpeed": "按 S 添加速度",
"pressBlur": "??????????"
"pressBlur": "从工具栏添加模糊区域"
},
"labels": {
"pan": "平移",
@@ -23,7 +23,7 @@
"annotationItem": "标注",
"imageItem": "图片",
"emptyText": "空文本",
"blurItem": "?? {{index}}"
"blurItem": "模糊 {{index}}"
},
"emptyState": {
"noVideo": "未加载视频",
+5 -1
View File
@@ -3,6 +3,7 @@ export const SHORTCUT_ACTIONS = [
"addTrim",
"addSpeed",
"addAnnotation",
"addBlur",
"addKeyframe",
"deleteSelected",
"playPause",
@@ -108,6 +109,7 @@ export const DEFAULT_SHORTCUTS: ShortcutsConfig = {
addTrim: { key: "t" },
addSpeed: { key: "s" },
addAnnotation: { key: "a" },
addBlur: { key: "b" },
addKeyframe: { key: "f" },
deleteSelected: { key: "d", ctrl: true },
playPause: { key: " " },
@@ -118,6 +120,7 @@ export const SHORTCUT_LABELS: Record<ShortcutAction, string> = {
addTrim: "Add Trim",
addSpeed: "Add Speed",
addAnnotation: "Add Annotation",
addBlur: "Add Blur",
addKeyframe: "Add Keyframe",
deleteSelected: "Delete Selected",
playPause: "Play / Pause",
@@ -125,9 +128,10 @@ export const SHORTCUT_LABELS: Record<ShortcutAction, string> = {
export function matchesShortcut(
e: KeyboardEvent,
binding: ShortcutBinding,
binding: ShortcutBinding | undefined,
isMacPlatform: boolean,
): boolean {
if (!binding) return false;
if (e.key.toLowerCase() !== binding.key.toLowerCase()) return false;
const primaryMod = isMacPlatform ? e.metaKey : e.ctrlKey;