@livepeer-frameworks/player-svelte 0.1.3 → 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/dist/DevModePanel.svelte +14 -15
- package/dist/IdleScreen.svelte +12 -4
- package/dist/LoadingScreen.svelte +90 -50
- 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 +109 -32
- package/dist/PlayerControls.svelte.d.ts +3 -0
- package/dist/StreamStateOverlay.svelte +17 -5
- 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/package.json +8 -8
- package/src/DevModePanel.svelte +14 -15
- 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 +109 -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/dist/DevModePanel.svelte
CHANGED
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
let internalIsOpen = $state(false);
|
|
68
68
|
let activeTab = $state<"config" | "stats">("config");
|
|
69
69
|
let hoveredComboIndex = $state<number | null>(null);
|
|
70
|
-
let
|
|
70
|
+
let tooltipPos = $state<{ top: number; left: number } | null>(null);
|
|
71
71
|
let showDisabledPlayers = $state(false);
|
|
72
72
|
let comboListRef: HTMLDivElement | undefined = $state();
|
|
73
73
|
|
|
@@ -163,14 +163,12 @@
|
|
|
163
163
|
|
|
164
164
|
function handleComboHover(index: number, e: MouseEvent) {
|
|
165
165
|
hoveredComboIndex = index;
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
tooltipAbove = relativePosition > 0.6;
|
|
173
|
-
}
|
|
166
|
+
const row = e.currentTarget as HTMLElement;
|
|
167
|
+
const rowRect = row.getBoundingClientRect();
|
|
168
|
+
tooltipPos = {
|
|
169
|
+
top: Math.max(8, Math.min(rowRect.top, window.innerHeight - 200)),
|
|
170
|
+
left: Math.max(8, rowRect.left - 228),
|
|
171
|
+
};
|
|
174
172
|
}
|
|
175
173
|
|
|
176
174
|
// Quality monitoring
|
|
@@ -387,7 +385,10 @@
|
|
|
387
385
|
class="fw-dev-combo"
|
|
388
386
|
role="listitem"
|
|
389
387
|
onmouseenter={(e) => handleComboHover(index, e)}
|
|
390
|
-
onmouseleave={() =>
|
|
388
|
+
onmouseleave={() => {
|
|
389
|
+
hoveredComboIndex = null;
|
|
390
|
+
tooltipPos = null;
|
|
391
|
+
}}
|
|
391
392
|
>
|
|
392
393
|
<button
|
|
393
394
|
type="button"
|
|
@@ -446,12 +447,10 @@
|
|
|
446
447
|
</button>
|
|
447
448
|
|
|
448
449
|
<!-- Tooltip -->
|
|
449
|
-
{#if hoveredComboIndex === index}
|
|
450
|
+
{#if hoveredComboIndex === index && tooltipPos}
|
|
450
451
|
<div
|
|
451
|
-
class=
|
|
452
|
-
|
|
453
|
-
tooltipAbove ? "fw-dev-tooltip--above" : "fw-dev-tooltip--below"
|
|
454
|
-
)}
|
|
452
|
+
class="fw-dev-tooltip"
|
|
453
|
+
style="top: {tooltipPos.top}px; left: {tooltipPos.left}px;"
|
|
455
454
|
>
|
|
456
455
|
<div class="fw-dev-tooltip-header">
|
|
457
456
|
<div class="fw-dev-tooltip-title">{combo.playerName}</div>
|
package/dist/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
|
|
|
@@ -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;
|
|
@@ -584,6 +562,56 @@
|
|
|
584
562
|
user-select: none;
|
|
585
563
|
}
|
|
586
564
|
|
|
565
|
+
.particle:nth-child(8n + 1) {
|
|
566
|
+
background: hsl(var(--fw-accent, 218 79% 73%));
|
|
567
|
+
}
|
|
568
|
+
.particle:nth-child(8n + 2) {
|
|
569
|
+
background: hsl(var(--fw-accent-secondary, 268 75% 76%));
|
|
570
|
+
}
|
|
571
|
+
.particle:nth-child(8n + 3) {
|
|
572
|
+
background: hsl(var(--fw-success, 97 52% 51%));
|
|
573
|
+
}
|
|
574
|
+
.particle:nth-child(8n + 4) {
|
|
575
|
+
background: hsl(var(--fw-info, 197 95% 74%));
|
|
576
|
+
}
|
|
577
|
+
.particle:nth-child(8n + 5) {
|
|
578
|
+
background: hsl(var(--fw-danger, 352 86% 71%));
|
|
579
|
+
}
|
|
580
|
+
.particle:nth-child(8n + 6) {
|
|
581
|
+
background: hsl(var(--fw-warning, 33 81% 64%));
|
|
582
|
+
}
|
|
583
|
+
.particle:nth-child(8n + 7) {
|
|
584
|
+
background: hsl(var(--fw-accent, 218 79% 73%) / 0.8);
|
|
585
|
+
}
|
|
586
|
+
.particle:nth-child(8n + 8) {
|
|
587
|
+
background: hsl(var(--fw-accent-secondary, 268 75% 76%) / 0.8);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.bubble:nth-child(8n + 1) {
|
|
591
|
+
background: hsl(var(--fw-accent, 218 79% 73%) / 0.2);
|
|
592
|
+
}
|
|
593
|
+
.bubble:nth-child(8n + 2) {
|
|
594
|
+
background: hsl(var(--fw-accent-secondary, 268 75% 76%) / 0.2);
|
|
595
|
+
}
|
|
596
|
+
.bubble:nth-child(8n + 3) {
|
|
597
|
+
background: hsl(var(--fw-success, 97 52% 51%) / 0.2);
|
|
598
|
+
}
|
|
599
|
+
.bubble:nth-child(8n + 4) {
|
|
600
|
+
background: hsl(var(--fw-info, 197 95% 74%) / 0.2);
|
|
601
|
+
}
|
|
602
|
+
.bubble:nth-child(8n + 5) {
|
|
603
|
+
background: hsl(var(--fw-danger, 352 86% 71%) / 0.2);
|
|
604
|
+
}
|
|
605
|
+
.bubble:nth-child(8n + 6) {
|
|
606
|
+
background: hsl(var(--fw-warning, 33 81% 64%) / 0.2);
|
|
607
|
+
}
|
|
608
|
+
.bubble:nth-child(8n + 7) {
|
|
609
|
+
background: hsl(var(--fw-accent, 218 79% 73%) / 0.15);
|
|
610
|
+
}
|
|
611
|
+
.bubble:nth-child(8n + 8) {
|
|
612
|
+
background: hsl(var(--fw-accent-secondary, 268 75% 76%) / 0.15);
|
|
613
|
+
}
|
|
614
|
+
|
|
587
615
|
.center-logo {
|
|
588
616
|
position: absolute;
|
|
589
617
|
top: 50%;
|
|
@@ -601,7 +629,7 @@
|
|
|
601
629
|
.logo-pulse {
|
|
602
630
|
position: absolute;
|
|
603
631
|
border-radius: 50%;
|
|
604
|
-
background:
|
|
632
|
+
background: hsl(var(--fw-accent, 218 79% 73%) / 0.15);
|
|
605
633
|
animation: logoPulse 3s ease-in-out infinite;
|
|
606
634
|
-webkit-user-select: none;
|
|
607
635
|
-moz-user-select: none;
|
|
@@ -624,7 +652,7 @@
|
|
|
624
652
|
.logo-image {
|
|
625
653
|
position: relative;
|
|
626
654
|
z-index: 1;
|
|
627
|
-
filter: drop-shadow(0 4px 8px
|
|
655
|
+
filter: drop-shadow(0 4px 8px hsl(var(--fw-surface-deep, 235 21% 11%) / 0.3));
|
|
628
656
|
transition: all 0.3s ease-out;
|
|
629
657
|
-webkit-user-select: none;
|
|
630
658
|
-moz-user-select: none;
|
|
@@ -634,7 +662,7 @@
|
|
|
634
662
|
}
|
|
635
663
|
|
|
636
664
|
.logo-image.hovered {
|
|
637
|
-
filter: drop-shadow(0 6px 12px
|
|
665
|
+
filter: drop-shadow(0 6px 12px hsl(var(--fw-surface-deep, 235 21% 11%) / 0.4)) brightness(1.1);
|
|
638
666
|
transform: scale(1.1);
|
|
639
667
|
cursor: pointer;
|
|
640
668
|
}
|
|
@@ -644,12 +672,12 @@
|
|
|
644
672
|
bottom: 20%;
|
|
645
673
|
left: 50%;
|
|
646
674
|
transform: translateX(-50%);
|
|
647
|
-
color:
|
|
675
|
+
color: hsl(var(--fw-text-muted, 227 24% 74%));
|
|
648
676
|
font-size: 16px;
|
|
649
677
|
font-weight: 500;
|
|
650
678
|
text-align: center;
|
|
651
679
|
animation: fadeInOut 2s ease-in-out infinite;
|
|
652
|
-
text-shadow: 0 2px 4px
|
|
680
|
+
text-shadow: 0 2px 4px hsl(var(--fw-surface-deep, 235 21% 11%) / 0.5);
|
|
653
681
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
654
682
|
-webkit-user-select: none;
|
|
655
683
|
-moz-user-select: none;
|
|
@@ -664,9 +692,21 @@
|
|
|
664
692
|
right: 0;
|
|
665
693
|
bottom: 0;
|
|
666
694
|
background:
|
|
667
|
-
radial-gradient(
|
|
668
|
-
|
|
669
|
-
|
|
695
|
+
radial-gradient(
|
|
696
|
+
circle at 20% 80%,
|
|
697
|
+
hsl(var(--fw-accent, 218 79% 73%) / 0.03) 0%,
|
|
698
|
+
transparent 50%
|
|
699
|
+
),
|
|
700
|
+
radial-gradient(
|
|
701
|
+
circle at 80% 20%,
|
|
702
|
+
hsl(var(--fw-accent-secondary, 268 75% 76%) / 0.03) 0%,
|
|
703
|
+
transparent 50%
|
|
704
|
+
),
|
|
705
|
+
radial-gradient(
|
|
706
|
+
circle at 40% 40%,
|
|
707
|
+
hsl(var(--fw-success, 97 52% 51%) / 0.02) 0%,
|
|
708
|
+
transparent 50%
|
|
709
|
+
);
|
|
670
710
|
pointer-events: none;
|
|
671
711
|
-webkit-user-select: none;
|
|
672
712
|
-moz-user-select: none;
|
|
@@ -686,8 +726,8 @@
|
|
|
686
726
|
position: absolute;
|
|
687
727
|
width: 12px;
|
|
688
728
|
height: 3px;
|
|
689
|
-
background-color:
|
|
690
|
-
box-shadow: 0 0 8px
|
|
729
|
+
background-color: hsl(var(--fw-text-bright, 220 13% 91%));
|
|
730
|
+
box-shadow: 0 0 8px hsl(var(--fw-text-bright, 220 13% 91%) / 0.8);
|
|
691
731
|
border-radius: 1px;
|
|
692
732
|
}
|
|
693
733
|
|