@livepeer-frameworks/player-wc 0.1.0

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.
Files changed (141) hide show
  1. package/dist/cjs/components/fw-context-menu.js +17 -0
  2. package/dist/cjs/components/fw-context-menu.js.map +1 -0
  3. package/dist/cjs/components/fw-dev-mode-panel.js +273 -0
  4. package/dist/cjs/components/fw-dev-mode-panel.js.map +1 -0
  5. package/dist/cjs/components/fw-error-overlay.js +101 -0
  6. package/dist/cjs/components/fw-error-overlay.js.map +1 -0
  7. package/dist/cjs/components/fw-idle-screen.js +182 -0
  8. package/dist/cjs/components/fw-idle-screen.js.map +1 -0
  9. package/dist/cjs/components/fw-loading-spinner.js +62 -0
  10. package/dist/cjs/components/fw-loading-spinner.js.map +1 -0
  11. package/dist/cjs/components/fw-player-controls.js +258 -0
  12. package/dist/cjs/components/fw-player-controls.js.map +1 -0
  13. package/dist/cjs/components/fw-player.js +570 -0
  14. package/dist/cjs/components/fw-player.js.map +1 -0
  15. package/dist/cjs/components/fw-seek-bar.js +233 -0
  16. package/dist/cjs/components/fw-seek-bar.js.map +1 -0
  17. package/dist/cjs/components/fw-settings-menu.js +126 -0
  18. package/dist/cjs/components/fw-settings-menu.js.map +1 -0
  19. package/dist/cjs/components/fw-skip-indicator.js +143 -0
  20. package/dist/cjs/components/fw-skip-indicator.js.map +1 -0
  21. package/dist/cjs/components/fw-speed-indicator.js +61 -0
  22. package/dist/cjs/components/fw-speed-indicator.js.map +1 -0
  23. package/dist/cjs/components/fw-stats-panel.js +141 -0
  24. package/dist/cjs/components/fw-stats-panel.js.map +1 -0
  25. package/dist/cjs/components/fw-subtitle-renderer.js +70 -0
  26. package/dist/cjs/components/fw-subtitle-renderer.js.map +1 -0
  27. package/dist/cjs/components/fw-title-overlay.js +72 -0
  28. package/dist/cjs/components/fw-title-overlay.js.map +1 -0
  29. package/dist/cjs/components/fw-toast.js +74 -0
  30. package/dist/cjs/components/fw-toast.js.map +1 -0
  31. package/dist/cjs/components/fw-volume-control.js +140 -0
  32. package/dist/cjs/components/fw-volume-control.js.map +1 -0
  33. package/dist/cjs/controllers/player-controller-host.js +315 -0
  34. package/dist/cjs/controllers/player-controller-host.js.map +1 -0
  35. package/dist/cjs/define.js +45 -0
  36. package/dist/cjs/define.js.map +1 -0
  37. package/dist/cjs/icons/index.js +153 -0
  38. package/dist/cjs/icons/index.js.map +1 -0
  39. package/dist/cjs/index.js +88 -0
  40. package/dist/cjs/index.js.map +1 -0
  41. package/dist/cjs/node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js +33 -0
  42. package/dist/cjs/node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js.map +1 -0
  43. package/dist/cjs/styles/shared-styles.js +1967 -0
  44. package/dist/cjs/styles/shared-styles.js.map +1 -0
  45. package/dist/cjs/styles/utility-styles.js +725 -0
  46. package/dist/cjs/styles/utility-styles.js.map +1 -0
  47. package/dist/esm/components/fw-context-menu.js +17 -0
  48. package/dist/esm/components/fw-context-menu.js.map +1 -0
  49. package/dist/esm/components/fw-dev-mode-panel.js +273 -0
  50. package/dist/esm/components/fw-dev-mode-panel.js.map +1 -0
  51. package/dist/esm/components/fw-error-overlay.js +101 -0
  52. package/dist/esm/components/fw-error-overlay.js.map +1 -0
  53. package/dist/esm/components/fw-idle-screen.js +182 -0
  54. package/dist/esm/components/fw-idle-screen.js.map +1 -0
  55. package/dist/esm/components/fw-loading-spinner.js +62 -0
  56. package/dist/esm/components/fw-loading-spinner.js.map +1 -0
  57. package/dist/esm/components/fw-player-controls.js +258 -0
  58. package/dist/esm/components/fw-player-controls.js.map +1 -0
  59. package/dist/esm/components/fw-player.js +570 -0
  60. package/dist/esm/components/fw-player.js.map +1 -0
  61. package/dist/esm/components/fw-seek-bar.js +233 -0
  62. package/dist/esm/components/fw-seek-bar.js.map +1 -0
  63. package/dist/esm/components/fw-settings-menu.js +126 -0
  64. package/dist/esm/components/fw-settings-menu.js.map +1 -0
  65. package/dist/esm/components/fw-skip-indicator.js +143 -0
  66. package/dist/esm/components/fw-skip-indicator.js.map +1 -0
  67. package/dist/esm/components/fw-speed-indicator.js +61 -0
  68. package/dist/esm/components/fw-speed-indicator.js.map +1 -0
  69. package/dist/esm/components/fw-stats-panel.js +141 -0
  70. package/dist/esm/components/fw-stats-panel.js.map +1 -0
  71. package/dist/esm/components/fw-subtitle-renderer.js +70 -0
  72. package/dist/esm/components/fw-subtitle-renderer.js.map +1 -0
  73. package/dist/esm/components/fw-title-overlay.js +72 -0
  74. package/dist/esm/components/fw-title-overlay.js.map +1 -0
  75. package/dist/esm/components/fw-toast.js +74 -0
  76. package/dist/esm/components/fw-toast.js.map +1 -0
  77. package/dist/esm/components/fw-volume-control.js +140 -0
  78. package/dist/esm/components/fw-volume-control.js.map +1 -0
  79. package/dist/esm/controllers/player-controller-host.js +313 -0
  80. package/dist/esm/controllers/player-controller-host.js.map +1 -0
  81. package/dist/esm/define.js +43 -0
  82. package/dist/esm/define.js.map +1 -0
  83. package/dist/esm/icons/index.js +141 -0
  84. package/dist/esm/icons/index.js.map +1 -0
  85. package/dist/esm/index.js +18 -0
  86. package/dist/esm/index.js.map +1 -0
  87. package/dist/esm/node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js +31 -0
  88. package/dist/esm/node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js.map +1 -0
  89. package/dist/esm/styles/shared-styles.js +1965 -0
  90. package/dist/esm/styles/shared-styles.js.map +1 -0
  91. package/dist/esm/styles/utility-styles.js +723 -0
  92. package/dist/esm/styles/utility-styles.js.map +1 -0
  93. package/dist/fw-player.iife.js +4362 -0
  94. package/dist/fw-player.iife.js.map +1 -0
  95. package/dist/types/components/fw-context-menu.d.ts +15 -0
  96. package/dist/types/components/fw-dev-mode-panel.d.ts +24 -0
  97. package/dist/types/components/fw-error-overlay.d.ts +14 -0
  98. package/dist/types/components/fw-idle-screen.d.ts +13 -0
  99. package/dist/types/components/fw-loading-spinner.d.ts +10 -0
  100. package/dist/types/components/fw-player-controls.d.ts +23 -0
  101. package/dist/types/components/fw-player.d.ts +74 -0
  102. package/dist/types/components/fw-seek-bar.d.ts +33 -0
  103. package/dist/types/components/fw-settings-menu.d.ts +16 -0
  104. package/dist/types/components/fw-skip-indicator.d.ts +18 -0
  105. package/dist/types/components/fw-speed-indicator.d.ts +11 -0
  106. package/dist/types/components/fw-stats-panel.d.ts +18 -0
  107. package/dist/types/components/fw-subtitle-renderer.d.ts +21 -0
  108. package/dist/types/components/fw-title-overlay.d.ts +12 -0
  109. package/dist/types/components/fw-toast.d.ts +12 -0
  110. package/dist/types/components/fw-volume-control.d.ts +18 -0
  111. package/dist/types/controllers/player-controller-host.d.ts +119 -0
  112. package/dist/types/define.d.ts +1 -0
  113. package/dist/types/icons/index.d.ts +23 -0
  114. package/dist/types/iife-entry.d.ts +11 -0
  115. package/dist/types/index.d.ts +25 -0
  116. package/dist/types/styles/shared-styles.d.ts +1 -0
  117. package/dist/types/styles/utility-styles.d.ts +1 -0
  118. package/package.json +65 -0
  119. package/src/components/fw-context-menu.ts +23 -0
  120. package/src/components/fw-dev-mode-panel.ts +285 -0
  121. package/src/components/fw-error-overlay.ts +96 -0
  122. package/src/components/fw-idle-screen.ts +182 -0
  123. package/src/components/fw-loading-spinner.ts +63 -0
  124. package/src/components/fw-player-controls.ts +256 -0
  125. package/src/components/fw-player.ts +557 -0
  126. package/src/components/fw-seek-bar.ts +219 -0
  127. package/src/components/fw-settings-menu.ts +128 -0
  128. package/src/components/fw-skip-indicator.ts +139 -0
  129. package/src/components/fw-speed-indicator.ts +57 -0
  130. package/src/components/fw-stats-panel.ts +154 -0
  131. package/src/components/fw-subtitle-renderer.ts +65 -0
  132. package/src/components/fw-title-overlay.ts +64 -0
  133. package/src/components/fw-toast.ts +70 -0
  134. package/src/components/fw-volume-control.ts +140 -0
  135. package/src/controllers/player-controller-host.ts +457 -0
  136. package/src/define.ts +43 -0
  137. package/src/icons/index.ts +209 -0
  138. package/src/iife-entry.ts +11 -0
  139. package/src/index.ts +31 -0
  140. package/src/styles/shared-styles.ts +1962 -0
  141. package/src/styles/utility-styles.ts +720 -0
