itube-modern-player 0.2.3 → 0.3.1

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/dist/types.d.ts CHANGED
@@ -103,6 +103,11 @@ export interface VideoSource {
103
103
  * "most replayed"). Sparse — only the moments you have data for.
104
104
  */
105
105
  heatmap?: HeatmapPoint[];
106
+ /**
107
+ * Short info lines shown in the "next video" hover preview (and reusable in
108
+ * other previews), e.g. `["2.3K views", "User uploaded"]`. Free text.
109
+ */
110
+ previewMeta?: string[];
106
111
  /** Free-form user data, carried around untouched. */
107
112
  meta?: Record<string, unknown>;
108
113
  }
@@ -164,12 +169,18 @@ export interface AdsOptions {
164
169
  */
165
170
  playOn?: 'every' | 'first';
166
171
  }
167
- /** A consumer-defined entry in the actions dropdown. */
172
+ /** A consumer-defined entry in the actions UI. */
168
173
  export interface CustomAction {
169
174
  id: string;
170
175
  title: string;
171
- /** Icon: image URL or raw `<svg>` markup. Optional. */
176
+ /** Icon: image URL or raw `<svg>` markup. Required when `placement: "bar"`. */
172
177
  icon?: string;
178
+ /**
179
+ * Where the action lives:
180
+ * - `"menu"` (default): an item in the ⋯ dropdown;
181
+ * - `"bar"`: a dedicated icon button in the control bar (tooltip = `title`).
182
+ */
183
+ placement?: 'menu' | 'bar';
173
184
  }
174
185
  export type BuiltinActionId = 'like' | 'dislike' | 'addTo' | 'share' | 'report';
175
186
  /**
@@ -196,6 +207,24 @@ export interface ActionsOptions {
196
207
  /** Extra dropdown entries. Click emits `customaction` with the entry id. */
197
208
  custom?: CustomAction[];
198
209
  }
