diff --git a/apps/web/src/app/contributors/page.tsx b/apps/web/src/app/contributors/page.tsx index 64792632..b15d9f27 100644 --- a/apps/web/src/app/contributors/page.tsx +++ b/apps/web/src/app/contributors/page.tsx @@ -3,7 +3,7 @@ import Link from "next/link"; import { GitHubContributeSection } from "@/components/gitHub-contribute-section"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Card, CardContent } from "@/components/ui/card"; -import { EXTERNAL_TOOLS } from "@/constants/site-constants"; +import { EXTERNAL_TOOLS } from "@/lib/site/external-tools"; import { BasePage } from "../base-page"; export const metadata: Metadata = { diff --git a/apps/web/src/app/metadata.ts b/apps/web/src/app/metadata.ts index 72f0c2aa..06276baa 100644 --- a/apps/web/src/app/metadata.ts +++ b/apps/web/src/app/metadata.ts @@ -1,5 +1,5 @@ import type { Metadata } from "next"; -import { SITE_INFO, SITE_URL } from "@/constants/site-constants"; +import { SITE_INFO, SITE_URL } from "@/lib/site/brand"; export const baseMetaData: Metadata = { metadataBase: new URL(SITE_URL), diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx index 43dbc104..460e8bc3 100644 --- a/apps/web/src/app/page.tsx +++ b/apps/web/src/app/page.tsx @@ -2,7 +2,7 @@ import { Hero } from "@/components/landing/hero"; import { Header } from "@/components/header"; import { Footer } from "@/components/footer"; import type { Metadata } from "next"; -import { SITE_URL } from "@/constants/site-constants"; +import { SITE_URL } from "@/lib/site/brand"; export const metadata: Metadata = { alternates: { diff --git a/apps/web/src/app/privacy/page.tsx b/apps/web/src/app/privacy/page.tsx index 0672cfe5..4963e2ab 100644 --- a/apps/web/src/app/privacy/page.tsx +++ b/apps/web/src/app/privacy/page.tsx @@ -7,7 +7,7 @@ import { AccordionTrigger, } from "@/components/ui/accordion"; import { Separator } from "@/components/ui/separator"; -import { SOCIAL_LINKS } from "@/constants/site-constants"; +import { SOCIAL_LINKS } from "@/lib/site/social"; export const metadata: Metadata = { title: "Privacy Policy - OpenCut", diff --git a/apps/web/src/app/robots.ts b/apps/web/src/app/robots.ts index c3e80a6a..38f6f487 100644 --- a/apps/web/src/app/robots.ts +++ b/apps/web/src/app/robots.ts @@ -1,5 +1,5 @@ import type { MetadataRoute } from "next"; -import { SITE_URL } from "@/constants/site-constants"; +import { SITE_URL } from "@/lib/site/brand"; export default function robots(): MetadataRoute.Robots { return { diff --git a/apps/web/src/app/rss.xml/route.ts b/apps/web/src/app/rss.xml/route.ts index 9cfad635..4dfccd59 100644 --- a/apps/web/src/app/rss.xml/route.ts +++ b/apps/web/src/app/rss.xml/route.ts @@ -1,6 +1,6 @@ import { Feed } from "feed"; import { getPosts } from "@/lib/blog/query"; -import { SITE_INFO, SITE_URL } from "@/constants/site-constants"; +import { SITE_INFO, SITE_URL } from "@/lib/site/brand"; export async function GET() { try { diff --git a/apps/web/src/app/sitemap.ts b/apps/web/src/app/sitemap.ts index 2dea655d..7b404642 100644 --- a/apps/web/src/app/sitemap.ts +++ b/apps/web/src/app/sitemap.ts @@ -1,4 +1,4 @@ -import { SITE_URL } from "@/constants/site-constants"; +import { SITE_URL } from "@/lib/site/brand"; import { getPosts } from "@/lib/blog/query"; import type { MetadataRoute } from "next"; diff --git a/apps/web/src/app/sponsors/page.tsx b/apps/web/src/app/sponsors/page.tsx index 64f18776..0de78c85 100644 --- a/apps/web/src/app/sponsors/page.tsx +++ b/apps/web/src/app/sponsors/page.tsx @@ -3,7 +3,7 @@ import Image from "next/image"; import Link from "next/link"; import { BasePage } from "@/app/base-page"; import { Card, CardContent } from "@/components/ui/card"; -import { SPONSORS, type Sponsor } from "@/constants/site-constants"; +import { SPONSORS, type Sponsor } from "@/lib/site/sponsors"; import { HugeiconsIcon } from "@hugeicons/react"; import { LinkSquare02Icon } from "@hugeicons/core-free-icons"; import { cn } from "@/utils/ui"; diff --git a/apps/web/src/app/terms/page.tsx b/apps/web/src/app/terms/page.tsx index 697a89ef..73a6cce1 100644 --- a/apps/web/src/app/terms/page.tsx +++ b/apps/web/src/app/terms/page.tsx @@ -7,7 +7,7 @@ import { AccordionTrigger, } from "@/components/ui/accordion"; import { Separator } from "@/components/ui/separator"; -import { SOCIAL_LINKS } from "@/constants/site-constants"; +import { SOCIAL_LINKS } from "@/lib/site/social"; export const metadata: Metadata = { title: "Terms of Service - OpenCut", diff --git a/apps/web/src/components/editor/editor-header.tsx b/apps/web/src/components/editor/editor-header.tsx index 460e8ed6..ddfcaad4 100644 --- a/apps/web/src/components/editor/editor-header.tsx +++ b/apps/web/src/components/editor/editor-header.tsx @@ -16,7 +16,8 @@ import { useRouter } from "next/navigation"; import { FaDiscord } from "react-icons/fa6"; import { ExportButton } from "./export-button"; import { ThemeToggle } from "../theme-toggle"; -import { DEFAULT_LOGO_URL, SOCIAL_LINKS } from "@/constants/site-constants"; +import { DEFAULT_LOGO_URL } from "@/lib/site/brand"; +import { SOCIAL_LINKS } from "@/lib/site/social"; import { toast } from "sonner"; import { useEditor } from "@/hooks/use-editor"; import { CommandIcon, Logout05Icon } from "@hugeicons/core-free-icons"; diff --git a/apps/web/src/components/editor/export-button.tsx b/apps/web/src/components/editor/export-button.tsx index 3fa4af7a..1f907953 100644 --- a/apps/web/src/components/editor/export-button.tsx +++ b/apps/web/src/components/editor/export-button.tsx @@ -33,7 +33,7 @@ import { SectionTitle, } from "@/components/section"; import { useEditor } from "@/hooks/use-editor"; -import { DEFAULT_EXPORT_OPTIONS } from "@/constants/export-constants"; +import { DEFAULT_EXPORT_OPTIONS } from "@/lib/export/defaults"; function isExportFormat(value: string): value is ExportFormat { return EXPORT_FORMAT_VALUES.some((formatValue) => formatValue === value); diff --git a/apps/web/src/components/editor/onboarding.tsx b/apps/web/src/components/editor/onboarding.tsx index 12bddc8e..54196c76 100644 --- a/apps/web/src/components/editor/onboarding.tsx +++ b/apps/web/src/components/editor/onboarding.tsx @@ -3,7 +3,7 @@ import { ArrowRightIcon } from "lucide-react"; import { useState } from "react"; import ReactMarkdown from "react-markdown"; -import { SOCIAL_LINKS } from "@/constants/site-constants"; +import { SOCIAL_LINKS } from "@/lib/site/social"; import { useLocalStorage } from "@/hooks/storage/use-local-storage"; import { Button } from "../ui/button"; import { Dialog, DialogBody, DialogContent, DialogTitle } from "../ui/dialog"; diff --git a/apps/web/src/components/editor/panels/assets/views/captions.tsx b/apps/web/src/components/editor/panels/assets/views/captions.tsx index 488875a8..7b6ae5ca 100644 --- a/apps/web/src/components/editor/panels/assets/views/captions.tsx +++ b/apps/web/src/components/editor/panels/assets/views/captions.tsx @@ -12,8 +12,8 @@ import { extractTimelineAudio } from "@/lib/media/mediabunny"; import { useEditor } from "@/hooks/use-editor"; import { DEFAULT_TRANSCRIPTION_SAMPLE_RATE, - TRANSCRIPTION_LANGUAGES, -} from "@/constants/transcription-constants"; +} from "@/lib/transcription/audio"; +import { TRANSCRIPTION_LANGUAGES } from "@/lib/transcription/supported-languages"; import type { CaptionChunk, TranscriptionLanguage, diff --git a/apps/web/src/components/editor/panels/assets/views/settings/background.tsx b/apps/web/src/components/editor/panels/assets/views/settings/background.tsx index 72883e35..0367559a 100644 --- a/apps/web/src/components/editor/panels/assets/views/settings/background.tsx +++ b/apps/web/src/components/editor/panels/assets/views/settings/background.tsx @@ -10,8 +10,8 @@ import { import { BACKGROUND_BLUR_INTENSITY_PRESETS, DEFAULT_BACKGROUND_BLUR_INTENSITY, - DEFAULT_BACKGROUND_COLOR, -} from "@/lib/background/constants"; +} from "@/lib/background/blur"; +import { DEFAULT_BACKGROUND_COLOR } from "@/lib/background/color"; import { patternCraftGradients } from "@/data/colors/pattern-craft"; import { colors } from "@/data/colors/solid"; import { syntaxUIGradients } from "@/data/colors/syntax-ui"; diff --git a/apps/web/src/components/editor/panels/assets/views/settings/index.tsx b/apps/web/src/components/editor/panels/assets/views/settings/index.tsx index 16faad3d..4d87493a 100644 --- a/apps/web/src/components/editor/panels/assets/views/settings/index.tsx +++ b/apps/web/src/components/editor/panels/assets/views/settings/index.tsx @@ -9,7 +9,7 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; -import { FPS_PRESETS } from "@/lib/fps/constants"; +import { FPS_PRESETS } from "@/lib/fps/presets"; import { floatToFrameRate, frameRateToFloat } from "@/lib/fps/utils"; import { useEditor } from "@/hooks/use-editor"; import { diff --git a/apps/web/src/components/editor/panels/assets/views/stickers.tsx b/apps/web/src/components/editor/panels/assets/views/stickers.tsx index 5b076466..1ab35d7d 100644 --- a/apps/web/src/components/editor/panels/assets/views/stickers.tsx +++ b/apps/web/src/components/editor/panels/assets/views/stickers.tsx @@ -15,7 +15,7 @@ import { buildGraphicElement, buildStickerElement, } from "@/lib/timeline/element-utils"; -import { STICKER_CATEGORIES } from "@/constants/sticker-constants"; +import { STICKER_CATEGORIES } from "@/lib/stickers/categories"; import { getRegionLabel, resolveQueryToRegions } from "@/lib/stickers"; import { parseShapeStickerId } from "@/lib/stickers/providers/shapes"; import type { TimelineDragData } from "@/lib/timeline/drag"; diff --git a/apps/web/src/components/editor/panels/preview/preview-viewport.tsx b/apps/web/src/components/editor/panels/preview/preview-viewport.tsx index 51e5d2d0..2ac6bd92 100644 --- a/apps/web/src/components/editor/panels/preview/preview-viewport.tsx +++ b/apps/web/src/components/editor/panels/preview/preview-viewport.tsx @@ -17,7 +17,7 @@ import { screenToCanvas, } from "@/lib/preview/preview-coords"; import { clamp, isNearlyEqual } from "@/utils/math"; -import { PREVIEW_ZOOM } from "@/lib/preview/constants"; +import { PREVIEW_ZOOM } from "@/lib/preview/zoom"; const MIDDLE_MOUSE_BUTTON = 1; const IS_AT_FIT_EPSILON = 0.001; diff --git a/apps/web/src/components/editor/panels/preview/text-edit-overlay.tsx b/apps/web/src/components/editor/panels/preview/text-edit-overlay.tsx index 78114b27..44281ade 100644 --- a/apps/web/src/components/editor/panels/preview/text-edit-overlay.tsx +++ b/apps/web/src/components/editor/panels/preview/text-edit-overlay.tsx @@ -6,7 +6,7 @@ import { useEditor } from "@/hooks/use-editor"; import type { TextElement } from "@/lib/timeline"; import { FONT_SIZE_SCALE_REFERENCE, -} from "@/constants/text-constants"; +} from "@/lib/text/typography"; import { DEFAULTS } from "@/lib/timeline/defaults"; import { getElementLocalTime, diff --git a/apps/web/src/components/editor/panels/preview/toolbar.tsx b/apps/web/src/components/editor/panels/preview/toolbar.tsx index c417ec6a..9ee6c822 100644 --- a/apps/web/src/components/editor/panels/preview/toolbar.tsx +++ b/apps/web/src/components/editor/panels/preview/toolbar.tsx @@ -22,7 +22,7 @@ import { SelectItem, SelectSeparator, } from "@/components/ui/select"; -import { PREVIEW_ZOOM_PRESETS } from "@/lib/preview/constants"; +import { PREVIEW_ZOOM_PRESETS } from "@/lib/preview/zoom"; import { usePreviewViewport } from "./preview-viewport"; import { GridPopover } from "./guide-popover"; import { usePreviewStore } from "@/stores/preview-store"; diff --git a/apps/web/src/components/editor/panels/properties/tabs/text-tab.tsx b/apps/web/src/components/editor/panels/properties/tabs/text-tab.tsx index 5fffbcec..d37379ea 100644 --- a/apps/web/src/components/editor/panels/properties/tabs/text-tab.tsx +++ b/apps/web/src/components/editor/panels/properties/tabs/text-tab.tsx @@ -20,11 +20,13 @@ import { clamp, formatNumberForDisplay } from "@/utils/math"; import { useEditor } from "@/hooks/use-editor"; import { CORNER_RADIUS_MAX, - DEFAULT_TEXT_COLOR, CORNER_RADIUS_MIN, +} from "@/lib/text/background"; +import { + DEFAULT_TEXT_COLOR, MAX_FONT_SIZE, MIN_FONT_SIZE, -} from "@/lib/text/constants"; +} from "@/lib/text/typography"; import { usePropertyDraft } from "../hooks/use-property-draft"; import { useKeyframedColorProperty } from "../hooks/use-keyframed-color-property"; import { useKeyframedNumberProperty } from "../hooks/use-keyframed-number-property"; diff --git a/apps/web/src/components/editor/panels/timeline/bookmarks.tsx b/apps/web/src/components/editor/panels/timeline/bookmarks.tsx index 9342c30e..c432b7d4 100644 --- a/apps/web/src/components/editor/panels/timeline/bookmarks.tsx +++ b/apps/web/src/components/editor/panels/timeline/bookmarks.tsx @@ -8,7 +8,7 @@ import { DEFAULT_TIMELINE_BOOKMARK_COLOR, } from "./theme"; import { TIMELINE_BOOKMARK_ROW_HEIGHT_PX } from "./layout"; -import { DEFAULT_FPS } from "@/lib/fps/constants"; +import { DEFAULT_FPS } from "@/lib/fps/defaults"; import { snappedSeekTime } from "opencut-wasm"; import { ArrowTurnBackwardIcon, diff --git a/apps/web/src/components/editor/panels/timeline/timeline-ruler.tsx b/apps/web/src/components/editor/panels/timeline/timeline-ruler.tsx index 8b8dab32..7b69e820 100644 --- a/apps/web/src/components/editor/panels/timeline/timeline-ruler.tsx +++ b/apps/web/src/components/editor/panels/timeline/timeline-ruler.tsx @@ -5,7 +5,7 @@ import { import { mediaTimeToSeconds } from "opencut-wasm"; import { TICKS_PER_SECOND } from "@/lib/wasm"; import { TIMELINE_RULER_HEIGHT_PX } from "./layout"; -import { DEFAULT_FPS } from "@/lib/fps/constants"; +import { DEFAULT_FPS } from "@/lib/fps/defaults"; import { useEditor } from "@/hooks/use-editor"; import { getRulerConfig, shouldShowLabel } from "@/lib/timeline/ruler-utils"; import { useScrollPosition } from "@/hooks/timeline/use-scroll-position"; diff --git a/apps/web/src/components/footer.tsx b/apps/web/src/components/footer.tsx index e453a491..21334267 100644 --- a/apps/web/src/components/footer.tsx +++ b/apps/web/src/components/footer.tsx @@ -2,7 +2,8 @@ import Link from "next/link"; import { RiDiscordFill, RiTwitterXLine } from "react-icons/ri"; import { FaGithub } from "react-icons/fa6"; import Image from "next/image"; -import { DEFAULT_LOGO_URL, SOCIAL_LINKS } from "@/constants/site-constants"; +import { DEFAULT_LOGO_URL } from "@/lib/site/brand"; +import { SOCIAL_LINKS } from "@/lib/site/social"; import { capitalizeFirstLetter } from "@/utils/string"; type Category = "resources" | "company"; diff --git a/apps/web/src/components/gitHub-contribute-section.tsx b/apps/web/src/components/gitHub-contribute-section.tsx index a06afaea..0239e366 100644 --- a/apps/web/src/components/gitHub-contribute-section.tsx +++ b/apps/web/src/components/gitHub-contribute-section.tsx @@ -1,6 +1,6 @@ import { Button } from "./ui/button"; import Link from "next/link"; -import { SOCIAL_LINKS } from "@/constants/site-constants"; +import { SOCIAL_LINKS } from "@/lib/site/social"; import { GithubIcon, Link04Icon } from "@hugeicons/core-free-icons"; import { HugeiconsIcon } from "@hugeicons/react"; diff --git a/apps/web/src/components/header.tsx b/apps/web/src/components/header.tsx index 5986308e..66fec0ea 100644 --- a/apps/web/src/components/header.tsx +++ b/apps/web/src/components/header.tsx @@ -16,7 +16,8 @@ import { } from "@hugeicons/core-free-icons"; import { HugeiconsIcon } from "@hugeicons/react"; import { cn } from "@/utils/ui"; -import { DEFAULT_LOGO_URL, SOCIAL_LINKS } from "@/constants/site-constants"; +import { DEFAULT_LOGO_URL, SITE_URL } from "@/lib/site/brand"; +import { SOCIAL_LINKS } from "@/lib/site/social"; import { ContextMenu, ContextMenuContent, diff --git a/apps/web/src/components/ui/font-picker.tsx b/apps/web/src/components/ui/font-picker.tsx index 016bbaf4..297d58a7 100644 --- a/apps/web/src/components/ui/font-picker.tsx +++ b/apps/web/src/components/ui/font-picker.tsx @@ -10,7 +10,7 @@ import { import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { loadFullFont } from "@/lib/fonts/google-fonts"; -import { SYSTEM_FONTS } from "@/constants/font-constants"; +import { SYSTEM_FONTS } from "@/lib/fonts/system-fonts"; import type { FontAtlas, FontAtlasEntry } from "@/lib/fonts/types"; import { useFontAtlas } from "@/hooks/use-font-atlas"; import { cn } from "@/utils/ui"; diff --git a/apps/web/src/constants/editor-constants.ts b/apps/web/src/constants/editor-constants.ts deleted file mode 100644 index 6428af32..00000000 --- a/apps/web/src/constants/editor-constants.ts +++ /dev/null @@ -1,23 +0,0 @@ -export type TPlatformLayout = - | "tiktok" - | "instagram" - | "youtube" - | "snapchat"; - -export const PREVIEW_ZOOM_PRESETS = [25, 50, 75, 100, 150, 200]; - -export const PREVIEW_ZOOM = { - min: 0.25, - max: 16, - step: 1.25, -}; - -export const PANEL_CONFIG = { - panels: { - tools: 25, - preview: 50, - properties: 25, - mainContent: 50, - timeline: 50, - }, -}; diff --git a/apps/web/src/constants/export-constants.ts b/apps/web/src/constants/export-constants.ts deleted file mode 100644 index 5579e7f0..00000000 --- a/apps/web/src/constants/export-constants.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { ExportOptions } from "@/lib/export"; - -export const DEFAULT_EXPORT_OPTIONS = { - format: "mp4", - quality: "high", - includeAudio: true, -} satisfies ExportOptions; - -export const EXPORT_MIME_TYPES = { - webm: "video/webm", - mp4: "video/mp4", -} as const; diff --git a/apps/web/src/constants/project-constants.ts b/apps/web/src/constants/project-constants.ts deleted file mode 100644 index 96e178dc..00000000 --- a/apps/web/src/constants/project-constants.ts +++ /dev/null @@ -1,27 +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 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 BLUR_INTENSITY_PRESETS: { label: string; value: number }[] = [ - { label: "Light", value: 50 }, - { label: "Medium", value: 250 }, - { label: "Heavy", value: 500 }, -] as const; - -export const DEFAULT_CANVAS_SIZE: TCanvasSize = { width: 1920, height: 1080 }; -export const DEFAULT_FPS = 30; -export const DEFAULT_BLUR_INTENSITY = 50; -export const DEFAULT_COLOR = "#000000"; diff --git a/apps/web/src/constants/site-constants.ts b/apps/web/src/constants/site-constants.ts deleted file mode 100644 index ea2d2fe2..00000000 --- a/apps/web/src/constants/site-constants.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { OcDataBuddyIcon, OcMarbleIcon } from "@/components/icons"; - -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 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, - }, -]; - -export const DEFAULT_LOGO_URL = "/logos/opencut/svg/logo.svg"; - -export const SOCIAL_LINKS = { - x: "https://x.com/opencutapp", - github: "https://github.com/OpenCut-app/OpenCut", - discord: "https://discord.com/invite/Mu3acKZvCp", -}; - -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/constants/text-constants.ts b/apps/web/src/constants/text-constants.ts deleted file mode 100644 index 67833949..00000000 --- a/apps/web/src/constants/text-constants.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const MIN_FONT_SIZE = 5; -export const MAX_FONT_SIZE = 300; - -/** - * 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/constants/timeline-constants.ts b/apps/web/src/constants/timeline-constants.ts deleted file mode 100644 index 99fa2d2d..00000000 --- a/apps/web/src/constants/timeline-constants.ts +++ /dev/null @@ -1,75 +0,0 @@ -import type { TrackType } from "@/lib/timeline"; - -export const TRACK_CONFIG: Record< - TrackType, - { - height: number; - defaultName: string; - } -> = { - video: { - height: 65, - defaultName: "Video track", - }, - text: { - height: 25, - defaultName: "Text track", - }, - audio: { - height: 50, - defaultName: "Audio track", - }, - graphic: { - height: 25, - defaultName: "Graphic track", - }, - effect: { - height: 25, - defaultName: "Effect track", - }, -} as const; - -export const ELEMENT_TYPE_CONFIG: Record< - TrackType, - { - background: string; - waveformColor?: string; - } -> = { - video: { background: "transparent" }, - text: { background: "bg-[#5DBAA0]" }, - audio: { - background: "bg-[#8F5DBA]", - waveformColor: "rgba(255, 255, 255, 0.5)", - }, - graphic: { background: "bg-[#BA5D7A]" }, - effect: { background: "bg-[#5d93ba]" }, -} as const; - -export const TRACK_GAP = 6; -export const TRACK_LABELS_WIDTH_PX = 112; - -export const TIMELINE_RULER_HEIGHT = 22; -export const TIMELINE_BOOKMARK_ROW_HEIGHT = 16; - -export const DEFAULT_BOOKMARK_COLOR = "#009dff"; -export const DRAG_THRESHOLD_PX = 5; -export const TIMELINE_SCROLLBAR_SIZE_PX = 12; -export const TIMELINE_LAYERS = { - trackContent: 10, - dragLine: 20, - playhead: 30, - snapIndicator: 40, -} as const; - -export const TIMELINE_CONSTANTS = { - PIXELS_PER_SECOND: 50, - DEFAULT_ELEMENT_DURATION: 5, - PADDING_TOP_PX: 2, - HORIZONTAL_WHEEL_STEP_PX: 40, - ZOOM_MIN: 0.1, - ZOOM_MAX: 100, - ZOOM_BUTTON_FACTOR: 1.7, - ZOOM_ANCHOR_PLAYHEAD_THRESHOLD: 0.15, - TRACK_SELECTED_BG: "bg-accent/50", -} as const; diff --git a/apps/web/src/core/managers/project-manager.ts b/apps/web/src/core/managers/project-manager.ts index 6324b988..48ea270c 100644 --- a/apps/web/src/core/managers/project-manager.ts +++ b/apps/web/src/core/managers/project-manager.ts @@ -12,9 +12,9 @@ import { storageService } from "@/services/storage/service"; import { toast } from "sonner"; import { generateUUID } from "@/utils/id"; import { UpdateProjectSettingsCommand } from "@/lib/commands/project"; -import { DEFAULT_BACKGROUND_COLOR } from "@/lib/background/constants"; -import { DEFAULT_CANVAS_SIZE } from "@/lib/canvas/constants"; -import { DEFAULT_FPS } from "@/lib/fps/constants"; +import { DEFAULT_BACKGROUND_COLOR } from "@/lib/background/color"; +import { DEFAULT_CANVAS_SIZE } from "@/lib/canvas/sizes"; +import { DEFAULT_FPS } from "@/lib/fps/defaults"; import { buildDefaultScene, getProjectDurationFromScenes } from "@/lib/scenes"; import { buildScene } from "@/services/renderer/scene-builder"; import { CanvasRenderer } from "@/services/renderer/canvas-renderer"; diff --git a/apps/web/src/hooks/use-font-atlas.ts b/apps/web/src/hooks/use-font-atlas.ts index 93cea7e4..aa48f3b4 100644 --- a/apps/web/src/hooks/use-font-atlas.ts +++ b/apps/web/src/hooks/use-font-atlas.ts @@ -5,7 +5,7 @@ import { clearFontAtlasCache, } from "@/lib/fonts/google-fonts"; import type { FontAtlas } from "@/lib/fonts/types"; -import { SYSTEM_FONTS } from "@/constants/font-constants"; +import { SYSTEM_FONTS } from "@/lib/fonts/system-fonts"; type Status = "idle" | "loading" | "error"; 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/constants/animation-constants.ts b/apps/web/src/lib/animation/transform.ts similarity index 100% rename from apps/web/src/constants/animation-constants.ts rename to apps/web/src/lib/animation/transform.ts diff --git a/apps/web/src/lib/background/constants.ts b/apps/web/src/lib/background/blur.ts similarity index 83% rename from apps/web/src/lib/background/constants.ts rename to apps/web/src/lib/background/blur.ts index b682c260..3b111482 100644 --- a/apps/web/src/lib/background/constants.ts +++ b/apps/web/src/lib/background/blur.ts @@ -8,4 +8,3 @@ export const BACKGROUND_BLUR_INTENSITY_PRESETS: Array<{ ] as const; export const DEFAULT_BACKGROUND_BLUR_INTENSITY = 10; -export const DEFAULT_BACKGROUND_COLOR = "#000000"; 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/canvas/constants.ts b/apps/web/src/lib/canvas/sizes.ts similarity index 100% rename from apps/web/src/lib/canvas/constants.ts rename to apps/web/src/lib/canvas/sizes.ts 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.ts b/apps/web/src/lib/export/index.ts similarity index 95% rename from apps/web/src/lib/export.ts rename to apps/web/src/lib/export/index.ts index f397ac4b..c5c522b3 100644 --- a/apps/web/src/lib/export.ts +++ b/apps/web/src/lib/export/index.ts @@ -1,5 +1,5 @@ import type { FrameRate } from "opencut-wasm"; -import { EXPORT_MIME_TYPES } from "@/constants/export-constants"; +import { EXPORT_MIME_TYPES } from "./mime-types"; export const EXPORT_QUALITY_VALUES = [ "low", 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/constants/font-constants.ts b/apps/web/src/lib/fonts/system-fonts.ts similarity index 93% rename from apps/web/src/constants/font-constants.ts rename to apps/web/src/lib/fonts/system-fonts.ts index 44f8220f..9cc363a3 100644 --- a/apps/web/src/constants/font-constants.ts +++ b/apps/web/src/lib/fonts/system-fonts.ts @@ -1,11 +1,11 @@ -export const SYSTEM_FONTS = new Set([ - "Arial", - "Helvetica", - "Times New Roman", - "Courier New", - "Verdana", - "Georgia", - "monospace", - "sans-serif", - "serif", -]); +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/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/constants.ts b/apps/web/src/lib/fps/presets.ts similarity index 64% rename from apps/web/src/lib/fps/constants.ts rename to apps/web/src/lib/fps/presets.ts index 30c3d2bc..b09920d4 100644 --- a/apps/web/src/lib/fps/constants.ts +++ b/apps/web/src/lib/fps/presets.ts @@ -1,5 +1,3 @@ -import type { FrameRate } from "opencut-wasm"; - export const FPS_PRESETS = [ { value: "24", label: "24 fps" }, { value: "25", label: "25 fps" }, @@ -7,5 +5,3 @@ export const FPS_PRESETS = [ { 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/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/constants/guide-constants.ts b/apps/web/src/lib/guides/grid.ts similarity index 96% rename from apps/web/src/constants/guide-constants.ts rename to apps/web/src/lib/guides/grid.ts index 4d5c6c41..0b707de7 100644 --- a/apps/web/src/constants/guide-constants.ts +++ b/apps/web/src/lib/guides/grid.ts @@ -1,4 +1,4 @@ -export const GRID_MIN = 1; -export const GRID_MAX = 24; - -export const DEFAULT_GRID_CONFIG = { rows: 3, cols: 3 } as const; +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/constants/mask-constants.ts b/apps/web/src/lib/masks/dimensions.ts similarity index 54% rename from apps/web/src/constants/mask-constants.ts rename to apps/web/src/lib/masks/dimensions.ts index 2b453e0e..dcfcdc0c 100644 --- a/apps/web/src/constants/mask-constants.ts +++ b/apps/web/src/lib/masks/dimensions.ts @@ -1,4 +1,2 @@ -export const MAX_FEATHER = 1000; -export const FEATHER_HANDLE_SCALE = 0.11; -export const DEFAULT_SHAPE_MASK_SHORT_SIDE_RATIO = 0.6; -export const MIN_MASK_DIMENSION = 0.01; +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/layout.ts similarity index 100% rename from apps/web/src/lib/panels/constants.ts rename to apps/web/src/lib/panels/layout.ts 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/constants.ts b/apps/web/src/lib/preview/zoom.ts similarity index 100% rename from apps/web/src/lib/preview/constants.ts rename to apps/web/src/lib/preview/zoom.ts diff --git a/apps/web/src/lib/selection/constants.ts b/apps/web/src/lib/selection/attributes.ts similarity index 98% rename from apps/web/src/lib/selection/constants.ts rename to apps/web/src/lib/selection/attributes.ts index a262c8ce..a1aee842 100644 --- a/apps/web/src/lib/selection/constants.ts +++ b/apps/web/src/lib/selection/attributes.ts @@ -1 +1 @@ -export const SELECTABLE_ITEM_ATTRIBUTE = "data-selectable-item"; +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/constants/sticker-constants.ts b/apps/web/src/lib/stickers/categories.ts similarity index 69% rename from apps/web/src/constants/sticker-constants.ts rename to apps/web/src/lib/stickers/categories.ts index 29e48c25..e8a8b71b 100644 --- a/apps/web/src/constants/sticker-constants.ts +++ b/apps/web/src/lib/stickers/categories.ts @@ -1,5 +1,3 @@ -export const STICKER_INTRINSIC_SIZE_FALLBACK = 200; - export const STICKER_CATEGORIES = { all: "All", // v0.4.0 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/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/constants.ts b/apps/web/src/lib/text/typography.ts similarity index 75% rename from apps/web/src/lib/text/constants.ts rename to apps/web/src/lib/text/typography.ts index a101f209..837236ab 100644 --- a/apps/web/src/lib/text/constants.ts +++ b/apps/web/src/lib/text/typography.ts @@ -7,6 +7,3 @@ export const DEFAULT_TEXT_COLOR = "#000000"; * 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/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/constants/language-constants.ts b/apps/web/src/lib/transcription/languages.ts similarity index 100% rename from apps/web/src/constants/language-constants.ts rename to apps/web/src/lib/transcription/languages.ts diff --git a/apps/web/src/constants/transcription-constants.ts b/apps/web/src/lib/transcription/models.ts similarity index 52% rename from apps/web/src/constants/transcription-constants.ts rename to apps/web/src/lib/transcription/models.ts index bb9ce0d7..ee9047e7 100644 --- a/apps/web/src/constants/transcription-constants.ts +++ b/apps/web/src/lib/transcription/models.ts @@ -1,60 +1,34 @@ -import { LANGUAGES } from "@/constants/language-constants"; -import type { - TranscriptionModel, - TranscriptionModelId, -} from "@/lib/transcription/types"; -import type { LanguageCode } from "@/constants/language-constants"; - -const SUPPORTED_TRANSCRIPTION_LANGS: ReadonlyArray = [ - "en", - "es", - "it", - "fr", - "de", - "pt", - "ru", - "ja", - "zh", -]; - -export const TRANSCRIPTION_LANGUAGES = LANGUAGES.filter((language) => - SUPPORTED_TRANSCRIPTION_LANGS.includes(language.code), -); - -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"; - -export const DEFAULT_TRANSCRIPTION_SAMPLE_RATE = 16000; - -export const DEFAULT_CHUNK_LENGTH_SECONDS = 30; -export const DEFAULT_STRIDE_SECONDS = 5; - -export const DEFAULT_WORDS_PER_CAPTION = 3; -export const MIN_CAPTION_DURATION_SECONDS = 0.8; +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/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/constants.ts b/apps/web/src/lib/wasm/ticks.ts similarity index 100% rename from apps/web/src/lib/wasm/constants.ts rename to apps/web/src/lib/wasm/ticks.ts diff --git a/apps/web/src/services/renderer/nodes/text-node.ts b/apps/web/src/services/renderer/nodes/text-node.ts index fc503991..c9e13261 100644 --- a/apps/web/src/services/renderer/nodes/text-node.ts +++ b/apps/web/src/services/renderer/nodes/text-node.ts @@ -5,7 +5,7 @@ import type { Transform } from "@/lib/rendering"; import { CORNER_RADIUS_MAX, CORNER_RADIUS_MIN, -} from "@/constants/text-constants"; +} from "@/lib/text/background"; import { drawTextDecoration, getTextBackgroundRect, diff --git a/apps/web/src/services/renderer/scene-builder.ts b/apps/web/src/services/renderer/scene-builder.ts index 68ba956b..47e6139c 100644 --- a/apps/web/src/services/renderer/scene-builder.ts +++ b/apps/web/src/services/renderer/scene-builder.ts @@ -11,7 +11,7 @@ import { BlurBackgroundNode } from "./nodes/blur-background-node"; import { EffectLayerNode } from "./nodes/effect-layer-node"; import type { AnyBaseNode } from "./nodes/base-node"; import type { TBackground, TCanvasSize } from "@/lib/project/types"; -import { DEFAULT_BACKGROUND_BLUR_INTENSITY } from "@/lib/background/constants"; +import { DEFAULT_BACKGROUND_BLUR_INTENSITY } from "@/lib/background/blur"; const PREVIEW_MAX_IMAGE_SIZE = 2048; diff --git a/apps/web/src/services/storage/migrations/__tests__/v1-to-v2.test.ts b/apps/web/src/services/storage/migrations/__tests__/v1-to-v2.test.ts index 7a0617a7..56c83403 100644 --- a/apps/web/src/services/storage/migrations/__tests__/v1-to-v2.test.ts +++ b/apps/web/src/services/storage/migrations/__tests__/v1-to-v2.test.ts @@ -1,9 +1,9 @@ import { describe, expect, test } from "bun:test"; import { DEFAULT_BACKGROUND_BLUR_INTENSITY, - DEFAULT_BACKGROUND_COLOR, -} from "@/lib/background/constants"; -import { DEFAULT_CANVAS_SIZE } from "@/lib/canvas/constants"; +} from "@/lib/background/blur"; +import { DEFAULT_BACKGROUND_COLOR } from "@/lib/background/color"; +import { DEFAULT_CANVAS_SIZE } from "@/lib/canvas/sizes"; const DEFAULT_FPS = 30; import type { MediaAssetData } from "@/services/storage/types"; import { getProjectId, transformProjectV1ToV2 } from "../transformers/v1-to-v2"; diff --git a/apps/web/src/services/storage/migrations/__tests__/v20-to-v21.test.ts b/apps/web/src/services/storage/migrations/__tests__/v20-to-v21.test.ts index af2124c8..3d77a775 100644 --- a/apps/web/src/services/storage/migrations/__tests__/v20-to-v21.test.ts +++ b/apps/web/src/services/storage/migrations/__tests__/v20-to-v21.test.ts @@ -1,7 +1,8 @@ import { describe, expect, test } from "bun:test"; -import { DEFAULT_BLUR_INTENSITY } from "@/constants/project-constants"; import { transformProjectV20ToV21 } from "../transformers/v20-to-v21"; +const LEGACY_DEFAULT_BACKGROUND_BLUR_INTENSITY = 50; + describe("V20 to V21 Migration", () => { test("multiplies blur background intensity by 5", () => { const result = transformProjectV20ToV21({ @@ -46,7 +47,9 @@ describe("V20 to V21 Migration", () => { expect(result.skipped).toBe(false); const settings = result.project.settings as Record; const background = settings.background as Record; - expect(background.blurIntensity).toBe(DEFAULT_BLUR_INTENSITY); + expect(background.blurIntensity).toBe( + LEGACY_DEFAULT_BACKGROUND_BLUR_INTENSITY, + ); }); test("leaves color background unchanged", () => { diff --git a/apps/web/src/services/storage/migrations/transformers/v1-to-v2.ts b/apps/web/src/services/storage/migrations/transformers/v1-to-v2.ts index 6313c311..b6b38f3c 100644 --- a/apps/web/src/services/storage/migrations/transformers/v1-to-v2.ts +++ b/apps/web/src/services/storage/migrations/transformers/v1-to-v2.ts @@ -1,8 +1,8 @@ import { DEFAULT_BACKGROUND_BLUR_INTENSITY, - DEFAULT_BACKGROUND_COLOR, -} from "@/lib/background/constants"; -import { DEFAULT_CANVAS_SIZE } from "@/lib/canvas/constants"; +} from "@/lib/background/blur"; +import { DEFAULT_BACKGROUND_COLOR } from "@/lib/background/color"; +import { DEFAULT_CANVAS_SIZE } from "@/lib/canvas/sizes"; const DEFAULT_FPS = 30; import { IndexedDBAdapter } from "@/services/storage/indexeddb-adapter"; import type { MediaAssetData } from "@/services/storage/types"; diff --git a/apps/web/src/services/storage/migrations/transformers/v14-to-v15.ts b/apps/web/src/services/storage/migrations/transformers/v14-to-v15.ts index e75c541b..36e3d9a8 100644 --- a/apps/web/src/services/storage/migrations/transformers/v14-to-v15.ts +++ b/apps/web/src/services/storage/migrations/transformers/v14-to-v15.ts @@ -1,4 +1,4 @@ -import { STICKER_INTRINSIC_SIZE_FALLBACK } from "@/constants/sticker-constants"; +import { STICKER_INTRINSIC_SIZE_FALLBACK } from "@/lib/stickers/intrinsic-size"; import type { MigrationResult, ProjectRecord } from "./types"; import { getProjectId, isRecord } from "./utils"; diff --git a/apps/web/src/services/storage/migrations/transformers/v20-to-v21.ts b/apps/web/src/services/storage/migrations/transformers/v20-to-v21.ts index 63ad24de..f5194bda 100644 --- a/apps/web/src/services/storage/migrations/transformers/v20-to-v21.ts +++ b/apps/web/src/services/storage/migrations/transformers/v20-to-v21.ts @@ -1,8 +1,9 @@ -import { DEFAULT_BLUR_INTENSITY } from "@/constants/project-constants"; import { INTENSITY_TO_SIGMA_DIVISOR } from "@/lib/effects/definitions/blur"; import type { MigrationResult, ProjectRecord } from "./types"; import { getProjectId, isRecord } from "./utils"; +const LEGACY_DEFAULT_BACKGROUND_BLUR_INTENSITY = 50; + export function transformProjectV20ToV21({ project, }: { @@ -51,7 +52,7 @@ function migrateBackgroundBlurScale({ const blurIntensity = typeof raw === "number" && Number.isFinite(raw) ? raw * INTENSITY_TO_SIGMA_DIVISOR - : DEFAULT_BLUR_INTENSITY; + : LEGACY_DEFAULT_BACKGROUND_BLUR_INTENSITY; return { ...project, diff --git a/apps/web/src/services/transcription/service.ts b/apps/web/src/services/transcription/service.ts index fa657032..443a4230 100644 --- a/apps/web/src/services/transcription/service.ts +++ b/apps/web/src/services/transcription/service.ts @@ -7,7 +7,7 @@ import type { import { DEFAULT_TRANSCRIPTION_MODEL, TRANSCRIPTION_MODELS, -} from "@/constants/transcription-constants"; +} from "@/lib/transcription/models"; import type { WorkerMessage, WorkerResponse } from "./worker"; type ProgressCallback = (progress: TranscriptionProgress) => void; diff --git a/apps/web/src/services/transcription/worker.ts b/apps/web/src/services/transcription/worker.ts index e22fe796..928b580e 100644 --- a/apps/web/src/services/transcription/worker.ts +++ b/apps/web/src/services/transcription/worker.ts @@ -7,7 +7,7 @@ import type { TranscriptionSegment } from "@/lib/transcription/types"; import { DEFAULT_CHUNK_LENGTH_SECONDS, DEFAULT_STRIDE_SECONDS, -} from "@/constants/transcription-constants"; +} from "@/lib/transcription/audio"; export type WorkerMessage = | { type: "init"; modelId: string } diff --git a/apps/web/src/stores/editor-store.ts b/apps/web/src/stores/editor-store.ts index 50aa1b08..07cb433e 100644 --- a/apps/web/src/stores/editor-store.ts +++ b/apps/web/src/stores/editor-store.ts @@ -1,5 +1,5 @@ import { create } from "zustand"; -import { DEFAULT_CANVAS_PRESETS } from "@/lib/canvas/constants"; +import { DEFAULT_CANVAS_PRESETS } from "@/lib/canvas/sizes"; import type { TCanvasSize } from "@/lib/project/types"; interface EditorState { diff --git a/apps/web/src/stores/panel-store.ts b/apps/web/src/stores/panel-store.ts index 72f4e9bc..757a37a6 100644 --- a/apps/web/src/stores/panel-store.ts +++ b/apps/web/src/stores/panel-store.ts @@ -1,6 +1,6 @@ import { create } from "zustand"; import { persist } from "zustand/middleware"; -import { PANEL_CONFIG } from "@/lib/panels/constants"; +import { PANEL_CONFIG } from "@/lib/panels/layout"; export interface PanelSizes { tools: number; diff --git a/apps/web/src/stores/preview-store.ts b/apps/web/src/stores/preview-store.ts index d0489e3b..b5957cb5 100644 --- a/apps/web/src/stores/preview-store.ts +++ b/apps/web/src/stores/preview-store.ts @@ -1,7 +1,7 @@ import { create } from "zustand"; import { persist } from "zustand/middleware"; import { isGuideId, type GuideId } from "@/lib/guides"; -import { DEFAULT_GRID_CONFIG } from "@/constants/guide-constants"; +import { DEFAULT_GRID_CONFIG } from "@/lib/guides/grid"; import type { GridConfig } from "@/lib/guides/types"; interface PreviewOverlaysState { diff --git a/apps/web/src/stores/stickers-store.ts b/apps/web/src/stores/stickers-store.ts index 7a678084..191050dd 100644 --- a/apps/web/src/stores/stickers-store.ts +++ b/apps/web/src/stores/stickers-store.ts @@ -7,7 +7,7 @@ import { searchStickers as searchStickersFromProviders, } from "@/lib/stickers"; import type { StickerBrowseResult, StickerSearchResult } from "@/lib/stickers"; -import { STICKER_CATEGORIES } from "@/constants/sticker-constants"; +import { STICKER_CATEGORIES } from "@/lib/stickers/categories"; import type { StickerCategory } from "@/lib/stickers/types"; import { registerDefaultStickerProviders } from "@/lib/stickers/providers"; import { stickersRegistry } from "@/lib/stickers/registry";