@livepeer-frameworks/player-svelte 0.1.2 → 0.2.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/LICENSE.md +24 -0
- package/README.md +6 -2
- package/dist/DevModePanel.svelte +53 -16
- package/dist/IdleScreen.svelte +36 -28
- package/dist/LoadingScreen.svelte +107 -67
- package/dist/LoadingScreen.svelte.bak +702 -0
- package/dist/Player.svelte +200 -53
- package/dist/Player.svelte.d.ts +6 -1
- package/dist/PlayerControls.svelte +114 -32
- package/dist/PlayerControls.svelte.d.ts +3 -0
- package/dist/StreamStateOverlay.svelte +33 -21
- package/dist/SubtitleRenderer.svelte +2 -2
- package/dist/controls/FullscreenButton.svelte +26 -0
- package/dist/controls/FullscreenButton.svelte.d.ts +3 -0
- package/dist/controls/LiveBadge.svelte +23 -0
- package/dist/controls/LiveBadge.svelte.d.ts +3 -0
- package/dist/controls/PlayButton.svelte +26 -0
- package/dist/controls/PlayButton.svelte.d.ts +3 -0
- package/dist/controls/SettingsMenu.svelte +208 -0
- package/dist/controls/SettingsMenu.svelte.d.ts +28 -0
- package/dist/controls/SkipButton.svelte +33 -0
- package/dist/controls/SkipButton.svelte.d.ts +7 -0
- package/dist/controls/TimeDisplay.svelte +18 -0
- package/dist/controls/TimeDisplay.svelte.d.ts +3 -0
- package/dist/controls/VolumeControl.svelte +26 -0
- package/dist/controls/VolumeControl.svelte.d.ts +3 -0
- package/dist/controls/index.d.ts +7 -0
- package/dist/controls/index.js +7 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -1
- package/dist/stores/i18n.d.ts +3 -0
- package/dist/stores/i18n.js +4 -0
- package/dist/stores/index.d.ts +1 -0
- package/dist/stores/index.js +2 -0
- package/dist/stores/playerController.d.ts +2 -0
- package/dist/stores/playerController.js +4 -0
- package/package.json +19 -19
- package/src/DevModePanel.svelte +53 -16
- package/src/IdleScreen.svelte +12 -4
- package/src/LoadingScreen.svelte +90 -50
- package/src/LoadingScreen.svelte.bak +702 -0
- package/src/Player.svelte +200 -53
- package/src/PlayerControls.svelte +114 -32
- package/src/StreamStateOverlay.svelte +17 -5
- package/src/controls/FullscreenButton.svelte +26 -0
- package/src/controls/LiveBadge.svelte +23 -0
- package/src/controls/PlayButton.svelte +26 -0
- package/src/controls/SettingsMenu.svelte +208 -0
- package/src/controls/SkipButton.svelte +33 -0
- package/src/controls/TimeDisplay.svelte +18 -0
- package/src/controls/VolumeControl.svelte +26 -0
- package/src/controls/index.ts +7 -0
- package/src/index.ts +10 -0
- package/src/stores/i18n.ts +7 -0
- package/src/stores/index.ts +3 -0
- package/src/stores/playerController.ts +7 -0
package/dist/Player.svelte
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Thin wrapper over PlayerController from @livepeer-frameworks/player-core
|
|
4
4
|
-->
|
|
5
5
|
<script lang="ts">
|
|
6
|
-
import { onMount } from "svelte";
|
|
6
|
+
import { onMount, setContext, type Snippet } from "svelte";
|
|
7
7
|
import IdleScreen from "./IdleScreen.svelte";
|
|
8
8
|
import SubtitleRenderer from "./SubtitleRenderer.svelte";
|
|
9
9
|
import PlayerControls from "./PlayerControls.svelte";
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
import { StatsIcon, SettingsIcon, PictureInPictureIcon } from "./icons";
|
|
24
24
|
import {
|
|
25
25
|
cn,
|
|
26
|
+
themeOverridesToStyle,
|
|
27
|
+
resolveTheme,
|
|
26
28
|
type PlaybackMode,
|
|
27
29
|
type ContentEndpoints,
|
|
28
30
|
type PlayerState,
|
|
@@ -30,11 +32,15 @@
|
|
|
30
32
|
type ContentType,
|
|
31
33
|
type EndpointInfo,
|
|
32
34
|
type PlayerMetadata,
|
|
35
|
+
type FwThemePreset,
|
|
36
|
+
type FwThemeOverrides,
|
|
37
|
+
type FwLocale,
|
|
33
38
|
} from "@livepeer-frameworks/player-core";
|
|
34
39
|
import {
|
|
35
40
|
createPlayerControllerStore,
|
|
36
41
|
type PlayerControllerStore,
|
|
37
42
|
} from "./stores/playerController";
|
|
43
|
+
import { localeStore, translatorStore } from "./stores/i18n";
|
|
38
44
|
import type { SkipDirection } from "./SkipIndicator.svelte";
|
|
39
45
|
|
|
40
46
|
// Props - aligned with React Player
|
|
@@ -57,9 +63,13 @@
|
|
|
57
63
|
forceType?: string;
|
|
58
64
|
forceSource?: number;
|
|
59
65
|
playbackMode?: PlaybackMode;
|
|
66
|
+
theme?: FwThemePreset;
|
|
67
|
+
themeOverrides?: FwThemeOverrides;
|
|
68
|
+
locale?: FwLocale;
|
|
60
69
|
};
|
|
61
70
|
onStateChange?: (state: PlayerState, context?: PlayerStateContext) => void;
|
|
62
71
|
onMetadata?: (metadata: PlayerMetadata) => void;
|
|
72
|
+
children?: Snippet;
|
|
63
73
|
}
|
|
64
74
|
|
|
65
75
|
let {
|
|
@@ -70,6 +80,7 @@
|
|
|
70
80
|
options = {},
|
|
71
81
|
onStateChange = undefined,
|
|
72
82
|
onMetadata = undefined,
|
|
83
|
+
children = undefined,
|
|
73
84
|
}: Props = $props();
|
|
74
85
|
|
|
75
86
|
// ============================================================================
|
|
@@ -79,6 +90,64 @@
|
|
|
79
90
|
let isDevPanelOpen = $state(false);
|
|
80
91
|
let skipDirection: SkipDirection = $state(null);
|
|
81
92
|
|
|
93
|
+
let activeTheme = $state<FwThemePreset>(options?.theme ?? "default");
|
|
94
|
+
let activeLocale = $state<FwLocale>(options?.locale ?? "en");
|
|
95
|
+
|
|
96
|
+
// Sync locale state to i18n store and provide translator context
|
|
97
|
+
$effect(() => {
|
|
98
|
+
localeStore.set(activeLocale);
|
|
99
|
+
});
|
|
100
|
+
setContext("fw-translator", translatorStore);
|
|
101
|
+
|
|
102
|
+
// Provide context for composable controls (reactive getters)
|
|
103
|
+
setContext("fw-player-controller", {
|
|
104
|
+
get isPlaying() {
|
|
105
|
+
return storeState.isPlaying;
|
|
106
|
+
},
|
|
107
|
+
get isPaused() {
|
|
108
|
+
return storeState.isPaused;
|
|
109
|
+
},
|
|
110
|
+
get isMuted() {
|
|
111
|
+
return storeState.isMuted;
|
|
112
|
+
},
|
|
113
|
+
get volume() {
|
|
114
|
+
return storeState.volume;
|
|
115
|
+
},
|
|
116
|
+
get currentTime() {
|
|
117
|
+
return storeState.currentTime;
|
|
118
|
+
},
|
|
119
|
+
get duration() {
|
|
120
|
+
return storeState.duration;
|
|
121
|
+
},
|
|
122
|
+
get isFullscreen() {
|
|
123
|
+
return storeState.isFullscreen;
|
|
124
|
+
},
|
|
125
|
+
get isEffectivelyLive() {
|
|
126
|
+
return storeState.isEffectivelyLive;
|
|
127
|
+
},
|
|
128
|
+
get isBuffering() {
|
|
129
|
+
return storeState.isBuffering;
|
|
130
|
+
},
|
|
131
|
+
get isLoopEnabled() {
|
|
132
|
+
return storeState.isLoopEnabled;
|
|
133
|
+
},
|
|
134
|
+
get error() {
|
|
135
|
+
return storeState.error;
|
|
136
|
+
},
|
|
137
|
+
get qualities() {
|
|
138
|
+
return playerStore?.getQualities() ?? [];
|
|
139
|
+
},
|
|
140
|
+
togglePlay: () => playerStore?.togglePlay(),
|
|
141
|
+
toggleMute: () => playerStore?.toggleMute(),
|
|
142
|
+
toggleFullscreen: () => playerStore?.toggleFullscreen(),
|
|
143
|
+
toggleLoop: () => playerStore?.toggleLoop(),
|
|
144
|
+
setVolume: (v: number) => playerStore?.setVolume(v),
|
|
145
|
+
jumpToLive: () => playerStore?.jumpToLive(),
|
|
146
|
+
seek: (t: number) => playerStore?.seek(t),
|
|
147
|
+
selectQuality: (id: string) => playerStore?.selectQuality(id),
|
|
148
|
+
getQualities: () => playerStore?.getQualities() ?? [],
|
|
149
|
+
});
|
|
150
|
+
|
|
82
151
|
// Playback mode preference (persistent)
|
|
83
152
|
let devPlaybackMode: PlaybackMode = $state("auto");
|
|
84
153
|
$effect(() => {
|
|
@@ -87,6 +156,33 @@
|
|
|
87
156
|
}
|
|
88
157
|
});
|
|
89
158
|
|
|
159
|
+
// Error fade-out: keep overlay visible while it animates out
|
|
160
|
+
let displayedError: string | null = $state(null);
|
|
161
|
+
let displayedIsPassive = $state(false);
|
|
162
|
+
let isErrorDismissing = $state(false);
|
|
163
|
+
let errorDismissTimer: ReturnType<typeof setTimeout> | null = null;
|
|
164
|
+
$effect(() => {
|
|
165
|
+
const error = storeState.error;
|
|
166
|
+
const passive = storeState.isPassiveError;
|
|
167
|
+
if (error) {
|
|
168
|
+
if (errorDismissTimer) {
|
|
169
|
+
clearTimeout(errorDismissTimer);
|
|
170
|
+
errorDismissTimer = null;
|
|
171
|
+
}
|
|
172
|
+
displayedError = error;
|
|
173
|
+
displayedIsPassive = passive;
|
|
174
|
+
isErrorDismissing = false;
|
|
175
|
+
} else if (displayedError) {
|
|
176
|
+
isErrorDismissing = true;
|
|
177
|
+
errorDismissTimer = setTimeout(() => {
|
|
178
|
+
displayedError = null;
|
|
179
|
+
displayedIsPassive = false;
|
|
180
|
+
isErrorDismissing = false;
|
|
181
|
+
errorDismissTimer = null;
|
|
182
|
+
}, 300);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
90
186
|
// Container ref
|
|
91
187
|
let containerRef: HTMLElement | undefined = $state();
|
|
92
188
|
let playerRootRef: HTMLDivElement | undefined = $state();
|
|
@@ -275,9 +371,9 @@
|
|
|
275
371
|
let waitingMessage = $derived(
|
|
276
372
|
options?.gatewayUrl
|
|
277
373
|
? storeState.state === "gateway_loading"
|
|
278
|
-
? "
|
|
279
|
-
: "
|
|
280
|
-
: "
|
|
374
|
+
? $translatorStore("resolvingEndpoint")
|
|
375
|
+
: $translatorStore("waitingForStream")
|
|
376
|
+
: $translatorStore("waitingForStream")
|
|
281
377
|
);
|
|
282
378
|
</script>
|
|
283
379
|
|
|
@@ -292,6 +388,16 @@
|
|
|
292
388
|
options?.devMode && "flex"
|
|
293
389
|
)}
|
|
294
390
|
data-player-container="true"
|
|
391
|
+
data-theme={activeTheme && activeTheme !== "default" ? activeTheme : undefined}
|
|
392
|
+
style={(() => {
|
|
393
|
+
const presetOverrides = activeTheme ? resolveTheme(activeTheme) : null;
|
|
394
|
+
const merged = { ...presetOverrides, ...options?.themeOverrides };
|
|
395
|
+
return Object.keys(merged).length > 0
|
|
396
|
+
? Object.entries(themeOverridesToStyle(merged))
|
|
397
|
+
.map(([k, v]) => `${k}: ${v}`)
|
|
398
|
+
.join("; ")
|
|
399
|
+
: undefined;
|
|
400
|
+
})()}
|
|
295
401
|
role="region"
|
|
296
402
|
aria-label="Video player"
|
|
297
403
|
onmouseenter={() => playerStore?.handleMouseEnter()}
|
|
@@ -380,7 +486,7 @@
|
|
|
380
486
|
status={storeState.isEffectivelyLive ? storeState.streamState?.status : undefined}
|
|
381
487
|
message={storeState.isEffectivelyLive
|
|
382
488
|
? storeState.streamState?.message
|
|
383
|
-
: "
|
|
489
|
+
: $translatorStore("loading")}
|
|
384
490
|
percentage={storeState.isEffectivelyLive
|
|
385
491
|
? storeState.streamState?.percentage
|
|
386
492
|
: undefined}
|
|
@@ -389,63 +495,72 @@
|
|
|
389
495
|
|
|
390
496
|
<!-- Buffering spinner -->
|
|
391
497
|
{#if showBufferingSpinner}
|
|
498
|
+
<div role="status" aria-live="polite" class="fw-buffering-overlay">
|
|
499
|
+
<div class="fw-buffering-pill">
|
|
500
|
+
<div class="fw-buffering-spinner"></div>
|
|
501
|
+
<span>{$translatorStore("buffering")}</span>
|
|
502
|
+
</div>
|
|
503
|
+
</div>
|
|
504
|
+
{/if}
|
|
505
|
+
|
|
506
|
+
<!-- Passive error toast (non-blocking) -->
|
|
507
|
+
{#if displayedError && !storeState.shouldShowIdleScreen && displayedIsPassive}
|
|
392
508
|
<div
|
|
393
|
-
class=
|
|
509
|
+
class={cn(
|
|
510
|
+
"absolute bottom-20 left-1/2 -translate-x-1/2 z-30 transition-opacity duration-300",
|
|
511
|
+
isErrorDismissing
|
|
512
|
+
? "opacity-0"
|
|
513
|
+
: "animate-in fade-in slide-in-from-bottom-2 duration-200"
|
|
514
|
+
)}
|
|
515
|
+
role="status"
|
|
516
|
+
aria-live="polite"
|
|
394
517
|
>
|
|
395
518
|
<div
|
|
396
|
-
class="flex items-center gap-
|
|
519
|
+
class="flex items-center gap-2 rounded-lg border border-yellow-500/30 bg-black/80 px-4 py-2 text-sm text-white shadow-lg backdrop-blur-sm"
|
|
397
520
|
>
|
|
398
|
-
<
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
<span>
|
|
521
|
+
<span class="text-yellow-400 text-xs font-semibold uppercase"
|
|
522
|
+
>{$translatorStore("warning")}</span
|
|
523
|
+
>
|
|
524
|
+
<span>{displayedError}</span>
|
|
525
|
+
<button
|
|
526
|
+
type="button"
|
|
527
|
+
onclick={() => playerStore?.clearError()}
|
|
528
|
+
class="ml-2 text-white/60 hover:text-white"
|
|
529
|
+
aria-label={$translatorStore("dismiss")}
|
|
530
|
+
>
|
|
531
|
+
<svg width="12" height="12" viewBox="0 0 12 12" fill="none">
|
|
532
|
+
<path
|
|
533
|
+
d="M9 3L3 9M3 3L9 9"
|
|
534
|
+
stroke="currentColor"
|
|
535
|
+
stroke-width="1.5"
|
|
536
|
+
stroke-linecap="round"
|
|
537
|
+
/>
|
|
538
|
+
</svg>
|
|
539
|
+
</button>
|
|
402
540
|
</div>
|
|
403
541
|
</div>
|
|
404
542
|
{/if}
|
|
405
543
|
|
|
406
|
-
<!--
|
|
407
|
-
{#if
|
|
544
|
+
<!-- Fatal error overlay (blocking) — auto-dismisses on playback resume -->
|
|
545
|
+
{#if displayedError && !storeState.shouldShowIdleScreen && !displayedIsPassive}
|
|
408
546
|
<div
|
|
409
547
|
role="alert"
|
|
410
548
|
aria-live="assertive"
|
|
411
549
|
class={cn(
|
|
412
|
-
"fw-error-overlay",
|
|
413
|
-
|
|
414
|
-
? "fw-error-overlay--passive"
|
|
415
|
-
: "fw-error-overlay--fullscreen"
|
|
550
|
+
"fw-error-overlay fw-error-overlay--fullscreen transition-opacity duration-300",
|
|
551
|
+
isErrorDismissing && "opacity-0"
|
|
416
552
|
)}
|
|
417
553
|
>
|
|
418
|
-
<div
|
|
419
|
-
class=
|
|
420
|
-
"fw-error-
|
|
421
|
-
|
|
422
|
-
? "fw-error-popup--passive"
|
|
423
|
-
: "fw-error-popup--fullscreen"
|
|
424
|
-
)}
|
|
425
|
-
>
|
|
426
|
-
<div
|
|
427
|
-
class={cn(
|
|
428
|
-
"fw-error-header",
|
|
429
|
-
storeState.isPassiveError
|
|
430
|
-
? "fw-error-header--warning"
|
|
431
|
-
: "fw-error-header--error"
|
|
432
|
-
)}
|
|
433
|
-
>
|
|
434
|
-
<span
|
|
435
|
-
class={cn(
|
|
436
|
-
"fw-error-title",
|
|
437
|
-
storeState.isPassiveError
|
|
438
|
-
? "fw-error-title--warning"
|
|
439
|
-
: "fw-error-title--error"
|
|
440
|
-
)}
|
|
554
|
+
<div class="fw-error-popup fw-error-popup--fullscreen">
|
|
555
|
+
<div class="fw-error-header fw-error-header--error">
|
|
556
|
+
<span class="fw-error-title fw-error-title--error"
|
|
557
|
+
>{$translatorStore("error")}</span
|
|
441
558
|
>
|
|
442
|
-
{storeState.isPassiveError ? "Warning" : "Error"}
|
|
443
|
-
</span>
|
|
444
559
|
<button
|
|
445
560
|
type="button"
|
|
446
561
|
class="fw-error-close"
|
|
447
562
|
onclick={() => playerStore?.clearError()}
|
|
448
|
-
aria-label="
|
|
563
|
+
aria-label={$translatorStore("dismiss")}
|
|
449
564
|
>
|
|
450
565
|
<svg width="12" height="12" viewBox="0 0 12 12" fill="none">
|
|
451
566
|
<path
|
|
@@ -458,7 +573,7 @@
|
|
|
458
573
|
</button>
|
|
459
574
|
</div>
|
|
460
575
|
<div class="fw-error-body">
|
|
461
|
-
<p class="fw-error-message">
|
|
576
|
+
<p class="fw-error-message">{displayedError}</p>
|
|
462
577
|
</div>
|
|
463
578
|
<div class="fw-error-actions">
|
|
464
579
|
<button
|
|
@@ -468,9 +583,33 @@
|
|
|
468
583
|
playerStore?.clearError();
|
|
469
584
|
playerStore?.retry();
|
|
470
585
|
}}
|
|
471
|
-
aria-label="
|
|
586
|
+
aria-label={$translatorStore("retry")}
|
|
587
|
+
>
|
|
588
|
+
{$translatorStore("retry")}
|
|
589
|
+
</button>
|
|
590
|
+
{#if playerStore?.getController()?.canAttemptFallback()}
|
|
591
|
+
<button
|
|
592
|
+
type="button"
|
|
593
|
+
class="fw-error-btn fw-error-btn--secondary"
|
|
594
|
+
onclick={() => {
|
|
595
|
+
playerStore?.clearError();
|
|
596
|
+
playerStore?.getController()?.retryWithFallback();
|
|
597
|
+
}}
|
|
598
|
+
aria-label={$translatorStore("tryNext")}
|
|
599
|
+
>
|
|
600
|
+
{$translatorStore("tryNext")}
|
|
601
|
+
</button>
|
|
602
|
+
{/if}
|
|
603
|
+
<button
|
|
604
|
+
type="button"
|
|
605
|
+
class="fw-error-btn fw-error-btn--secondary"
|
|
606
|
+
onclick={() => {
|
|
607
|
+
playerStore?.clearError();
|
|
608
|
+
playerStore?.reload();
|
|
609
|
+
}}
|
|
610
|
+
aria-label={$translatorStore("reloadPlayer")}
|
|
472
611
|
>
|
|
473
|
-
|
|
612
|
+
{$translatorStore("reloadPlayer")}
|
|
474
613
|
</button>
|
|
475
614
|
</div>
|
|
476
615
|
</div>
|
|
@@ -492,7 +631,7 @@
|
|
|
492
631
|
type="button"
|
|
493
632
|
onclick={() => playerStore?.dismissToast()}
|
|
494
633
|
class="ml-2 text-white/60 hover:text-white"
|
|
495
|
-
aria-label="
|
|
634
|
+
aria-label={$translatorStore("dismiss")}
|
|
496
635
|
>
|
|
497
636
|
<svg width="12" height="12" viewBox="0 0 12 12" fill="none">
|
|
498
637
|
<path
|
|
@@ -507,8 +646,10 @@
|
|
|
507
646
|
</div>
|
|
508
647
|
{/if}
|
|
509
648
|
|
|
510
|
-
<!-- Player controls -->
|
|
511
|
-
{#if
|
|
649
|
+
<!-- Player controls — custom children or default -->
|
|
650
|
+
{#if children}
|
|
651
|
+
{@render children()}
|
|
652
|
+
{:else if !useStockControls}
|
|
512
653
|
<PlayerControls
|
|
513
654
|
currentTime={storeState.currentTime}
|
|
514
655
|
duration={storeState.duration}
|
|
@@ -524,6 +665,10 @@
|
|
|
524
665
|
onStatsToggle={() => (isStatsOpen = !isStatsOpen)}
|
|
525
666
|
isContentLive={storeState.isEffectivelyLive}
|
|
526
667
|
onJumpToLive={() => playerStore?.getController()?.jumpToLive()}
|
|
668
|
+
{activeLocale}
|
|
669
|
+
onLocaleChange={(l) => {
|
|
670
|
+
activeLocale = l;
|
|
671
|
+
}}
|
|
527
672
|
/>
|
|
528
673
|
{/if}
|
|
529
674
|
</div>
|
|
@@ -569,7 +714,7 @@
|
|
|
569
714
|
}}
|
|
570
715
|
>
|
|
571
716
|
<StatsIcon size={14} class="opacity-70 flex-shrink-0 mr-2" />
|
|
572
|
-
{isStatsOpen ? "
|
|
717
|
+
{isStatsOpen ? $translatorStore("hideStats") : $translatorStore("showStats")}
|
|
573
718
|
</ContextMenuItem>
|
|
574
719
|
{#if options?.devMode}
|
|
575
720
|
<ContextMenuSeparator />
|
|
@@ -579,13 +724,13 @@
|
|
|
579
724
|
}}
|
|
580
725
|
>
|
|
581
726
|
<SettingsIcon size={14} class="opacity-70 flex-shrink-0 mr-2" />
|
|
582
|
-
{isDevPanelOpen ? "
|
|
727
|
+
{isDevPanelOpen ? $translatorStore("hideSettings") : $translatorStore("settings")}
|
|
583
728
|
</ContextMenuItem>
|
|
584
729
|
{/if}
|
|
585
730
|
<ContextMenuSeparator />
|
|
586
731
|
<ContextMenuItem onSelect={() => playerStore?.togglePiP()}>
|
|
587
732
|
<PictureInPictureIcon size={14} class="opacity-70 flex-shrink-0 mr-2" />
|
|
588
|
-
|
|
733
|
+
{$translatorStore("pictureInPicture")}
|
|
589
734
|
</ContextMenuItem>
|
|
590
735
|
<ContextMenuItem onSelect={() => playerStore?.toggleLoop()}>
|
|
591
736
|
<svg
|
|
@@ -604,7 +749,9 @@
|
|
|
604
749
|
<polyline points="7 23 3 19 7 15"></polyline>
|
|
605
750
|
<path d="M21 13v2a4 4 0 0 1-4 4H3"></path>
|
|
606
751
|
</svg>
|
|
607
|
-
{storeState.isLoopEnabled
|
|
752
|
+
{storeState.isLoopEnabled
|
|
753
|
+
? $translatorStore("disableLoop")
|
|
754
|
+
: $translatorStore("enableLoop")}
|
|
608
755
|
</ContextMenuItem>
|
|
609
756
|
</ContextMenuContent>
|
|
610
757
|
</ContextMenuPortal>
|
package/dist/Player.svelte.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Snippet } from "svelte";
|
|
2
|
+
import { type PlaybackMode, type ContentEndpoints, type PlayerState, type PlayerStateContext, type ContentType, type PlayerMetadata, type FwThemePreset, type FwThemeOverrides, type FwLocale } from "@livepeer-frameworks/player-core";
|
|
2
3
|
interface Props {
|
|
3
4
|
contentId: string;
|
|
4
5
|
contentType?: ContentType;
|
|
@@ -18,9 +19,13 @@ interface Props {
|
|
|
18
19
|
forceType?: string;
|
|
19
20
|
forceSource?: number;
|
|
20
21
|
playbackMode?: PlaybackMode;
|
|
22
|
+
theme?: FwThemePreset;
|
|
23
|
+
themeOverrides?: FwThemeOverrides;
|
|
24
|
+
locale?: FwLocale;
|
|
21
25
|
};
|
|
22
26
|
onStateChange?: (state: PlayerState, context?: PlayerStateContext) => void;
|
|
23
27
|
onMetadata?: (metadata: PlayerMetadata) => void;
|
|
28
|
+
children?: Snippet;
|
|
24
29
|
}
|
|
25
30
|
declare const Player: import("svelte").Component<Props, {}, "">;
|
|
26
31
|
type Player = ReturnType<typeof Player>;
|