@twick/video-editor 0.15.22 → 0.15.23

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.
@@ -0,0 +1,77 @@
1
+ import { MediaItem } from './types';
2
+
3
+ export type MediaType = "video" | "audio" | "image";
4
+ export interface Paginated<T> {
5
+ items: T[];
6
+ page: number;
7
+ pageSize: number;
8
+ total: number;
9
+ }
10
+ export interface AssetListParams {
11
+ source: "user" | "public";
12
+ type?: MediaType;
13
+ query?: string;
14
+ page?: number;
15
+ pageSize?: number;
16
+ /** Optional concrete provider id for public assets (e.g. 'pexels'). */
17
+ provider?: string;
18
+ }
19
+ export interface AssetProviderConfig {
20
+ /** Stable provider id (e.g. 'pexels', 'unsplash', 'pixabay', 'twick-stock'). */
21
+ id: string;
22
+ /** Human readable label for UI (e.g. 'Pexels'). */
23
+ label: string;
24
+ /** Media types this provider can return. */
25
+ supportedTypes: MediaType[] | "all";
26
+ /** Whether this provider is currently enabled for the active tenant/deployment. */
27
+ enabled: boolean;
28
+ /** Optional URL to provider terms of use or attribution guidelines. */
29
+ termsUrl?: string;
30
+ /** Optional URL to provider logo/icon for UI. */
31
+ iconUrl?: string;
32
+ /** Optional rate-limit or quota hint for UX messaging. */
33
+ quotaHint?: string;
34
+ }
35
+ /**
36
+ * High-level asset library abstraction used by @twick/video-editor and
37
+ * @twick/studio. Implementations may back this with:
38
+ *
39
+ * - Local IndexedDB (BrowserMediaManager)
40
+ * - Twick Cloud asset services
41
+ * - Host application backends (Next.js / Node / serverless)
42
+ *
43
+ * The interface is intentionally minimal and provider-agnostic so that
44
+ * Studio and the editor do not need to know about individual vendors
45
+ * like Pexels or Unsplash.
46
+ */
47
+ export interface AssetLibrary {
48
+ /**
49
+ * List or search assets from the unified library.
50
+ * - For source='user', this should return user-owned assets.
51
+ * - For source='public', this should fan out to one or more public providers.
52
+ */
53
+ listAssets(params: AssetListParams): Promise<Paginated<MediaItem>>;
54
+ /** Fetch a single asset by id, regardless of source. */
55
+ getAsset(id: string): Promise<MediaItem | null>;
56
+ /**
57
+ * Upload a new user asset.
58
+ * Implementations are free to use browser uploads, presigned URLs, or
59
+ * any other storage strategy; the resulting MediaItem must be fully
60
+ * usable by the editor (url + type).
61
+ */
62
+ uploadAsset(file: File, options?: {
63
+ type?: MediaType;
64
+ /**
65
+ * Optional metadata the caller wants to persist (e.g. user-provided
66
+ * tags or attribution notes).
67
+ */
68
+ metadata?: Record<string, unknown>;
69
+ }): Promise<MediaItem>;
70
+ /** Delete a user asset. Public/provider assets are read-only. */
71
+ deleteAsset(id: string): Promise<void>;
72
+ /**
73
+ * Discover which public providers are available in the current
74
+ * environment (and their capabilities).
75
+ */
76
+ listPublicProviders(): Promise<AssetProviderConfig[]>;
77
+ }
@@ -23,19 +23,96 @@ export interface TextEffect {
23
23
  bufferTime?: number;
24
24
  getSample?: () => string;
25
25
  }
