diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-03-02 13:13:07 +0100 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-03-02 13:13:07 +0100 |
| commit | e7dcb586c0408255a0bf788e355fdb6d50d9b923 (patch) | |
| tree | 74ff0fc0f1ba501a075342db9b4e454450926154 /apps/web/src/components/editor/panels/assets/views/settings.tsx | |
| parent | 93bea01c9ed3fcbebc64c9cef382a51d24c925ed (diff) | |
| download | opencut-e7dcb586c0408255a0bf788e355fdb6d50d9b923.tar.gz | |
feat: Clip effects, asset sorting, and timeline improvements
Major features and improvements:
* **Clip Effects**:
* Added UI in Properties Panel to manage effects on video/image clips (add, remove, toggle, reorder).
* Implemented dynamic parameter fields for effects.
* Added support for keyframing effect parameters.
* **Assets Panel**:
* Added sorting options: Name, Type, Duration, and File Size.
* Persisted view preferences (grid/list mode, sort order) to local storage.
* Refactored media item rendering and drag interactions.
* **Timeline & Interaction**:
* **Keyframe Dragging**: Added ability to drag keyframes directly on the timeline element.
* **Resizing**: Improved resize logic to respect neighboring clips (prevents overlaps).
* **Visuals**: Implemented tiled background rendering for video/image clips on the timeline.
* **Shortcuts**: Added "Deselect All" action bound to the `Escape` key.
* **Fixes**: Corrected drag-and-drop coordinate calculations when the timeline track area is scrolled.
* **Text Elements**:
* Refactored text background storage to use an explicit `enabled` flag.
* Added `V8toV9` storage migration to update existing projects.
* **Architecture**:
* Moved export state management to `ProjectManager` for better lifecycle handling.
* Refactored `PropertiesPanel` sections to be more composable (custom headers, borders).
Diffstat (limited to 'apps/web/src/components/editor/panels/assets/views/settings.tsx')
| -rw-r--r-- | apps/web/src/components/editor/panels/assets/views/settings.tsx | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/apps/web/src/components/editor/panels/assets/views/settings.tsx b/apps/web/src/components/editor/panels/assets/views/settings.tsx index 7e10ac9d..d46e9d1f 100644 --- a/apps/web/src/components/editor/panels/assets/views/settings.tsx +++ b/apps/web/src/components/editor/panels/assets/views/settings.tsx @@ -16,6 +16,7 @@ import { Section, SectionContent, SectionHeader, + SectionTitle, } from "@/components/editor/panels/properties/section"; import { Label } from "@/components/ui/label"; import { @@ -23,25 +24,46 @@ import { PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; -import { useState } from "react"; -export function SettingsView() { - const [open, setOpen] = useState(false); +const ORIGINAL_PRESET_VALUE = "original"; +export function findPresetIndexByAspectRatio({ + presets, + targetAspectRatio, +}: { + presets: Array<{ width: number; height: number }>; + targetAspectRatio: string; +}) { + for (let index = 0; index < presets.length; index++) { + const preset = presets[index]; + const presetAspectRatio = dimensionToAspectRatio({ + width: preset.width, + height: preset.height, + }); + if (presetAspectRatio === targetAspectRatio) { + return index; + } + } + return -1; +} + +export function SettingsView() { return ( <PanelView contentClassName="px-0" hideHeader> <div className="flex flex-col"> - <Section hasBorderTop={false}> + <Section showTopBorder={false}> <SectionContent> <ProjectInfoContent /> </SectionContent> </Section> - <Popover open={open} onOpenChange={setOpen}> + <Popover> <Section className="cursor-pointer"> <PopoverTrigger asChild> <div> - <SectionHeader title="Background"> - <div className="size-4 rounded-sm bg-red-500" /> + <SectionHeader + trailing={<div className="size-4 rounded-sm bg-red-500" />} + > + <SectionTitle>Background</SectionTitle> </SectionHeader> </div> </PopoverTrigger> @@ -60,26 +82,6 @@ function ProjectInfoContent() { const activeProject = editor.project.getActive(); const { canvasPresets } = useEditorStore(); - const findPresetIndexByAspectRatio = ({ - presets, - targetAspectRatio, - }: { - presets: Array<{ width: number; height: number }>; - targetAspectRatio: string; - }) => { - for (let index = 0; index < presets.length; index++) { - const preset = presets[index]; - const presetAspectRatio = dimensionToAspectRatio({ - width: preset.width, - height: preset.height, - }); - if (presetAspectRatio === targetAspectRatio) { - return index; - } - } - return -1; - }; - const currentCanvasSize = activeProject.settings.canvasSize; const currentAspectRatio = dimensionToAspectRatio(currentCanvasSize); const originalCanvasSize = activeProject.settings.originalCanvasSize ?? null; @@ -87,12 +89,11 @@ function ProjectInfoContent() { presets: canvasPresets, targetAspectRatio: currentAspectRatio, }); - const originalPresetValue = "original"; const selectedPresetValue = - presetIndex !== -1 ? presetIndex.toString() : originalPresetValue; + presetIndex !== -1 ? presetIndex.toString() : ORIGINAL_PRESET_VALUE; const handleAspectRatioChange = ({ value }: { value: string }) => { - if (value === originalPresetValue) { + if (value === ORIGINAL_PRESET_VALUE) { const canvasSize = originalCanvasSize ?? currentCanvasSize; editor.project.updateSettings({ settings: { canvasSize }, @@ -106,7 +107,7 @@ function ProjectInfoContent() { } }; - const handleFpsChange = (value: string) => { + const handleFpsChange = ({ value }: { value: string }) => { const fps = parseFloat(value); editor.project.updateSettings({ settings: { fps } }); }; @@ -129,7 +130,7 @@ function ProjectInfoContent() { <SelectValue placeholder="Select an aspect ratio" /> </SelectTrigger> <SelectContent> - <SelectItem value={originalPresetValue}>Original</SelectItem> + <SelectItem value={ORIGINAL_PRESET_VALUE}>Original</SelectItem> {canvasPresets.map((preset, index) => { const label = dimensionToAspectRatio({ width: preset.width, @@ -148,7 +149,7 @@ function ProjectInfoContent() { <Label>Frame rate</Label> <Select value={activeProject.settings.fps.toString()} - onValueChange={handleFpsChange} + onValueChange={(value) => handleFpsChange({ value })} > <SelectTrigger className="w-fit"> <SelectValue placeholder="Select a frame rate" /> |
