From 281ec63d7e0dfe70534790deb790c5bbd6701502 Mon Sep 17 00:00:00 2001 From: Vlad Date: Wed, 30 Jul 2025 10:25:35 -0400 Subject: [PATCH 01/38] Fixed BUG Editor cursor does not stop at the end of an audio file Get duration of content on the timeline to make sure the playhead moves until the end of the timeline content when the content is less than 10 seconds. Originally it would go all the way to the 10 seconds when timeline content was less than that. I checked how clipchamp does it and they have a min 10 sec timeline but video timeline plays at length of content, so we are doing it like the pros. timeline is jumpy though will probably work on that. --- .../src/components/editor/preview-panel.tsx | 22 +- .../src/components/editor/timeline/index.tsx | 30 +- .../web/src/components/landing/handlebars.tsx | 4 +- apps/web/src/hooks/use-editor-actions.ts | 286 +++++++++++------- apps/web/src/stores/playback-store.ts | 16 +- 5 files changed, 236 insertions(+), 122 deletions(-) diff --git a/apps/web/src/components/editor/preview-panel.tsx b/apps/web/src/components/editor/preview-panel.tsx index 639858d0..6cb06061 100644 --- a/apps/web/src/components/editor/preview-panel.tsx +++ b/apps/web/src/components/editor/preview-panel.tsx @@ -211,7 +211,7 @@ export function PreviewPanel() { setDragState({ isDragging: true, elementId: element.id, - trackId: trackId, + trackId, startX: e.clientX, startY: e.clientY, initialElementX: element.x, @@ -355,8 +355,24 @@ export function PreviewPanel() { handleTextMouseDown(e, element, elementData.track.id) } style={{ - left: `${50 + ((dragState.isDragging && dragState.elementId === element.id ? dragState.currentX : element.x) / canvasSize.width) * 100}%`, - top: `${50 + ((dragState.isDragging && dragState.elementId === element.id ? dragState.currentY : element.y) / canvasSize.height) * 100}%`, + left: `${ + 50 + + ( + (dragState.isDragging && dragState.elementId === element.id + ? dragState.currentX + : element.x) / canvasSize.width + ) * + 100 + }%`, + top: `${ + 50 + + ( + (dragState.isDragging && dragState.elementId === element.id + ? dragState.currentY + : element.y) / canvasSize.height + ) * + 100 + }%`, transform: `translate(-50%, -50%) rotate(${element.rotation}deg) scale(${scaleRatio})`, opacity: element.opacity, zIndex: 100 + index, // Text elements on top diff --git a/apps/web/src/components/editor/timeline/index.tsx b/apps/web/src/components/editor/timeline/index.tsx index bdb4433c..7943af06 100644 --- a/apps/web/src/components/editor/timeline/index.tsx +++ b/apps/web/src/components/editor/timeline/index.tsx @@ -607,7 +607,11 @@ export function Timeline() { : "border-l border-muted-foreground/20" }`} style={{ - left: `${time * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel}px`, + left: `${ + time * + TIMELINE_CONSTANTS.PIXELS_PER_SECOND * + zoomLevel + }px`, }} > 0) { - return `${hours}:${minutes.toString().padStart(2, "0")}:${Math.floor(secs).toString().padStart(2, "0")}`; + return `${hours}:${minutes + .toString() + .padStart(2, "0")}:${Math.floor(secs) + .toString() + .padStart(2, "0")}`; } if (minutes > 0) { - return `${minutes}:${Math.floor(secs).toString().padStart(2, "0")}`; + return `${minutes}:${Math.floor(secs) + .toString() + .padStart(2, "0")}`; } if (interval >= 1) { return `${Math.floor(secs)}s`; @@ -710,7 +720,10 @@ export function Timeline() {
@@ -724,7 +737,10 @@ export function Timeline() {
{ @@ -1092,7 +1108,9 @@ function TimelineToolbar({ diff --git a/apps/web/src/components/landing/handlebars.tsx b/apps/web/src/components/landing/handlebars.tsx index 26cf9254..e87d50e9 100644 --- a/apps/web/src/components/landing/handlebars.tsx +++ b/apps/web/src/components/landing/handlebars.tsx @@ -62,7 +62,7 @@ export function Handlebars({ children }: HandlebarsProps) { whileDrag={{ scale: 1.1, cursor: "grabbing" }} transition={{ type: "spring", stiffness: 400, damping: 30 }} > -
+
-
+
diff --git a/apps/web/src/hooks/use-editor-actions.ts b/apps/web/src/hooks/use-editor-actions.ts index b2fad55f..bfe9a7b9 100644 --- a/apps/web/src/hooks/use-editor-actions.ts +++ b/apps/web/src/hooks/use-editor-actions.ts @@ -26,136 +26,204 @@ export function useEditorActions() { const { activeProject } = useProjectStore(); // Playback actions - useActionHandler("toggle-play", () => { - toggle(); - }, undefined); - - useActionHandler("stop-playback", () => { - if (isPlaying) { + useActionHandler( + "toggle-play", + () => { toggle(); - } - seek(0); - }, undefined); + }, + undefined + ); - useActionHandler("seek-forward", (args) => { - const seconds = args?.seconds ?? 1; - seek(Math.min(duration, currentTime + seconds)); - }, undefined); + useActionHandler( + "stop-playback", + () => { + if (isPlaying) { + toggle(); + } + seek(0); + }, + undefined + ); - useActionHandler("seek-backward", (args) => { - const seconds = args?.seconds ?? 1; - seek(Math.max(0, currentTime - seconds)); - }, undefined); + useActionHandler( + "seek-forward", + (args) => { + const seconds = args?.seconds ?? 1; + seek(Math.min(duration, currentTime + seconds)); + }, + undefined + ); - useActionHandler("frame-step-forward", () => { - const projectFps = activeProject?.fps || 30; - seek(Math.min(duration, currentTime + 1 / projectFps)); - }, undefined); + useActionHandler( + "seek-backward", + (args) => { + const seconds = args?.seconds ?? 1; + seek(Math.max(0, currentTime - seconds)); + }, + undefined + ); - useActionHandler("frame-step-backward", () => { - const projectFps = activeProject?.fps || 30; - seek(Math.max(0, currentTime - 1 / projectFps)); - }, undefined); + useActionHandler( + "frame-step-forward", + () => { + const projectFps = activeProject?.fps || 30; + seek(Math.min(duration, currentTime + 1 / projectFps)); + }, + undefined + ); - useActionHandler("jump-forward", (args) => { - const seconds = args?.seconds ?? 5; - seek(Math.min(duration, currentTime + seconds)); - }, undefined); + useActionHandler( + "frame-step-backward", + () => { + const projectFps = activeProject?.fps || 30; + seek(Math.max(0, currentTime - 1 / projectFps)); + }, + undefined + ); - useActionHandler("jump-backward", (args) => { - const seconds = args?.seconds ?? 5; - seek(Math.max(0, currentTime - seconds)); - }, undefined); + useActionHandler( + "jump-forward", + (args) => { + const seconds = args?.seconds ?? 5; + seek(Math.min(duration, currentTime + seconds)); + }, + undefined + ); - useActionHandler("goto-start", () => { - seek(0); - }, undefined); + useActionHandler( + "jump-backward", + (args) => { + const seconds = args?.seconds ?? 5; + seek(Math.max(0, currentTime - seconds)); + }, + undefined + ); - useActionHandler("goto-end", () => { - seek(duration); - }, undefined); + useActionHandler( + "goto-start", + () => { + seek(0); + }, + undefined + ); + + useActionHandler( + "goto-end", + () => { + seek(duration); + }, + undefined + ); // Timeline editing actions - useActionHandler("split-element", () => { - if (selectedElements.length !== 1) { - toast.error("Select exactly one element to split"); - return; - } - - const { trackId, elementId } = selectedElements[0]; - const track = tracks.find((t: any) => t.id === trackId); - const element = track?.elements.find((el: any) => el.id === elementId); - - if (element) { - const effectiveStart = element.startTime; - const effectiveEnd = - element.startTime + - (element.duration - element.trimStart - element.trimEnd); - - if (currentTime > effectiveStart && currentTime < effectiveEnd) { - splitElement(trackId, elementId, currentTime); - } else { - toast.error("Playhead must be within selected element"); + useActionHandler( + "split-element", + () => { + if (selectedElements.length !== 1) { + toast.error("Select exactly one element to split"); + return; } - } - }, undefined); - useActionHandler("delete-selected", () => { - if (selectedElements.length === 0) { - return; - } - selectedElements.forEach( - ({ trackId, elementId }: { trackId: string; elementId: string }) => { - removeElementFromTrack(trackId, elementId); + const { trackId, elementId } = selectedElements[0]; + const track = tracks.find((t: any) => t.id === trackId); + const element = track?.elements.find((el: any) => el.id === elementId); + + if (element) { + const effectiveStart = element.startTime; + const effectiveEnd = + element.startTime + + (element.duration - element.trimStart - element.trimEnd); + + if (currentTime > effectiveStart && currentTime < effectiveEnd) { + splitElement(trackId, elementId, currentTime); + } else { + toast.error("Playhead must be within selected element"); + } } - ); - clearSelectedElements(); - }, undefined); + }, + undefined + ); - useActionHandler("select-all", () => { - const allElements = tracks.flatMap((track: any) => - track.elements.map((element: any) => ({ - trackId: track.id, - elementId: element.id, - })) - ); - setSelectedElements(allElements); - }, undefined); + useActionHandler( + "delete-selected", + () => { + if (selectedElements.length === 0) { + return; + } + selectedElements.forEach( + ({ trackId, elementId }: { trackId: string; elementId: string }) => { + removeElementFromTrack(trackId, elementId); + } + ); + clearSelectedElements(); + }, + undefined + ); - useActionHandler("duplicate-selected", () => { - if (selectedElements.length !== 1) { - toast.error("Select exactly one element to duplicate"); - return; - } + useActionHandler( + "select-all", + () => { + const allElements = tracks.flatMap((track: any) => + track.elements.map((element: any) => ({ + trackId: track.id, + elementId: element.id, + })) + ); + setSelectedElements(allElements); + }, + undefined + ); - const { trackId, elementId } = selectedElements[0]; - const track = tracks.find((t: any) => t.id === trackId); - const element = track?.elements.find((el: any) => el.id === elementId); + useActionHandler( + "duplicate-selected", + () => { + if (selectedElements.length !== 1) { + toast.error("Select exactly one element to duplicate"); + return; + } - if (element) { - const newStartTime = - element.startTime + - (element.duration - element.trimStart - element.trimEnd) + - 0.1; - const { id, ...elementWithoutId } = element; + const { trackId, elementId } = selectedElements[0]; + const track = tracks.find((t: any) => t.id === trackId); + const element = track?.elements.find((el: any) => el.id === elementId); - addElementToTrack(trackId, { - ...elementWithoutId, - startTime: newStartTime, - }); - } - }, undefined); + if (element) { + const newStartTime = + element.startTime + + (element.duration - element.trimStart - element.trimEnd) + + 0.1; + const { id, ...elementWithoutId } = element; - useActionHandler("toggle-snapping", () => { - toggleSnapping(); - }, undefined); + addElementToTrack(trackId, { + ...elementWithoutId, + startTime: newStartTime, + }); + } + }, + undefined + ); + + useActionHandler( + "toggle-snapping", + () => { + toggleSnapping(); + }, + undefined + ); // History actions - useActionHandler("undo", () => { - undo(); - }, undefined); + useActionHandler( + "undo", + () => { + undo(); + }, + undefined + ); - useActionHandler("redo", () => { - redo(); - }, undefined); + useActionHandler( + "redo", + () => { + redo(); + }, + undefined + ); } diff --git a/apps/web/src/stores/playback-store.ts b/apps/web/src/stores/playback-store.ts index 543865f9..70ff490d 100644 --- a/apps/web/src/stores/playback-store.ts +++ b/apps/web/src/stores/playback-store.ts @@ -20,8 +20,20 @@ const startTimer = (store: () => PlaybackStore) => { lastUpdate = now; const newTime = state.currentTime + delta * state.speed; - if (newTime >= state.duration) { - // When video completes, pause and reset playhead to start + + // Get actual content duration from timeline store + const { useTimelineStore } = require("@/stores/timeline-store"); + const actualContentDuration = useTimelineStore + .getState() + .getTotalDuration(); + + // Stop at actual content end, not timeline duration (which has 10s minimum) + // It was either this or reducing default min timeline to 1 second + const effectiveDuration = + actualContentDuration > 0 ? actualContentDuration : state.duration; + + if (newTime >= effectiveDuration) { + // When content completes, pause and reset playhead to start state.pause(); state.setCurrentTime(0); // Notify video elements to sync with reset From df1e80b5287ff71867bad1a1bfebb102cef7d5bf Mon Sep 17 00:00:00 2001 From: Brandon McConnell Date: Wed, 30 Jul 2025 13:15:09 -0400 Subject: [PATCH 02/38] Lay groundwork for Tailwind v4 upgrade --- apps/web/package.json | 3 +- apps/web/postcss.config.mjs | 2 +- apps/web/src/app/blog/[slug]/page.tsx | 4 +- apps/web/src/app/blog/page.tsx | 4 +- apps/web/src/app/contributors/page.tsx | 10 +- apps/web/src/app/globals.css | 24 +- apps/web/src/app/privacy/page.tsx | 6 +- apps/web/src/app/projects/page.tsx | 18 +- apps/web/src/app/roadmap/page.tsx | 14 +- apps/web/src/app/terms/page.tsx | 6 +- apps/web/src/app/why-not-capcut/page.tsx | 4 +- .../src/components/background-settings.tsx | 16 +- .../components/editor/media-panel/tabbar.tsx | 6 +- .../editor/media-panel/views/media.tsx | 2 +- .../src/components/editor/preview-panel.tsx | 26 +- .../properties-panel/text-properties.tsx | 4 +- .../src/components/editor/snap-indicator.tsx | 2 +- .../src/components/editor/speed-control.tsx | 2 +- .../src/components/editor/timeline/index.tsx | 14 +- .../editor/timeline/timeline-element.tsx | 2 +- .../editor/timeline/timeline-playhead.tsx | 4 +- .../components/keyboard-shortcuts-help.tsx | 2 +- .../web/src/components/landing/handlebars.tsx | 4 +- apps/web/src/components/onboarding.tsx | 2 +- apps/web/src/components/ui/alert-dialog.tsx | 2 +- apps/web/src/components/ui/badge.tsx | 6 +- apps/web/src/components/ui/button.tsx | 12 +- apps/web/src/components/ui/calendar.tsx | 2 +- apps/web/src/components/ui/carousel.tsx | 4 +- apps/web/src/components/ui/chart.tsx | 6 +- apps/web/src/components/ui/checkbox.tsx | 2 +- apps/web/src/components/ui/command.tsx | 4 +- apps/web/src/components/ui/context-menu.tsx | 6 +- apps/web/src/components/ui/dialog.tsx | 6 +- apps/web/src/components/ui/draggable-item.tsx | 6 +- apps/web/src/components/ui/dropdown-menu.tsx | 6 +- apps/web/src/components/ui/hover-card.tsx | 2 +- .../ui/image-timeline-treatment.tsx | 4 +- apps/web/src/components/ui/input-otp.tsx | 4 +- apps/web/src/components/ui/input.tsx | 2 +- apps/web/src/components/ui/menubar.tsx | 16 +- .../web/src/components/ui/navigation-menu.tsx | 8 +- apps/web/src/components/ui/pagination.tsx | 2 +- apps/web/src/components/ui/popover.tsx | 2 +- apps/web/src/components/ui/radio-group.tsx | 2 +- apps/web/src/components/ui/resizable.tsx | 2 +- apps/web/src/components/ui/scroll-area.tsx | 4 +- apps/web/src/components/ui/select.tsx | 8 +- apps/web/src/components/ui/separator.tsx | 2 +- apps/web/src/components/ui/sheet.tsx | 2 +- apps/web/src/components/ui/sidebar.tsx | 44 +-- apps/web/src/components/ui/slider.tsx | 2 +- apps/web/src/components/ui/sponsor-button.tsx | 2 +- apps/web/src/components/ui/switch.tsx | 2 +- apps/web/src/components/ui/table.tsx | 2 +- apps/web/src/components/ui/tabs.tsx | 4 +- apps/web/src/components/ui/textarea.tsx | 2 +- apps/web/src/components/ui/toast.tsx | 8 +- apps/web/src/components/ui/toggle.tsx | 4 +- apps/web/src/stores/project-store.ts | 4 +- apps/web/src/types/editor.ts | 2 +- apps/web/src/types/project.ts | 2 +- apps/web/tailwind.config.ts | 56 ++-- bun.lock | 258 ++++++------------ package.json | 5 +- 65 files changed, 318 insertions(+), 382 deletions(-) diff --git a/apps/web/package.json b/apps/web/package.json index 9531b6c7..d9947643 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -70,6 +70,7 @@ "zustand": "^5.0.2" }, "devDependencies": { + "@tailwindcss/postcss": "^4.1.11", "@tailwindcss/typography": "^0.5.16", "@types/bun": "latest", "@types/pg": "^8.15.4", @@ -78,7 +79,7 @@ "cross-env": "^7.0.3", "drizzle-kit": "^0.31.4", "postcss": "^8", - "tailwindcss": "^3.4.1", + "tailwindcss": "^4.1.11", "tsx": "^4.7.1", "typescript": "^5.8.3" } diff --git a/apps/web/postcss.config.mjs b/apps/web/postcss.config.mjs index 1a69fd2a..79bcf135 100644 --- a/apps/web/postcss.config.mjs +++ b/apps/web/postcss.config.mjs @@ -1,7 +1,7 @@ /** @type {import('postcss-load-config').Config} */ const config = { plugins: { - tailwindcss: {}, + "@tailwindcss/postcss": {}, }, }; diff --git a/apps/web/src/app/blog/[slug]/page.tsx b/apps/web/src/app/blog/[slug]/page.tsx index 0de1e0a8..d759050b 100644 --- a/apps/web/src/app/blog/[slug]/page.tsx +++ b/apps/web/src/app/blog/[slug]/page.tsx @@ -87,8 +87,8 @@ async function Page({ params }: PageProps) {
-
-
+
+
diff --git a/apps/web/src/app/blog/page.tsx b/apps/web/src/app/blog/page.tsx index ca553a67..08da9fd7 100644 --- a/apps/web/src/app/blog/page.tsx +++ b/apps/web/src/app/blog/page.tsx @@ -28,8 +28,8 @@ export default async function BlogPage() {
-
-
+
+
diff --git a/apps/web/src/app/contributors/page.tsx b/apps/web/src/app/contributors/page.tsx index 29151bd8..3ad99023 100644 --- a/apps/web/src/app/contributors/page.tsx +++ b/apps/web/src/app/contributors/page.tsx @@ -77,8 +77,8 @@ export default async function ContributorsPage() {
-
-
+
+
@@ -138,8 +138,8 @@ export default async function ContributorsPage() { className="group block flex-1" >
-
- +
+
@@ -268,7 +268,7 @@ export default async function ContributorsPage() { animationDelay: `${index * 100}ms`, }} > - +
diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css index 2f7158cc..9cc7ed6b 100644 --- a/apps/web/src/app/globals.css +++ b/apps/web/src/app/globals.css @@ -1,6 +1,24 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import 'tailwindcss'; + +@config '../../tailwind.config.ts'; + +/* + The default border color has changed to `currentcolor` in Tailwind CSS v4, + so we've added these compatibility styles to make sure everything still + looks the same as it did with Tailwind CSS v3. + + If we ever want to remove these styles, we need to add an explicit border + color utility to any element that depends on these defaults. +*/ +@layer base { + *, + ::after, + ::before, + ::backdrop, + ::file-selector-button { + border-color: var(--color-gray-200, currentcolor); + } +} @layer base { :root { diff --git a/apps/web/src/app/privacy/page.tsx b/apps/web/src/app/privacy/page.tsx index b7d700b5..4bb1e023 100644 --- a/apps/web/src/app/privacy/page.tsx +++ b/apps/web/src/app/privacy/page.tsx @@ -24,8 +24,8 @@ export default function PrivacyPage() {
-
-
+
+
@@ -47,7 +47,7 @@ export default function PrivacyPage() { have any questions.

- +

diff --git a/apps/web/src/app/projects/page.tsx b/apps/web/src/app/projects/page.tsx index 4b68791b..37c1ced2 100644 --- a/apps/web/src/app/projects/page.tsx +++ b/apps/web/src/app/projects/page.tsx @@ -142,7 +142,7 @@ export default function ProjectsPage() { href="/" className="flex items-center gap-1 hover:text-muted-foreground transition-colors" > - + Back
@@ -153,7 +153,7 @@ export default function ProjectsPage() { size="sm" onClick={handleCancelSelection} > - + Cancel {selectedProjects.size > 0 && ( @@ -162,7 +162,7 @@ export default function ProjectsPage() { size="sm" onClick={() => setIsBulkDeleteDialogOpen(true)} > - + Delete ({selectedProjects.size}) )} @@ -192,7 +192,7 @@ export default function ProjectsPage() { {isSelectionMode ? (
{selectedProjects.size > 0 && ( @@ -200,7 +200,7 @@ export default function ProjectsPage() { variant="destructive" onClick={() => setIsBulkDeleteDialogOpen(true)} > - + Delete Selected ({selectedProjects.size}) )} @@ -399,7 +399,7 @@ function ProjectCard({ > {isSelectionMode && (
-
+
@@ -426,7 +426,7 @@ function ProjectCard({ /> ) : (
-
)}
@@ -501,7 +501,7 @@ function ProjectCard({
- + Created {formatDate(project.createdAt)}
@@ -543,7 +543,7 @@ function ProjectCard({ function CreateButton({ onClick }: { onClick?: () => void }) { return ( ); diff --git a/apps/web/src/app/roadmap/page.tsx b/apps/web/src/app/roadmap/page.tsx index 5c003cf0..b26da5aa 100644 --- a/apps/web/src/app/roadmap/page.tsx +++ b/apps/web/src/app/roadmap/page.tsx @@ -122,8 +122,8 @@ export default function RoadmapPage() {
-
-
+
+
@@ -148,7 +148,7 @@ export default function RoadmapPage() { {roadmapItems.map((item, index) => (
- + {index + 1}.
@@ -156,13 +156,13 @@ export default function RoadmapPage() {

{item.title}

diff --git a/apps/web/src/app/terms/page.tsx b/apps/web/src/app/terms/page.tsx index 7d1fda7f..ee202d8b 100644 --- a/apps/web/src/app/terms/page.tsx +++ b/apps/web/src/app/terms/page.tsx @@ -24,8 +24,8 @@ export default function TermsPage() {
-
-
+
+
@@ -47,7 +47,7 @@ export default function TermsPage() { editor.

- +

diff --git a/apps/web/src/app/why-not-capcut/page.tsx b/apps/web/src/app/why-not-capcut/page.tsx index 7fe6df66..b05860a6 100644 --- a/apps/web/src/app/why-not-capcut/page.tsx +++ b/apps/web/src/app/why-not-capcut/page.tsx @@ -7,8 +7,8 @@ export default function WhyNotCapcut() {
-
-
+
+
diff --git a/apps/web/src/components/background-settings.tsx b/apps/web/src/components/background-settings.tsx index a640dc4c..2a5a3ac0 100644 --- a/apps/web/src/components/background-settings.tsx +++ b/apps/web/src/components/background-settings.tsx @@ -7,7 +7,7 @@ import { colors } from "@/data/colors"; import { useProjectStore } from "@/stores/project-store"; import { PipetteIcon } from "lucide-react"; -type BackgroundTab = "color" | "blur"; +type BackgroundTab = "color" | "blur-sm"; export function BackgroundSettings() { const { activeProject, updateBackgroundType } = useProjectStore(); @@ -20,7 +20,7 @@ export function BackgroundSettings() { }; const handleBlurSelect = (blurIntensity: number) => { - updateBackgroundType("blur", { blurIntensity }); + updateBackgroundType("blur-sm", { blurIntensity }); }; const tabs = [ @@ -30,7 +30,7 @@ export function BackgroundSettings() { }, { label: "Blur", - value: "blur", + value: "blur-sm", }, ]; @@ -40,12 +40,12 @@ export function BackgroundSettings() { - +

Background

@@ -60,7 +60,7 @@ export function BackgroundSettings() { activeProject?.backgroundColor || "#000000", }); } else { - updateBackgroundType("blur", { + updateBackgroundType("blur-sm", { blurIntensity: activeProject?.blurIntensity || 8, }); } @@ -100,7 +100,7 @@ function ColorView({ }) { return (
-
+
diff --git a/apps/web/src/components/editor/media-panel/tabbar.tsx b/apps/web/src/components/editor/media-panel/tabbar.tsx index bce84a46..92482559 100644 --- a/apps/web/src/components/editor/media-panel/tabbar.tsx +++ b/apps/web/src/components/editor/media-panel/tabbar.tsx @@ -82,7 +82,7 @@ export function TabBar() { onClick={() => setActiveTab(tabKey)} key={tabKey} > - + {tab.label}
); @@ -114,10 +114,10 @@ function ScrollButton({
); diff --git a/apps/web/src/components/editor/media-panel/views/media.tsx b/apps/web/src/components/editor/media-panel/views/media.tsx index f218dc14..d1533736 100644 --- a/apps/web/src/components/editor/media-panel/views/media.tsx +++ b/apps/web/src/components/editor/media-panel/views/media.tsx @@ -169,7 +169,7 @@ export function MediaView() { if (item.type === "audio") { return ( -
+
Audio {item.duration && ( diff --git a/apps/web/src/components/editor/preview-panel.tsx b/apps/web/src/components/editor/preview-panel.tsx index 639858d0..2c6cbf96 100644 --- a/apps/web/src/components/editor/preview-panel.tsx +++ b/apps/web/src/components/editor/preview-panel.tsx @@ -274,7 +274,7 @@ export function PreviewPanel() { const renderBlurBackground = () => { if ( !activeProject?.backgroundType || - activeProject.backgroundType !== "blur" || + activeProject.backgroundType !== "blur-sm" || blurBackgroundElements.length === 0 ) { return null; @@ -392,7 +392,7 @@ export function PreviewPanel() { return (
🎬
@@ -474,7 +474,7 @@ export function PreviewPanel() { width: previewDimensions.width, height: previewDimensions.height, backgroundColor: - activeProject?.backgroundType === "blur" + activeProject?.backgroundType === "blur-sm" ? "transparent" : activeProject?.backgroundColor || "#000000", }} @@ -489,7 +489,7 @@ export function PreviewPanel() { renderElement(elementData, index) ) )} - {activeProject?.backgroundType === "blur" && + {activeProject?.backgroundType === "blur-sm" && blurBackgroundElements.length === 0 && activeElements.length > 0 && (
@@ -675,7 +675,7 @@ function FullscreenToolbar({ style={{ width: `${progress}%` }} />
@@ -684,11 +684,11 @@ function FullscreenToolbar({
); @@ -722,7 +722,7 @@ function FullscreenPreview({ getTotalDuration: () => number; }) { return ( -
+
0 && (
@@ -868,7 +868,7 @@ function PreviewToolbar({
diff --git a/apps/web/src/components/editor/properties-panel/text-properties.tsx b/apps/web/src/components/editor/properties-panel/text-properties.tsx index e147ea65..61dd806b 100644 --- a/apps/web/src/components/editor/properties-panel/text-properties.tsx +++ b/apps/web/src/components/editor/properties-panel/text-properties.tsx @@ -25,7 +25,7 @@ export function TextProperties({