@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.
Files changed (56) hide show
  1. package/LICENSE.md +24 -0
  2. package/README.md +6 -2
  3. package/dist/DevModePanel.svelte +53 -16
  4. package/dist/IdleScreen.svelte +36 -28
  5. package/dist/LoadingScreen.svelte +107 -67
  6. package/dist/LoadingScreen.svelte.bak +702 -0
  7. package/dist/Player.svelte +200 -53
  8. package/dist/Player.svelte.d.ts +6 -1
  9. package/dist/PlayerControls.svelte +114 -32
  10. package/dist/PlayerControls.svelte.d.ts +3 -0
  11. package/dist/StreamStateOverlay.svelte +33 -21
  12. package/dist/SubtitleRenderer.svelte +2 -2
  13. package/dist/controls/FullscreenButton.svelte +26 -0
  14. package/dist/controls/FullscreenButton.svelte.d.ts +3 -0
  15. package/dist/controls/LiveBadge.svelte +23 -0
  16. package/dist/controls/LiveBadge.svelte.d.ts +3 -0
  17. package/dist/controls/PlayButton.svelte +26 -0
  18. package/dist/controls/PlayButton.svelte.d.ts +3 -0
  19. package/dist/controls/SettingsMenu.svelte +208 -0
  20. package/dist/controls/SettingsMenu.svelte.d.ts +28 -0
  21. package/dist/controls/SkipButton.svelte +33 -0
  22. package/dist/controls/SkipButton.svelte.d.ts +7 -0
  23. package/dist/controls/TimeDisplay.svelte +18 -0
  24. package/dist/controls/TimeDisplay.svelte.d.ts +3 -0
  25. package/dist/controls/VolumeControl.svelte +26 -0
  26. package/dist/controls/VolumeControl.svelte.d.ts +3 -0
  27. package/dist/controls/index.d.ts +7 -0
  28. package/dist/controls/index.js +7 -0
  29. package/dist/index.d.ts +3 -2
  30. package/dist/index.js +3 -1
  31. package/dist/stores/i18n.d.ts +3 -0
  32. package/dist/stores/i18n.js +4 -0
  33. package/dist/stores/index.d.ts +1 -0
  34. package/dist/stores/index.js +2 -0
  35. package/dist/stores/playerController.d.ts +2 -0
  36. package/dist/stores/playerController.js +4 -0
  37. package/package.json +19 -19
  38. package/src/DevModePanel.svelte +53 -16
  39. package/src/IdleScreen.svelte +12 -4
  40. package/src/LoadingScreen.svelte +90 -50
  41. package/src/LoadingScreen.svelte.bak +702 -0
  42. package/src/Player.svelte +200 -53
  43. package/src/PlayerControls.svelte +114 -32
  44. package/src/StreamStateOverlay.svelte +17 -5
  45. package/src/controls/FullscreenButton.svelte +26 -0
  46. package/src/controls/LiveBadge.svelte +23 -0
  47. package/src/controls/PlayButton.svelte +26 -0
  48. package/src/controls/SettingsMenu.svelte +208 -0
  49. package/src/controls/SkipButton.svelte +33 -0
  50. package/src/controls/TimeDisplay.svelte +18 -0
  51. package/src/controls/VolumeControl.svelte +26 -0
  52. package/src/controls/index.ts +7 -0
  53. package/src/index.ts +10 -0
  54. package/src/stores/i18n.ts +7 -0
  55. package/src/stores/index.ts +3 -0
  56. package/src/stores/playerController.ts +7 -0
