@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/src/IdleScreen.svelte
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
- Status overlay at bottom
|
|
14
14
|
-->
|
|
15
15
|
<script lang="ts">
|
|
16
|
-
import { onMount, onDestroy } from "svelte";
|
|
16
|
+
import { onMount, onDestroy, getContext } from "svelte";
|
|
17
|
+
import type { Readable } from "svelte/store";
|
|
18
|
+
import { createTranslator, type TranslateFn } from "@livepeer-frameworks/player-core";
|
|
17
19
|
import type { StreamStatus } from "@livepeer-frameworks/player-core";
|
|
18
20
|
import DvdLogo from "./DvdLogo.svelte";
|
|
19
21
|
import logomarkAsset from "./assets/logomark.svg";
|
|
@@ -26,14 +28,20 @@
|
|
|
26
28
|
onRetry?: () => void;
|
|
27
29
|
}
|
|
28
30
|
|
|
31
|
+
const translatorCtx = getContext<Readable<TranslateFn> | undefined>("fw-translator");
|
|
32
|
+
const fallbackT = createTranslator({ locale: "en" });
|
|
33
|
+
let t: TranslateFn = $derived(translatorCtx ? $translatorCtx : fallbackT);
|
|
34
|
+
|
|
29
35
|
let {
|
|
30
36
|
status = "OFFLINE",
|
|
31
|
-
message =
|
|
37
|
+
message = undefined,
|
|
32
38
|
percentage = undefined,
|
|
33
39
|
error = undefined,
|
|
34
40
|
onRetry = undefined,
|
|
35
41
|
}: Props = $props();
|
|
36
42
|
|
|
43
|
+
let effectiveMessage = $derived(message ?? t("waitingForStream"));
|
|
44
|
+
|
|
37
45
|
// Container ref for mouse tracking
|
|
38
46
|
let containerRef: HTMLDivElement | undefined = $state();
|
|
39
47
|
|
|
@@ -316,7 +324,7 @@
|
|
|
316
324
|
let _statusLabel = $derived(getStatusLabel(status));
|
|
317
325
|
let showRetry = $derived((status === "ERROR" || status === "INVALID") && onRetry);
|
|
318
326
|
let showProgress = $derived(status === "INITIALIZING" && percentage !== undefined);
|
|
319
|
-
let displayMessage = $derived(error ||
|
|
327
|
+
let displayMessage = $derived(error || effectiveMessage);
|
|
320
328
|
let isLoading = $derived(
|
|
321
329
|
status === "INITIALIZING" || status === "BOOTING" || status === "WAITING_FOR_DATA" || !status
|
|
322
330
|
);
|
|
@@ -522,7 +530,7 @@
|
|
|
522
530
|
|
|
523
531
|
<!-- Retry button -->
|
|
524
532
|
{#if showRetry}
|
|
525
|
-
<button type="button" class="retry-button" onclick={onRetry}>
|
|
533
|
+
<button type="button" class="retry-button" onclick={onRetry}> {t("retry")} </button>
|
|
526
534
|
{/if}
|
|
527
535
|
</div>
|
|
528
536
|
|
package/src/LoadingScreen.svelte
CHANGED
|
@@ -12,16 +12,23 @@
|
|
|
12
12
|
- Animated background gradient shifts
|
|
13
13
|
-->
|
|
14
14
|
<script lang="ts">
|
|
15
|
-
import { onMount, onDestroy } from "svelte";
|
|
15
|
+
import { onMount, onDestroy, getContext } from "svelte";
|
|
16
|
+
import type { Readable } from "svelte/store";
|
|
17
|
+
import { createTranslator, type TranslateFn } from "@livepeer-frameworks/player-core";
|
|
16
18
|
import DvdLogo from "./DvdLogo.svelte";
|
|
17
19
|
import logomarkAsset from "./assets/logomark.svg";
|
|
18
20
|
|
|
21
|
+
const translatorCtx = getContext<Readable<TranslateFn> | undefined>("fw-translator");
|
|
22
|
+
const fallbackT = createTranslator({ locale: "en" });
|
|
23
|
+
let t: TranslateFn = $derived(translatorCtx ? $translatorCtx : fallbackT);
|
|
24
|
+
|
|
19
25
|
interface Props {
|
|
20
26
|
message?: string;
|
|
21
27
|
logoSrc?: string;
|
|
22
28
|
}
|
|
23
29
|
|
|
24
|
-
let { message =
|
|
30
|
+
let { message = undefined, logoSrc }: Props = $props();
|
|
31
|
+
let effectiveMessage = $derived(message ?? t("waitingForSource"));
|
|
25
32
|
|
|
26
33
|
// Use imported asset as default if logoSrc not provided
|
|
27
34
|
let effectiveLogoSrc = $derived(logoSrc || logomarkAsset);
|
|
@@ -42,35 +49,10 @@
|
|
|
42
49
|
let offset = $state({ x: 0, y: 0 });
|
|
43
50
|
let isHovered = $state(false);
|
|
44
51
|
|
|
45
|
-
// Tokyo Night inspired pastel colors for bubbles
|
|
46
|
-
const bubbleColors = [
|
|
47
|
-
"rgba(122, 162, 247, 0.2)", // Terminal Blue
|
|
48
|
-
"rgba(187, 154, 247, 0.2)", // Terminal Magenta
|
|
49
|
-
"rgba(158, 206, 106, 0.2)", // Strings/CSS classes
|
|
50
|
-
"rgba(115, 218, 202, 0.2)", // Terminal Green
|
|
51
|
-
"rgba(125, 207, 255, 0.2)", // Terminal Cyan
|
|
52
|
-
"rgba(247, 118, 142, 0.2)", // Keywords/Terminal Red
|
|
53
|
-
"rgba(224, 175, 104, 0.2)", // Terminal Yellow
|
|
54
|
-
"rgba(42, 195, 222, 0.2)", // Language functions
|
|
55
|
-
];
|
|
56
|
-
|
|
57
|
-
// Particle colors
|
|
58
|
-
const particleColors = [
|
|
59
|
-
"#7aa2f7", // Terminal Blue
|
|
60
|
-
"#bb9af7", // Terminal Magenta
|
|
61
|
-
"#9ece6a", // Strings/CSS classes
|
|
62
|
-
"#73daca", // Terminal Green
|
|
63
|
-
"#7dcfff", // Terminal Cyan
|
|
64
|
-
"#f7768e", // Keywords/Terminal Red
|
|
65
|
-
"#e0af68", // Terminal Yellow
|
|
66
|
-
"#2ac3de", // Language functions
|
|
67
|
-
];
|
|
68
|
-
|
|
69
52
|
// Generate random particles
|
|
70
|
-
const particles = Array.from({ length: 12 }, (
|
|
53
|
+
const particles = Array.from({ length: 12 }, () => ({
|
|
71
54
|
left: Math.random() * 100,
|
|
72
55
|
size: Math.random() * 4 + 2,
|
|
73
|
-
color: particleColors[i % 8],
|
|
74
56
|
duration: 8 + Math.random() * 4,
|
|
75
57
|
delay: Math.random() * 8,
|
|
76
58
|
}));
|
|
@@ -80,16 +62,14 @@
|
|
|
80
62
|
position: { top: number; left: number };
|
|
81
63
|
size: number;
|
|
82
64
|
opacity: number;
|
|
83
|
-
color: string;
|
|
84
65
|
timeoutId: ReturnType<typeof setTimeout> | null;
|
|
85
66
|
}
|
|
86
67
|
|
|
87
68
|
let bubbles = $state<BubbleState[]>(
|
|
88
|
-
Array.from({ length: 8 }, (
|
|
69
|
+
Array.from({ length: 8 }, () => ({
|
|
89
70
|
position: { top: Math.random() * 80 + 10, left: Math.random() * 80 + 10 },
|
|
90
71
|
size: Math.random() * 60 + 30,
|
|
91
72
|
opacity: 0,
|
|
92
|
-
color: bubbleColors[i % bubbleColors.length],
|
|
93
73
|
timeoutId: null,
|
|
94
74
|
}))
|
|
95
75
|
);
|
|
@@ -361,7 +341,7 @@
|
|
|
361
341
|
bind:this={containerRef}
|
|
362
342
|
class="loading-container fw-player-root"
|
|
363
343
|
role="status"
|
|
364
|
-
aria-label="
|
|
344
|
+
aria-label={t("loading")}
|
|
365
345
|
onmousemove={handleMouseMove}
|
|
366
346
|
onmouseleave={handleMouseLeave}
|
|
367
347
|
>
|
|
@@ -383,7 +363,6 @@
|
|
|
383
363
|
left: {particle.left}%;
|
|
384
364
|
width: {particle.size}px;
|
|
385
365
|
height: {particle.size}px;
|
|
386
|
-
background: {particle.color};
|
|
387
366
|
animation-duration: {particle.duration}s;
|
|
388
367
|
animation-delay: {particle.delay}s;
|
|
389
368
|
"
|
|
@@ -399,7 +378,6 @@
|
|
|
399
378
|
left: {bubble.position.left}%;
|
|
400
379
|
width: {bubble.size}px;
|
|
401
380
|
height: {bubble.size}px;
|
|
402
|
-
background: {bubble.color};
|
|
403
381
|
opacity: {bubble.opacity};
|
|
404
382
|
"
|
|
405
383
|
></div>
|
|
@@ -435,7 +413,7 @@
|
|
|
435
413
|
|
|
436
414
|
<!-- Message -->
|
|
437
415
|
<div class="message">
|
|
438
|
-
{
|
|
416
|
+
{effectiveMessage}
|
|
439
417
|
</div>
|
|
440
418
|
|
|
441
419
|
<!-- Subtle overlay texture -->
|
|
@@ -544,11 +522,11 @@
|
|
|
544
522
|
min-height: 300px;
|
|
545
523
|
background: linear-gradient(
|
|
546
524
|
135deg,
|
|
547
|
-
hsl(var(--
|
|
548
|
-
hsl(var(--
|
|
549
|
-
hsl(var(--
|
|
550
|
-
hsl(var(--
|
|
551
|
-
hsl(var(--
|
|
525
|
+
hsl(var(--fw-surface-deep, 235 21% 11%)) 0%,
|
|
526
|
+
hsl(var(--fw-surface, 233 23% 17%)) 25%,
|
|
527
|
+
hsl(var(--fw-surface-deep, 235 21% 11%)) 50%,
|
|
528
|
+
hsl(var(--fw-surface, 233 23% 17%)) 75%,
|
|
529
|
+
hsl(var(--fw-surface-deep, 235 21% 11%)) 100%
|
|
552
530
|
);
|
|
553
531
|
background-size: 400% 400%;
|
|
554
532
|
animation: gradientShift 16s ease-in-out infinite;
|
|
@@ -579,6 +557,56 @@
|
|
|
579
557
|
user-select: none;
|
|
580
558
|
}
|
|
581
559
|
|
|
560
|
+
.particle:nth-child(8n + 1) {
|
|
561
|
+
background: hsl(var(--fw-accent, 218 79% 73%));
|
|
562
|
+
}
|
|
563
|
+
.particle:nth-child(8n + 2) {
|
|
564
|
+
background: hsl(var(--fw-accent-secondary, 268 75% 76%));
|
|
565
|
+
}
|
|
566
|
+
.particle:nth-child(8n + 3) {
|
|
567
|
+
background: hsl(var(--fw-success, 97 52% 51%));
|
|
568
|
+
}
|
|
569
|
+
.particle:nth-child(8n + 4) {
|
|
570
|
+
background: hsl(var(--fw-info, 197 95% 74%));
|
|
571
|
+
}
|
|
572
|
+
.particle:nth-child(8n + 5) {
|
|
573
|
+
background: hsl(var(--fw-danger, 352 86% 71%));
|
|
574
|
+
}
|
|
575
|
+
.particle:nth-child(8n + 6) {
|
|
576
|
+
background: hsl(var(--fw-warning, 33 81% 64%));
|
|
577
|
+
}
|
|
578
|
+
.particle:nth-child(8n + 7) {
|
|
579
|
+
background: hsl(var(--fw-accent, 218 79% 73%) / 0.8);
|
|
580
|
+
}
|
|
581
|
+
.particle:nth-child(8n + 8) {
|
|
582
|
+
background: hsl(var(--fw-accent-secondary, 268 75% 76%) / 0.8);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
.bubble:nth-child(8n + 1) {
|
|
586
|
+
background: hsl(var(--fw-accent, 218 79% 73%) / 0.2);
|
|
587
|
+
}
|
|
588
|
+
.bubble:nth-child(8n + 2) {
|
|
589
|
+
background: hsl(var(--fw-accent-secondary, 268 75% 76%) / 0.2);
|
|
590
|
+
}
|
|
591
|
+
.bubble:nth-child(8n + 3) {
|
|
592
|
+
background: hsl(var(--fw-success, 97 52% 51%) / 0.2);
|
|
593
|
+
}
|
|
594
|
+
.bubble:nth-child(8n + 4) {
|
|
595
|
+
background: hsl(var(--fw-info, 197 95% 74%) / 0.2);
|
|
596
|
+
}
|
|
597
|
+
.bubble:nth-child(8n + 5) {
|
|
598
|
+
background: hsl(var(--fw-danger, 352 86% 71%) / 0.2);
|
|
599
|
+
}
|
|
600
|
+
.bubble:nth-child(8n + 6) {
|
|
601
|
+
background: hsl(var(--fw-warning, 33 81% 64%) / 0.2);
|
|
602
|
+
}
|
|
603
|
+
.bubble:nth-child(8n + 7) {
|
|
604
|
+
background: hsl(var(--fw-accent, 218 79% 73%) / 0.15);
|
|
605
|
+
}
|
|
606
|
+
.bubble:nth-child(8n + 8) {
|
|
607
|
+
background: hsl(var(--fw-accent-secondary, 268 75% 76%) / 0.15);
|
|
608
|
+
}
|
|
609
|
+
|
|
582
610
|
.center-logo {
|
|
583
611
|
position: absolute;
|
|
584
612
|
top: 50%;
|
|
@@ -594,7 +622,7 @@
|
|
|
594
622
|
.logo-pulse {
|
|
595
623
|
position: absolute;
|
|
596
624
|
border-radius: 50%;
|
|
597
|
-
background:
|
|
625
|
+
background: hsl(var(--fw-accent, 218 79% 73%) / 0.15);
|
|
598
626
|
animation: logoPulse 3s ease-in-out infinite;
|
|
599
627
|
user-select: none;
|
|
600
628
|
pointer-events: none;
|
|
@@ -615,7 +643,7 @@
|
|
|
615
643
|
.logo-image {
|
|
616
644
|
position: relative;
|
|
617
645
|
z-index: 1;
|
|
618
|
-
filter: drop-shadow(0 4px 8px
|
|
646
|
+
filter: drop-shadow(0 4px 8px hsl(var(--fw-surface-deep, 235 21% 11%) / 0.3));
|
|
619
647
|
transition: all 0.3s ease-out;
|
|
620
648
|
user-select: none;
|
|
621
649
|
-webkit-user-drag: none;
|
|
@@ -623,7 +651,7 @@
|
|
|
623
651
|
}
|
|
624
652
|
|
|
625
653
|
.logo-image.hovered {
|
|
626
|
-
filter: drop-shadow(0 6px 12px
|
|
654
|
+
filter: drop-shadow(0 6px 12px hsl(var(--fw-surface-deep, 235 21% 11%) / 0.4)) brightness(1.1);
|
|
627
655
|
transform: scale(1.1);
|
|
628
656
|
cursor: pointer;
|
|
629
657
|
}
|
|
@@ -633,12 +661,12 @@
|
|
|
633
661
|
bottom: 20%;
|
|
634
662
|
left: 50%;
|
|
635
663
|
transform: translateX(-50%);
|
|
636
|
-
color:
|
|
664
|
+
color: hsl(var(--fw-text-muted, 227 24% 74%));
|
|
637
665
|
font-size: 16px;
|
|
638
666
|
font-weight: 500;
|
|
639
667
|
text-align: center;
|
|
640
668
|
animation: fadeInOut 2s ease-in-out infinite;
|
|
641
|
-
text-shadow: 0 2px 4px
|
|
669
|
+
text-shadow: 0 2px 4px hsl(var(--fw-surface-deep, 235 21% 11%) / 0.5);
|
|
642
670
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
643
671
|
user-select: none;
|
|
644
672
|
pointer-events: none;
|
|
@@ -651,9 +679,21 @@
|
|
|
651
679
|
right: 0;
|
|
652
680
|
bottom: 0;
|
|
653
681
|
background:
|
|
654
|
-
radial-gradient(
|
|
655
|
-
|
|
656
|
-
|
|
682
|
+
radial-gradient(
|
|
683
|
+
circle at 20% 80%,
|
|
684
|
+
hsl(var(--fw-accent, 218 79% 73%) / 0.03) 0%,
|
|
685
|
+
transparent 50%
|
|
686
|
+
),
|
|
687
|
+
radial-gradient(
|
|
688
|
+
circle at 80% 20%,
|
|
689
|
+
hsl(var(--fw-accent-secondary, 268 75% 76%) / 0.03) 0%,
|
|
690
|
+
transparent 50%
|
|
691
|
+
),
|
|
692
|
+
radial-gradient(
|
|
693
|
+
circle at 40% 40%,
|
|
694
|
+
hsl(var(--fw-success, 97 52% 51%) / 0.02) 0%,
|
|
695
|
+
transparent 50%
|
|
696
|
+
);
|
|
657
697
|
pointer-events: none;
|
|
658
698
|
user-select: none;
|
|
659
699
|
}
|
|
@@ -671,8 +711,8 @@
|
|
|
671
711
|
position: absolute;
|
|
672
712
|
width: 12px;
|
|
673
713
|
height: 3px;
|
|
674
|
-
background-color:
|
|
675
|
-
box-shadow: 0 0 8px
|
|
714
|
+
background-color: hsl(var(--fw-text-bright, 220 13% 91%));
|
|
715
|
+
box-shadow: 0 0 8px hsl(var(--fw-text-bright, 220 13% 91%) / 0.8);
|
|
676
716
|
border-radius: 1px;
|
|
677
717
|
}
|
|
678
718
|
|