210
+ /**
211
+ * Where a settings-type control lives:
212
+ * - `"gear"` (default): a section inside the unified ⚙ settings dropdown;
213
+ * - `"bar"`: its own dedicated button in the control bar;
214
+ * - `false`: off. `true` is an alias for `"gear"`.
215
+ */
216
+ export type SettingPlacement = boolean | 'gear' | 'bar';
217
+ /** What the "next video" hover preview shows. `true`/`false` toggle all of it. */
218
+ export interface NextPreviewOptions {
219
+ /** Thumbnail (next source's `poster`). Default true. */
220
+ thumbnail?: boolean;
221
+ /** Title (next source's `title`). Default true. */
222
+ title?: boolean;
223
+ /** Duration badge (next source's `duration`). Default true. */
224
+ duration?: boolean;
225
+ /** Extra info lines from the next source's `previewMeta`. Default true. */
226
+ meta?: boolean;
227
+ }
199
228
  export interface ControlsOptions {
200
229
  play?: boolean;
201
230
  progress?: boolean;
@@ -203,22 +232,43 @@ export interface ControlsOptions {
203
232
  volume?: boolean;
204
233
  fullscreen?: boolean;
205
234
  pip?: boolean;
206
- /** Playback-speed menu (speedometer icon). */
207
- settings?: boolean;
208
- /** Quality menu (gear icon). OFF by default; needs `source.qualities` or an HLS source. */
209
- quality?: boolean;
235
+ /** Playback speed. Default `"gear"` (inside the settings dropdown). */
236
+ speed?: SettingPlacement;
237
+ /** @deprecated alias for `speed`. */
238
+ settings?: SettingPlacement;
239
+ /** Quality. Default `"gear"`; needs `source.qualities` or an HLS source to appear. */
240
+ quality?: SettingPlacement;
210
241
  /** Scene list button — appears when the source has chapters. Default true. */
211
242
  scenes?: boolean;
212
243
  /** Popularity heatmap above the progress bar (needs `source.heatmap` data). Default true. */
213
244
  heatmap?: boolean;
214
- subtitles?: boolean;
245
+ /** Subtitles. Default `"gear"` (inside the settings dropdown). */
246
+ subtitles?: SettingPlacement;
215
247
  /** Skip-back / skip-forward buttons. Pass an object to change the step (seconds). */
216
248
  seekButtons?: boolean | {
217
249
  back?: number;
218
250
  forward?: number;
219
251
  };
252
+ /**
253
+ * Where the prev/seek/play/next cluster lives:
254
+ * - `"overlay"` (default): big buttons centered over the video, on every viewport;
255
+ * - `"bar"`: seek buttons in the bottom control bar (the cluster still appears
256
+ * over the video on mobile). This is the pre-0.3 desktop behaviour.
257
+ */
258
+ seekPlacement?: 'overlay' | 'bar';
220
259
  /** Previous / next / list buttons (only rendered when a playlist is present). */
221
260
  playlist?: boolean;
261
+ /**
262
+ * Hide the "previous" button in the control bar (the bar keeps only "next").
263
+ * Default true. The mobile center cluster still shows prev. Set false to bring
264
+ * the bar prev button back.
265
+ */
266
+ hidePrev?: boolean;
267
+ /**
268
+ * Hover preview of the next playlist item over the "next" button (desktop).
269
+ * Default true when a playlist is present. Pass an object to pick fields.
270
+ */
271
+ nextPreview?: boolean | NextPreviewOptions;
222
272
  /** ms of pointer inactivity before controls fade out during playback. Default 2500. */
223
273
  hideDelay?: number;
224
274
  }
@@ -235,6 +285,15 @@ export interface PlaylistOptions {
235
285
  /** Panel placement: `"sidebar"` (right, default) or `"bottom"` (horizontal strip). */
236
286
  layout?: 'sidebar' | 'bottom';
237
287
  }
288
+ /** Which parts of the default pause-screen overlay to render (all default true). */
289
+ export interface PauseScreenContent {
290
+ /** Video title. */
291
+ title?: boolean;
292
+ /** Video description. */
293
+ description?: boolean;
294
+ /** Sponsor / promo link. */
295
+ sponsor?: boolean;
296
+ }
238
297
  /** Scene (chapter) list panel — timecodes with sprite previews. */
239
298
  export interface ScenesOptions {
240
299
  /** Panel placement. Default `"bottom"`. */
@@ -270,6 +329,8 @@ export interface PlayerLabels {
270
329
  more: string;
271
330
  seekForward: string;
272
331
  seekBack: string;
332
+ /** Short unit appended to the seek-step caption, e.g. the "s" in "+15s". */
333
+ secondsShort: string;
273
334
  live: string;
274
335
  related: string;
275
336
  adLabel: string;
@@ -297,10 +358,13 @@ export interface PlayerOptions {
297
358
  keyboard?: boolean;
298
359
  controls?: ControlsOptions;
299
360
  /**
300
- * Pause-screen "slot". `true` renders the default title/description overlay,
301
- * an element or a factory lets you inject arbitrary markup.
361
+ * Pause-screen "slot":
362
+ * - `true` (default) / `false` show or hide the default title/description overlay;
363
+ * - an `HTMLElement` or factory — inject arbitrary markup;
364
+ * - a `PauseScreenContent` object — default overlay with specific parts hidden
365
+ * (e.g. `{ title: false, description: false }` when the page renders them itself).
302
366
  */
303
- pauseScreen?: boolean | HTMLElement | ((player: unknown) => HTMLElement);
367
+ pauseScreen?: boolean | HTMLElement | ((player: unknown) => HTMLElement) | PauseScreenContent;
304
368
  related?: RelatedOptions;
305
369
  /** Ad configuration: pre/mid/post rolls, skip timer, playlist frequency. */
306
370
  adConfig?: AdsOptions;
@@ -26,6 +26,14 @@ export declare class Controls {
26
26
  private moreWrap;
27
27
  private qualityBtn;
28
28
  private qualityMenu;
29
+ /** Unified ⚙ dropdown holding the settings placed in `"gear"`. */
30
+ private gearBtn;
31
+ private gearMenu;
32
+ /** Which settings live in the gear menu (vs their own bar button / off). */
33
+ private gear;
34
+ /** Next-up hover preview (desktop). */
35
+ private nextPreviewEl;
36
+ private nextPreviewOpts;
29
37
  private scenesBtn;
30
38
  private likeBtn;
31
39
  private dislikeBtn;
@@ -40,8 +48,6 @@ export declare class Controls {
40
48
  private centerPlayBtn;
41
49
  private centerPrevBtn;
42
50
  private centerNextBtn;
43
- /** Controls that live in the center cluster on mobile (not in the bottom bar). */
44
- private static readonly CENTER_KEYS;
45
51
  private collapsibles;
46
52
  private overflowed;
47
53
  private resizeObserver;
@@ -55,6 +61,17 @@ export declare class Controls {
55
61
  private registerCollapsible;
56
62
  /** Center-cluster button — deliberately NOT `.imp-btn` (own sizing/look). */
57
63
  private makeCenterButton;
64
+ /** Caption under the seek arrow showing the signed step, e.g. "−15s" / "+15s". */
65
+ private addStepBadge;
66
+ /** Sections for the gear when overflowed into ⋯ (expanded, no drill-down). */
67
+ private gearSections;
68
+ /** Gear drill-down rows: one per setting, each showing its current value. */
69
+ private gearEntries;
70
+ private toggleGearMenu;
71
+ private setupNextPreview;
72
+ private bindNextPreview;
73
+ private showNextPreview;
74
+ private hideNextPreview;
58
75
  /** like/dislike — visible buttons (collapsible), highlightable via `setLikeState`. */
59
76
  private buildLikeDislike;
60
77
  private attachCountTooltip;
package/dist/ui/menu.d.ts CHANGED
@@ -10,6 +10,15 @@ export interface MenuSection {
10
10
  items: MenuItem[];
11
11
  onSelect(value: string): void;
12
12
  }
13
+ /** One row in the settings (gear) drill-down: label + current value → options. */
14
+ export interface SettingEntry {
15
+ key: string;
16
+ label: string;
17
+ /** Current value shown on the row, e.g. "Auto", "1×", "Off". */
18
+ value: string;
19
+ /** The options panel to drill into when the row is clicked. */
20
+ section(): MenuSection;
21
+ }
13
22
  /**
14
23
  * Popup menu anchored above a control button. One instance per button;
15
24
  * rebuilt from data on every open, closed on outside click / Escape.
@@ -24,6 +33,15 @@ export declare class Menu {
24
33
  get open(): boolean;
25
34
  toggle(sections: MenuSection[]): void;
26
35
  show(sections: MenuSection[]): void;
36
+ /** Settings (gear) drill-down: a root list of rows, each opening its options. */
37
+ toggleSettings(title: string, entries: SettingEntry[]): void;
38
+ showSettings(_title: string, entries: SettingEntry[]): void;
39
+ private renderSettingsRoot;
40
+ private renderSettingsDetail;
41
+ /** Build one option block (radio items) from a section. */
42
+ private renderSection;
43
+ /** Reveal the populated menu + backdrop and arm the outside-click listener. */
44
+ private reveal;
27
45
  close(): void;
28
46
  destroy(): void;
29
47
  }
@@ -29,10 +29,18 @@ export declare class PauseScreen {
29
29
  private sponsorLabel;
30
30
  private sponsorText;
31
31
  private custom;
32
+ /** Which parts the consumer allows (a hidden part stays hidden even with data). */
33
+ private visible;
32
34
  constructor(labels: PlayerLabels);
33
35
  setCustomContent(element: HTMLElement | null): void;
34
36
  /** True while consumer-provided custom content is mounted. */
35
37
  get hasCustom(): boolean;
38
+ /** Hide specific parts of the default overlay (consumer renders them itself). */
39
+ setVisibility(parts: {
40
+ title?: boolean;
41
+ description?: boolean;
42
+ sponsor?: boolean;
43
+ }): void;
36
44
  setSource(source: VideoSource | null): void;
37
45
  show(): void;
38
46
  hide(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "itube-modern-player",
3
- "version": "0.2.3",
3
+ "version": "0.3.1",
4
4
  "description": "Lightweight, framework-agnostic HTML5 video player: HLS streams, playlists, chapters, VTT subtitles, sprite previews, VAST ads. Ships with a Vue 3 wrapper.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -1 +0,0 @@
1
- {"version":3,"file":"labels-C3gAZEm-.js","sources":["../src/core/labels.ts"],"sourcesContent":["import type { PlayerLabels } from '../types'\n\nexport const defaultLabels: PlayerLabels = {\n play: 'Play',\n pause: 'Pause',\n replay: 'Replay',\n mute: 'Mute',\n unmute: 'Unmute',\n fullscreen: 'Fullscreen',\n exitFullscreen: 'Exit fullscreen',\n pip: 'Picture-in-picture',\n settings: 'Playback speed',\n scenes: 'Scenes',\n shuffle: 'Shuffle',\n repeat: 'Repeat',\n subtitles: 'Subtitles',\n subtitlesOff: 'Off',\n speed: 'Speed',\n quality: 'Quality',\n qualityAuto: 'Auto',\n next: 'Next',\n previous: 'Previous',\n playlist: 'Playlist',\n like: 'Like',\n dislike: 'Dislike',\n addTo: 'Save to…',\n share: 'Share',\n report: 'Report',\n more: 'More actions',\n seekForward: 'Seek forward',\n seekBack: 'Seek back',\n live: 'LIVE',\n related: 'More videos',\n adLabel: 'Ad',\n skipAd: 'Skip ad',\n skipAdIn: 'Skip in',\n visitAdvertiser: 'Visit advertiser',\n sponsored: 'Sponsored',\n}\n"],"names":["defaultLabels"],"mappings":"AAEO,MAAMA,IAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,KAAK;AAAA,EACL,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,cAAc;AAAA,EACd,OAAO;AAAA,EACP,SAAS;AAAA,EACT,aAAa;AAAA,EACb,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,WAAW;AACb;"}