Create standalone browser port of LTX Athena with authenticated native API transport
This commit is contained in:
@@ -0,0 +1,333 @@
|
||||
import type {
|
||||
Asset,
|
||||
AssetTake,
|
||||
AssetBins,
|
||||
GenerationParams,
|
||||
SubtitleClip,
|
||||
SubtitleStyle,
|
||||
Timeline,
|
||||
TimelineClip,
|
||||
Track,
|
||||
} from '../../types/project-model'
|
||||
import {
|
||||
DEFAULT_LAYOUT,
|
||||
type EditorLayout,
|
||||
type ToolType,
|
||||
} from './video-editor-utils'
|
||||
|
||||
export interface EditorModel {
|
||||
assets: Asset[]
|
||||
bins: AssetBins
|
||||
timelines: Timeline[]
|
||||
activeTimelineId: string | null
|
||||
}
|
||||
|
||||
export interface TimelineGapSelection {
|
||||
trackIndex: number
|
||||
startTime: number
|
||||
endTime: number
|
||||
}
|
||||
|
||||
export interface TimelineInOutRange {
|
||||
inPoint: number | null
|
||||
outPoint: number | null
|
||||
}
|
||||
|
||||
export interface EditorUndoSnapshot {
|
||||
assets: Asset[]
|
||||
bins: AssetBins
|
||||
timelines: Timeline[]
|
||||
}
|
||||
|
||||
export interface EditorClipboardState {
|
||||
kind: 'clips' | null
|
||||
clips: TimelineClip[]
|
||||
copiedFromTimelineId: string | null
|
||||
}
|
||||
|
||||
export interface EditorHistoryState {
|
||||
undoStack: EditorUndoSnapshot[]
|
||||
redoStack: EditorUndoSnapshot[]
|
||||
}
|
||||
|
||||
export interface EditorProjectSyncState {
|
||||
dirty: boolean
|
||||
}
|
||||
|
||||
export interface EditorSelectionState {
|
||||
clipIds: Set<string>
|
||||
subtitleId: string | null
|
||||
editingSubtitleId: string | null
|
||||
gap: TimelineGapSelection | null
|
||||
}
|
||||
|
||||
export interface EditorTransportState {
|
||||
currentTime: number
|
||||
isPlaying: boolean
|
||||
shuttleSpeed: number
|
||||
playingInOut: boolean
|
||||
timelineInOutMap: Record<string, TimelineInOutRange>
|
||||
}
|
||||
|
||||
export interface EditorToolsState {
|
||||
zoom: number
|
||||
snapEnabled: boolean
|
||||
activeTool: ToolType
|
||||
lastTrimTool: ToolType
|
||||
}
|
||||
|
||||
export interface EditorUiState {
|
||||
showImportTimelineModal: boolean
|
||||
showExportModal: boolean
|
||||
showSourceMonitor: boolean
|
||||
showPropertiesPanel: boolean
|
||||
showEffectsBrowser: boolean
|
||||
activeFocusArea: 'source' | 'timeline'
|
||||
sourceSplitPercent: number
|
||||
hasSourceAsset: boolean
|
||||
openTimelineIds: Set<string>
|
||||
renamingTimelineId: string | null
|
||||
renameValue: string
|
||||
renameSource: 'tab' | 'panel'
|
||||
layout: EditorLayout
|
||||
subtitleTrackStyleIdx: number | null
|
||||
gapGenerateMode: 'text-to-video' | 'image-to-video' | 'text-to-image' | null
|
||||
}
|
||||
|
||||
export interface EditorRegenerationState {
|
||||
regeneratingAssetId: string | null
|
||||
regeneratingClipId: string | null
|
||||
preError: string | null
|
||||
}
|
||||
|
||||
export interface EditorSessionState {
|
||||
selection: EditorSelectionState
|
||||
transport: EditorTransportState
|
||||
tools: EditorToolsState
|
||||
ui: EditorUiState
|
||||
regeneration: EditorRegenerationState
|
||||
clipboard: EditorClipboardState
|
||||
}
|
||||
|
||||
export interface EditorState {
|
||||
editorModel: EditorModel
|
||||
session: EditorSessionState
|
||||
history: EditorHistoryState
|
||||
projectSync: EditorProjectSyncState
|
||||
}
|
||||
|
||||
export interface TimelineListItem {
|
||||
timeline: Timeline
|
||||
isActive: boolean
|
||||
isOpen: boolean
|
||||
isRenaming: boolean
|
||||
clipCount: number
|
||||
duration: number
|
||||
}
|
||||
|
||||
export interface ClipDimensions {
|
||||
width: number
|
||||
height: number
|
||||
}
|
||||
|
||||
export interface ClipResolutionInfo {
|
||||
label: string
|
||||
color: string
|
||||
height: number
|
||||
displayName: string
|
||||
}
|
||||
|
||||
export interface OrderedTrackEntry {
|
||||
track: Track
|
||||
realIndex: number
|
||||
displayRow: number
|
||||
}
|
||||
|
||||
export interface TimelineCutPoint {
|
||||
leftClip: TimelineClip
|
||||
rightClip: TimelineClip
|
||||
time: number
|
||||
trackIndex: number
|
||||
hasDissolve: boolean
|
||||
}
|
||||
|
||||
export interface ClipMetadata {
|
||||
liveAsset: Asset | null | undefined
|
||||
dimensions: ClipDimensions | null
|
||||
resolution: ClipResolutionInfo | null
|
||||
generationParams: GenerationParams | undefined
|
||||
totalTakes: number
|
||||
currentTakeIdx: number
|
||||
displayTakeNum: number
|
||||
filePath: string
|
||||
isUpscaled: boolean
|
||||
}
|
||||
|
||||
export interface ClipCapabilities {
|
||||
isVideo: boolean
|
||||
isImage: boolean
|
||||
isAudio: boolean
|
||||
isAdjustment: boolean
|
||||
isText: boolean
|
||||
canCreateVideoFromImage: boolean
|
||||
canCreateVideoFromAudio: boolean
|
||||
canRegenerate: boolean
|
||||
canRetake: boolean
|
||||
canUseIcLora: boolean
|
||||
}
|
||||
|
||||
export interface SelectedClipPropertiesModel {
|
||||
clip: TimelineClip
|
||||
metadata: ClipMetadata
|
||||
capabilities: ClipCapabilities
|
||||
}
|
||||
|
||||
export interface SelectedSubtitleEditorModel {
|
||||
subtitle: SubtitleClip
|
||||
track: Track | undefined
|
||||
effectiveStyle: Partial<SubtitleStyle>
|
||||
}
|
||||
|
||||
export interface SubtitleTrackStyleEditorModel {
|
||||
trackIndex: number
|
||||
track: Track
|
||||
style: SubtitleStyle
|
||||
}
|
||||
|
||||
export interface KeyboardCommandContext {
|
||||
clips: TimelineClip[]
|
||||
selectedClipIds: Set<string>
|
||||
totalDuration: number
|
||||
currentTime: number
|
||||
inPoint: number | null
|
||||
outPoint: number | null
|
||||
}
|
||||
|
||||
export interface MenuState {
|
||||
selectedClip: TimelineClip | null
|
||||
selectedClipIds: Set<string>
|
||||
clips: TimelineClip[]
|
||||
tracks: Track[]
|
||||
subtitles: SubtitleClip[]
|
||||
snapEnabled: boolean
|
||||
showEffectsBrowser: boolean
|
||||
showSourceMonitor: boolean
|
||||
showPropertiesPanel: boolean
|
||||
hasSourceAsset: boolean
|
||||
activeTool: ToolType
|
||||
activeTimeline: Timeline | null
|
||||
timelines: Timeline[]
|
||||
}
|
||||
|
||||
export interface AssetListFilters {
|
||||
assetFilter?: Asset['type'] | 'all'
|
||||
selectedBinId?: string | null
|
||||
assetViewMode?: 'grid' | 'list'
|
||||
listSortCol?: 'name' | 'type' | 'duration' | 'resolution' | 'date' | 'color'
|
||||
listSortDir?: 'asc' | 'desc'
|
||||
}
|
||||
|
||||
export interface AssetTakeView {
|
||||
asset: Asset | undefined
|
||||
takes: AssetTake[]
|
||||
activeTakeIndex: number
|
||||
}
|
||||
|
||||
export const EMPTY_IN_OUT_RANGE: TimelineInOutRange = {
|
||||
inPoint: null,
|
||||
outPoint: null,
|
||||
}
|
||||
|
||||
export function createInitialEditorState(
|
||||
editorModel: EditorModel,
|
||||
layout: EditorLayout = DEFAULT_LAYOUT,
|
||||
): EditorState {
|
||||
return {
|
||||
editorModel,
|
||||
session: {
|
||||
selection: {
|
||||
clipIds: new Set(),
|
||||
subtitleId: null,
|
||||
editingSubtitleId: null,
|
||||
gap: null,
|
||||
},
|
||||
transport: {
|
||||
currentTime: 0,
|
||||
isPlaying: false,
|
||||
shuttleSpeed: 0,
|
||||
playingInOut: false,
|
||||
timelineInOutMap: {},
|
||||
},
|
||||
tools: {
|
||||
zoom: 1,
|
||||
snapEnabled: true,
|
||||
activeTool: 'select',
|
||||
lastTrimTool: 'ripple',
|
||||
},
|
||||
ui: {
|
||||
showImportTimelineModal: false,
|
||||
showExportModal: false,
|
||||
showSourceMonitor: false,
|
||||
showPropertiesPanel: false,
|
||||
showEffectsBrowser: false,
|
||||
activeFocusArea: 'timeline',
|
||||
sourceSplitPercent: 50,
|
||||
hasSourceAsset: false,
|
||||
openTimelineIds: editorModel.activeTimelineId ? new Set([editorModel.activeTimelineId]) : new Set(),
|
||||
renamingTimelineId: null,
|
||||
renameValue: '',
|
||||
renameSource: 'tab',
|
||||
layout,
|
||||
subtitleTrackStyleIdx: null,
|
||||
gapGenerateMode: null,
|
||||
},
|
||||
regeneration: {
|
||||
regeneratingAssetId: null,
|
||||
regeneratingClipId: null,
|
||||
preError: null,
|
||||
},
|
||||
clipboard: {
|
||||
kind: null,
|
||||
clips: [],
|
||||
copiedFromTimelineId: null,
|
||||
},
|
||||
},
|
||||
history: {
|
||||
undoStack: [],
|
||||
redoStack: [],
|
||||
},
|
||||
projectSync: {
|
||||
dirty: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export function getUndoSnapshot(state: EditorState): EditorUndoSnapshot {
|
||||
return {
|
||||
assets: state.editorModel.assets,
|
||||
bins: state.editorModel.bins,
|
||||
timelines: state.editorModel.timelines,
|
||||
}
|
||||
}
|
||||
|
||||
export function applyUndoSnapshot(
|
||||
state: EditorState,
|
||||
snapshot: EditorUndoSnapshot,
|
||||
): EditorState {
|
||||
return {
|
||||
...state,
|
||||
editorModel: {
|
||||
...state.editorModel,
|
||||
assets: snapshot.assets,
|
||||
bins: snapshot.bins,
|
||||
timelines: snapshot.timelines,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export function equalUndoSnapshot(
|
||||
left: EditorUndoSnapshot,
|
||||
right: EditorUndoSnapshot,
|
||||
): boolean {
|
||||
return left.assets === right.assets && left.bins === right.bins && left.timelines === right.timelines
|
||||
}
|
||||
Reference in New Issue
Block a user