@linker-design-plus/timeline-track 2.0.10 → 2.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -1
- package/dist/assets/AlibabaPuHuiTi-3-55-Regular.woff2 +0 -0
- package/dist/components/panel/ClipConfigPanel.d.ts +76 -38
- package/dist/components/panel/ClipConfigPanelRenderer.d.ts +104 -0
- package/dist/components/panel/TrackInfoPanel.d.ts +3 -3
- package/dist/components/panel/TrackInfoPanelRenderer.d.ts +33 -0
- package/dist/components/track/Track.d.ts +4 -0
- package/dist/core/commands/timelineCommands.d.ts +1 -0
- package/dist/core/controllers/index.d.ts +1 -0
- package/dist/core/controllers/previewBackend.d.ts +4 -1
- package/dist/core/controllers/previewPendingOverlayRenderer.d.ts +17 -0
- package/dist/core/controllers/timelineClipConfigController.d.ts +5 -1
- package/dist/core/controllers/timelineClipEventController.d.ts +1 -0
- package/dist/core/controllers/timelineKeyboardShortcutsController.d.ts +29 -0
- package/dist/core/controllers/timelinePreviewSession.d.ts +36 -4
- package/dist/core/controllers/timelineSelectionController.d.ts +7 -1
- package/dist/core/controllers/timelineTrackMutationController.d.ts +2 -2
- package/dist/core/facade/timelineManager.d.ts +38 -6
- package/dist/core/layout/TimelineManagerLayoutRenderer.d.ts +25 -0
- package/dist/core/layout/timelineManagerDom.d.ts +2 -11
- package/dist/core/models/constants.d.ts +1 -0
- package/dist/core/models/types.d.ts +90 -10
- package/dist/core/renderers/domRenderer.d.ts +17 -0
- package/dist/core/resources/sourceMediaRegistry.d.ts +24 -0
- package/dist/core/testing/konva-test-stub.d.ts +2 -0
- package/dist/core/theme/colorTokens.d.ts +147 -0
- package/dist/index.cjs.js +521 -74
- package/dist/index.es.js +7543 -4865
- package/dist/utils/rendering/KonvaUtils.d.ts +2 -2
- package/dist/utils/rendering/clipCoverRenderer.d.ts +1 -0
- package/dist/utils/rendering/clipVisualRenderer.d.ts +2 -2
- package/dist/utils/svgIcon.d.ts +1 -0
- package/dist/utils/time/timeUtils.d.ts +8 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -39,7 +39,12 @@ const timeline = new TimelineManager({
|
|
|
39
39
|
container,
|
|
40
40
|
zoom: 100,
|
|
41
41
|
currentTime: 0,
|
|
42
|
-
previewBackend: 'dom'
|
|
42
|
+
previewBackend: 'dom',
|
|
43
|
+
keyboardShortcuts: {
|
|
44
|
+
bindings: {
|
|
45
|
+
togglePlay: 'Mod+Alt+P'
|
|
46
|
+
}
|
|
47
|
+
}
|
|
43
48
|
});
|
|
44
49
|
|
|
45
50
|
timeline.attachPreview(preview);
|
|
@@ -88,6 +93,21 @@ timeline.on('history_change', (_event, data) => {
|
|
|
88
93
|
- `attachPreview(containerOrConfig)` / `detachPreview()`
|
|
89
94
|
- `exportTimeline()` / `loadDraft(data)`
|
|
90
95
|
|
|
96
|
+
快捷键配置:
|
|
97
|
+
|
|
98
|
+
- `keyboardShortcuts: false` 可彻底关闭快捷键
|
|
99
|
+
- `keyboardShortcuts.bindings` 可按动作覆盖默认键位
|
|
100
|
+
- 时间轴挂载后默认在当前页面生效
|
|
101
|
+
|
|
102
|
+
默认快捷键:
|
|
103
|
+
|
|
104
|
+
- 播放 / 暂停:`Space`
|
|
105
|
+
- 删除片段:`Delete` / `Backspace`
|
|
106
|
+
- 分离 / 还原音频:`Mod+Alt+A`
|
|
107
|
+
- 分割片段:`Mod+B`
|
|
108
|
+
- 撤销:`Mod+Z`
|
|
109
|
+
- 还原:`Mod+Shift+Z`,Windows 另支持 `Ctrl+Y`
|
|
110
|
+
|
|
91
111
|
常用事件:
|
|
92
112
|
|
|
93
113
|
- `time_change`
|
|
@@ -190,3 +210,4 @@ pnpm exec tsc -p tsconfig.json --noEmit
|
|
|
190
210
|
- [docs/interaction-model.md](./docs/interaction-model.md): 指针交互分层和拖拽约束
|
|
191
211
|
- [docs/refactor-roadmap.md](./docs/refactor-roadmap.md): 主线重构归档与后续收敛方向
|
|
192
212
|
- [docs/maintenance-audit.md](./docs/maintenance-audit.md): 本轮仓库审计、验证结果和依赖建议
|
|
213
|
+
- [docs/review-remediation-plan.md](./docs/review-remediation-plan.md): 基于审查结论的修复计划与阶段性落地建议
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Clip, type VoiceOption } from '../../core/models';
|
|
2
2
|
export interface ClipConfigPanelTheme {
|
|
3
3
|
backgroundColor: string;
|
|
4
4
|
borderColor: string;
|
|
@@ -17,54 +17,92 @@ export declare const defaultDarkTheme: ClipConfigPanelTheme;
|
|
|
17
17
|
export interface ClipConfigPanelConfig {
|
|
18
18
|
container: HTMLElement;
|
|
19
19
|
theme?: ClipConfigPanelTheme;
|
|
20
|
+
voiceCatalog?: VoiceOption[];
|
|
20
21
|
onClipUpdate?: (clipId: string, updates: Partial<Clip>) => void;
|
|
22
|
+
onGenerateVoice?: (clip: Clip, voice: VoiceOption, followTextUpdates: boolean) => Promise<void>;
|
|
21
23
|
}
|
|
24
|
+
export declare const CSS_CLASSES: {
|
|
25
|
+
readonly container: "clip-config-panel";
|
|
26
|
+
readonly tabBar: "clip-config-tab-bar";
|
|
27
|
+
readonly tabButton: "clip-config-tab-button";
|
|
28
|
+
readonly content: "clip-config-content";
|
|
29
|
+
readonly visualPanel: "clip-config-visual-panel";
|
|
30
|
+
readonly audioPanel: "clip-config-audio-panel";
|
|
31
|
+
readonly textPanel: "clip-config-text-panel";
|
|
32
|
+
readonly voicePanel: "clip-config-voice-panel";
|
|
33
|
+
readonly actionBar: "clip-config-action-bar";
|
|
34
|
+
readonly section: "clip-config-section";
|
|
35
|
+
readonly sectionTitle: "clip-config-section-title";
|
|
36
|
+
readonly row: "clip-config-row";
|
|
37
|
+
readonly label: "clip-config-label";
|
|
38
|
+
readonly slider: "clip-config-slider";
|
|
39
|
+
readonly input: "clip-config-input";
|
|
40
|
+
readonly textarea: "clip-config-textarea";
|
|
41
|
+
readonly colorInput: "clip-config-color-input";
|
|
42
|
+
readonly presetGrid: "clip-config-preset-grid";
|
|
43
|
+
readonly presetButton: "clip-config-preset-button";
|
|
44
|
+
readonly resetButton: "clip-config-reset-button";
|
|
45
|
+
readonly emptyState: "clip-config-empty-state";
|
|
46
|
+
readonly filterGroup: "clip-config-filter-group";
|
|
47
|
+
readonly filterButton: "clip-config-filter-button";
|
|
48
|
+
readonly voiceCardGrid: "clip-config-voice-grid";
|
|
49
|
+
readonly voiceCard: "clip-config-voice-card";
|
|
50
|
+
readonly voiceCardAvatar: "clip-config-voice-avatar";
|
|
51
|
+
readonly voiceCardMeta: "clip-config-voice-meta";
|
|
52
|
+
readonly voiceCardTitle: "clip-config-voice-title";
|
|
53
|
+
readonly voiceCardSubtitle: "clip-config-voice-subtitle";
|
|
54
|
+
readonly voiceCardCheck: "clip-config-voice-check";
|
|
55
|
+
readonly voiceCheckbox: "clip-config-voice-checkbox";
|
|
56
|
+
readonly primaryButton: "clip-config-primary-button";
|
|
57
|
+
readonly errorText: "clip-config-error-text";
|
|
58
|
+
readonly voiceLoadingOverlay: "clip-config-voice-loading-overlay";
|
|
59
|
+
readonly voiceLoadingCard: "clip-config-voice-loading-card";
|
|
60
|
+
readonly voiceLoadingIcon: "clip-config-voice-loading-icon";
|
|
61
|
+
readonly voiceLoadingText: "clip-config-voice-loading-text";
|
|
62
|
+
};
|
|
22
63
|
export declare class ClipConfigPanel {
|
|
23
|
-
private container;
|
|
24
|
-
private
|
|
25
|
-
private
|
|
26
|
-
private onClipUpdate?;
|
|
64
|
+
private readonly container;
|
|
65
|
+
private readonly theme;
|
|
66
|
+
private readonly renderer;
|
|
67
|
+
private readonly onClipUpdate?;
|
|
68
|
+
private readonly onGenerateVoice?;
|
|
69
|
+
private readonly voiceCatalog;
|
|
27
70
|
private currentClip;
|
|
28
71
|
private activeTab;
|
|
29
|
-
private iconCache;
|
|
30
|
-
private
|
|
31
|
-
private
|
|
32
|
-
private
|
|
33
|
-
private
|
|
34
|
-
private
|
|
35
|
-
private
|
|
36
|
-
private
|
|
37
|
-
private
|
|
38
|
-
private
|
|
39
|
-
private
|
|
40
|
-
private volumeSlider;
|
|
41
|
-
private volumeInput;
|
|
72
|
+
private readonly iconCache;
|
|
73
|
+
private pendingPreferredTab;
|
|
74
|
+
private selectedVoiceId;
|
|
75
|
+
private activeVoiceFilterTag;
|
|
76
|
+
private textDraftContent;
|
|
77
|
+
private followTextUpdates;
|
|
78
|
+
private voiceLoadingBusyCount;
|
|
79
|
+
private isVoiceLoadingOverlayRendered;
|
|
80
|
+
private isVoiceLoadingOverlayExiting;
|
|
81
|
+
private voiceLoadingOverlayHideTimer;
|
|
82
|
+
private voiceErrorMessage;
|
|
42
83
|
constructor(config: ClipConfigPanelConfig);
|
|
43
84
|
setClip(clip: Clip | null): void;
|
|
85
|
+
setPreferredTab(tab: 'voice' | null): void;
|
|
86
|
+
setVoiceGenerationBusy(isBusy: boolean): void;
|
|
44
87
|
destroy(): void;
|
|
45
|
-
private getAvailableTabs;
|
|
46
88
|
private render;
|
|
47
|
-
private
|
|
48
|
-
private
|
|
49
|
-
private
|
|
50
|
-
private
|
|
51
|
-
private
|
|
52
|
-
private
|
|
53
|
-
private
|
|
54
|
-
private
|
|
55
|
-
private
|
|
56
|
-
private
|
|
57
|
-
private
|
|
58
|
-
private
|
|
59
|
-
private calculatePresetPosition;
|
|
60
|
-
private renderScaleControl;
|
|
61
|
-
private renderVolumeControl;
|
|
89
|
+
private getAvailableTabs;
|
|
90
|
+
private resetVoiceState;
|
|
91
|
+
private syncVoiceStateForClip;
|
|
92
|
+
private syncActiveTab;
|
|
93
|
+
private supportsVoicePanel;
|
|
94
|
+
private resolveDefaultVoiceFilterTag;
|
|
95
|
+
private getVisibleVoiceOptions;
|
|
96
|
+
private ensureVoiceFilters;
|
|
97
|
+
private handleVoiceFilterChange;
|
|
98
|
+
private handleVoiceSelect;
|
|
99
|
+
private handleVoiceFollowTextUpdatesChange;
|
|
100
|
+
private handleGenerateVoice;
|
|
62
101
|
private handleVolumeChange;
|
|
63
|
-
private updateVolumeControls;
|
|
64
102
|
private clampValue;
|
|
65
|
-
private updateUIControls;
|
|
66
|
-
private updateSliderAndInput;
|
|
67
|
-
private updateSliderVisual;
|
|
68
103
|
private handleTransformChange;
|
|
69
104
|
private handleTransformChanges;
|
|
105
|
+
private handleTextContentInput;
|
|
106
|
+
private handleTextContentCommit;
|
|
107
|
+
private handleTextStyleChange;
|
|
70
108
|
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { type Clip, type VoiceOption } from '../../core/models';
|
|
3
|
+
import { LitDomRenderer } from '../../core/renderers/domRenderer';
|
|
4
|
+
import type { ClipConfigPanelTheme } from './ClipConfigPanel';
|
|
5
|
+
export type ClipConfigPanelTabKey = 'visual' | 'audio' | 'text' | 'voice';
|
|
6
|
+
export interface ClipConfigPanelCallbacks {
|
|
7
|
+
onTabChange: (tab: ClipConfigPanelTabKey) => void;
|
|
8
|
+
onTransformChange: (property: 'x' | 'y' | 'scale', value: number) => void;
|
|
9
|
+
onPresetSelect: (x: number, y: number) => void;
|
|
10
|
+
onVolumeChange: (value: number) => void;
|
|
11
|
+
onTextContentInput: (value: string) => void;
|
|
12
|
+
onTextContentCommit: () => void;
|
|
13
|
+
onTextStyleChange: (property: 'fontSize' | 'color' | 'rotation' | 'x' | 'y', value: number | string) => void;
|
|
14
|
+
onVoiceFilterChange: (tag: string) => void;
|
|
15
|
+
onVoiceSelect: (voiceId: string) => void;
|
|
16
|
+
onVoiceFollowTextUpdatesChange: (value: boolean) => void;
|
|
17
|
+
onGenerateVoice: () => Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export interface ClipConfigPanelViewModel {
|
|
20
|
+
clip: Clip | null;
|
|
21
|
+
activeTab: ClipConfigPanelTabKey;
|
|
22
|
+
theme: ClipConfigPanelTheme;
|
|
23
|
+
emptyStateIconSvg: string;
|
|
24
|
+
loadingIconSvg: string;
|
|
25
|
+
selectedIconSvg: string;
|
|
26
|
+
textDraftContent: string;
|
|
27
|
+
voiceCatalog: VoiceOption[];
|
|
28
|
+
selectedVoiceId: string | null;
|
|
29
|
+
activeVoiceFilterTag: string | null;
|
|
30
|
+
followTextUpdates: boolean;
|
|
31
|
+
isVoiceLoadingOverlayVisible: boolean;
|
|
32
|
+
isVoiceLoadingOverlayExiting: boolean;
|
|
33
|
+
voiceErrorMessage: string | null;
|
|
34
|
+
callbacks: ClipConfigPanelCallbacks;
|
|
35
|
+
}
|
|
36
|
+
export declare const CLIP_CONFIG_CSS_CLASSES: {
|
|
37
|
+
readonly container: "clip-config-panel";
|
|
38
|
+
readonly tabBar: "clip-config-tab-bar";
|
|
39
|
+
readonly tabButton: "clip-config-tab-button";
|
|
40
|
+
readonly content: "clip-config-content";
|
|
41
|
+
readonly visualPanel: "clip-config-visual-panel";
|
|
42
|
+
readonly audioPanel: "clip-config-audio-panel";
|
|
43
|
+
readonly textPanel: "clip-config-text-panel";
|
|
44
|
+
readonly voicePanel: "clip-config-voice-panel";
|
|
45
|
+
readonly actionBar: "clip-config-action-bar";
|
|
46
|
+
readonly section: "clip-config-section";
|
|
47
|
+
readonly sectionTitle: "clip-config-section-title";
|
|
48
|
+
readonly row: "clip-config-row";
|
|
49
|
+
readonly label: "clip-config-label";
|
|
50
|
+
readonly slider: "clip-config-slider";
|
|
51
|
+
readonly input: "clip-config-input";
|
|
52
|
+
readonly textarea: "clip-config-textarea";
|
|
53
|
+
readonly colorInput: "clip-config-color-input";
|
|
54
|
+
readonly presetGrid: "clip-config-preset-grid";
|
|
55
|
+
readonly presetButton: "clip-config-preset-button";
|
|
56
|
+
readonly resetButton: "clip-config-reset-button";
|
|
57
|
+
readonly emptyState: "clip-config-empty-state";
|
|
58
|
+
readonly filterGroup: "clip-config-filter-group";
|
|
59
|
+
readonly filterButton: "clip-config-filter-button";
|
|
60
|
+
readonly voiceCardGrid: "clip-config-voice-grid";
|
|
61
|
+
readonly voiceCard: "clip-config-voice-card";
|
|
62
|
+
readonly voiceCardAvatar: "clip-config-voice-avatar";
|
|
63
|
+
readonly voiceCardMeta: "clip-config-voice-meta";
|
|
64
|
+
readonly voiceCardTitle: "clip-config-voice-title";
|
|
65
|
+
readonly voiceCardSubtitle: "clip-config-voice-subtitle";
|
|
66
|
+
readonly voiceCardCheck: "clip-config-voice-check";
|
|
67
|
+
readonly voiceCheckbox: "clip-config-voice-checkbox";
|
|
68
|
+
readonly primaryButton: "clip-config-primary-button";
|
|
69
|
+
readonly errorText: "clip-config-error-text";
|
|
70
|
+
readonly voiceLoadingOverlay: "clip-config-voice-loading-overlay";
|
|
71
|
+
readonly voiceLoadingCard: "clip-config-voice-loading-card";
|
|
72
|
+
readonly voiceLoadingIcon: "clip-config-voice-loading-icon";
|
|
73
|
+
readonly voiceLoadingText: "clip-config-voice-loading-text";
|
|
74
|
+
};
|
|
75
|
+
export declare class ClipConfigPanelRenderer extends LitDomRenderer<ClipConfigPanelViewModel> {
|
|
76
|
+
protected renderTemplate(viewModel: ClipConfigPanelViewModel): TemplateResult;
|
|
77
|
+
private renderVoiceLoadingOverlay;
|
|
78
|
+
private renderEmptyState;
|
|
79
|
+
private renderPanel;
|
|
80
|
+
private renderTabBar;
|
|
81
|
+
private renderActionBar;
|
|
82
|
+
private renderVoiceActionBar;
|
|
83
|
+
private renderVisualPanel;
|
|
84
|
+
private renderPositionSection;
|
|
85
|
+
private renderScaleSection;
|
|
86
|
+
private renderAudioPanel;
|
|
87
|
+
private renderTextPanel;
|
|
88
|
+
private renderVoicePanel;
|
|
89
|
+
private renderFilterButton;
|
|
90
|
+
private renderVoiceCard;
|
|
91
|
+
private renderPositionControl;
|
|
92
|
+
private renderPresetGrid;
|
|
93
|
+
private renderSectionTitle;
|
|
94
|
+
private renderRangeInput;
|
|
95
|
+
private renderNumberInput;
|
|
96
|
+
private renderLabeledNumberInput;
|
|
97
|
+
private getContainerStyle;
|
|
98
|
+
private getSliderStyle;
|
|
99
|
+
private getAvailableTabs;
|
|
100
|
+
private supportsVoicePanel;
|
|
101
|
+
private getTransform;
|
|
102
|
+
private calculatePresetPosition;
|
|
103
|
+
private resizeSvg;
|
|
104
|
+
}
|
|
@@ -20,8 +20,9 @@ export declare class TrackInfoPanel {
|
|
|
20
20
|
private width;
|
|
21
21
|
private timeScaleHeight;
|
|
22
22
|
private includeTimeScaleSpacer;
|
|
23
|
-
private
|
|
24
|
-
private
|
|
23
|
+
private scrollTop;
|
|
24
|
+
private readonly renderer;
|
|
25
|
+
private readonly iconCache;
|
|
25
26
|
private onMuteTrack?;
|
|
26
27
|
constructor(config: TrackInfoPanelConfig, _onRenameTrack?: (trackId: string, newName: string) => void, _onDeleteTrack?: (trackId: string) => void, onMuteTrack?: (trackId: string, isMuted: boolean) => void);
|
|
27
28
|
private init;
|
|
@@ -29,6 +30,5 @@ export declare class TrackInfoPanel {
|
|
|
29
30
|
getTracks(): Track[];
|
|
30
31
|
render(): void;
|
|
31
32
|
setScrollTop(scrollTop: number): void;
|
|
32
|
-
private createTrackItem;
|
|
33
33
|
destroy(): void;
|
|
34
34
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { Track } from '../../core/models';
|
|
3
|
+
import { LitDomRenderer } from '../../core/renderers/domRenderer';
|
|
4
|
+
export interface TrackInfoPanelTheme {
|
|
5
|
+
background: string;
|
|
6
|
+
border: string;
|
|
7
|
+
text: string;
|
|
8
|
+
buttonBackground: string;
|
|
9
|
+
buttonHover: string;
|
|
10
|
+
buttonDanger: string;
|
|
11
|
+
}
|
|
12
|
+
export interface TrackInfoPanelViewModel {
|
|
13
|
+
tracks: Track[];
|
|
14
|
+
scrollTop: number;
|
|
15
|
+
theme: TrackInfoPanelTheme;
|
|
16
|
+
timeScaleHeight: number;
|
|
17
|
+
includeTimeScaleSpacer: boolean;
|
|
18
|
+
onMuteTrack?: (trackId: string, isMuted: boolean) => void;
|
|
19
|
+
icons: {
|
|
20
|
+
textTrack: string;
|
|
21
|
+
videoTrack: string;
|
|
22
|
+
audioTrack: string;
|
|
23
|
+
display: string;
|
|
24
|
+
hide: string;
|
|
25
|
+
volume: string;
|
|
26
|
+
volumeMuted: string;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export declare class TrackInfoPanelRenderer extends LitDomRenderer<TrackInfoPanelViewModel> {
|
|
30
|
+
protected renderTemplate(viewModel: TrackInfoPanelViewModel): TemplateResult;
|
|
31
|
+
private renderTrackItem;
|
|
32
|
+
private resizeSvg;
|
|
33
|
+
}
|
|
@@ -99,6 +99,9 @@ export declare class Track {
|
|
|
99
99
|
private readonly handleEdgeAutoScrollFrame;
|
|
100
100
|
private handleTrackBackgroundClick;
|
|
101
101
|
private handleTrackBackgroundMouseDown;
|
|
102
|
+
private getClipDisplayLabel;
|
|
103
|
+
private getClipAudioBadgeText;
|
|
104
|
+
private isSourceBoundClip;
|
|
102
105
|
updateClipSelection(clipId: string, isSelected: boolean): void;
|
|
103
106
|
private createClipGroup;
|
|
104
107
|
private handleClipClick;
|
|
@@ -130,6 +133,7 @@ export declare class Track {
|
|
|
130
133
|
setCurrentTime(_time: TimeMs): void;
|
|
131
134
|
setScrollLeft(scrollLeft: number): void;
|
|
132
135
|
private updateClipVisibility;
|
|
136
|
+
private updateClipViewportState;
|
|
133
137
|
setTrackY(trackY: number): void;
|
|
134
138
|
setTrackStackOrder(order: number): void;
|
|
135
139
|
setDragOverlayLayer(layer: Konva.Layer | null): void;
|
|
@@ -61,6 +61,7 @@ export type TrackPlacementCommandResult = {
|
|
|
61
61
|
status: 'create_track';
|
|
62
62
|
trackType: TrackType;
|
|
63
63
|
suggestedTrackName: string;
|
|
64
|
+
insertionPlacement: TrackInsertionPlacement;
|
|
64
65
|
};
|
|
65
66
|
export type CrossTrackMoveCommandResult = {
|
|
66
67
|
status: 'missing_target_track_by_position';
|
|
@@ -10,6 +10,7 @@ export { TimelinePlaybackResolver } from './timelinePlaybackResolver';
|
|
|
10
10
|
export { TimelinePreviewSession } from './timelinePreviewSession';
|
|
11
11
|
export { TimelinePreviewRuntimeController } from './timelinePreviewRuntimeController';
|
|
12
12
|
export { TimelinePreviewStateController, type TimelinePendingPreviewState } from './timelinePreviewStateController';
|
|
13
|
+
export { TimelineKeyboardShortcutsController, type TimelineKeyboardShortcutsControllerCallbacks } from './timelineKeyboardShortcutsController';
|
|
13
14
|
export * from './timelineSelectionController';
|
|
14
15
|
export * from './timelineTrackMutationController';
|
|
15
16
|
export { TimelineTrackInfoPanelController } from './timelineTrackInfoPanelController';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { ActiveClipPlaybackInfo, Clip, ClipVisualTransform, PlayState, PreviewAspectRatio, PreviewMediaSource, PreviewSourceResolver, TimeMs } from '../models/types';
|
|
1
|
+
import type { ActiveClipPlaybackInfo, Clip, ClipVisualTransform, PlayState, PreviewAspectRatio, PreviewMediaSource, PreviewSourceResolver, TextPreviewFontConfig, TimeMs } from '../models/types';
|
|
2
|
+
import type { SourceMediaRegistry } from '../resources/sourceMediaRegistry';
|
|
2
3
|
export interface TimelinePreviewSyncPayload {
|
|
3
4
|
activeClips: ActiveClipPlaybackInfo[];
|
|
4
5
|
nextClips: ActiveClipPlaybackInfo[];
|
|
@@ -66,6 +67,8 @@ export interface PreviewBackendClockState {
|
|
|
66
67
|
export interface TimelinePreviewBackendOptions {
|
|
67
68
|
callbacks?: TimelinePreviewBackendCallbacks;
|
|
68
69
|
previewSourceResolver?: PreviewSourceResolver;
|
|
70
|
+
textPreviewFont?: TextPreviewFontConfig | null;
|
|
71
|
+
sourceMediaRegistry?: SourceMediaRegistry;
|
|
69
72
|
rootClassName?: string;
|
|
70
73
|
frameClassName?: string;
|
|
71
74
|
slotClassNamePrefix?: string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { PreviewPendingState, PreviewRuntimeState } from './previewBackend';
|
|
2
|
+
import type { DomRenderer } from '../renderers/domRenderer';
|
|
3
|
+
export interface PreviewPendingOverlayViewModel {
|
|
4
|
+
pendingState: PreviewPendingState | null;
|
|
5
|
+
runtimeState: PreviewRuntimeState;
|
|
6
|
+
}
|
|
7
|
+
export declare class PreviewPendingOverlayRenderer implements DomRenderer<PreviewPendingOverlayViewModel> {
|
|
8
|
+
private container;
|
|
9
|
+
private statusElement;
|
|
10
|
+
private detailElement;
|
|
11
|
+
private actionElement;
|
|
12
|
+
private readonly onRetry;
|
|
13
|
+
constructor(onRetry: () => void);
|
|
14
|
+
mount(container: HTMLElement): void;
|
|
15
|
+
update(viewModel: PreviewPendingOverlayViewModel): void;
|
|
16
|
+
destroy(): void;
|
|
17
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { Theme, Clip } from '../models';
|
|
1
|
+
import { Theme, Clip, type VoiceOption } from '../models';
|
|
2
2
|
export interface TimelineClipConfigControllerConfig {
|
|
3
3
|
container: HTMLElement;
|
|
4
4
|
theme: Theme;
|
|
5
5
|
getPrimarySelectedClip: () => Clip | null;
|
|
6
|
+
voiceCatalog: VoiceOption[];
|
|
6
7
|
updateClip: (clipId: string, updates: Partial<Clip>) => void;
|
|
8
|
+
onGenerateVoice?: (clip: Clip, voice: VoiceOption, followTextUpdates: boolean) => Promise<void>;
|
|
7
9
|
}
|
|
8
10
|
export declare class TimelineClipConfigController {
|
|
9
11
|
private panel;
|
|
@@ -13,5 +15,7 @@ export declare class TimelineClipConfigController {
|
|
|
13
15
|
update(): void;
|
|
14
16
|
updateFromExternal(): void;
|
|
15
17
|
destroy(): void;
|
|
18
|
+
setPreferredTab(tab: 'voice' | null): void;
|
|
19
|
+
setVoiceGenerationBusy(isBusy: boolean): void;
|
|
16
20
|
private convertTheme;
|
|
17
21
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Clip, PlayState } from '../models/types';
|
|
2
2
|
export interface ClipMutationEffectHandlers {
|
|
3
3
|
notifySelectionChange: () => void;
|
|
4
|
+
emitSelectionChangeEvent?: () => void;
|
|
4
5
|
emitSelectedClipChangeIfNeeded: () => void;
|
|
5
6
|
handleClipChange: () => void;
|
|
6
7
|
checkTrackDurationChange?: () => void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { TimelineKeyboardShortcutsConfig } from '../models';
|
|
2
|
+
export interface TimelineKeyboardShortcutsControllerCallbacks {
|
|
3
|
+
togglePlay(): void;
|
|
4
|
+
deleteSelectedClips(): void;
|
|
5
|
+
toggleSelectedClipsAudio(): Promise<boolean>;
|
|
6
|
+
splitCurrentClip(): void;
|
|
7
|
+
undo(): boolean;
|
|
8
|
+
redo(): boolean;
|
|
9
|
+
canDeleteSelectedClips(): boolean;
|
|
10
|
+
canSplitSelectedClip(): boolean;
|
|
11
|
+
canToggleSelectedClipsAudio(): boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface TimelineKeyboardShortcutsControllerOptions {
|
|
14
|
+
root: HTMLElement;
|
|
15
|
+
config?: false | TimelineKeyboardShortcutsConfig;
|
|
16
|
+
callbacks: TimelineKeyboardShortcutsControllerCallbacks;
|
|
17
|
+
isMacLike?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare class TimelineKeyboardShortcutsController {
|
|
20
|
+
private readonly callbacks;
|
|
21
|
+
private readonly bindings;
|
|
22
|
+
private readonly enabled;
|
|
23
|
+
private readonly keydownListener;
|
|
24
|
+
constructor(options: TimelineKeyboardShortcutsControllerOptions);
|
|
25
|
+
init(): void;
|
|
26
|
+
destroy(): void;
|
|
27
|
+
private handleKeydown;
|
|
28
|
+
private dispatchAction;
|
|
29
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { ActiveClipPlaybackInfo, ClipVisualTransform, PlayState, PreviewAspectRatio, PreviewSourceResolver, TimeMs, TrackType } from '../models/types';
|
|
1
|
+
import type { ActiveClipPlaybackInfo, ClipVisualTransform, PlayState, PreviewAspectRatio, PreviewSourceResolver, TextPreviewFontConfig, TimeMs, TrackType } from '../models/types';
|
|
2
|
+
import type { SourceMediaRegistry } from '../resources/sourceMediaRegistry';
|
|
2
3
|
import type { PreviewPendingState, PreviewRuntimeState } from './previewBackend';
|
|
3
4
|
interface TimelinePreviewSessionCallbacks {
|
|
4
5
|
onBufferingStateChange?: (isBuffering: boolean) => void;
|
|
@@ -17,6 +18,8 @@ interface TimelinePreviewSessionDependencies {
|
|
|
17
18
|
frameClassName?: string;
|
|
18
19
|
slotClassNamePrefix?: string;
|
|
19
20
|
previewSourceResolver?: PreviewSourceResolver;
|
|
21
|
+
textPreviewFont?: TextPreviewFontConfig | null;
|
|
22
|
+
sourceMediaRegistry?: SourceMediaRegistry;
|
|
20
23
|
}
|
|
21
24
|
export interface TimelinePreviewSyncPayload {
|
|
22
25
|
activeClips: ActiveClipPlaybackInfo[];
|
|
@@ -33,12 +36,12 @@ export declare class TimelinePreviewSession {
|
|
|
33
36
|
private container;
|
|
34
37
|
private rootElement;
|
|
35
38
|
private frameElement;
|
|
39
|
+
private textOverlayRoot;
|
|
36
40
|
private pendingOverlayElement;
|
|
37
|
-
private
|
|
38
|
-
private pendingOverlayDetailElement;
|
|
39
|
-
private pendingOverlayActionElement;
|
|
41
|
+
private readonly pendingOverlayRenderer;
|
|
40
42
|
private resizeObserver;
|
|
41
43
|
private readonly trackSlots;
|
|
44
|
+
private readonly textPreviewEntries;
|
|
42
45
|
private audioContext;
|
|
43
46
|
private masterGainNode;
|
|
44
47
|
private loadingCount;
|
|
@@ -49,9 +52,18 @@ export declare class TimelinePreviewSession {
|
|
|
49
52
|
private lastSettledSyncRequestId;
|
|
50
53
|
private primarySelectedClipId;
|
|
51
54
|
private transientVisualTransform;
|
|
55
|
+
private textPreviewDragState;
|
|
56
|
+
private textPreviewFontStyleElement;
|
|
57
|
+
private textPreviewFontSignature;
|
|
58
|
+
private textPreviewFontLoadState;
|
|
59
|
+
private textPreviewFontLoadToken;
|
|
52
60
|
private readonly callbacks;
|
|
53
61
|
private readonly dependencies;
|
|
54
62
|
private readonly transformOverlay;
|
|
63
|
+
private readonly boundTextPreviewPointerMove;
|
|
64
|
+
private readonly boundTextPreviewPointerUp;
|
|
65
|
+
private readonly boundTextPreviewVisibilityChange;
|
|
66
|
+
private readonly boundTextPreviewWindowBlur;
|
|
55
67
|
private requestedAspectRatio;
|
|
56
68
|
private resolvedAutoAspectRatio;
|
|
57
69
|
private aspectRatioProbe;
|
|
@@ -96,6 +108,7 @@ export declare class TimelinePreviewSession {
|
|
|
96
108
|
private updateFrameLayout;
|
|
97
109
|
private maybeResolveAutoAspectRatio;
|
|
98
110
|
private resolveAspectRatioProbeSource;
|
|
111
|
+
private buildPreviewSourceCacheKey;
|
|
99
112
|
private getAspectRatioProbe;
|
|
100
113
|
private tryResolveAutoAspectRatioFromSlot;
|
|
101
114
|
private handleResolvedAutoAspectRatio;
|
|
@@ -105,9 +118,28 @@ export declare class TimelinePreviewSession {
|
|
|
105
118
|
private refreshPendingOverlay;
|
|
106
119
|
private handlePreviewTransformChange;
|
|
107
120
|
private refreshVisualLayout;
|
|
121
|
+
private syncTextPreviewEntries;
|
|
122
|
+
private clearTextPreviewEntries;
|
|
123
|
+
private removeTextPreviewEntry;
|
|
124
|
+
private applyTextPreviewEntry;
|
|
125
|
+
private refreshTextPreviewLayout;
|
|
126
|
+
private refreshTextPreviewEntries;
|
|
127
|
+
private createTextPreviewPointerDownHandler;
|
|
128
|
+
private bindTextPreviewDocumentListeners;
|
|
129
|
+
private unbindTextPreviewDocumentListeners;
|
|
130
|
+
private handleTextPreviewPointerMove;
|
|
131
|
+
private finishTextPreviewDrag;
|
|
132
|
+
private refreshTextPreviewInteractionState;
|
|
133
|
+
private getTextPreviewFontConfig;
|
|
134
|
+
private getTextPreviewFontFamily;
|
|
135
|
+
private ensureTextPreviewFontReady;
|
|
136
|
+
private resetTextPreviewFontState;
|
|
108
137
|
private refreshSlotVisualLayout;
|
|
109
138
|
private buildSelectedOverlayState;
|
|
110
139
|
private getFrameSize;
|
|
140
|
+
private getDocument;
|
|
141
|
+
private toFrameLocalPoint;
|
|
142
|
+
private getTextPreviewBaselineMetrics;
|
|
111
143
|
private getMediaSize;
|
|
112
144
|
private getEffectiveVisualTransform;
|
|
113
145
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Clip } from '../models/types';
|
|
1
|
+
import type { Clip, SelectedClipAudioAction, SelectionChangeData } from '../models/types';
|
|
2
2
|
export interface SelectedClipSnapshot {
|
|
3
3
|
clip: Clip | null;
|
|
4
4
|
hasSelectedClip: boolean;
|
|
@@ -7,11 +7,17 @@ interface ResolveSelectedClipOptions {
|
|
|
7
7
|
getPrimarySelectedClip: () => Clip | null;
|
|
8
8
|
findFallbackSelectedClip?: () => Clip | null;
|
|
9
9
|
}
|
|
10
|
+
interface ResolveSelectionChangeOptions extends ResolveSelectedClipOptions {
|
|
11
|
+
getSelectedClipIds: () => string[];
|
|
12
|
+
canSplitSelectedClip: () => boolean;
|
|
13
|
+
getSelectedClipAudioAction: () => SelectedClipAudioAction;
|
|
14
|
+
}
|
|
10
15
|
interface EmitSelectedClipChangeOptions {
|
|
11
16
|
lastSelectedClipId: string | null;
|
|
12
17
|
resolveSelectedClip: () => SelectedClipSnapshot;
|
|
13
18
|
emitSelectedClipChange: (payload: SelectedClipSnapshot) => void;
|
|
14
19
|
}
|
|
15
20
|
export declare function resolveSelectedClipSnapshot(options: ResolveSelectedClipOptions): SelectedClipSnapshot;
|
|
21
|
+
export declare function resolveSelectionChangeData(options: ResolveSelectionChangeOptions): SelectionChangeData;
|
|
16
22
|
export declare function emitSelectedClipChangeIfNeeded(options: EmitSelectedClipChangeOptions): string | null;
|
|
17
23
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { MoveClipToTrackCommandResult, RemoveClipCommandResult, TrackPlacementCommandResult } from '../commands/timelineCommands';
|
|
2
|
-
import type { Clip, TrackType } from '../models/types';
|
|
2
|
+
import type { Clip, TrackInsertionPlacement, TrackType } from '../models/types';
|
|
3
3
|
import type { TimelineTrackCollection } from '../tracks/timelineTrackCollection';
|
|
4
4
|
interface CreateTrackHandler {
|
|
5
|
-
(type: TrackType, name?: string): string;
|
|
5
|
+
(type: TrackType, name?: string, insertionPlacement?: TrackInsertionPlacement, referenceTrackId?: string): string;
|
|
6
6
|
}
|
|
7
7
|
interface ApplyClipPlacementOptions {
|
|
8
8
|
clip: Clip;
|