mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
refactor not done
This commit is contained in:
@@ -0,0 +1,528 @@
|
||||
import type { EditorCore } from "@/core";
|
||||
import type {
|
||||
TrackType,
|
||||
CreateTimelineElement,
|
||||
TimelineTrack,
|
||||
TextElement,
|
||||
DragData,
|
||||
} from "@/types/timeline";
|
||||
import type { MediaFile } from "@/types/media";
|
||||
import { calculateTotalDuration } from "@/lib/timeline/calculation-utils";
|
||||
|
||||
export class TimelineManager {
|
||||
private _tracks: TimelineTrack[] = [];
|
||||
private history: TimelineTrack[][] = [];
|
||||
private redoStack: TimelineTrack[][] = [];
|
||||
private clipboard: {
|
||||
items: Array<{ trackType: TrackType; element: CreateTimelineElement }>;
|
||||
} | null = null;
|
||||
private tracks: TimelineTrack[] = [];
|
||||
private snappingEnabled = true;
|
||||
private rippleEditingEnabled = false;
|
||||
private selectedElements: { trackId: string; elementId: string }[] = [];
|
||||
private dragState = {
|
||||
isDragging: false,
|
||||
elementId: null as string | null,
|
||||
trackId: null as string | null,
|
||||
startMouseX: 0,
|
||||
startElementTime: 0,
|
||||
clickOffsetTime: 0,
|
||||
currentTime: 0,
|
||||
};
|
||||
private listeners = new Set<() => void>();
|
||||
|
||||
constructor(private editor: EditorCore) {
|
||||
this.initializeTracks();
|
||||
}
|
||||
|
||||
private initializeTracks(): void {
|
||||
this._tracks = [];
|
||||
this.tracks = [];
|
||||
}
|
||||
|
||||
getSortedTracks(): TimelineTrack[] {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
toggleSnapping(): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
toggleRippleEditing(): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
selectElement({
|
||||
trackId,
|
||||
elementId,
|
||||
multi = false,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
multi?: boolean;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
deselectElement({
|
||||
trackId,
|
||||
elementId,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
clearSelectedElements(): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
setSelectedElements({
|
||||
elements,
|
||||
}: {
|
||||
elements: { trackId: string; elementId: string }[];
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
setDragState({
|
||||
dragState,
|
||||
}: {
|
||||
dragState: Partial<{
|
||||
isDragging: boolean;
|
||||
elementId: string | null;
|
||||
trackId: string | null;
|
||||
startMouseX: number;
|
||||
startElementTime: number;
|
||||
clickOffsetTime: number;
|
||||
currentTime: number;
|
||||
}>;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
startDrag({
|
||||
elementId,
|
||||
trackId,
|
||||
startMouseX,
|
||||
startElementTime,
|
||||
clickOffsetTime,
|
||||
}: {
|
||||
elementId: string;
|
||||
trackId: string;
|
||||
startMouseX: number;
|
||||
startElementTime: number;
|
||||
clickOffsetTime: number;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
updateDragTime({ currentTime }: { currentTime: number }): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
endDrag(): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
addTrack({ type }: { type: TrackType }): string {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
insertTrackAt({ type, index }: { type: TrackType; index: number }): string {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
removeTrack({ trackId }: { trackId: string }): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
removeTrackWithRipple({ trackId }: { trackId: string }): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
addElementToTrack({
|
||||
trackId,
|
||||
element,
|
||||
}: {
|
||||
trackId: string;
|
||||
element: CreateTimelineElement;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
moveElementToTrack({
|
||||
fromTrackId,
|
||||
toTrackId,
|
||||
elementId,
|
||||
}: {
|
||||
fromTrackId: string;
|
||||
toTrackId: string;
|
||||
elementId: string;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
updateElementTrim({
|
||||
trackId,
|
||||
elementId,
|
||||
trimStart,
|
||||
trimEnd,
|
||||
pushHistory = true,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
trimStart: number;
|
||||
trimEnd: number;
|
||||
pushHistory?: boolean;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
updateElementDuration({
|
||||
trackId,
|
||||
elementId,
|
||||
duration,
|
||||
pushHistory = true,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
duration: number;
|
||||
pushHistory?: boolean;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
updateElementStartTime({
|
||||
trackId,
|
||||
elementId,
|
||||
startTime,
|
||||
pushHistory = true,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
startTime: number;
|
||||
pushHistory?: boolean;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
toggleTrackMute({ trackId }: { trackId: string }): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
splitAndKeepLeft({
|
||||
trackId,
|
||||
elementId,
|
||||
splitTime,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
splitTime: number;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
splitAndKeepRight({
|
||||
trackId,
|
||||
elementId,
|
||||
splitTime,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
splitTime: number;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
separateAudio({
|
||||
trackId,
|
||||
elementId,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
}): string | null {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
replaceElementMedia({
|
||||
trackId,
|
||||
elementId,
|
||||
newFile,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
newFile: File;
|
||||
}): Promise<{ success: boolean; error?: string }> {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
updateElementStartTimeWithRipple({
|
||||
trackId,
|
||||
elementId,
|
||||
newStartTime,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
newStartTime: number;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
removeElementFromTrackWithRipple({
|
||||
trackId,
|
||||
elementId,
|
||||
pushHistory = true,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
pushHistory?: boolean;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
getTotalDuration(): number {
|
||||
return calculateTotalDuration({ tracks: this._tracks });
|
||||
}
|
||||
|
||||
getProjectThumbnail({
|
||||
projectId,
|
||||
}: {
|
||||
projectId: string;
|
||||
}): Promise<string | null> {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
undo(): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
redo(): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
pushHistory(): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
async loadProjectTimeline({
|
||||
projectId,
|
||||
sceneId,
|
||||
}: {
|
||||
projectId: string;
|
||||
sceneId?: string;
|
||||
}): Promise<void> {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
async saveProjectTimeline({
|
||||
projectId,
|
||||
sceneId,
|
||||
}: {
|
||||
projectId: string;
|
||||
sceneId?: string;
|
||||
}): Promise<void> {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
clearTimeline(): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
copySelected(): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
pasteAtTime({ time }: { time: number }): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
deleteSelected({
|
||||
trackId,
|
||||
elementId,
|
||||
}: {
|
||||
trackId?: string;
|
||||
elementId?: string;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
splitSelected({
|
||||
splitTime,
|
||||
trackId,
|
||||
elementId,
|
||||
}: {
|
||||
splitTime: number;
|
||||
trackId?: string;
|
||||
elementId?: string;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
toggleSelectedHidden({
|
||||
trackId,
|
||||
elementId,
|
||||
}: {
|
||||
trackId?: string;
|
||||
elementId?: string;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
toggleSelectedMuted({
|
||||
trackId,
|
||||
elementId,
|
||||
}: {
|
||||
trackId?: string;
|
||||
elementId?: string;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
duplicateElement({
|
||||
trackId,
|
||||
elementId,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
revealElementInMedia({ elementId }: { elementId: string }): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
async replaceElementWithFile({
|
||||
trackId,
|
||||
elementId,
|
||||
file,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
file: File;
|
||||
}): Promise<void> {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
getContextMenuState({
|
||||
trackId,
|
||||
elementId,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
}): {
|
||||
isMultipleSelected: boolean;
|
||||
isCurrentElementSelected: boolean;
|
||||
hasAudioElements: boolean;
|
||||
canSplitSelected: boolean;
|
||||
currentTime: number;
|
||||
} {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
updateTextElement({
|
||||
trackId,
|
||||
elementId,
|
||||
updates,
|
||||
}: {
|
||||
trackId: string;
|
||||
elementId: string;
|
||||
updates: Partial<
|
||||
Pick<
|
||||
TextElement,
|
||||
| "content"
|
||||
| "fontSize"
|
||||
| "fontFamily"
|
||||
| "color"
|
||||
| "backgroundColor"
|
||||
| "textAlign"
|
||||
| "fontWeight"
|
||||
| "fontStyle"
|
||||
| "textDecoration"
|
||||
| "x"
|
||||
| "y"
|
||||
| "rotation"
|
||||
| "opacity"
|
||||
>
|
||||
>;
|
||||
}): void {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
checkElementOverlap({
|
||||
trackId,
|
||||
startTime,
|
||||
duration,
|
||||
excludeElementId,
|
||||
}: {
|
||||
trackId: string;
|
||||
startTime: number;
|
||||
duration: number;
|
||||
excludeElementId?: string;
|
||||
}): boolean {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
findOrCreateTrack({ trackType }: { trackType: TrackType }): string {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
addElementAtTime({
|
||||
item,
|
||||
currentTime = 0,
|
||||
}: {
|
||||
item: MediaFile | TextElement;
|
||||
currentTime?: number;
|
||||
}): boolean {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
addElementToNewTrack({
|
||||
item,
|
||||
}: {
|
||||
item: MediaFile | TextElement | DragData;
|
||||
}): boolean {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
getTracks(): TimelineTrack[] {
|
||||
return this.tracks;
|
||||
}
|
||||
|
||||
getTracksWithMain(): TimelineTrack[] {
|
||||
return this._tracks;
|
||||
}
|
||||
|
||||
getSelectedElements(): { trackId: string; elementId: string }[] {
|
||||
return this.selectedElements;
|
||||
}
|
||||
|
||||
getDragState(): typeof this.dragState {
|
||||
return this.dragState;
|
||||
}
|
||||
|
||||
getSnappingEnabled(): boolean {
|
||||
return this.snappingEnabled;
|
||||
}
|
||||
|
||||
getRippleEditingEnabled(): boolean {
|
||||
return this.rippleEditingEnabled;
|
||||
}
|
||||
|
||||
subscribe(listener: () => void): () => void {
|
||||
this.listeners.add(listener);
|
||||
return () => this.listeners.delete(listener);
|
||||
}
|
||||
|
||||
private notify(): void {
|
||||
this.listeners.forEach((fn) => fn());
|
||||
}
|
||||
|
||||
private updateTracks(newTracks: TimelineTrack[]): void {
|
||||
this._tracks = newTracks;
|
||||
this.tracks = newTracks; // TODO: Implement proper sorting with main track
|
||||
this.notify();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user