@@ -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 = "Waiting for source...", logoSrc }: Props = $props();
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 }, (_, i) => ({
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 }, (_, i) => ({
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="Loading"
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
- {message}
416
+ {effectiveMessage}
439
417
  </div>
440
418
 
441
419
  <!-- Subtle overlay texture -->
@@ -537,18 +515,18 @@
537
515
  }
538
516
  }
539
517
 
540
- .fw-player-root .loading-container {
518
+ .loading-container {
541
519
  position: relative;
542
520
  width: 100%;
543
521
  height: 100%;
544
522
  min-height: 300px;
545
523
  background: linear-gradient(
546
524
  135deg,
547
- hsl(var(--tn-bg-dark, 235 21% 11%)) 0%,
548
- hsl(var(--tn-bg, 233 23% 17%)) 25%,
549
- hsl(var(--tn-bg-dark, 235 21% 11%)) 50%,
550
- hsl(var(--tn-bg, 233 23% 17%)) 75%,
551
- hsl(var(--tn-bg-dark, 235 21% 11%)) 100%
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;
@@ -563,7 +541,7 @@
563
541
  -webkit-user-select: none;
564
542
  }
565
543
 
566
- .fw-player-root .bubble {
544
+ .bubble {
567
545
  position: absolute;
568
546
  border-radius: 50%;
569
547
  transition: opacity 1s ease-in-out;
@@ -573,7 +551,7 @@
573
551
  user-select: none;
574
552
  }
575
553
 
576
- .fw-player-root .particle {
554
+ .particle {
577
555
  position: absolute;
578
556
  border-radius: 50%;
579
557
  opacity: 0;
@@ -584,7 +562,57 @@
584
562
  user-select: none;
585
563
  }
586
564
 
587
- .fw-player-root .center-logo {
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
+
615
+ .center-logo {
588
616
  position: absolute;
589
617
  top: 50%;
590
618
  left: 50%;
@@ -598,10 +626,10 @@
598
626
  user-select: none;
599
627
  }
600
628
 
601
- .fw-player-root .logo-pulse {
629
+ .logo-pulse {
602
630
  position: absolute;
603
631
  border-radius: 50%;
604
- background: rgba(122, 162, 247, 0.15);
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;
@@ -610,21 +638,21 @@
610
638
  transition: transform 0.3s ease-out;
611
639
  }
612
640
 
613
- .fw-player-root .logo-pulse.hovered {
641
+ .logo-pulse.hovered {
614
642
  animation: logoPulse 1s ease-in-out infinite;
615
643
  transform: scale(1.2);
616
644
  }
617
645
 
618
- .fw-player-root .logo-button {
646
+ .logo-button {
619
647
  all: unset;
620
648
  cursor: pointer;
621
649
  display: block;
622
650
  }
623
651
 
624
- .fw-player-root .logo-image {
652
+ .logo-image {
625
653
  position: relative;
626
654
  z-index: 1;
627
- filter: drop-shadow(0 4px 8px rgba(36, 40, 59, 0.3));
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;
@@ -633,23 +661,23 @@
633
661
  -webkit-touch-callout: none;
634
662
  }
635
663
 
636
- .fw-player-root .logo-image.hovered {
637
- filter: drop-shadow(0 6px 12px rgba(36, 40, 59, 0.4)) brightness(1.1);
664
+ .logo-image.hovered {
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
  }
641
669
 
642
- .fw-player-root .message {
670
+ .message {
643
671
  position: absolute;
644
672
  bottom: 20%;
645
673
  left: 50%;
646
674
  transform: translateX(-50%);
647
- color: #a9b1d6;
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 rgba(36, 40, 59, 0.5);
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;
@@ -657,23 +685,35 @@
657
685
  pointer-events: none;
658
686
  }
659
687
 
660
- .fw-player-root .overlay-texture {
688
+ .overlay-texture {
661
689
  position: absolute;
662
690
  top: 0;
663
691
  left: 0;
664
692
  right: 0;
665
693
  bottom: 0;
666
694
  background:
667
- radial-gradient(circle at 20% 80%, rgba(122, 162, 247, 0.03) 0%, transparent 50%),
668
- radial-gradient(circle at 80% 20%, rgba(187, 154, 247, 0.03) 0%, transparent 50%),
669
- radial-gradient(circle at 40% 40%, rgba(158, 206, 106, 0.02) 0%, transparent 50%);
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;
673
713
  user-select: none;
674
714
  }
675
715
 
676
- .fw-player-root .hitmarker {
716
+ .hitmarker {
677
717
  position: absolute;
678
718
  transform: translate(-50%, -50%);
679
719
  pointer-events: none;
@@ -682,34 +722,34 @@
682
722
  height: 40px;
683
723
  }
684
724
 
685
- .fw-player-root .hitmarker-line {
725
+ .hitmarker-line {
686
726
  position: absolute;
687
727
  width: 12px;
688
728
  height: 3px;
689
- background-color: #ffffff;
690
- box-shadow: 0 0 8px rgba(255, 255, 255, 0.8);
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
 
694
- .fw-player-root .hitmarker-line.tl {
734
+ .hitmarker-line.tl {
695
735
  top: 25%;
696
736
  left: 25%;
697
737
  animation: hitmarkerFade45 0.6s ease-out forwards;
698
738
  }
699
739
 
700
- .fw-player-root .hitmarker-line.tr {
740
+ .hitmarker-line.tr {
701
741
  top: 25%;
702
742
  left: 75%;
703
743
  animation: hitmarkerFadeNeg45 0.6s ease-out forwards;
704
744
  }
705
745
 
706
- .fw-player-root .hitmarker-line.bl {
746
+ .hitmarker-line.bl {
707
747
  top: 75%;
708
748
  left: 25%;
709
749
  animation: hitmarkerFadeNeg45 0.6s ease-out forwards;
710
750
  }
711
751
 
712
- .fw-player-root .hitmarker-line.br {
752
+ .hitmarker-line.br {
713
753
  top: 75%;
714
754
  left: 75%;
715
755
  animation: hitmarkerFade45 0.6s ease-out forwards;