@@ -0,0 +1,256 @@
1
+ /**
2
+ * <fw-player-controls> — Control bar with play/pause, seek, volume, quality, fullscreen.
3
+ * Port of PlayerControls.tsx from player-react.
4
+ */
5
+ import { LitElement, html, css, nothing } from "lit";
6
+ import { customElement, property, state } from "lit/decorators.js";
7
+ import { classMap } from "lit/directives/class-map.js";
8
+ import { sharedStyles } from "../styles/shared-styles.js";
9
+ import { utilityStyles } from "../styles/utility-styles.js";
10
+ import {
11
+ playIcon,
12
+ pauseIcon,
13
+ fullscreenIcon,
14
+ fullscreenExitIcon,
15
+ settingsIcon,
16
+ seekToLiveIcon,
17
+ } from "../icons/index.js";
18
+ import type { PlayerControllerHost } from "../controllers/player-controller-host.js";
19
+ import type { PlaybackMode } from "@livepeer-frameworks/player-core";
20
+
21
+ @customElement("fw-player-controls")
22
+ export class FwPlayerControls extends LitElement {
23
+ @property({ attribute: false }) pc!: PlayerControllerHost;
24
+ @property({ type: String }) playbackMode: PlaybackMode = "auto";
25
+ @property({ type: Boolean, attribute: "is-content-live" }) isContentLive = false;
26
+ @property({ type: Boolean, attribute: "is-stats-open" }) isStatsOpen = false;
27
+
28
+ @state() private _settingsOpen = false;
29
+
30
+ static styles = [
31
+ sharedStyles,
32
+ utilityStyles,
33
+ css`
34
+ :host {
35
+ display: contents;
36
+ }
37
+ .controls-wrapper {
38
+ position: absolute;
39
+ bottom: 0;
40
+ left: 0;
41
+ right: 0;
42
+ z-index: 20;
43
+ background: linear-gradient(to top, rgb(0 0 0 / 0.7), transparent);
44
+ padding: 2rem 0.75rem 0.5rem;
45
+ opacity: 0;
46
+ transition: opacity 200ms ease;
47
+ pointer-events: none;
48
+ }
49
+ .controls-wrapper--visible {
50
+ opacity: 1;
51
+ pointer-events: auto;
52
+ }
53
+ .bar {
54
+ display: flex;
55
+ flex-direction: column;
56
+ gap: 0.25rem;
57
+ }
58
+ .row {
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: space-between;
62
+ gap: 0.25rem;
63
+ }
64
+ .group {
65
+ display: flex;
66
+ align-items: center;
67
+ gap: 0.125rem;
68
+ }
69
+ .btn {
70
+ display: flex;
71
+ align-items: center;
72
+ justify-content: center;
73
+ width: 2rem;
74
+ height: 2rem;
75
+ background: none;
76
+ border: none;
77
+ color: rgb(255 255 255 / 0.8);
78
+ cursor: pointer;
79
+ padding: 0;
80
+ border-radius: 0.25rem;
81
+ transition: color 150ms;
82
+ }
83
+ .btn:hover {
84
+ color: white;
85
+ }
86
+ .btn:disabled {
87
+ opacity: 0.4;
88
+ cursor: not-allowed;
89
+ }
90
+ .time {
91
+ font-size: 0.6875rem;
92
+ color: rgb(255 255 255 / 0.7);
93
+ font-variant-numeric: tabular-nums;
94
+ padding: 0 0.375rem;
95
+ white-space: nowrap;
96
+ }
97
+ .live-badge {
98
+ display: inline-flex;
99
+ align-items: center;
100
+ gap: 0.375rem;
101
+ padding: 0.125rem 0.5rem;
102
+ border-radius: 0.25rem;
103
+ font-size: 0.6875rem;
104
+ font-weight: 600;
105
+ text-transform: uppercase;
106
+ letter-spacing: 0.025em;
107
+ cursor: pointer;
108
+ border: none;
109
+ background: none;
110
+ transition: color 150ms;
111
+ }
112
+ .live-badge--active {
113
+ color: hsl(var(--tn-red, 348 74% 64%));
114
+ }
115
+ .live-badge--behind {
116
+ color: rgb(255 255 255 / 0.5);
117
+ }
118
+ .live-dot {
119
+ width: 6px;
120
+ height: 6px;
121
+ border-radius: 50%;
122
+ background: currentColor;
123
+ }
124
+ .settings-anchor {
125
+ position: relative;
126
+ }
127
+ `,
128
+ ];
129
+
130
+ private _formatTime(seconds: number): string {
131
+ if (!isFinite(seconds) || isNaN(seconds)) return "0:00";
132
+ const abs = Math.abs(Math.floor(seconds));
133
+ const h = Math.floor(abs / 3600);
134
+ const m = Math.floor((abs % 3600) / 60);
135
+ const s = abs % 60;
136
+ if (h > 0) return `${h}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
137
+ return `${m}:${String(s).padStart(2, "0")}`;
138
+ }
139
+
140
+ private get _isNearLive(): boolean {
141
+ if (!this.isContentLive) return false;
142
+ const { currentTime, duration } = this.pc.s;
143
+ if (!isFinite(duration) || duration <= 0) return true;
144
+ return duration - currentTime < 10;
145
+ }
146
+
147
+ protected render() {
148
+ const s = this.pc.s;
149
+ const disabled = !s.videoElement;
150
+
151
+ return html`
152
+ <div
153
+ class=${classMap({
154
+ "controls-wrapper": true,
155
+ "controls-wrapper--visible": s.shouldShowControls,
156
+ "fw-controls-wrapper": true,
157
+ })}
158
+ >
159
+ <div class="bar fw-control-bar">
160
+ <!-- Seek bar -->
161
+ <fw-seek-bar
162
+ .currentTime=${s.currentTime}
163
+ .duration=${s.duration}
164
+ .disabled=${disabled}
165
+ .isLive=${this.isContentLive}
166
+ @fw-seek=${(e: CustomEvent) => this.pc.seek(e.detail.time)}
167
+ ></fw-seek-bar>
168
+
169
+ <!-- Button row -->
170
+ <div class="row">
171
+ <div class="group fw-control-group">
172
+ <!-- Play/Pause -->
173
+ <button
174
+ class="btn fw-btn-flush"
175
+ type="button"
176
+ ?disabled=${disabled}
177
+ @click=${() => this.pc.togglePlay()}
178
+ aria-label="${s.isPlaying ? "Pause" : "Play"}"
179
+ >
180
+ ${s.isPlaying ? pauseIcon(18) : playIcon(18)}
181
+ </button>
182
+
183
+ <!-- Volume -->
184
+ <fw-volume-control .pc=${this.pc}></fw-volume-control>
185
+
186
+ <!-- Time display -->
187
+ ${!this.isContentLive
188
+ ? html`
189
+ <span class="time fw-time-display">
190
+ ${this._formatTime(s.currentTime)} / ${this._formatTime(s.duration)}
191
+ </span>
192
+ `
193
+ : nothing}
194
+
195
+ <!-- Live badge -->
196
+ ${this.isContentLive
197
+ ? html`
198
+ <button
199
+ class=${classMap({
200
+ "live-badge": true,
201
+ "fw-live-badge": true,
202
+ "live-badge--active": this._isNearLive,
203
+ "fw-live-badge--active": this._isNearLive,
204
+ "live-badge--behind": !this._isNearLive,
205
+ "fw-live-badge--behind": !this._isNearLive,
206
+ })}
207
+ type="button"
208
+ @click=${() => this.pc.jumpToLive()}
209
+ aria-label="Jump to live"
210
+ >
211
+ <span class="live-dot"></span>
212
+ LIVE
213
+ </button>
214
+ `
215
+ : nothing}
216
+ </div>
217
+
218
+ <div class="group fw-control-group">
219
+ <!-- Settings -->
220
+ <div class="settings-anchor">
221
+ <button
222
+ class="btn fw-btn-flush"
223
+ type="button"
224
+ @click=${() => {
225
+ this._settingsOpen = !this._settingsOpen;
226
+ }}
227
+ aria-label="Settings"
228
+ >
229
+ ${settingsIcon(16)}
230
+ </button>
231
+ <fw-settings-menu .pc=${this.pc} .open=${this._settingsOpen}></fw-settings-menu>
232
+ </div>
233
+
234
+ <!-- Fullscreen -->
235
+ <button
236
+ class="btn fw-btn-flush"
237
+ type="button"
238
+ ?disabled=${disabled}
239
+ @click=${() => this.pc.toggleFullscreen()}
240
+ aria-label="${s.isFullscreen ? "Exit fullscreen" : "Fullscreen"}"
241
+ >
242
+ ${s.isFullscreen ? fullscreenExitIcon(16) : fullscreenIcon(16)}
243
+ </button>
244
+ </div>
245
+ </div>
246
+ </div>
247
+ </div>
248
+ `;
249
+ }
250
+ }
251
+
252
+ declare global {
253
+ interface HTMLElementTagNameMap {
254
+ "fw-player-controls": FwPlayerControls;
255
+ }
256
+ }