fix: address remaining settings review feedback

This commit is contained in:
webadderall
2026-04-17 01:03:24 +10:00
parent 993c7aff9c
commit 0206e38e2c
14 changed files with 104 additions and 30 deletions
@@ -2227,12 +2227,9 @@ export function SettingsPanel({
</section>
<section className="flex flex-col gap-2">
<SectionLabel>{tSettings("keyboardShortcuts.title", "Keybinds")}</SectionLabel>
<SectionLabel>{t("editor.keyboardShortcuts.title")}</SectionLabel>
<KeyboardShortcutsDialog
triggerLabel={tSettings(
"keyboardShortcuts.customize",
"Customise Keybinds",
)}
triggerLabel={t("editor.keyboardShortcuts.customize")}
triggerClassName="h-10 w-full justify-start rounded-xl border border-white/10 bg-white/5 px-3 text-sm text-slate-200 hover:bg-white/10 hover:text-white"
/>
</section>
+20 -15
View File
@@ -1772,9 +1772,10 @@ export default function VideoEditor() {
]);
useEffect(() => {
pendingFreshRecordingAutoZoomPathRef.current =
autoApplyFreshRecordingAutoZooms && videoPath ? videoPath : null;
}, [autoApplyFreshRecordingAutoZooms, videoPath]);
if (!autoApplyFreshRecordingAutoZooms) {
pendingFreshRecordingAutoZoomPathRef.current = null;
}
}, [autoApplyFreshRecordingAutoZooms]);
useEffect(() => {
saveEditorPreferences({
@@ -2717,9 +2718,12 @@ export default function VideoEditor() {
const handleClipSpeedChange = useCallback(
(speed: number) => {
if (!selectedClipId) return;
if (!Number.isFinite(speed) || speed <= 0) {
return;
}
const clip = clipRegions.find((c) => c.id === selectedClipId);
if (!clip) return;
const oldSpeed = clip.speed ?? 1;
const oldSpeed = Number.isFinite(clip.speed) && clip.speed > 0 ? clip.speed : 1;
const sourceDurationMs = (clip.endMs - clip.startMs) * oldSpeed;
const newEndMs = Math.round(clip.startMs + sourceDurationMs / speed);
const scaleFactor = oldSpeed / speed;
@@ -4917,7 +4921,7 @@ export default function VideoEditor() {
className="h-7 gap-1 rounded-full border border-white/[0.08] bg-white/[0.04] px-2.5 text-[11px] text-white/65 shadow-[inset_0_1px_0_rgba(255,255,255,0.06)] transition-all hover:bg-white/[0.08] hover:text-white"
>
<Plus className="w-3.5 h-3.5" />
<span className="font-medium">Add Layer</span>
<span className="font-medium">{t("editor.toolbar.addLayer")}</span>
<ChevronDown className="w-3 h-3" />
</Button>
</DropdownMenuTrigger>
@@ -4939,13 +4943,13 @@ export default function VideoEditor() {
}}
className="text-slate-300 hover:text-white hover:bg-white/10 cursor-pointer"
>
Annotation
{t("timeline.annotation.label")}
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => timelineRef.current?.addAudio()}
className="text-slate-300 hover:text-white hover:bg-white/10 cursor-pointer"
>
Audio
{t("timeline.audio.label")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
@@ -4955,7 +4959,7 @@ export default function VideoEditor() {
variant="ghost"
size="icon"
className="h-7 w-7 rounded-full text-slate-400 transition-all hover:bg-[#2563EB]/10 hover:text-[#2563EB]"
title="Add Zoom (Z)"
title={t("timeline.zoom.addZoom")}
>
<ZoomIn className="w-4 h-4" />
</Button>
@@ -4964,7 +4968,7 @@ export default function VideoEditor() {
variant="ghost"
size="icon"
className="h-7 w-7 rounded-full text-slate-400 transition-all hover:bg-[#2563EB]/10 hover:text-[#2563EB]"
title="Suggest Zooms from Cursor"
title={t("timeline.zoom.suggestZooms")}
>
<WandSparkles className="w-4 h-4" />
</Button>
@@ -4973,7 +4977,7 @@ export default function VideoEditor() {
variant="ghost"
size="icon"
className="h-7 w-7 rounded-full text-slate-400 transition-all hover:bg-white/10 hover:text-white"
title="Split Clip (C)"
title={t("editor.toolbar.splitClip")}
>
<Scissors className="w-4 h-4" />
</Button>
@@ -4988,7 +4992,7 @@ export default function VideoEditor() {
variant="ghost"
size="icon"
className="h-7 w-7 rounded-full text-slate-400 transition-all hover:bg-white/10 hover:text-white"
title="Skip Back"
title={t("editor.playback.skipBack")}
onClick={() => {
const currentMs = timelinePlayheadTime * 1000;
const kfs = timelineRef.current?.keyframes ?? [];
@@ -5021,7 +5025,7 @@ export default function VideoEditor() {
variant="ghost"
size="icon"
className="h-7 w-7 rounded-full text-slate-400 transition-all hover:bg-white/10 hover:text-white"
title="Skip Forward"
title={t("editor.playback.skipForward")}
onClick={() => {
const currentMs = timelinePlayheadTime * 1000;
const kfs = timelineRef.current?.keyframes ?? [];
@@ -5046,11 +5050,12 @@ export default function VideoEditor() {
variant="ghost"
size="icon"
title={
timelineCollapsed ? "Expand Timeline" : "Collapse Timeline"
timelineCollapsed
? t("editor.timeline.expand")
: t("editor.timeline.collapse")
}
className="h-7 w-7 rounded-full text-slate-400 transition-all hover:bg-white/10 hover:text-white"
onClick={() => {
timelineRef.current?.toggleCollapsed();
setTimelineCollapsed((p) => !p);
}}
>
@@ -5064,7 +5069,7 @@ export default function VideoEditor() {
<button
type="button"
className="text-slate-400 hover:text-white transition-colors"
title="Mute/Unmute"
title={t("editor.playback.muteUnmute")}
onClick={() =>
setPreviewVolume(previewVolume <= 0.001 ? 1 : 0)
}
@@ -336,6 +336,10 @@ export function normalizeProjectEditor(editor: Partial<ProjectEditorState>): Pro
1,
),
},
mode:
region.mode === "auto" || region.mode === "manual"
? region.mode
: undefined,
};
})
: [];
@@ -98,7 +98,6 @@ export interface TimelineEditorHandle {
splitClip: () => void;
addAnnotation: (trackIndex?: number) => void;
addAudio: () => Promise<void>;
toggleCollapsed: () => void;
keyframes: { id: string; time: number }[];
}
@@ -688,7 +687,7 @@ const TimelineEditor = forwardRef<TimelineEditorHandle, TimelineEditorProps>(fun
selectedAudioId,
onSelectAudio,
aspectRatio = 'native',
onAspectRatioChange = () => {},
onAspectRatioChange,
onOpenCropEditor,
isCropped = false,
videoPath,
@@ -747,7 +746,7 @@ const TimelineEditor = forwardRef<TimelineEditorHandle, TimelineEditorProps>(fun
toast.error('Custom aspect ratio must be positive numbers.');
return;
}
onAspectRatioChange(`${width}:${height}` as AspectRatio);
onAspectRatioChange?.(`${width}:${height}` as AspectRatio);
}, [customAspectHeight, customAspectWidth, onAspectRatioChange]);
const handleCustomAspectRatioKeyDown = useCallback((event: ReactKeyboardEvent<HTMLInputElement>) => {
@@ -1374,7 +1373,6 @@ const TimelineEditor = forwardRef<TimelineEditorHandle, TimelineEditorProps>(fun
splitClip: handleSplitClip,
addAnnotation: handleAddAnnotation,
addAudio: handleAddAudio,
toggleCollapsed: () => {},
keyframes,
}), [handleAddAnnotation, handleAddAudio, handleAddZoom, handleSuggestZooms, handleSplitClip, keyframes]);
@@ -1580,7 +1578,7 @@ const TimelineEditor = forwardRef<TimelineEditorHandle, TimelineEditorProps>(fun
{ASPECT_RATIOS.map((ratio) => (
<DropdownMenuItem
key={ratio}
onClick={() => onAspectRatioChange(ratio)}
onClick={() => onAspectRatioChange?.(ratio)}
className="text-slate-300 hover:text-white hover:bg-white/10 cursor-pointer flex items-center justify-between gap-3"
>
<span>{getAspectRatioLabel(ratio)}</span>
+12 -1
View File
@@ -1,7 +1,10 @@
{
"playback": {
"play": "Play",
"pause": "Pause"
"pause": "Pause",
"skipBack": "Skip Back",
"skipForward": "Skip Forward",
"muteUnmute": "Mute/Unmute"
},
"annotations": {
"settings": "Annotation Settings",
@@ -119,5 +122,13 @@
"complete": "Export complete",
"savedSuccessfully": "Your file was saved successfully."
},
"toolbar": {
"addLayer": "Add Layer",
"splitClip": "Split Clip (C)"
},
"timeline": {
"expand": "Expand Timeline",
"collapse": "Collapse Timeline"
},
"openRecordingsFolder": "Open recordings folder"
}
+3
View File
@@ -32,6 +32,9 @@
"image": "Image",
"addAnnotation": "Add Annotation (A)"
},
"audio": {
"label": "Audio"
},
"addSpeed": "Add Speed (S)",
"resizeLeft": "Resize left",
"resizeRight": "Resize right"
+12 -1
View File
@@ -1,7 +1,10 @@
{
"playback": {
"play": "Reproducir",
"pause": "Pausar"
"pause": "Pausar",
"skipBack": "Retroceder",
"skipForward": "Avanzar",
"muteUnmute": "Silenciar/activar sonido"
},
"annotations": {
"settings": "Configuración de anotaciones",
@@ -119,5 +122,13 @@
"complete": "Exportación completada",
"savedSuccessfully": "Tu archivo se guardó correctamente."
},
"toolbar": {
"addLayer": "Agregar capa",
"splitClip": "Dividir clip (C)"
},
"timeline": {
"expand": "Expandir línea de tiempo",
"collapse": "Contraer línea de tiempo"
},
"openRecordingsFolder": "Abrir carpeta de grabaciones"
}
+3
View File
@@ -32,6 +32,9 @@
"image": "Imagen",
"addAnnotation": "Agregar Anotación (A)"
},
"audio": {
"label": "Audio"
},
"addSpeed": "Agregar Velocidad (S)",
"resizeLeft": "Redimensionar izquierda",
"resizeRight": "Redimensionar derecha"
+12 -1
View File
@@ -1,7 +1,10 @@
{
"playback": {
"play": "재생",
"pause": "일시 정지"
"pause": "일시 정지",
"skipBack": "뒤로 건너뛰기",
"skipForward": "앞으로 건너뛰기",
"muteUnmute": "음소거/해제"
},
"annotations": {
"settings": "주석 설정",
@@ -120,5 +123,13 @@
"complete": "내보내기 완료",
"savedSuccessfully": "파일이 성공적으로 저장되었습니다."
},
"toolbar": {
"addLayer": "레이어 추가",
"splitClip": "클립 분할 (C)"
},
"timeline": {
"expand": "타임라인 펼치기",
"collapse": "타임라인 접기"
},
"openRecordingsFolder": "녹화 폴더 열기"
}
+3
View File
@@ -32,6 +32,9 @@
"image": "이미지",
"addAnnotation": "주석 추가 (A)"
},
"audio": {
"label": "오디오"
},
"addSpeed": "속도 추가 (S)",
"resizeLeft": "왼쪽 크기 조절",
"resizeRight": "오른쪽 크기 조절"
+12 -1
View File
@@ -1,7 +1,10 @@
{
"playback": {
"play": "Afspelen",
"pause": "Pauzeren"
"pause": "Pauzeren",
"skipBack": "Terug springen",
"skipForward": "Vooruit springen",
"muteUnmute": "Dempen/dempen opheffen"
},
"annotations": {
"settings": "Annotatie-instellingen",
@@ -120,5 +123,13 @@
"complete": "Export voltooid",
"savedSuccessfully": "Je bestand is succesvol opgeslagen."
},
"toolbar": {
"addLayer": "Laag toevoegen",
"splitClip": "Clip splitsen (C)"
},
"timeline": {
"expand": "Tijdlijn uitvouwen",
"collapse": "Tijdlijn samenvouwen"
},
"openRecordingsFolder": "Opnamemap openen"
}
+3
View File
@@ -32,6 +32,9 @@
"image": "Afbeelding",
"addAnnotation": "Annotatie toevoegen (A)"
},
"audio": {
"label": "Audio"
},
"addSpeed": "Snelheid toevoegen (S)",
"resizeLeft": "Links verkleinen",
"resizeRight": "Rechts verkleinen"
+12 -1
View File
@@ -1,7 +1,10 @@
{
"playback": {
"play": "播放",
"pause": "暂停"
"pause": "暂停",
"skipBack": "后退",
"skipForward": "前进",
"muteUnmute": "静音/取消静音"
},
"annotations": {
"settings": "注释设置",
@@ -119,5 +122,13 @@
"complete": "导出完成",
"savedSuccessfully": "文件已成功保存。"
},
"toolbar": {
"addLayer": "添加图层",
"splitClip": "拆分片段 (C)"
},
"timeline": {
"expand": "展开时间轴",
"collapse": "折叠时间轴"
},
"openRecordingsFolder": "打开录制文件夹"
}
+3
View File
@@ -32,6 +32,9 @@
"image": "图片",
"addAnnotation": "添加注释 (A)"
},
"audio": {
"label": "音频"
},
"addSpeed": "添加变速 (S)",
"resizeLeft": "向左调整",
"resizeRight": "向右调整"