From 6de6c7fd95de1de9d8d3107eaf7ce1dd150ed094 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Tue, 14 Apr 2026 18:17:14 +0200 Subject: refactor: move constants to domain modules --- apps/web/src/lib/animation/property-registry.ts | 4 +- apps/web/src/lib/animation/transform.ts | 1 + apps/web/src/lib/background/blur.ts | 10 ++++ apps/web/src/lib/background/color.ts | 1 + apps/web/src/lib/background/constants.ts | 11 ---- apps/web/src/lib/canvas/constants.ts | 10 ---- apps/web/src/lib/canvas/sizes.ts | 10 ++++ apps/web/src/lib/export.ts | 70 ---------------------- apps/web/src/lib/export/defaults.ts | 7 +++ apps/web/src/lib/export/index.ts | 70 ++++++++++++++++++++++ apps/web/src/lib/export/mime-types.ts | 4 ++ apps/web/src/lib/fonts/google-fonts.ts | 2 +- apps/web/src/lib/fonts/system-fonts.ts | 11 ++++ apps/web/src/lib/fps/constants.ts | 11 ---- apps/web/src/lib/fps/defaults.ts | 3 + apps/web/src/lib/fps/presets.ts | 7 +++ apps/web/src/lib/guides/definitions/grid.tsx | 2 +- apps/web/src/lib/guides/grid.ts | 4 ++ apps/web/src/lib/masks/definitions/box-like.ts | 2 +- apps/web/src/lib/masks/dimensions.ts | 2 + apps/web/src/lib/masks/feather.ts | 2 + apps/web/src/lib/masks/geometry.ts | 2 +- apps/web/src/lib/masks/handle-positions.ts | 2 +- apps/web/src/lib/masks/param-update.ts | 2 +- apps/web/src/lib/masks/registry.ts | 2 +- apps/web/src/lib/masks/snap.ts | 2 +- apps/web/src/lib/media/audio.ts | 1 - apps/web/src/lib/panels/constants.ts | 9 --- apps/web/src/lib/panels/layout.ts | 9 +++ apps/web/src/lib/preview/constants.ts | 7 --- apps/web/src/lib/preview/element-bounds.ts | 2 +- apps/web/src/lib/preview/zoom.ts | 7 +++ apps/web/src/lib/selection/attributes.ts | 1 + apps/web/src/lib/selection/constants.ts | 1 - apps/web/src/lib/selection/selectable-item.tsx | 2 +- apps/web/src/lib/selection/selectable-surface.tsx | 2 +- apps/web/src/lib/site/brand.ts | 13 ++++ apps/web/src/lib/site/external-tools.ts | 24 ++++++++ apps/web/src/lib/site/social.ts | 5 ++ apps/web/src/lib/site/sponsors.ts | 24 ++++++++ apps/web/src/lib/stickers/categories.ts | 7 +++ apps/web/src/lib/stickers/index.ts | 4 +- apps/web/src/lib/stickers/intrinsic-size.ts | 1 + apps/web/src/lib/stickers/types.ts | 2 +- .../lib/subtitles/build-subtitle-text-element.ts | 2 +- apps/web/src/lib/text/background.ts | 2 + apps/web/src/lib/text/constants.ts | 12 ---- apps/web/src/lib/text/measure-element.ts | 6 +- apps/web/src/lib/text/typography.ts | 9 +++ apps/web/src/lib/timeline/creation.ts | 2 +- apps/web/src/lib/transcription/audio.ts | 4 ++ apps/web/src/lib/transcription/caption-defaults.ts | 2 + apps/web/src/lib/transcription/caption.ts | 2 +- apps/web/src/lib/transcription/languages.ts | 14 +++++ apps/web/src/lib/transcription/models.ts | 34 +++++++++++ .../src/lib/transcription/supported-languages.ts | 1 + apps/web/src/lib/transcription/types.ts | 2 +- apps/web/src/lib/wasm/constants.ts | 3 - apps/web/src/lib/wasm/index.ts | 2 +- apps/web/src/lib/wasm/ticks.ts | 3 + 60 files changed, 315 insertions(+), 160 deletions(-) create mode 100644 apps/web/src/lib/animation/transform.ts create mode 100644 apps/web/src/lib/background/blur.ts create mode 100644 apps/web/src/lib/background/color.ts delete mode 100644 apps/web/src/lib/background/constants.ts delete mode 100644 apps/web/src/lib/canvas/constants.ts create mode 100644 apps/web/src/lib/canvas/sizes.ts delete mode 100644 apps/web/src/lib/export.ts create mode 100644 apps/web/src/lib/export/defaults.ts create mode 100644 apps/web/src/lib/export/index.ts create mode 100644 apps/web/src/lib/export/mime-types.ts create mode 100644 apps/web/src/lib/fonts/system-fonts.ts delete mode 100644 apps/web/src/lib/fps/constants.ts create mode 100644 apps/web/src/lib/fps/defaults.ts create mode 100644 apps/web/src/lib/fps/presets.ts create mode 100644 apps/web/src/lib/guides/grid.ts create mode 100644 apps/web/src/lib/masks/dimensions.ts create mode 100644 apps/web/src/lib/masks/feather.ts delete mode 100644 apps/web/src/lib/panels/constants.ts create mode 100644 apps/web/src/lib/panels/layout.ts delete mode 100644 apps/web/src/lib/preview/constants.ts create mode 100644 apps/web/src/lib/preview/zoom.ts create mode 100644 apps/web/src/lib/selection/attributes.ts delete mode 100644 apps/web/src/lib/selection/constants.ts create mode 100644 apps/web/src/lib/site/brand.ts create mode 100644 apps/web/src/lib/site/external-tools.ts create mode 100644 apps/web/src/lib/site/social.ts create mode 100644 apps/web/src/lib/site/sponsors.ts create mode 100644 apps/web/src/lib/stickers/categories.ts create mode 100644 apps/web/src/lib/stickers/intrinsic-size.ts create mode 100644 apps/web/src/lib/text/background.ts delete mode 100644 apps/web/src/lib/text/constants.ts create mode 100644 apps/web/src/lib/text/typography.ts create mode 100644 apps/web/src/lib/transcription/audio.ts create mode 100644 apps/web/src/lib/transcription/caption-defaults.ts create mode 100644 apps/web/src/lib/transcription/languages.ts create mode 100644 apps/web/src/lib/transcription/models.ts create mode 100644 apps/web/src/lib/transcription/supported-languages.ts delete mode 100644 apps/web/src/lib/wasm/constants.ts create mode 100644 apps/web/src/lib/wasm/ticks.ts (limited to 'apps/web/src/lib') diff --git a/apps/web/src/lib/animation/property-registry.ts b/apps/web/src/lib/animation/property-registry.ts index 65713e6d..56340fd8 100644 --- a/apps/web/src/lib/animation/property-registry.ts +++ b/apps/web/src/lib/animation/property-registry.ts @@ -6,11 +6,11 @@ import type { } from "@/lib/animation/types"; import { parseColorToLinearRgba } from "./binding-values"; import type { TimelineElement } from "@/lib/timeline"; -import { MIN_TRANSFORM_SCALE } from "@/constants/animation-constants"; +import { MIN_TRANSFORM_SCALE } from "@/lib/animation/transform"; import { CORNER_RADIUS_MAX, CORNER_RADIUS_MIN, -} from "@/constants/text-constants"; +} from "@/lib/text/background"; import { canElementHaveAudio, isVisualElement, diff --git a/apps/web/src/lib/animation/transform.ts b/apps/web/src/lib/animation/transform.ts new file mode 100644 index 00000000..ab932ea2 --- /dev/null +++ b/apps/web/src/lib/animation/transform.ts @@ -0,0 +1 @@ +export const MIN_TRANSFORM_SCALE = 0.01; diff --git a/apps/web/src/lib/background/blur.ts b/apps/web/src/lib/background/blur.ts new file mode 100644 index 00000000..3b111482 --- /dev/null +++ b/apps/web/src/lib/background/blur.ts @@ -0,0 +1,10 @@ +export const BACKGROUND_BLUR_INTENSITY_PRESETS: Array<{ + label: string; + value: number; +}> = [ + { label: "Light", value: 100 }, + { label: "Medium", value: 200 }, + { label: "Heavy", value: 500 }, +] as const; + +export const DEFAULT_BACKGROUND_BLUR_INTENSITY = 10; diff --git a/apps/web/src/lib/background/color.ts b/apps/web/src/lib/background/color.ts new file mode 100644 index 00000000..7b86faf5 --- /dev/null +++ b/apps/web/src/lib/background/color.ts @@ -0,0 +1 @@ +export const DEFAULT_BACKGROUND_COLOR = "#000000"; diff --git a/apps/web/src/lib/background/constants.ts b/apps/web/src/lib/background/constants.ts deleted file mode 100644 index b682c260..00000000 --- a/apps/web/src/lib/background/constants.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const BACKGROUND_BLUR_INTENSITY_PRESETS: Array<{ - label: string; - value: number; -}> = [ - { label: "Light", value: 100 }, - { label: "Medium", value: 200 }, - { label: "Heavy", value: 500 }, -] as const; - -export const DEFAULT_BACKGROUND_BLUR_INTENSITY = 10; -export const DEFAULT_BACKGROUND_COLOR = "#000000"; diff --git a/apps/web/src/lib/canvas/constants.ts b/apps/web/src/lib/canvas/constants.ts deleted file mode 100644 index dce75bcb..00000000 --- a/apps/web/src/lib/canvas/constants.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { TCanvasSize } from "@/lib/project/types"; - -export const DEFAULT_CANVAS_PRESETS: TCanvasSize[] = [ - { width: 1920, height: 1080 }, - { width: 1080, height: 1920 }, - { width: 1080, height: 1080 }, - { width: 1440, height: 1080 }, -]; - -export const DEFAULT_CANVAS_SIZE: TCanvasSize = { width: 1920, height: 1080 }; diff --git a/apps/web/src/lib/canvas/sizes.ts b/apps/web/src/lib/canvas/sizes.ts new file mode 100644 index 00000000..dce75bcb --- /dev/null +++ b/apps/web/src/lib/canvas/sizes.ts @@ -0,0 +1,10 @@ +import type { TCanvasSize } from "@/lib/project/types"; + +export const DEFAULT_CANVAS_PRESETS: TCanvasSize[] = [ + { width: 1920, height: 1080 }, + { width: 1080, height: 1920 }, + { width: 1080, height: 1080 }, + { width: 1440, height: 1080 }, +]; + +export const DEFAULT_CANVAS_SIZE: TCanvasSize = { width: 1920, height: 1080 }; diff --git a/apps/web/src/lib/export.ts b/apps/web/src/lib/export.ts deleted file mode 100644 index f397ac4b..00000000 --- a/apps/web/src/lib/export.ts +++ /dev/null @@ -1,70 +0,0 @@ -import type { FrameRate } from "opencut-wasm"; -import { EXPORT_MIME_TYPES } from "@/constants/export-constants"; - -export const EXPORT_QUALITY_VALUES = [ - "low", - "medium", - "high", - "very_high", -] as const; - -export const EXPORT_FORMAT_VALUES = ["mp4", "webm"] as const; - -export type ExportFormat = (typeof EXPORT_FORMAT_VALUES)[number]; -export type ExportQuality = (typeof EXPORT_QUALITY_VALUES)[number]; - -export interface ExportOptions { - format: ExportFormat; - quality: ExportQuality; - fps?: FrameRate; - includeAudio?: boolean; -} - -export interface ExportResult { - success: boolean; - buffer?: ArrayBuffer; - error?: string; - cancelled?: boolean; -} - -export interface ExportState { - isExporting: boolean; - progress: number; - result: ExportResult | null; -} - -export function getExportMimeType({ - format, -}: { - format: ExportFormat; -}): string { - return EXPORT_MIME_TYPES[format]; -} - -export function getExportFileExtension({ - format, -}: { - format: ExportFormat; -}): string { - return `.${format}`; -} - -export function downloadBuffer({ - buffer, - filename, - mimeType, -}: { - buffer: ArrayBuffer; - filename: string; - mimeType: string; -}): void { - const blob = new Blob([buffer], { type: mimeType }); - const url = URL.createObjectURL(blob); - const downloadLink = document.createElement("a"); - downloadLink.href = url; - downloadLink.download = filename; - document.body.appendChild(downloadLink); - downloadLink.click(); - document.body.removeChild(downloadLink); - URL.revokeObjectURL(url); -} diff --git a/apps/web/src/lib/export/defaults.ts b/apps/web/src/lib/export/defaults.ts new file mode 100644 index 00000000..0247f8a8 --- /dev/null +++ b/apps/web/src/lib/export/defaults.ts @@ -0,0 +1,7 @@ +import type { ExportOptions } from "./index"; + +export const DEFAULT_EXPORT_OPTIONS = { + format: "mp4", + quality: "high", + includeAudio: true, +} satisfies ExportOptions; diff --git a/apps/web/src/lib/export/index.ts b/apps/web/src/lib/export/index.ts new file mode 100644 index 00000000..c5c522b3 --- /dev/null +++ b/apps/web/src/lib/export/index.ts @@ -0,0 +1,70 @@ +import type { FrameRate } from "opencut-wasm"; +import { EXPORT_MIME_TYPES } from "./mime-types"; + +export const EXPORT_QUALITY_VALUES = [ + "low", + "medium", + "high", + "very_high", +] as const; + +export const EXPORT_FORMAT_VALUES = ["mp4", "webm"] as const; + +export type ExportFormat = (typeof EXPORT_FORMAT_VALUES)[number]; +export type ExportQuality = (typeof EXPORT_QUALITY_VALUES)[number]; + +export interface ExportOptions { + format: ExportFormat; + quality: ExportQuality; + fps?: FrameRate; + includeAudio?: boolean; +} + +export interface ExportResult { + success: boolean; + buffer?: ArrayBuffer; + error?: string; + cancelled?: boolean; +} + +export interface ExportState { + isExporting: boolean; + progress: number; + result: ExportResult | null; +} + +export function getExportMimeType({ + format, +}: { + format: ExportFormat; +}): string { + return EXPORT_MIME_TYPES[format]; +} + +export function getExportFileExtension({ + format, +}: { + format: ExportFormat; +}): string { + return `.${format}`; +} + +export function downloadBuffer({ + buffer, + filename, + mimeType, +}: { + buffer: ArrayBuffer; + filename: string; + mimeType: string; +}): void { + const blob = new Blob([buffer], { type: mimeType }); + const url = URL.createObjectURL(blob); + const downloadLink = document.createElement("a"); + downloadLink.href = url; + downloadLink.download = filename; + document.body.appendChild(downloadLink); + downloadLink.click(); + document.body.removeChild(downloadLink); + URL.revokeObjectURL(url); +} diff --git a/apps/web/src/lib/export/mime-types.ts b/apps/web/src/lib/export/mime-types.ts new file mode 100644 index 00000000..b98900bf --- /dev/null +++ b/apps/web/src/lib/export/mime-types.ts @@ -0,0 +1,4 @@ +export const EXPORT_MIME_TYPES = { + webm: "video/webm", + mp4: "video/mp4", +} as const; diff --git a/apps/web/src/lib/fonts/google-fonts.ts b/apps/web/src/lib/fonts/google-fonts.ts index 580ce406..8ac55a08 100644 --- a/apps/web/src/lib/fonts/google-fonts.ts +++ b/apps/web/src/lib/fonts/google-fonts.ts @@ -1,5 +1,5 @@ import type { FontAtlas } from "@/lib/fonts/types"; -import { SYSTEM_FONTS } from "@/constants/font-constants"; +import { SYSTEM_FONTS } from "@/lib/fonts/system-fonts"; const GOOGLE_FONTS_CSS = "https://fonts.googleapis.com/css2"; const FONT_ATLAS_PATH = "/fonts/font-atlas.json"; diff --git a/apps/web/src/lib/fonts/system-fonts.ts b/apps/web/src/lib/fonts/system-fonts.ts new file mode 100644 index 00000000..9cc363a3 --- /dev/null +++ b/apps/web/src/lib/fonts/system-fonts.ts @@ -0,0 +1,11 @@ +export const SYSTEM_FONTS = new Set([ + "Arial", + "Helvetica", + "Times New Roman", + "Courier New", + "Verdana", + "Georgia", + "monospace", + "sans-serif", + "serif", +]); diff --git a/apps/web/src/lib/fps/constants.ts b/apps/web/src/lib/fps/constants.ts deleted file mode 100644 index 30c3d2bc..00000000 --- a/apps/web/src/lib/fps/constants.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { FrameRate } from "opencut-wasm"; - -export const FPS_PRESETS = [ - { value: "24", label: "24 fps" }, - { value: "25", label: "25 fps" }, - { value: "30", label: "30 fps" }, - { value: "60", label: "60 fps" }, - { value: "120", label: "120 fps" }, -] as const; - -export const DEFAULT_FPS: FrameRate = { numerator: 30, denominator: 1 }; diff --git a/apps/web/src/lib/fps/defaults.ts b/apps/web/src/lib/fps/defaults.ts new file mode 100644 index 00000000..66bf0b1c --- /dev/null +++ b/apps/web/src/lib/fps/defaults.ts @@ -0,0 +1,3 @@ +import type { FrameRate } from "opencut-wasm"; + +export const DEFAULT_FPS: FrameRate = { numerator: 30, denominator: 1 }; diff --git a/apps/web/src/lib/fps/presets.ts b/apps/web/src/lib/fps/presets.ts new file mode 100644 index 00000000..b09920d4 --- /dev/null +++ b/apps/web/src/lib/fps/presets.ts @@ -0,0 +1,7 @@ +export const FPS_PRESETS = [ + { value: "24", label: "24 fps" }, + { value: "25", label: "25 fps" }, + { value: "30", label: "30 fps" }, + { value: "60", label: "60 fps" }, + { value: "120", label: "120 fps" }, +] as const; diff --git a/apps/web/src/lib/guides/definitions/grid.tsx b/apps/web/src/lib/guides/definitions/grid.tsx index 0e7a2004..7677a1d9 100644 --- a/apps/web/src/lib/guides/definitions/grid.tsx +++ b/apps/web/src/lib/guides/definitions/grid.tsx @@ -9,7 +9,7 @@ import { GRID_MIN, GRID_MAX, DEFAULT_GRID_CONFIG, -} from "@/constants/guide-constants"; +} from "@/lib/guides/grid"; import { usePreviewStore } from "@/stores/preview-store"; import { clampRound } from "@/utils/math"; import { cn } from "@/utils/ui"; diff --git a/apps/web/src/lib/guides/grid.ts b/apps/web/src/lib/guides/grid.ts new file mode 100644 index 00000000..0b707de7 --- /dev/null +++ b/apps/web/src/lib/guides/grid.ts @@ -0,0 +1,4 @@ +export const GRID_MIN = 1; +export const GRID_MAX = 24; + +export const DEFAULT_GRID_CONFIG = { rows: 3, cols: 3 } as const; diff --git a/apps/web/src/lib/masks/definitions/box-like.ts b/apps/web/src/lib/masks/definitions/box-like.ts index 98aefba7..cf42a9f0 100644 --- a/apps/web/src/lib/masks/definitions/box-like.ts +++ b/apps/web/src/lib/masks/definitions/box-like.ts @@ -1,7 +1,7 @@ import { DEFAULT_SHAPE_MASK_SHORT_SIDE_RATIO, MIN_MASK_DIMENSION, -} from "@/constants/mask-constants"; +} from "@/lib/masks/dimensions"; import { computeFeatherUpdate } from "../param-update"; import type { BaseMaskParams, diff --git a/apps/web/src/lib/masks/dimensions.ts b/apps/web/src/lib/masks/dimensions.ts new file mode 100644 index 00000000..dcfcdc0c --- /dev/null +++ b/apps/web/src/lib/masks/dimensions.ts @@ -0,0 +1,2 @@ +export const DEFAULT_SHAPE_MASK_SHORT_SIDE_RATIO = 0.6; +export const MIN_MASK_DIMENSION = 0.01; diff --git a/apps/web/src/lib/masks/feather.ts b/apps/web/src/lib/masks/feather.ts new file mode 100644 index 00000000..83e80a0c --- /dev/null +++ b/apps/web/src/lib/masks/feather.ts @@ -0,0 +1,2 @@ +export const MAX_FEATHER = 1000; +export const FEATHER_HANDLE_SCALE = 0.11; diff --git a/apps/web/src/lib/masks/geometry.ts b/apps/web/src/lib/masks/geometry.ts index 0d4d3905..0a631735 100644 --- a/apps/web/src/lib/masks/geometry.ts +++ b/apps/web/src/lib/masks/geometry.ts @@ -1,6 +1,6 @@ import type { ElementBounds } from "@/lib/preview/element-bounds"; import type { SnapLine } from "@/lib/preview/preview-snap"; -import { MIN_MASK_DIMENSION } from "@/constants/mask-constants"; +import { MIN_MASK_DIMENSION } from "@/lib/masks/dimensions"; import type { ParamValues } from "@/lib/params"; import type { RectangleMaskParams } from "@/lib/masks/types"; diff --git a/apps/web/src/lib/masks/handle-positions.ts b/apps/web/src/lib/masks/handle-positions.ts index 92133df6..91f301c5 100644 --- a/apps/web/src/lib/masks/handle-positions.ts +++ b/apps/web/src/lib/masks/handle-positions.ts @@ -1,4 +1,4 @@ -import { FEATHER_HANDLE_SCALE } from "@/constants/mask-constants"; +import { FEATHER_HANDLE_SCALE } from "@/lib/masks/feather"; import type { ElementBounds } from "@/lib/preview/element-bounds"; import type { MaskFeatures, diff --git a/apps/web/src/lib/masks/param-update.ts b/apps/web/src/lib/masks/param-update.ts index 8d0fa2f6..c4cb92e6 100644 --- a/apps/web/src/lib/masks/param-update.ts +++ b/apps/web/src/lib/masks/param-update.ts @@ -1,4 +1,4 @@ -import { FEATHER_HANDLE_SCALE, MAX_FEATHER } from "@/constants/mask-constants"; +import { FEATHER_HANDLE_SCALE, MAX_FEATHER } from "@/lib/masks/feather"; import { masksRegistry } from "@/lib/masks"; import type { ParamValues } from "@/lib/params"; import type { diff --git a/apps/web/src/lib/masks/registry.ts b/apps/web/src/lib/masks/registry.ts index 5a98cb41..0aa38d87 100644 --- a/apps/web/src/lib/masks/registry.ts +++ b/apps/web/src/lib/masks/registry.ts @@ -1,4 +1,4 @@ -import { MAX_FEATHER } from "@/constants/mask-constants"; +import { MAX_FEATHER } from "@/lib/masks/feather"; import type { ParamDefinition } from "@/lib/params"; import type { BaseMaskParams, MaskDefinition, MaskType } from "@/lib/masks/types"; import type { HugeiconsIconProps } from "@hugeicons/react"; diff --git a/apps/web/src/lib/masks/snap.ts b/apps/web/src/lib/masks/snap.ts index 13deb7cd..2d858f61 100644 --- a/apps/web/src/lib/masks/snap.ts +++ b/apps/web/src/lib/masks/snap.ts @@ -1,5 +1,5 @@ import type { ElementBounds } from "@/lib/preview/element-bounds"; -import { MIN_MASK_DIMENSION } from "@/constants/mask-constants"; +import { MIN_MASK_DIMENSION } from "@/lib/masks/dimensions"; import { snapPosition, snapRotation, diff --git a/apps/web/src/lib/media/audio.ts b/apps/web/src/lib/media/audio.ts index a70a6fa1..5a45b6ea 100644 --- a/apps/web/src/lib/media/audio.ts +++ b/apps/web/src/lib/media/audio.ts @@ -20,7 +20,6 @@ import { canTrackHaveAudio } from "@/lib/timeline"; import { mediaSupportsAudio } from "@/lib/media/media-utils"; import { getSourceTimeAtClipTime, renderRetimedBuffer } from "@/lib/retime"; import { Input, ALL_FORMATS, BlobSource, AudioBufferSink } from "mediabunny"; - import { TICKS_PER_SECOND } from "@/lib/wasm"; const MAX_AUDIO_CHANNELS = 2; diff --git a/apps/web/src/lib/panels/constants.ts b/apps/web/src/lib/panels/constants.ts deleted file mode 100644 index 5a570469..00000000 --- a/apps/web/src/lib/panels/constants.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const PANEL_CONFIG = { - panels: { - tools: 25, - preview: 50, - properties: 25, - mainContent: 50, - timeline: 50, - }, -} as const; diff --git a/apps/web/src/lib/panels/layout.ts b/apps/web/src/lib/panels/layout.ts new file mode 100644 index 00000000..5a570469 --- /dev/null +++ b/apps/web/src/lib/panels/layout.ts @@ -0,0 +1,9 @@ +export const PANEL_CONFIG = { + panels: { + tools: 25, + preview: 50, + properties: 25, + mainContent: 50, + timeline: 50, + }, +} as const; diff --git a/apps/web/src/lib/preview/constants.ts b/apps/web/src/lib/preview/constants.ts deleted file mode 100644 index 9e6f5905..00000000 --- a/apps/web/src/lib/preview/constants.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const PREVIEW_ZOOM_PRESETS = [25, 50, 75, 100, 150, 200]; - -export const PREVIEW_ZOOM = { - min: 0.25, - max: 16, - step: 1.25, -} as const; diff --git a/apps/web/src/lib/preview/element-bounds.ts b/apps/web/src/lib/preview/element-bounds.ts index 0dc2d0d5..39595c33 100644 --- a/apps/web/src/lib/preview/element-bounds.ts +++ b/apps/web/src/lib/preview/element-bounds.ts @@ -1,6 +1,6 @@ import type { SceneTracks, TimelineElement } from "@/lib/timeline"; import type { MediaAsset } from "@/lib/media/types"; -import { STICKER_INTRINSIC_SIZE_FALLBACK } from "@/constants/sticker-constants"; +import { STICKER_INTRINSIC_SIZE_FALLBACK } from "@/lib/stickers/intrinsic-size"; import { DEFAULT_GRAPHIC_SOURCE_SIZE } from "@/lib/graphics"; import { measureTextElement } from "@/lib/text/measure-element"; import { diff --git a/apps/web/src/lib/preview/zoom.ts b/apps/web/src/lib/preview/zoom.ts new file mode 100644 index 00000000..9e6f5905 --- /dev/null +++ b/apps/web/src/lib/preview/zoom.ts @@ -0,0 +1,7 @@ +export const PREVIEW_ZOOM_PRESETS = [25, 50, 75, 100, 150, 200]; + +export const PREVIEW_ZOOM = { + min: 0.25, + max: 16, + step: 1.25, +} as const; diff --git a/apps/web/src/lib/selection/attributes.ts b/apps/web/src/lib/selection/attributes.ts new file mode 100644 index 00000000..a1aee842 --- /dev/null +++ b/apps/web/src/lib/selection/attributes.ts @@ -0,0 +1 @@ +export const SELECTABLE_ITEM_ATTRIBUTE = "data-selectable-item"; diff --git a/apps/web/src/lib/selection/constants.ts b/apps/web/src/lib/selection/constants.ts deleted file mode 100644 index a262c8ce..00000000 --- a/apps/web/src/lib/selection/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const SELECTABLE_ITEM_ATTRIBUTE = "data-selectable-item"; diff --git a/apps/web/src/lib/selection/selectable-item.tsx b/apps/web/src/lib/selection/selectable-item.tsx index 52fd679b..03264753 100644 --- a/apps/web/src/lib/selection/selectable-item.tsx +++ b/apps/web/src/lib/selection/selectable-item.tsx @@ -2,7 +2,7 @@ import { forwardRef, useCallback } from "react"; import { useSelectionContext } from "@/lib/selection/context"; -import { SELECTABLE_ITEM_ATTRIBUTE } from "@/lib/selection/constants"; +import { SELECTABLE_ITEM_ATTRIBUTE } from "@/lib/selection/attributes"; import type { SelectableItemProps } from "@/lib/selection/types"; import { cn } from "@/utils/ui"; diff --git a/apps/web/src/lib/selection/selectable-surface.tsx b/apps/web/src/lib/selection/selectable-surface.tsx index 20c7adb3..012bc486 100644 --- a/apps/web/src/lib/selection/selectable-surface.tsx +++ b/apps/web/src/lib/selection/selectable-surface.tsx @@ -3,7 +3,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { SelectionBox } from "@/lib/selection/selection-box"; import { SelectionContext } from "@/lib/selection/context"; -import { SELECTABLE_ITEM_ATTRIBUTE } from "@/lib/selection/constants"; +import { SELECTABLE_ITEM_ATTRIBUTE } from "@/lib/selection/attributes"; import { resolveElementIntersections } from "@/lib/selection/hit-testing"; import { applyBoxSelection, diff --git a/apps/web/src/lib/site/brand.ts b/apps/web/src/lib/site/brand.ts new file mode 100644 index 00000000..2701608c --- /dev/null +++ b/apps/web/src/lib/site/brand.ts @@ -0,0 +1,13 @@ +export const SITE_URL = "https://opencut.app"; + +export const SITE_INFO = { + title: "OpenCut", + description: + "A simple but powerful video editor that gets the job done. In your browser.", + url: SITE_URL, + openGraphImage: "/open-graph/default.jpg", + twitterImage: "/open-graph/default.jpg", + favicon: "/favicon.ico", +}; + +export const DEFAULT_LOGO_URL = "/logos/opencut/svg/logo.svg"; diff --git a/apps/web/src/lib/site/external-tools.ts b/apps/web/src/lib/site/external-tools.ts new file mode 100644 index 00000000..610ea158 --- /dev/null +++ b/apps/web/src/lib/site/external-tools.ts @@ -0,0 +1,24 @@ +import { OcDataBuddyIcon, OcMarbleIcon } from "@/components/icons"; + +export type ExternalTool = { + name: string; + description: string; + url: string; + icon: React.ElementType; +}; + +export const EXTERNAL_TOOLS: ExternalTool[] = [ + { + name: "Marble", + description: + "Modern headless CMS for content management and the blog for OpenCut", + url: "https://marblecms.com?utm_source=opencut", + icon: OcMarbleIcon, + }, + { + name: "Databuddy", + description: "GDPR compliant analytics and user insights for OpenCut", + url: "https://databuddy.cc?utm_source=opencut", + icon: OcDataBuddyIcon, + }, +]; diff --git a/apps/web/src/lib/site/social.ts b/apps/web/src/lib/site/social.ts new file mode 100644 index 00000000..571e45d5 --- /dev/null +++ b/apps/web/src/lib/site/social.ts @@ -0,0 +1,5 @@ +export const SOCIAL_LINKS = { + x: "https://x.com/opencutapp", + github: "https://github.com/OpenCut-app/OpenCut", + discord: "https://discord.com/invite/Mu3acKZvCp", +}; diff --git a/apps/web/src/lib/site/sponsors.ts b/apps/web/src/lib/site/sponsors.ts new file mode 100644 index 00000000..2bd201b7 --- /dev/null +++ b/apps/web/src/lib/site/sponsors.ts @@ -0,0 +1,24 @@ +export type Sponsor = { + name: string; + url: string; + logo: string; + description: string; + invertOnDark?: boolean; +}; + +export const SPONSORS: Sponsor[] = [ + { + name: "Fal.ai", + url: "https://fal.ai?utm_source=opencut", + logo: "/logos/others/fal.svg", + description: "Generative image, video, and audio models all in one place.", + invertOnDark: true, + }, + { + name: "Vercel", + url: "https://vercel.com?utm_source=opencut", + logo: "/logos/others/vercel.svg", + description: "Platform where we deploy and host OpenCut.", + invertOnDark: true, + }, +]; diff --git a/apps/web/src/lib/stickers/categories.ts b/apps/web/src/lib/stickers/categories.ts new file mode 100644 index 00000000..e8a8b71b --- /dev/null +++ b/apps/web/src/lib/stickers/categories.ts @@ -0,0 +1,7 @@ +export const STICKER_CATEGORIES = { + all: "All", + // v0.4.0 + // logos: "Logos", + flags: "Flags", + shapes: "Shapes", +}; diff --git a/apps/web/src/lib/stickers/index.ts b/apps/web/src/lib/stickers/index.ts index d39fe0f5..d3e14ed1 100644 --- a/apps/web/src/lib/stickers/index.ts +++ b/apps/web/src/lib/stickers/index.ts @@ -1,7 +1,7 @@ import { STICKER_CATEGORIES, - STICKER_INTRINSIC_SIZE_FALLBACK, -} from "@/constants/sticker-constants"; +} from "@/lib/stickers/categories"; +import { STICKER_INTRINSIC_SIZE_FALLBACK } from "@/lib/stickers/intrinsic-size"; import type { StickerCategory } from "@/lib/stickers/types"; import { stickersRegistry } from "./registry"; import { resolveStickerId } from "./resolver"; diff --git a/apps/web/src/lib/stickers/intrinsic-size.ts b/apps/web/src/lib/stickers/intrinsic-size.ts new file mode 100644 index 00000000..43436237 --- /dev/null +++ b/apps/web/src/lib/stickers/intrinsic-size.ts @@ -0,0 +1 @@ +export const STICKER_INTRINSIC_SIZE_FALLBACK = 200; diff --git a/apps/web/src/lib/stickers/types.ts b/apps/web/src/lib/stickers/types.ts index 9d16e4be..bc7dd490 100644 --- a/apps/web/src/lib/stickers/types.ts +++ b/apps/web/src/lib/stickers/types.ts @@ -1,4 +1,4 @@ -import type { STICKER_CATEGORIES } from "@/constants/sticker-constants"; +import type { STICKER_CATEGORIES } from "@/lib/stickers/categories"; export type StickerCategory = keyof typeof STICKER_CATEGORIES; diff --git a/apps/web/src/lib/subtitles/build-subtitle-text-element.ts b/apps/web/src/lib/subtitles/build-subtitle-text-element.ts index 8be93e9d..698310a6 100644 --- a/apps/web/src/lib/subtitles/build-subtitle-text-element.ts +++ b/apps/web/src/lib/subtitles/build-subtitle-text-element.ts @@ -1,4 +1,4 @@ -import { FONT_SIZE_SCALE_REFERENCE } from "@/constants/text-constants"; +import { FONT_SIZE_SCALE_REFERENCE } from "@/lib/text/typography"; import { getTextVisualRect, measureTextBlock, diff --git a/apps/web/src/lib/text/background.ts b/apps/web/src/lib/text/background.ts new file mode 100644 index 00000000..be5ab6f5 --- /dev/null +++ b/apps/web/src/lib/text/background.ts @@ -0,0 +1,2 @@ +export const CORNER_RADIUS_MIN = 0; +export const CORNER_RADIUS_MAX = 100; diff --git a/apps/web/src/lib/text/constants.ts b/apps/web/src/lib/text/constants.ts deleted file mode 100644 index a101f209..00000000 --- a/apps/web/src/lib/text/constants.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const MIN_FONT_SIZE = 5; -export const MAX_FONT_SIZE = 300; -export const DEFAULT_TEXT_COLOR = "#000000"; - -/** - * higher value: smaller font size - * lower value: larger font size - */ -export const FONT_SIZE_SCALE_REFERENCE = 90; - -export const CORNER_RADIUS_MIN = 0; -export const CORNER_RADIUS_MAX = 100; diff --git a/apps/web/src/lib/text/measure-element.ts b/apps/web/src/lib/text/measure-element.ts index 99b8a7ba..213682ab 100644 --- a/apps/web/src/lib/text/measure-element.ts +++ b/apps/web/src/lib/text/measure-element.ts @@ -1,7 +1,5 @@ -import { - CORNER_RADIUS_MIN, - FONT_SIZE_SCALE_REFERENCE, -} from "@/constants/text-constants"; +import { CORNER_RADIUS_MIN } from "@/lib/text/background"; +import { FONT_SIZE_SCALE_REFERENCE } from "@/lib/text/typography"; import { resolveNumberAtTime } from "@/lib/animation"; import { DEFAULTS } from "@/lib/timeline/defaults"; import type { TextBackground, TextElement } from "@/lib/timeline"; diff --git a/apps/web/src/lib/text/typography.ts b/apps/web/src/lib/text/typography.ts new file mode 100644 index 00000000..837236ab --- /dev/null +++ b/apps/web/src/lib/text/typography.ts @@ -0,0 +1,9 @@ +export const MIN_FONT_SIZE = 5; +export const MAX_FONT_SIZE = 300; +export const DEFAULT_TEXT_COLOR = "#000000"; + +/** + * higher value: smaller font size + * lower value: larger font size + */ +export const FONT_SIZE_SCALE_REFERENCE = 90; diff --git a/apps/web/src/lib/timeline/creation.ts b/apps/web/src/lib/timeline/creation.ts index a339d806..19f46115 100644 --- a/apps/web/src/lib/timeline/creation.ts +++ b/apps/web/src/lib/timeline/creation.ts @@ -1,3 +1,3 @@ -import { TICKS_PER_SECOND } from "@/lib/wasm"; +import { TICKS_PER_SECOND } from "@/lib/wasm/ticks"; export const DEFAULT_NEW_ELEMENT_DURATION = 5 * TICKS_PER_SECOND; diff --git a/apps/web/src/lib/transcription/audio.ts b/apps/web/src/lib/transcription/audio.ts new file mode 100644 index 00000000..e2dc96d9 --- /dev/null +++ b/apps/web/src/lib/transcription/audio.ts @@ -0,0 +1,4 @@ +export const DEFAULT_TRANSCRIPTION_SAMPLE_RATE = 16000; + +export const DEFAULT_CHUNK_LENGTH_SECONDS = 30; +export const DEFAULT_STRIDE_SECONDS = 5; diff --git a/apps/web/src/lib/transcription/caption-defaults.ts b/apps/web/src/lib/transcription/caption-defaults.ts new file mode 100644 index 00000000..fc277158 --- /dev/null +++ b/apps/web/src/lib/transcription/caption-defaults.ts @@ -0,0 +1,2 @@ +export const DEFAULT_WORDS_PER_CAPTION = 3; +export const MIN_CAPTION_DURATION_SECONDS = 0.8; diff --git a/apps/web/src/lib/transcription/caption.ts b/apps/web/src/lib/transcription/caption.ts index 6f73ddec..5e23bad8 100644 --- a/apps/web/src/lib/transcription/caption.ts +++ b/apps/web/src/lib/transcription/caption.ts @@ -2,7 +2,7 @@ import type { TranscriptionSegment, CaptionChunk } from "@/lib/transcription/typ import { DEFAULT_WORDS_PER_CAPTION, MIN_CAPTION_DURATION_SECONDS, -} from "@/constants/transcription-constants"; +} from "@/lib/transcription/caption-defaults"; export function buildCaptionChunks({ segments, diff --git a/apps/web/src/lib/transcription/languages.ts b/apps/web/src/lib/transcription/languages.ts new file mode 100644 index 00000000..e5678145 --- /dev/null +++ b/apps/web/src/lib/transcription/languages.ts @@ -0,0 +1,14 @@ +export const LANGUAGES = [ + { code: "en", name: "English" }, + { code: "es", name: "Spanish" }, + { code: "it", name: "Italian" }, + { code: "fr", name: "French" }, + { code: "de", name: "German" }, + { code: "pt", name: "Portuguese" }, + { code: "ru", name: "Russian" }, + { code: "ja", name: "Japanese" }, + { code: "zh", name: "Chinese" }, +] as const; + +export type Language = (typeof LANGUAGES)[number]; +export type LanguageCode = Language["code"]; diff --git a/apps/web/src/lib/transcription/models.ts b/apps/web/src/lib/transcription/models.ts new file mode 100644 index 00000000..ee9047e7 --- /dev/null +++ b/apps/web/src/lib/transcription/models.ts @@ -0,0 +1,34 @@ +import type { + TranscriptionModel, + TranscriptionModelId, +} from "./types"; + +export const TRANSCRIPTION_MODELS: TranscriptionModel[] = [ + { + id: "whisper-tiny", + name: "Tiny", + huggingFaceId: "onnx-community/whisper-tiny", + description: "Fastest, lower accuracy", + }, + { + id: "whisper-small", + name: "Small", + huggingFaceId: "onnx-community/whisper-small", + description: "Good balance of speed and accuracy", + }, + { + id: "whisper-medium", + name: "Medium", + huggingFaceId: "onnx-community/whisper-medium", + description: "Higher accuracy, slower", + }, + { + id: "whisper-large-v3-turbo", + name: "Large v3 Turbo", + huggingFaceId: "onnx-community/whisper-large-v3-turbo", + description: "Best accuracy, requires WebGPU for good performance", + }, +]; + +export const DEFAULT_TRANSCRIPTION_MODEL: TranscriptionModelId = + "whisper-small"; diff --git a/apps/web/src/lib/transcription/supported-languages.ts b/apps/web/src/lib/transcription/supported-languages.ts new file mode 100644 index 00000000..0adc1332 --- /dev/null +++ b/apps/web/src/lib/transcription/supported-languages.ts @@ -0,0 +1 @@ +export { LANGUAGES as TRANSCRIPTION_LANGUAGES } from "./languages"; diff --git a/apps/web/src/lib/transcription/types.ts b/apps/web/src/lib/transcription/types.ts index c4a87aa8..7ab0da7f 100644 --- a/apps/web/src/lib/transcription/types.ts +++ b/apps/web/src/lib/transcription/types.ts @@ -1,4 +1,4 @@ -import type { LanguageCode } from "@/constants/language-constants"; +import type { LanguageCode } from "./languages"; export type TranscriptionLanguage = LanguageCode | "auto"; diff --git a/apps/web/src/lib/wasm/constants.ts b/apps/web/src/lib/wasm/constants.ts deleted file mode 100644 index ababe6b3..00000000 --- a/apps/web/src/lib/wasm/constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { TICKS_PER_SECOND as _TICKS_PER_SECOND } from "opencut-wasm"; - -export const TICKS_PER_SECOND = _TICKS_PER_SECOND(); diff --git a/apps/web/src/lib/wasm/index.ts b/apps/web/src/lib/wasm/index.ts index b04bfcf7..60031a0e 100644 --- a/apps/web/src/lib/wasm/index.ts +++ b/apps/web/src/lib/wasm/index.ts @@ -1 +1 @@ -export * from "./constants"; +export * from "./ticks"; diff --git a/apps/web/src/lib/wasm/ticks.ts b/apps/web/src/lib/wasm/ticks.ts new file mode 100644 index 00000000..ababe6b3 --- /dev/null +++ b/apps/web/src/lib/wasm/ticks.ts @@ -0,0 +1,3 @@ +import { TICKS_PER_SECOND as _TICKS_PER_SECOND } from "opencut-wasm"; + +export const TICKS_PER_SECOND = _TICKS_PER_SECOND(); -- cgit v1.3.1