shipping too hard
This commit is contained in:
@ -8,7 +8,7 @@ import {
|
|||||||
ResizableHandle,
|
ResizableHandle,
|
||||||
} from "../../../components/ui/resizable";
|
} from "../../../components/ui/resizable";
|
||||||
import { MediaPanel } from "../../../components/editor/media-panel";
|
import { MediaPanel } from "../../../components/editor/media-panel";
|
||||||
// import { PropertiesPanel } from "../../components/editor/properties-panel";
|
import { PropertiesPanel } from "../../../components/editor/properties-panel";
|
||||||
import { Timeline } from "../../../components/editor/timeline";
|
import { Timeline } from "../../../components/editor/timeline";
|
||||||
import { PreviewPanel } from "../../../components/editor/preview-panel";
|
import { PreviewPanel } from "../../../components/editor/preview-panel";
|
||||||
import { EditorHeader } from "@/components/editor-header";
|
import { EditorHeader } from "@/components/editor-header";
|
||||||
@ -27,6 +27,8 @@ export default function Editor() {
|
|||||||
setPreviewPanel,
|
setPreviewPanel,
|
||||||
setMainContent,
|
setMainContent,
|
||||||
setTimeline,
|
setTimeline,
|
||||||
|
propertiesPanel,
|
||||||
|
setPropertiesPanel,
|
||||||
} = usePanelStore();
|
} = usePanelStore();
|
||||||
|
|
||||||
const { activeProject, loadProject, createNewProject } = useProjectStore();
|
const { activeProject, loadProject, createNewProject } = useProjectStore();
|
||||||
@ -94,8 +96,8 @@ export default function Editor() {
|
|||||||
|
|
||||||
<ResizableHandle withHandle />
|
<ResizableHandle withHandle />
|
||||||
|
|
||||||
{/* Properties Panel - Hidden for now but ready */}
|
|
||||||
{/* <ResizablePanel
|
<ResizablePanel
|
||||||
defaultSize={propertiesPanel}
|
defaultSize={propertiesPanel}
|
||||||
minSize={15}
|
minSize={15}
|
||||||
maxSize={40}
|
maxSize={40}
|
||||||
@ -103,7 +105,7 @@ export default function Editor() {
|
|||||||
className="min-w-0"
|
className="min-w-0"
|
||||||
>
|
>
|
||||||
<PropertiesPanel />
|
<PropertiesPanel />
|
||||||
</ResizablePanel> */}
|
</ResizablePanel>
|
||||||
</ResizablePanelGroup>
|
</ResizablePanelGroup>
|
||||||
</ResizablePanel>
|
</ResizablePanel>
|
||||||
|
|
||||||
|
@ -173,8 +173,7 @@ export function TimelineElement({
|
|||||||
const renderElementContent = () => {
|
const renderElementContent = () => {
|
||||||
if (element.type === "text") {
|
if (element.type === "text") {
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full flex items-center justify-center px-2">
|
<div className="w-full h-full flex items-center justify-center">
|
||||||
<Type className="h-4 w-4 mr-2 text-purple-400 flex-shrink-0" />
|
|
||||||
<span className="text-xs text-foreground/80 truncate">
|
<span className="text-xs text-foreground/80 truncate">
|
||||||
{element.content}
|
{element.content}
|
||||||
</span>
|
</span>
|
||||||
@ -195,6 +194,7 @@ export function TimelineElement({
|
|||||||
if (mediaItem.type === "image") {
|
if (mediaItem.type === "image") {
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full flex items-center justify-center">
|
<div className="w-full h-full flex items-center justify-center">
|
||||||
|
<div className="bg-[#004D52] py-3 w-full h-full">
|
||||||
<img
|
<img
|
||||||
src={mediaItem.url}
|
src={mediaItem.url}
|
||||||
alt={mediaItem.name}
|
alt={mediaItem.name}
|
||||||
@ -202,6 +202,7 @@ export function TimelineElement({
|
|||||||
draggable={false}
|
draggable={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +277,7 @@ export function TimelineElement({
|
|||||||
onElementMouseDown && onElementMouseDown(e, element)
|
onElementMouseDown && onElementMouseDown(e, element)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="absolute inset-1 flex items-center p-1">
|
<div className="absolute inset-0 flex items-center h-full">
|
||||||
{renderElementContent()}
|
{renderElementContent()}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -46,6 +46,9 @@ import { TimelineTrackContent } from "./timeline-track";
|
|||||||
import type { DragData } from "@/types/timeline";
|
import type { DragData } from "@/types/timeline";
|
||||||
import {
|
import {
|
||||||
getTrackLabelColor,
|
getTrackLabelColor,
|
||||||
|
getTrackHeight,
|
||||||
|
getCumulativeHeightBefore,
|
||||||
|
getTotalTracksHeight,
|
||||||
TIMELINE_CONSTANTS,
|
TIMELINE_CONSTANTS,
|
||||||
} from "@/lib/timeline-constants";
|
} from "@/lib/timeline-constants";
|
||||||
|
|
||||||
@ -242,9 +245,9 @@ export function Timeline() {
|
|||||||
track.elements.forEach((element) => {
|
track.elements.forEach((element) => {
|
||||||
const clipLeft =
|
const clipLeft =
|
||||||
element.startTime * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel;
|
element.startTime * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel;
|
||||||
const clipTop = trackIdx * TIMELINE_CONSTANTS.TRACK_HEIGHT;
|
const clipTop = getCumulativeHeightBefore(tracks, trackIdx);
|
||||||
const clipBottom = clipTop + TIMELINE_CONSTANTS.TRACK_HEIGHT;
|
const clipBottom = clipTop + getTrackHeight(track.type);
|
||||||
const clipRight = clipLeft + TIMELINE_CONSTANTS.TRACK_HEIGHT;
|
const clipRight = clipLeft + getTrackHeight(track.type);
|
||||||
if (
|
if (
|
||||||
bx1 < clipRight &&
|
bx1 < clipRight &&
|
||||||
bx2 > clipLeft &&
|
bx2 > clipLeft &&
|
||||||
@ -1021,7 +1024,8 @@ export function Timeline() {
|
|||||||
{tracks.map((track) => (
|
{tracks.map((track) => (
|
||||||
<div
|
<div
|
||||||
key={track.id}
|
key={track.id}
|
||||||
className="h-[60px] flex items-center px-3 border-b border-muted/30 bg-background group"
|
className="flex items-center px-3 border-b border-muted/30 bg-background group"
|
||||||
|
style={{ height: `${getTrackHeight(track.type)}px` }}
|
||||||
>
|
>
|
||||||
<div className="flex items-center flex-1 min-w-0">
|
<div className="flex items-center flex-1 min-w-0">
|
||||||
<div
|
<div
|
||||||
@ -1048,7 +1052,7 @@ export function Timeline() {
|
|||||||
<div
|
<div
|
||||||
className="relative flex-1"
|
className="relative flex-1"
|
||||||
style={{
|
style={{
|
||||||
height: `${Math.max(200, Math.min(800, tracks.length * TIMELINE_CONSTANTS.TRACK_HEIGHT))}px`,
|
height: `${Math.max(200, Math.min(800, getTotalTracksHeight(tracks)))}px`,
|
||||||
width: `${dynamicTimelineWidth}px`,
|
width: `${dynamicTimelineWidth}px`,
|
||||||
}}
|
}}
|
||||||
onClick={handleTimelineClick}
|
onClick={handleTimelineClick}
|
||||||
@ -1064,8 +1068,8 @@ export function Timeline() {
|
|||||||
<div
|
<div
|
||||||
className="absolute left-0 right-0 border-b border-muted/30"
|
className="absolute left-0 right-0 border-b border-muted/30"
|
||||||
style={{
|
style={{
|
||||||
top: `${index * TIMELINE_CONSTANTS.TRACK_HEIGHT}px`,
|
top: `${getCumulativeHeightBefore(tracks, index)}px`,
|
||||||
height: `${TIMELINE_CONSTANTS.TRACK_HEIGHT}px`,
|
height: `${getTrackHeight(track.type)}px`,
|
||||||
}}
|
}}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
// If clicking empty area (not on a element), deselect all elements
|
// If clicking empty area (not on a element), deselect all elements
|
||||||
@ -1098,7 +1102,7 @@ export function Timeline() {
|
|||||||
className="absolute top-0 w-0.5 bg-red-500 pointer-events-auto z-50 cursor-col"
|
className="absolute top-0 w-0.5 bg-red-500 pointer-events-auto z-50 cursor-col"
|
||||||
style={{
|
style={{
|
||||||
left: `${playheadPosition * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel}px`,
|
left: `${playheadPosition * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel}px`,
|
||||||
height: `${tracks.length * TIMELINE_CONSTANTS.TRACK_HEIGHT}px`,
|
height: `${getTotalTracksHeight(tracks)}px`,
|
||||||
}}
|
}}
|
||||||
onMouseDown={handlePlayheadMouseDown}
|
onMouseDown={handlePlayheadMouseDown}
|
||||||
/>
|
/>
|
||||||
|
@ -1,32 +1,30 @@
|
|||||||
import type { TrackType } from "@/types/timeline";
|
import type { TrackType } from "@/types/timeline";
|
||||||
|
|
||||||
// Track color definitions
|
// Track color definitions
|
||||||
export const TRACK_COLORS = {
|
export const TRACK_COLORS: Record<
|
||||||
|
TrackType,
|
||||||
|
{ solid: string; background: string; border: string }
|
||||||
|
> = {
|
||||||
media: {
|
media: {
|
||||||
solid: "bg-blue-500",
|
solid: "bg-blue-500",
|
||||||
background: "bg-blue-500/20",
|
background: "bg-blue-500/20",
|
||||||
border: "border-blue-500/30",
|
border: "border-blue-500/30",
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
solid: "bg-purple-500",
|
solid: "bg-[#9C4937]",
|
||||||
background: "bg-purple-500/20",
|
background: "bg-[#9C4937]",
|
||||||
border: "border-purple-500/30",
|
border: "border-[#9C4937]/40",
|
||||||
},
|
},
|
||||||
audio: {
|
audio: {
|
||||||
solid: "bg-green-500",
|
solid: "bg-green-500",
|
||||||
background: "bg-green-500/20",
|
background: "bg-green-500/20",
|
||||||
border: "border-green-500/30",
|
border: "border-green-500/30",
|
||||||
},
|
},
|
||||||
default: {
|
|
||||||
solid: "bg-gray-500",
|
|
||||||
background: "bg-gray-500/20",
|
|
||||||
border: "border-gray-500/30",
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
export function getTrackColors(type: TrackType) {
|
export function getTrackColors(type: TrackType) {
|
||||||
return TRACK_COLORS[type] || TRACK_COLORS.default;
|
return TRACK_COLORS[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTrackElementClasses(type: TrackType) {
|
export function getTrackElementClasses(type: TrackType) {
|
||||||
@ -38,11 +36,40 @@ export function getTrackLabelColor(type: TrackType) {
|
|||||||
return getTrackColors(type).solid;
|
return getTrackColors(type).solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Track height definitions
|
||||||
|
export const TRACK_HEIGHTS: Record<TrackType, number> = {
|
||||||
|
media: 65,
|
||||||
|
text: 25,
|
||||||
|
audio: 50,
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
// Utility function for track heights
|
||||||
|
export function getTrackHeight(type: TrackType): number {
|
||||||
|
return TRACK_HEIGHTS[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate cumulative height up to (but not including) a track index
|
||||||
|
export function getCumulativeHeightBefore(
|
||||||
|
tracks: Array<{ type: TrackType }>,
|
||||||
|
trackIndex: number
|
||||||
|
): number {
|
||||||
|
return tracks
|
||||||
|
.slice(0, trackIndex)
|
||||||
|
.reduce((sum, track) => sum + getTrackHeight(track.type), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate total height of all tracks
|
||||||
|
export function getTotalTracksHeight(
|
||||||
|
tracks: Array<{ type: TrackType }>
|
||||||
|
): number {
|
||||||
|
return tracks.reduce((sum, track) => sum + getTrackHeight(track.type), 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Other timeline constants
|
// Other timeline constants
|
||||||
export const TIMELINE_CONSTANTS = {
|
export const TIMELINE_CONSTANTS = {
|
||||||
ELEMENT_MIN_WIDTH: 80,
|
ELEMENT_MIN_WIDTH: 80,
|
||||||
PIXELS_PER_SECOND: 50,
|
PIXELS_PER_SECOND: 50,
|
||||||
TRACK_HEIGHT: 60,
|
TRACK_HEIGHT: 60, // Default fallback
|
||||||
DEFAULT_TEXT_DURATION: 5,
|
DEFAULT_TEXT_DURATION: 5,
|
||||||
ZOOM_LEVELS: [0.25, 0.5, 1, 1.5, 2, 3, 4],
|
ZOOM_LEVELS: [0.25, 0.5, 1, 1.5, 2, 3, 4],
|
||||||
} as const;
|
} as const;
|
||||||
|
Reference in New Issue
Block a user