26
+ export type MediaSource = "user" | "public";
27
+ export type MediaOrigin = "upload" | "pexels" | "unsplash" | "pixabay" | "custom" | string;
28
+ /**
29
+ * Generic media entity used by the editor and Studio.
30
+ *
31
+ * This shape is intentionally provider-agnostic and can represent:
32
+ * - User-uploaded assets (local or cloud-backed)
33
+ * - Public/provider assets (Pexels, Unsplash, internal stock, etc.)
34
+ *
35
+ * NOTE:
36
+ * - Existing consumers can continue to treat this as a simple MediaItem
37
+ * (id, type, url, thumbnail, duration, etc.).
38
+ * - New fields (source/origin/provider/attribution) enable richer asset
39
+ * library experiences without breaking backwards compatibility.
40
+ */
26
41
  export interface MediaItem {
42
+ /** Stable internal id for this asset within the host app/library. */
27
43
  id: string;
44
+ /** Human-readable name (file name, provider title, etc.). */
28
45
  name: string;
46
+ /** Logical media type (video, audio, image, etc.). */
29
47
  type: string;
48
+ /**
49
+ * Primary URL used by canvas/visualizer and exports.
50
+ * This may point to user storage, CDN, or a third-party provider.
51
+ */
30
52
  url: string;
53
+ /**
54
+ * Optional preview image URL (thumbnail or poster frame).
55
+ * Prefer using this over the full asset for grid/list views.
56
+ */
57
+ previewUrl?: string;
58
+ /**
59
+ * Backwards-compatible thumbnail alias for previewUrl.
60
+ */
31
61
  thumbnail?: string;
62
+ /**
63
+ * Optional URL to a precomputed audio waveform or spectrogram.
64
+ */
65
+ waveformUrl?: string;
66
+ /** Duration in milliseconds for audio/video assets (if known). */
32
67
  duration?: number;
68
+ /** Pixel dimensions for image/video assets (if known). */
33
69
  width?: number;
34
70
  height?: number;
71
+ /** Approximate size of the original asset in bytes (if known). */
72
+ sizeBytes?: number;
73
+ /**
74
+ * High-level source category: user-owned vs public/provider.
75
+ * Undefined for legacy items defaults to user-owned semantics.
76
+ */
77
+ source?: MediaSource;
78
+ /**
79
+ * Origin of the asset (upload, pexels, unsplash, etc.).
80
+ * Useful for analytics and provider-specific policies.
81
+ */
82
+ origin?: MediaOrigin;
83
+ /**
84
+ * Provider metadata (for public assets).
85
+ * - provider: canonical provider id ('pexels', 'unsplash', ...)
86
+ * - providerId: provider-specific asset id
87
+ * - providerUrl: link back to the provider's detail page
88
+ */
89
+ provider?: string;
90
+ providerId?: string;
91
+ providerUrl?: string;
92
+ /**
93
+ * Attribution and licensing hints for public assets.
94
+ * The host app can surface this in UI or export flows.
95
+ */
96
+ attribution?: {
97
+ text?: string;
98
+ author?: string;
99
+ authorUrl?: string;
100
+ licenseUrl?: string;
101
+ };
102
+ /** Free-form tags for search and filtering. */
103
+ tags?: string[];
104
+ /**
105
+ * Arbitrary structured metadata.
106
+ * Consumers should namespace their keys to avoid collisions.
107
+ */
35
108
  metadata?: {
36
109
  title?: string;
37
110
  [key: string]: any;
38
111
  };
112
+ /**
113
+ * Optional serialized binary representation for local-only storage
114
+ * (e.g. IndexedDB via BrowserMediaManager).
115
+ */
39
116
  arrayBuffer?: ArrayBuffer;
40
117
  }
41
118
  export interface PaginationOptions {
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ import { usePlayerControl } from './hooks/use-player-control';
5
5
  import { useEditorManager } from './hooks/use-editor-manager';
6
6
  import { default as BrowserMediaManager } from './helpers/media-manager/browser-media-manager';
7
7
  import { MediaItem, PaginationOptions, SearchOptions, Animation, TextEffect, ElementColors, CanvasConfig } from './helpers/types';
8
+ import { AssetLibrary, AssetListParams, AssetProviderConfig, Paginated as AssetPaginated } from './helpers/asset-library';
8
9
  import { default as BaseMediaManager } from './helpers/media-manager/base-media-manager';
9
10
  import { animationGifs, getAnimationGif } from './assets';
10
11
  import { ANIMATIONS } from './helpers/animation-manager';
@@ -13,7 +14,7 @@ import { default as useTimelineControl } from './hooks/use-timeline-control';
13
14
  import { setElementColors } from './helpers/editor.utils';
14
15
 
15
16
  export { setElementColors };
16
- export type { MediaItem, PaginationOptions, SearchOptions, Animation, TextEffect, ElementColors };
17
+ export type { MediaItem, PaginationOptions, SearchOptions, Animation, TextEffect, ElementColors, AssetLibrary, AssetListParams, AssetProviderConfig, AssetPaginated, };
17
18
  export type { PlayerControlsProps, VideoEditorProps, VideoEditorConfig, TimelineTickConfig, TimelineZoomConfig, CanvasConfig };
18
19
  export { throttle, debounce } from './helpers/function.utils';
19
20
  export { ANIMATIONS, TEXT_EFFECTS };
package/dist/index.js CHANGED
@@ -9352,7 +9352,8 @@ const usePlayerManager = ({
9352
9352
  setSelectedItem,
9353
9353
  editor,
9354
9354
  changeLog,
9355
- videoResolution
9355
+ videoResolution,
9356
+ selectedIds
9356
9357
  } = timeline.useTimelineContext();
9357
9358
  const { getCurrentTime, setSeekTime } = livePlayer.useLivePlayerContext();
9358
9359
  const currentChangeLog = React.useRef(changeLog);
@@ -9508,8 +9509,23 @@ const usePlayerManager = ({
9508
9509
  captionProps,
9509
9510
  cleanAndAdd: true,
9510
9511
  lockAspectRatio: canvasConfig == null ? void 0 : canvasConfig.lockAspectRatio
9512
+ }).then(() => {
9513
+ currentChangeLog.current = changeLog;
9514
+ if (twickCanvas && selectedIds.size > 0) {
9515
+ const primaryId = [...selectedIds][0];
9516
+ const objects = twickCanvas.getObjects();
9517
+ const activeObject = objects.find(
9518
+ (obj) => {
9519
+ var _a2;
9520
+ return ((_a2 = obj == null ? void 0 : obj.get) == null ? void 0 : _a2.call(obj, "id")) === primaryId;
9521
+ }
9522
+ );
9523
+ if (activeObject && twickCanvas.getActiveObject() !== activeObject) {
9524
+ twickCanvas.setActiveObject(activeObject);
9525
+ twickCanvas.requestRenderAll();
9526
+ }
9527
+ }
9511
9528
  });
9512
- currentChangeLog.current = changeLog;
9513
9529
  };
9514
9530
  updateCanvasRef.current = updateCanvas;
9515
9531
  const onPlayerUpdate = (event) => {