Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 65 additions & 132 deletions apps/desktop/src/routes/editor/ConfigSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NumberField } from "@kobalte/core";

Check failure on line 1 in apps/desktop/src/routes/editor/ConfigSidebar.tsx

View workflow job for this annotation

GitHub Actions / Lint (Biome)

format

File content differs from formatting output
import {
Collapsible,
Collapsible as KCollapsible,
Expand Down Expand Up @@ -72,7 +72,7 @@
import { CaptionsTab } from "./CaptionsTab";
import { syncCaptionWordsWithText } from "./captions";
import { getColorPreviewBorderColor, hexToRgb, RgbInput } from "./color-utils";
import { type CornerRoundingType, useEditorContext } from "./context";
import { useEditorContext } from "./context";
import { GradientEditor } from "./GradientEditor";
import { KeyboardTab } from "./KeyboardTab";
import { evaluateMask, type MaskKind, type MaskSegment } from "./masks";
Expand Down Expand Up @@ -220,11 +220,6 @@
] satisfies CameraXPosition[];
const CAMERA_Y_POSITIONS = ["top", "bottom"] satisfies CameraYPosition[];

const CORNER_STYLE_OPTIONS = [
{ name: "Squircle", value: "squircle" },
{ name: "Rounded", value: "rounded" },
] satisfies Array<{ name: string; value: CornerRoundingType }>;

const BACKGROUND_THEMES = {
macOS: "macOS",
dark: "Dark",
Expand Down Expand Up @@ -305,11 +300,11 @@
(option) =>
option.preset &&
Math.abs(option.preset.tension - values.tension) <=
CURSOR_PRESET_TOLERANCE.tension &&
CURSOR_PRESET_TOLERANCE.tension &&
Math.abs(option.preset.mass - values.mass) <=
CURSOR_PRESET_TOLERANCE.mass &&
CURSOR_PRESET_TOLERANCE.mass &&
Math.abs(option.preset.friction - values.friction) <=
CURSOR_PRESET_TOLERANCE.friction,
CURSOR_PRESET_TOLERANCE.friction,
);

