}>
From 70dbbd486342b7f9b414c524d07a9dad46ddcc10 Mon Sep 17 00:00:00 2001
From: Richie McIlroy <33632126+richiemcilroy@users.noreply.github.com>
Date: Mon, 10 Nov 2025 17:00:14 +0000
Subject: [PATCH 15/17] format
---
.../src/routes/editor/ConfigSidebar.tsx | 5784 ++++++++---------
1 file changed, 2892 insertions(+), 2892 deletions(-)
diff --git a/apps/desktop/src/routes/editor/ConfigSidebar.tsx b/apps/desktop/src/routes/editor/ConfigSidebar.tsx
index ba438bf702..d5a34b79da 100644
--- a/apps/desktop/src/routes/editor/ConfigSidebar.tsx
+++ b/apps/desktop/src/routes/editor/ConfigSidebar.tsx
@@ -1,11 +1,11 @@
import { NumberField } from "@kobalte/core";
import {
- Collapsible,
- Collapsible as KCollapsible,
+ Collapsible,
+ Collapsible as KCollapsible,
} from "@kobalte/core/collapsible";
import {
- RadioGroup as KRadioGroup,
- RadioGroup,
+ RadioGroup as KRadioGroup,
+ RadioGroup,
} from "@kobalte/core/radio-group";
import { Select as KSelect } from "@kobalte/core/select";
import { Tabs as KTabs } from "@kobalte/core/tabs";
@@ -18,19 +18,19 @@ import { BaseDirectory, writeFile } from "@tauri-apps/plugin-fs";
import { type as ostype } from "@tauri-apps/plugin-os";
import { cx } from "cva";
import {
- batch,
- createEffect,
- createMemo,
- createResource,
- createRoot,
- createSignal,
- For,
- Index,
- on,
- onMount,
- Show,
- Suspense,
- type ValidComponent,
+ batch,
+ createEffect,
+ createMemo,
+ createResource,
+ createRoot,
+ createSignal,
+ For,
+ Index,
+ on,
+ onMount,
+ Show,
+ Suspense,
+ type ValidComponent,
} from "solid-js";
import { createStore, produce } from "solid-js/store";
import { Dynamic } from "solid-js/web";
@@ -42,15 +42,15 @@ import transparentBg from "~/assets/illustrations/transparent.webp";
import { Toggle } from "~/components/Toggle";
import { generalSettingsStore } from "~/store";
import {
- type BackgroundSource,
- type CameraShape,
- type ClipOffsets,
- type CursorAnimationStyle,
- commands,
- type SceneSegment,
- type StereoMode,
- type TimelineSegment,
- type ZoomSegment,
+ type BackgroundSource,
+ type CameraShape,
+ type ClipOffsets,
+ type CursorAnimationStyle,
+ commands,
+ type SceneSegment,
+ type StereoMode,
+ type TimelineSegment,
+ type ZoomSegment,
} from "~/utils/tauri";
import IconLucideMonitor from "~icons/lucide/monitor";
import IconLucideRabbit from "~icons/lucide/rabbit";
@@ -60,654 +60,654 @@ import IconLucideWind from "~icons/lucide/wind";
import { CaptionsTab } from "./CaptionsTab";
import { type CornerRoundingType, useEditorContext } from "./context";
import {
- DEFAULT_GRADIENT_FROM,
- DEFAULT_GRADIENT_TO,
- type RGBColor,
+ DEFAULT_GRADIENT_FROM,
+ DEFAULT_GRADIENT_TO,
+ type RGBColor,
} from "./projectConfig";
import ShadowSettings from "./ShadowSettings";
import { TextInput } from "./TextInput";
import {
- ComingSoonTooltip,
- EditorButton,
- Field,
- MenuItem,
- MenuItemList,
- PopperContent,
- Slider,
- Subfield,
- topSlideAnimateClasses,
+ ComingSoonTooltip,
+ EditorButton,
+ Field,
+ MenuItem,
+ MenuItemList,
+ PopperContent,
+ Slider,
+ Subfield,
+ topSlideAnimateClasses,
} from "./ui";
const BACKGROUND_SOURCES = {
- wallpaper: "Wallpaper",
- image: "Image",
- color: "Color",
- gradient: "Gradient",
+ wallpaper: "Wallpaper",
+ image: "Image",
+ color: "Color",
+ gradient: "Gradient",
} satisfies Record
;
const BACKGROUND_ICONS = {
- wallpaper: imageBg,
- image: transparentBg,
- color: colorBg,
- gradient: gradientBg,
+ wallpaper: imageBg,
+ image: transparentBg,
+ color: colorBg,
+ gradient: gradientBg,
} satisfies Record;
const BACKGROUND_SOURCES_LIST = [
- "wallpaper",
- "image",
- "color",
- "gradient",
+ "wallpaper",
+ "image",
+ "color",
+ "gradient",
] satisfies Array;
const BACKGROUND_COLORS = [
- "#FF0000", // Red
- "#FF4500", // Orange-Red
- "#FF8C00", // Orange
- "#FFD700", // Gold
- "#FFFF00", // Yellow
- "#ADFF2F", // Green-Yellow
- "#32CD32", // Lime Green
- "#008000", // Green
- "#00CED1", // Dark Turquoise
- "#4785FF", // Dodger Blue
- "#0000FF", // Blue
- "#4B0082", // Indigo
- "#800080", // Purple
- "#A9A9A9", // Dark Gray
- "#FFFFFF", // White
- "#000000", // Black
- "#00000000", // Transparent
+ "#FF0000", // Red
+ "#FF4500", // Orange-Red
+ "#FF8C00", // Orange
+ "#FFD700", // Gold
+ "#FFFF00", // Yellow
+ "#ADFF2F", // Green-Yellow
+ "#32CD32", // Lime Green
+ "#008000", // Green
+ "#00CED1", // Dark Turquoise
+ "#4785FF", // Dodger Blue
+ "#0000FF", // Blue
+ "#4B0082", // Indigo
+ "#800080", // Purple
+ "#A9A9A9", // Dark Gray
+ "#FFFFFF", // White
+ "#000000", // Black
+ "#00000000", // Transparent
];
const BACKGROUND_GRADIENTS = [
- { from: [15, 52, 67], to: [52, 232, 158] }, // Dark Blue to Teal
- { from: [34, 193, 195], to: [253, 187, 45] }, // Turquoise to Golden Yellow
- { from: [29, 253, 251], to: [195, 29, 253] }, // Cyan to Purple
- { from: [69, 104, 220], to: [176, 106, 179] }, // Blue to Violet
- { from: [106, 130, 251], to: [252, 92, 125] }, // Soft Blue to Pinkish Red
- { from: [131, 58, 180], to: [253, 29, 29] }, // Purple to Red
- { from: [249, 212, 35], to: [255, 78, 80] }, // Yellow to Coral Red
- { from: [255, 94, 0], to: [255, 42, 104] }, // Orange to Reddish Pink
- { from: [255, 0, 150], to: [0, 204, 255] }, // Pink to Sky Blue
- { from: [0, 242, 96], to: [5, 117, 230] }, // Green to Blue
- { from: [238, 205, 163], to: [239, 98, 159] }, // Peach to Soft Pink
- { from: [44, 62, 80], to: [52, 152, 219] }, // Dark Gray Blue to Light Blue
- { from: [168, 239, 255], to: [238, 205, 163] }, // Light Blue to Peach
- { from: [74, 0, 224], to: [143, 0, 255] }, // Deep Blue to Bright Purple
- { from: [252, 74, 26], to: [247, 183, 51] }, // Deep Orange to Soft Yellow
- { from: [0, 255, 255], to: [255, 20, 147] }, // Cyan to Deep Pink
- { from: [255, 127, 0], to: [255, 255, 0] }, // Orange to Yellow
- { from: [255, 0, 255], to: [0, 255, 0] }, // Magenta to Green
+ { from: [15, 52, 67], to: [52, 232, 158] }, // Dark Blue to Teal
+ { from: [34, 193, 195], to: [253, 187, 45] }, // Turquoise to Golden Yellow
+ { from: [29, 253, 251], to: [195, 29, 253] }, // Cyan to Purple
+ { from: [69, 104, 220], to: [176, 106, 179] }, // Blue to Violet
+ { from: [106, 130, 251], to: [252, 92, 125] }, // Soft Blue to Pinkish Red
+ { from: [131, 58, 180], to: [253, 29, 29] }, // Purple to Red
+ { from: [249, 212, 35], to: [255, 78, 80] }, // Yellow to Coral Red
+ { from: [255, 94, 0], to: [255, 42, 104] }, // Orange to Reddish Pink
+ { from: [255, 0, 150], to: [0, 204, 255] }, // Pink to Sky Blue
+ { from: [0, 242, 96], to: [5, 117, 230] }, // Green to Blue
+ { from: [238, 205, 163], to: [239, 98, 159] }, // Peach to Soft Pink
+ { from: [44, 62, 80], to: [52, 152, 219] }, // Dark Gray Blue to Light Blue
+ { from: [168, 239, 255], to: [238, 205, 163] }, // Light Blue to Peach
+ { from: [74, 0, 224], to: [143, 0, 255] }, // Deep Blue to Bright Purple
+ { from: [252, 74, 26], to: [247, 183, 51] }, // Deep Orange to Soft Yellow
+ { from: [0, 255, 255], to: [255, 20, 147] }, // Cyan to Deep Pink
+ { from: [255, 127, 0], to: [255, 255, 0] }, // Orange to Yellow
+ { from: [255, 0, 255], to: [0, 255, 0] }, // Magenta to Green
] satisfies Array<{ from: RGBColor; to: RGBColor }>;
const WALLPAPER_NAMES = [
- // macOS wallpapers
- "macOS/tahoe-dusk-min",
- "macOS/tahoe-dawn-min",
- "macOS/tahoe-day-min",
- "macOS/tahoe-night-min",
- "macOS/tahoe-dark",
- "macOS/tahoe-light",
- "macOS/sequoia-dark",
- "macOS/sequoia-light",
- "macOS/sonoma-clouds",
- "macOS/sonoma-dark",
- "macOS/sonoma-evening",
- "macOS/sonoma-fromabove",
- "macOS/sonoma-horizon",
- "macOS/sonoma-light",
- "macOS/sonoma-river",
- "macOS/ventura-dark",
- "macOS/ventura-semi-dark",
- "macOS/ventura",
- // Blue wallpapers
- "blue/1",
- "blue/2",
- "blue/3",
- "blue/4",
- "blue/5",
- "blue/6",
- // Purple wallpapers
- "purple/1",
- "purple/2",
- "purple/3",
- "purple/4",
- "purple/5",
- "purple/6",
- // Dark wallpapers
- "dark/1",
- "dark/2",
- "dark/3",
- "dark/4",
- "dark/5",
- "dark/6",
- // Orange wallpapers
- "orange/1",
- "orange/2",
- "orange/3",
- "orange/4",
- "orange/5",
- "orange/6",
- "orange/7",
- "orange/8",
- "orange/9",
+ // macOS wallpapers
+ "macOS/tahoe-dusk-min",
+ "macOS/tahoe-dawn-min",
+ "macOS/tahoe-day-min",
+ "macOS/tahoe-night-min",
+ "macOS/tahoe-dark",
+ "macOS/tahoe-light",
+ "macOS/sequoia-dark",
+ "macOS/sequoia-light",
+ "macOS/sonoma-clouds",
+ "macOS/sonoma-dark",
+ "macOS/sonoma-evening",
+ "macOS/sonoma-fromabove",
+ "macOS/sonoma-horizon",
+ "macOS/sonoma-light",
+ "macOS/sonoma-river",
+ "macOS/ventura-dark",
+ "macOS/ventura-semi-dark",
+ "macOS/ventura",
+ // Blue wallpapers
+ "blue/1",
+ "blue/2",
+ "blue/3",
+ "blue/4",
+ "blue/5",
+ "blue/6",
+ // Purple wallpapers
+ "purple/1",
+ "purple/2",
+ "purple/3",
+ "purple/4",
+ "purple/5",
+ "purple/6",
+ // Dark wallpapers
+ "dark/1",
+ "dark/2",
+ "dark/3",
+ "dark/4",
+ "dark/5",
+ "dark/6",
+ // Orange wallpapers
+ "orange/1",
+ "orange/2",
+ "orange/3",
+ "orange/4",
+ "orange/5",
+ "orange/6",
+ "orange/7",
+ "orange/8",
+ "orange/9",
] as const;
const STEREO_MODES = [
- { name: "Stereo", value: "stereo" },
- { name: "Mono L", value: "monoL" },
- { name: "Mono R", value: "monoR" },
+ { name: "Stereo", value: "stereo" },
+ { name: "Mono L", value: "monoL" },
+ { name: "Mono R", value: "monoR" },
] satisfies Array<{ name: string; value: StereoMode }>;
const CAMERA_SHAPES = [
- {
- name: "Square",
- value: "square",
- },
- {
- name: "Source",
- value: "source",
- },
+ {
+ name: "Square",
+ value: "square",
+ },
+ {
+ name: "Source",
+ value: "source",
+ },
] satisfies Array<{ name: string; value: CameraShape }>;
const CORNER_STYLE_OPTIONS = [
- { name: "Squircle", value: "squircle" },
- { name: "Rounded", value: "rounded" },
+ { name: "Squircle", value: "squircle" },
+ { name: "Rounded", value: "rounded" },
] satisfies Array<{ name: string; value: CornerRoundingType }>;
const BACKGROUND_THEMES = {
- macOS: "macOS",
- dark: "Dark",
- blue: "Blue",
- purple: "Purple",
- orange: "Orange",
+ macOS: "macOS",
+ dark: "Dark",
+ blue: "Blue",
+ purple: "Purple",
+ orange: "Orange",
};
type CursorPresetValues = {
- tension: number;
- mass: number;
- friction: number;
+ tension: number;
+ mass: number;
+ friction: number;
};
const DEFAULT_CURSOR_MOTION_BLUR = 0.5;
const CURSOR_ANIMATION_STYLE_OPTIONS = [
- {
- value: "slow",
- label: "Slow",
- description: "Relaxed easing with a gentle follow and higher inertia.",
- preset: { tension: 65, mass: 1.8, friction: 16 },
- },
- {
- value: "mellow",
- label: "Mellow",
- description: "Balanced smoothing for everyday tutorials and walkthroughs.",
- preset: { tension: 120, mass: 1.1, friction: 18 },
- },
- {
- value: "custom",
- label: "Custom",
- description: "Tune tension, friction, and mass manually for full control.",
- },
+ {
+ value: "slow",
+ label: "Slow",
+ description: "Relaxed easing with a gentle follow and higher inertia.",
+ preset: { tension: 65, mass: 1.8, friction: 16 },
+ },
+ {
+ value: "mellow",
+ label: "Mellow",
+ description: "Balanced smoothing for everyday tutorials and walkthroughs.",
+ preset: { tension: 120, mass: 1.1, friction: 18 },
+ },
+ {
+ value: "custom",
+ label: "Custom",
+ description: "Tune tension, friction, and mass manually for full control.",
+ },
] satisfies Array<{
- value: CursorAnimationStyle;
- label: string;
- description: string;
- preset?: CursorPresetValues;
+ value: CursorAnimationStyle;
+ label: string;
+ description: string;
+ preset?: CursorPresetValues;
}>;
const CURSOR_PRESET_TOLERANCE = {
- tension: 1,
- mass: 0.05,
- friction: 0.2,
+ tension: 1,
+ mass: 0.05,
+ friction: 0.2,
} as const;
const findCursorPreset = (
- values: CursorPresetValues
+ values: CursorPresetValues,
): CursorAnimationStyle | null => {
- const preset = CURSOR_ANIMATION_STYLE_OPTIONS.find(
- (option) =>
- option.preset &&
- Math.abs(option.preset.tension - values.tension) <=
- CURSOR_PRESET_TOLERANCE.tension &&
- Math.abs(option.preset.mass - values.mass) <=
- CURSOR_PRESET_TOLERANCE.mass &&
- Math.abs(option.preset.friction - values.friction) <=
- CURSOR_PRESET_TOLERANCE.friction
- );
-
- return preset?.value ?? null;
+ const preset = CURSOR_ANIMATION_STYLE_OPTIONS.find(
+ (option) =>
+ option.preset &&
+ Math.abs(option.preset.tension - values.tension) <=
+ CURSOR_PRESET_TOLERANCE.tension &&
+ Math.abs(option.preset.mass - values.mass) <=
+ CURSOR_PRESET_TOLERANCE.mass &&
+ Math.abs(option.preset.friction - values.friction) <=
+ CURSOR_PRESET_TOLERANCE.friction,
+ );
+
+ return preset?.value ?? null;
};
const TAB_IDS = {
- background: "background",
- camera: "camera",
- transcript: "transcript",
- audio: "audio",
- cursor: "cursor",
- hotkeys: "hotkeys",
+ background: "background",
+ camera: "camera",
+ transcript: "transcript",
+ audio: "audio",
+ cursor: "cursor",
+ hotkeys: "hotkeys",
} as const;
export function ConfigSidebar() {
- const {
- project,
- setProject,
- setEditorState,
- projectActions,
- editorInstance,
- editorState,
- meta,
- } = useEditorContext();
-
- const cursorIdleDelay = () =>
- ((project.cursor as { hideWhenIdleDelay?: number }).hideWhenIdleDelay ??
- 2) as number;
-
- const clampIdleDelay = (value: number) =>
- Math.round(Math.min(5, Math.max(0.5, value)) * 10) / 10;
-
- type CursorPhysicsKey = "tension" | "mass" | "friction";
-
- const setCursorPhysics = (key: CursorPhysicsKey, value: number) => {
- const nextValues: CursorPresetValues = {
- tension: key === "tension" ? value : project.cursor.tension,
- mass: key === "mass" ? value : project.cursor.mass,
- friction: key === "friction" ? value : project.cursor.friction,
- };
- const matched = findCursorPreset(nextValues);
- const nextStyle = (matched ?? "custom") as CursorAnimationStyle;
-
- batch(() => {
- setProject("cursor", key, value);
- if (project.cursor.animationStyle !== nextStyle) {
- setProject("cursor", "animationStyle", nextStyle);
- }
- });
- };
-
- const applyCursorStylePreset = (style: CursorAnimationStyle) => {
- const option = CURSOR_ANIMATION_STYLE_OPTIONS.find(
- (item) => item.value === style
- );
-
- batch(() => {
- setProject("cursor", "animationStyle", style);
- if (option?.preset) {
- setProject("cursor", "tension", option.preset.tension);
- setProject("cursor", "mass", option.preset.mass);
- setProject("cursor", "friction", option.preset.friction);
- }
- });
- };
-
- const [state, setState] = createStore({
- selectedTab: "background" as
- | "background"
- | "camera"
- | "transcript"
- | "audio"
- | "cursor"
- | "hotkeys"
- | "captions",
- });
-
- let scrollRef!: HTMLDivElement;
-
- return (
-
-
- s.camera === null
- ),
- },
- { id: TAB_IDS.audio, icon: IconCapAudioOn },
- {
- id: TAB_IDS.cursor,
- icon: IconCapCursor,
- disabled: !(
- meta().type === "multiple" && (meta() as any).segments[0].cursor
- ),
- },
- window.FLAGS.captions && {
- id: "captions" as const,
- icon: IconCapMessageBubble,
- },
- // { id: "hotkeys" as const, icon: IconCapHotkeys },
- ].filter(Boolean)}
- >
- {(item) => (
- {
- // Clear any active selection first
- if (editorState.timeline.selection) {
- setEditorState("timeline", "selection", null);
- }
- setState("selectedTab", item.id);
- scrollRef.scrollTo({
- top: 0,
- });
- }}
- disabled={item.disabled}
- >
-
-
-
-
- )}
-
-
- {/** Center the indicator with the icon */}
-
-
-
-
-
-
-
-
-
-
- }
- >
-
- setProject("audio", "mute", v)}
- />
-
- {editorInstance.recordings.segments[0].mic?.channels === 2 && (
-
-
- options={STEREO_MODES}
- optionValue="value"
- optionTextValue="name"
- value={STEREO_MODES.find(
- (v) => v.value === project.audio.micStereoMode
- )}
- onChange={(v) => {
- if (v) setProject("audio", "micStereoMode", v.value);
- }}
- disallowEmptySelection
- itemComponent={(props) => (
-
- )}
- >
-
- class="flex-1 text-sm text-left truncate text-[--gray-500] font-normal">
- {(state) => {state.selectedOption().name}}
-
-
- as={(props) => (
-
- )}
- />
-
-
-
- as={KSelect.Content}
- class={cx(topSlideAnimateClasses, "z-50")}
- >
-
- class="overflow-y-auto max-h-32"
- as={KSelect.Listbox}
- />
-
-
-
-
- )}
-
- {/*
+ const {
+ project,
+ setProject,
+ setEditorState,
+ projectActions,
+ editorInstance,
+ editorState,
+ meta,
+ } = useEditorContext();
+
+ const cursorIdleDelay = () =>
+ ((project.cursor as { hideWhenIdleDelay?: number }).hideWhenIdleDelay ??
+ 2) as number;
+
+ const clampIdleDelay = (value: number) =>
+ Math.round(Math.min(5, Math.max(0.5, value)) * 10) / 10;
+
+ type CursorPhysicsKey = "tension" | "mass" | "friction";
+
+ const setCursorPhysics = (key: CursorPhysicsKey, value: number) => {
+ const nextValues: CursorPresetValues = {
+ tension: key === "tension" ? value : project.cursor.tension,
+ mass: key === "mass" ? value : project.cursor.mass,
+ friction: key === "friction" ? value : project.cursor.friction,
+ };
+ const matched = findCursorPreset(nextValues);
+ const nextStyle = (matched ?? "custom") as CursorAnimationStyle;
+
+ batch(() => {
+ setProject("cursor", key, value);
+ if (project.cursor.animationStyle !== nextStyle) {
+ setProject("cursor", "animationStyle", nextStyle);
+ }
+ });
+ };
+
+ const applyCursorStylePreset = (style: CursorAnimationStyle) => {
+ const option = CURSOR_ANIMATION_STYLE_OPTIONS.find(
+ (item) => item.value === style,
+ );
+
+ batch(() => {
+ setProject("cursor", "animationStyle", style);
+ if (option?.preset) {
+ setProject("cursor", "tension", option.preset.tension);
+ setProject("cursor", "mass", option.preset.mass);
+ setProject("cursor", "friction", option.preset.friction);
+ }
+ });
+ };
+
+ const [state, setState] = createStore({
+ selectedTab: "background" as
+ | "background"
+ | "camera"
+ | "transcript"
+ | "audio"
+ | "cursor"
+ | "hotkeys"
+ | "captions",
+ });
+
+ let scrollRef!: HTMLDivElement;
+
+ return (
+
+
+ s.camera === null,
+ ),
+ },
+ { id: TAB_IDS.audio, icon: IconCapAudioOn },
+ {
+ id: TAB_IDS.cursor,
+ icon: IconCapCursor,
+ disabled: !(
+ meta().type === "multiple" && (meta() as any).segments[0].cursor
+ ),
+ },
+ window.FLAGS.captions && {
+ id: "captions" as const,
+ icon: IconCapMessageBubble,
+ },
+ // { id: "hotkeys" as const, icon: IconCapHotkeys },
+ ].filter(Boolean)}
+ >
+ {(item) => (
+ {
+ // Clear any active selection first
+ if (editorState.timeline.selection) {
+ setEditorState("timeline", "selection", null);
+ }
+ setState("selectedTab", item.id);
+ scrollRef.scrollTo({
+ top: 0,
+ });
+ }}
+ disabled={item.disabled}
+ >
+
+
+
+
+ )}
+
+
+ {/** Center the indicator with the icon */}
+
+
+
+
+
+
+
+
+
+
+ }
+ >
+
+ setProject("audio", "mute", v)}
+ />
+
+ {editorInstance.recordings.segments[0].mic?.channels === 2 && (
+
+
+ options={STEREO_MODES}
+ optionValue="value"
+ optionTextValue="name"
+ value={STEREO_MODES.find(
+ (v) => v.value === project.audio.micStereoMode,
+ )}
+ onChange={(v) => {
+ if (v) setProject("audio", "micStereoMode", v.value);
+ }}
+ disallowEmptySelection
+ itemComponent={(props) => (
+
+ )}
+ >
+
+ class="flex-1 text-sm text-left truncate text-[--gray-500] font-normal">
+ {(state) => {state.selectedOption().name}}
+
+
+ as={(props) => (
+
+ )}
+ />
+
+
+
+ as={KSelect.Content}
+ class={cx(topSlideAnimateClasses, "z-50")}
+ >
+
+ class="overflow-y-auto max-h-32"
+ as={KSelect.Listbox}
+ />
+
+
+
+
+ )}
+
+ {/*
setProject("audio", "mute", v)}
/>
*/}
- {/*
+ {/*
*/}
-
- {meta().hasMicrophone && (
- }
- >
- setProject("audio", "micVolumeDb", v[0])}
- minValue={-30}
- maxValue={10}
- step={0.1}
- formatTooltip={(v) =>
- v <= -30 ? "Muted" : `${v > 0 ? "+" : ""}${v.toFixed(1)} dB`
- }
- />
-
- )}
- {meta().hasSystemAudio && (
- }
- >
- setProject("audio", "systemVolumeDb", v[0])}
- minValue={-30}
- maxValue={10}
- step={0.1}
- formatTooltip={(v) =>
- v <= -30 ? "Muted" : `${v > 0 ? "+" : ""}${v.toFixed(1)} dB`
- }
- />
-
- )}
-
-
- }
- value={
- {
- setProject("cursor", "hide", !v);
- }}
- />
- }
- />
-
- }>
- setProject("cursor", "size", v[0])}
- minValue={20}
- maxValue={300}
- step={1}
- />
-
- }
- value={
-
- setProject("cursor", "hideWhenIdle", value)
- }
- />
- }
- />
-
-
-
- {
- const rounded = clampIdleDelay(v[0]);
- setProject("cursor", "hideWhenIdleDelay" as any, rounded);
- }}
- minValue={0.5}
- maxValue={5}
- step={0.1}
- formatTooltip={(value) => `${value.toFixed(1)}s`}
- />
-
- {cursorIdleDelay().toFixed(1)}s
-
-
-
-
- }
- >
-
- applyCursorStylePreset(value as CursorAnimationStyle)
- }
- >
- {CURSOR_ANIMATION_STYLE_OPTIONS.map((option) => (
-
-
-
-
-
-
- {option.label}
-
-
- {option.description}
-
-
-
-
- ))}
-
-
-
- }
- value={
- {
- setProject("cursor", "raw", !value);
- }}
- />
- }
- />
-
- {/* if Content has padding or margin the animation doesn't look as good */}
-
-
- setCursorPhysics("tension", v[0])}
- minValue={1}
- maxValue={500}
- step={1}
- />
-
-
- setCursorPhysics("friction", v[0])}
- minValue={0}
- maxValue={50}
- step={0.1}
- />
-
-
- setCursorPhysics("mass", v[0])}
- minValue={0.1}
- maxValue={10}
- step={0.01}
- />
-
-
-
-
- }
- value={
- {
- setProject("cursor", "useSvg" as any, value);
- }}
- />
- }
- />
-
-
- {/* }>
+
+ {meta().hasMicrophone && (
+ }
+ >
+ setProject("audio", "micVolumeDb", v[0])}
+ minValue={-30}
+ maxValue={10}
+ step={0.1}
+ formatTooltip={(v) =>
+ v <= -30 ? "Muted" : `${v > 0 ? "+" : ""}${v.toFixed(1)} dB`
+ }
+ />
+
+ )}
+ {meta().hasSystemAudio && (
+ }
+ >
+ setProject("audio", "systemVolumeDb", v[0])}
+ minValue={-30}
+ maxValue={10}
+ step={0.1}
+ formatTooltip={(v) =>
+ v <= -30 ? "Muted" : `${v > 0 ? "+" : ""}${v.toFixed(1)} dB`
+ }
+ />
+
+ )}
+
+
+ }
+ value={
+ {
+ setProject("cursor", "hide", !v);
+ }}
+ />
+ }
+ />
+
+ }>
+ setProject("cursor", "size", v[0])}
+ minValue={20}
+ maxValue={300}
+ step={1}
+ />
+
+ }
+ value={
+
+ setProject("cursor", "hideWhenIdle", value)
+ }
+ />
+ }
+ />
+
+
+
+ {
+ const rounded = clampIdleDelay(v[0]);
+ setProject("cursor", "hideWhenIdleDelay" as any, rounded);
+ }}
+ minValue={0.5}
+ maxValue={5}
+ step={0.1}
+ formatTooltip={(value) => `${value.toFixed(1)}s`}
+ />
+
+ {cursorIdleDelay().toFixed(1)}s
+
+
+
+
+ }
+ >
+
+ applyCursorStylePreset(value as CursorAnimationStyle)
+ }
+ >
+ {CURSOR_ANIMATION_STYLE_OPTIONS.map((option) => (
+
+
+
+
+
+
+ {option.label}
+
+
+ {option.description}
+
+
+
+
+ ))}
+
+
+
+ }
+ value={
+ {
+ setProject("cursor", "raw", !value);
+ }}
+ />
+ }
+ />
+
+ {/* if Content has padding or margin the animation doesn't look as good */}
+
+
+ setCursorPhysics("tension", v[0])}
+ minValue={1}
+ maxValue={500}
+ step={1}
+ />
+
+
+ setCursorPhysics("friction", v[0])}
+ minValue={0}
+ maxValue={50}
+ step={0.1}
+ />
+
+
+ setCursorPhysics("mass", v[0])}
+ minValue={0.1}
+ maxValue={10}
+ step={0.01}
+ />
+
+
+
+
+ }
+ value={
+ {
+ setProject("cursor", "useSvg" as any, value);
+ }}
+ />
+ }
+ />
+
+
+ {/* }>
*/}
-
-
- }>
-
-
-
-
-
-
-
-
-
-
-
-
-
- {(selection) => (
-
- {
- const zoomSelection = selection();
- if (zoomSelection.type !== "zoom") return;
-
- const segments = zoomSelection.indices
- .map((index) => ({
- index,
- segment: project.timeline?.zoomSegments?.[index],
- }))
- .filter(
- (item): item is { index: number; segment: ZoomSegment } =>
- item.segment !== undefined
- );
-
- if (segments.length === 0) {
- setEditorState("timeline", "selection", null);
- return;
- }
- return { selection: zoomSelection, segments };
- })()}
- >
- {(value) => (
-
-
-
-
- setEditorState("timeline", "selection", null)
- }
- leftIcon={}
- >
- Done
-
-
- {value().segments.length} zoom{" "}
- {value().segments.length === 1
- ? "segment"
- : "segments"}{" "}
- selected
-
-
-
{
- projectActions.deleteZoomSegments(
- value().segments.map((s) => s.index)
- );
- }}
- leftIcon={}
- >
- Delete
-
-
-
-
- {(item, index) => (
-
-
-
- )}
-
-
- }
- >
-
- {(item) => (
-
-
-
- )}
-
-
-
- )}
-
- {
- const sceneSelection = selection();
- if (sceneSelection.type !== "scene") return;
-
- const segments = sceneSelection.indices
- .map((idx) => ({
- segment: project.timeline?.sceneSegments?.[idx],
- index: idx,
- }))
- .filter((s) => s.segment !== undefined);
-
- if (segments.length === 0) return;
- return { selection: sceneSelection, segments };
- })()}
- >
- {(value) => (
- 1}
- fallback={
-
- }
- >
-
-
-
-
- setEditorState("timeline", "selection", null)
- }
- leftIcon={}
- >
- Done
-
-
- {value().segments.length} scene{" "}
- {value().segments.length === 1
- ? "segment"
- : "segments"}{" "}
- selected
-
-
-
{
- const indices = value().selection.indices;
-
- // Delete segments in reverse order to maintain indices
- [...indices]
- .sort((a, b) => b - a)
- .forEach((idx) => {
- projectActions.deleteSceneSegment(idx);
- });
- }}
- leftIcon={}
- >
- Delete
-
-
-
-
- )}
-
- {
- const clipSelection = selection();
- if (clipSelection.type !== "clip") return;
-
- const segments = clipSelection.indices
- .map((idx) => ({
- segment: project.timeline?.segments?.[idx],
- index: idx,
- }))
- .filter((s) => s.segment !== undefined);
-
- if (segments.length === 0) return;
- return { selection: clipSelection, segments };
- })()}
- >
- {(value) => (
- 1}
- fallback={
-
- }
- >
-
-
-
-
- setEditorState("timeline", "selection", null)
- }
- leftIcon={}
- >
- Done
-
-
- {value().segments.length} clip{" "}
- {value().segments.length === 1
- ? "segment"
- : "segments"}{" "}
- selected
-
-
-
{
- const indices = value().selection.indices;
-
- // Delete segments in reverse order to maintain indices
- [...indices]
- .sort((a, b) => b - a)
- .forEach((idx) => {
- projectActions.deleteClipSegment(idx);
- });
- }}
- leftIcon={}
- >
- Delete
-
-
-
-
- )}
-
-
- )}
-
-
-
- );
+
+
+ }>
+
+
+
+
+
+
+
+
+
+
+
+