return preset?.value ?? null;
Expand Down Expand Up @@ -450,7 +445,7 @@
class={cx(
"flex justify-center relative border-transparent border z-10 items-center rounded-md size-9 transition will-change-transform",
state.selectedTab !== item.id &&
"group-hover:border-gray-300 group-disabled:border-none",
"group-hover:border-gray-300 group-disabled:border-none",
)}
>
<Dynamic component={item.icon} />
Expand Down Expand Up @@ -1737,17 +1732,13 @@
ref={setBackgroundRef}
class="flex overflow-x-auto overscroll-contain relative z-10 flex-row gap-2 items-center mb-3 text-xs hide-scroll"
style={{
"-webkit-mask-image": `linear-gradient(to right, transparent, black ${
scrollX() > 0 ? "24px" : "0"
}, black calc(100% - ${
reachedEndOfScroll() ? "0px" : "24px"
}), transparent)`,

"mask-image": `linear-gradient(to right, transparent, black ${
scrollX() > 0 ? "24px" : "0"
}, black calc(100% - ${
reachedEndOfScroll() ? "0px" : "24px"
}), transparent);`,
"-webkit-mask-image": `linear-gradient(to right, transparent, black ${scrollX() > 0 ? "24px" : "0"
}, black calc(100% - ${reachedEndOfScroll() ? "0px" : "24px"
}), transparent)`,

"mask-image": `linear-gradient(to right, transparent, black ${scrollX() > 0 ? "24px" : "0"
}, black calc(100% - ${reachedEndOfScroll() ? "0px" : "24px"
}), transparent);`,
}}
>
<For each={Object.entries(BACKGROUND_THEMES)}>
Expand All @@ -1774,10 +1765,10 @@
value={
project.background.source.type === "wallpaper"
? (wallpapers()?.find((w) =>
(
project.background.source as { path?: string }
).path?.includes(w.id),
)?.url ?? undefined)
(
project.background.source as { path?: string }
).path?.includes(w.id),
)?.url ?? undefined)
: undefined
}
onChange={(photoUrl) => {
Expand Down Expand Up @@ -1907,9 +1898,9 @@
if (!file) return;

/*
this is a Tauri bug in WebKit so we need to validate the file type manually
https://github.com/tauri-apps/tauri/issues/9158
*/
this is a Tauri bug in WebKit so we need to validate the file type manually
https://github.com/tauri-apps/tauri/issues/9158
*/
Comment on lines 1900 to +1903
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Remove the Tauri bug comment block to match “no comments” guideline

The multi‑line /* ... */ comment about the Tauri WebKit bug was modified in this PR and violates the guideline that .ts/.tsx/.js/.jsx/.rs files should not contain code comments. The surrounding code (manual extension validation) is already self‑explanatory.

Consider deleting this block entirely and, if needed, capturing the context in commit messages or external docs instead.

🤖 Prompt for AI Agents
In apps/desktop/src/routes/editor/ConfigSidebar.tsx around lines 1715 to 1718,
remove the multi-line comment block (/* this is a Tauri bug in WebKit so we need
to validate the file type manually
https://github.com/tauri-apps/tauri/issues/9158 */) so the file complies with
the "no comments" guideline; delete the block only and keep the surrounding
manual extension validation code unchanged, and capture any needed rationale in
the PR description or external docs instead.

const validExtensions = [
"jpg",
"jpeg",
Expand Down Expand Up @@ -2055,23 +2046,27 @@
/>
</Field>
<Field name="Rounded Corners" icon={<IconCapCorners class="size-4" />}>
<div class="flex flex-col gap-3">
<Slider
value={[project.background.rounding]}
onChange={(v) => setProject("background", "rounding", v[0])}
minValue={0}
maxValue={100}
step={0.1}
formatTooltip="%"
/>
<CornerStyleSelect
label="Corner Style"
value={project.background.roundingType}
onChange={(value) =>
setProject("background", "roundingType", value)
}
/>
</div>
<Slider
value={[project.background.rounding]}
onChange={(v) => setProject("background", "rounding", v[0])}
minValue={0}
maxValue={100}
step={0.1}
formatTooltip="%"
/>
</Field>
<Field
name="Corner Smoothness"
icon={<IconLucideSquareRoundCorner class="size-4" />}
>
<Slider
value={[project.background.roundingSmoothness ?? 0]}
onChange={(v) => setProject("background", "roundingSmoothness", v[0])}
minValue={0}
maxValue={1}
step={0.01}
formatTooltip={(value) => `${Math.round(value * 100)}%`}
/>
</Field>
<Field name="Motion Blur" icon={<IconLucideWind class="size-4" />}>
<Slider
Expand Down Expand Up @@ -2486,21 +2481,27 @@
/>
</Field>
<Field name="Rounded Corners" icon={<IconCapCorners class="size-4" />}>
<div class="flex flex-col gap-3">
<Slider
value={[project.camera.rounding ?? 0]}
onChange={(v) => setProject("camera", "rounding", v[0])}
minValue={0}
maxValue={100}
step={0.1}
formatTooltip="%"
/>
<CornerStyleSelect
label="Corner Style"
value={project.camera.roundingType}
onChange={(value) => setProject("camera", "roundingType", value)}
/>
</div>
<Slider
value={[project.camera.rounding ?? 0]}
onChange={(v) => setProject("camera", "rounding", v[0])}
minValue={0}
maxValue={100}
step={0.1}
formatTooltip="%"
/>
</Field>
<Field
name="Corner Smoothness"
icon={<IconLucideSquareRoundCorner class="size-4" />}
>
<Slider
value={[project.camera.roundingSmoothness ?? 0]}
onChange={(v) => setProject("camera", "roundingSmoothness", v[0])}
minValue={0}
maxValue={1}
step={0.01}
formatTooltip={(value) => `${Math.round(value * 100)}%`}
/>
</Field>
<Field name="Shadow" icon={<IconCapShadow class="size-4" />}>
<div class="space-y-8">
Expand Down Expand Up @@ -2571,72 +2572,6 @@
);
}

function CornerStyleSelect(props: {
label?: string;
value: CornerRoundingType;
onChange: (value: CornerRoundingType) => void;
}) {
return (
<div class="flex flex-col gap-1.5">
<Show when={props.label}>
{(label) => (
<span class="text-[0.65rem] uppercase tracking-wide text-gray-11">
{label()}
</span>
)}
</Show>
<KSelect<{ name: string; value: CornerRoundingType }>
options={CORNER_STYLE_OPTIONS}
optionValue="value"
optionTextValue="name"
value={CORNER_STYLE_OPTIONS.find(
(option) => option.value === props.value,
)}
onChange={(option) => option && props.onChange(option.value)}
disallowEmptySelection
itemComponent={(itemProps) => (
<MenuItem<typeof KSelect.Item>
as={KSelect.Item}
item={itemProps.item}
>
<KSelect.ItemLabel class="flex-1">
{itemProps.item.rawValue.name}
</KSelect.ItemLabel>
</MenuItem>
)}
>
<KSelect.Trigger class="flex flex-row gap-2 items-center px-2 w-full h-8 rounded-lg transition-colors bg-gray-3 disabled:text-gray-11">
<KSelect.Value<{
name: string;
value: CornerRoundingType;
}> class="flex-1 text-sm text-left truncate text-[--gray-500] font-normal">
{(state) => <span>{state.selectedOption().name}</span>}
</KSelect.Value>
<KSelect.Icon<ValidComponent>
as={(iconProps) => (
<IconCapChevronDown
{...iconProps}
class="size-4 shrink-0 transform transition-transform ui-expanded:rotate-180 text-[--gray-500]"
/>
)}
/>
</KSelect.Trigger>
<KSelect.Portal>
<PopperContent<typeof KSelect.Content>
as={KSelect.Content}
class={cx(topSlideAnimateClasses, "z-50")}
>
<MenuItemList<typeof KSelect.Listbox>
class="overflow-y-auto max-h-32"
as={KSelect.Listbox}
/>
</PopperContent>
</KSelect.Portal>
</KSelect>
</div>
);
}

function HexColorInput(props: {
value: string;
onChange: (value: string) => void;
Expand Down Expand Up @@ -3285,8 +3220,7 @@
createEffect(() => {
// TODO: make this not hardcoded
const path = convertFileSrc(
`${editorInstance.path}/content/segments/segment-${
clipSegment()?.recordingSegment ?? 0
`${editorInstance.path}/content/segments/segment-${clipSegment()?.recordingSegment ?? 0
}/display.mp4`,
);
video.src = path;
Expand Down Expand Up @@ -3489,8 +3423,7 @@
createEffect(() => {
const path = convertFileSrc(
// TODO: this shouldn't be so hardcoded
`${
editorInstance.path
`${editorInstance.path
}/content/segments/segment-${segmentIndex()}/display.mp4`,
);
video.src = path;
Expand Down Expand Up @@ -3620,15 +3553,15 @@
x: Math.max(
Math.min(
(moveEvent.clientX - bounds.left) /
bounds.width,
bounds.width,
1,
),
0,
),
y: Math.max(
Math.min(
(moveEvent.clientY - bounds.top) /
bounds.height,
bounds.height,
1,
),
0,
Expand Down
36 changes: 4 additions & 32 deletions apps/desktop/src/routes/editor/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,6 @@ export type CustomDomainResponse = {
domain_verified: boolean | null;
};

export type CornerRoundingType = "rounded" | "squircle";

type WithCornerStyle<T> = T & { roundingType: CornerRoundingType };

type EditorTimelineConfiguration = Omit<
TimelineConfiguration,
"sceneSegments" | "maskSegments"
Expand All @@ -149,25 +145,12 @@ export type EditorProjectConfiguration = Omit<
ProjectConfiguration,
"background" | "camera" | "timeline"
> & {
background: WithCornerStyle<ProjectConfiguration["background"]>;
camera: WithCornerStyle<ProjectConfiguration["camera"]>;
background: ProjectConfiguration["background"];
camera: ProjectConfiguration["camera"];
timeline?: EditorTimelineConfiguration | null;
hiddenTextSegments?: number[];
};

function withCornerDefaults<
T extends {
roundingType?: CornerRoundingType;
rounding_type?: CornerRoundingType;
},
>(value: T): T & { roundingType: CornerRoundingType } {
const roundingType = value.roundingType ?? value.rounding_type ?? "squircle";
return {
...value,
roundingType,
};
}

export function normalizeProject(
config: ProjectConfiguration,
): EditorProjectConfiguration {
Expand Down Expand Up @@ -209,18 +192,13 @@ export function normalizeProject(
...config,
keyboard,
timeline,
background: withCornerDefaults(config.background),
camera: withCornerDefaults(config.camera),
};
}

export function serializeProjectConfiguration(
project: EditorProjectConfiguration,
): ProjectConfiguration {
const { background, camera, ...rest } = project;
const { roundingType: backgroundRoundingType, ...backgroundRest } =
background;
const { roundingType: cameraRoundingType, ...cameraRest } = camera;

const timeline = project.timeline
? {
Expand All @@ -235,14 +213,8 @@ export function serializeProjectConfiguration(
return {
...rest,
timeline: timeline as unknown as ProjectConfiguration["timeline"],
background: {
...backgroundRest,
roundingType: backgroundRoundingType,
},
camera: {
...cameraRest,
roundingType: cameraRoundingType,
},
background,
camera,
};
}

Expand Down
Loading
Loading