@cinecrew/cinecrew-player 0.1.3 → 0.1.4

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.
@@ -40,10 +40,9 @@
40
40
  }
41
41
 
42
42
  .cinecrew-player__title {
43
- position: absolute;
44
- top: 62px;
45
- left: 20px;
46
- right: 20px;
43
+ flex: 1 1 auto;
44
+ min-width: 0;
45
+ text-align: center;
47
46
  z-index: 2;
48
47
  overflow: hidden;
49
48
  font-weight: 700;
@@ -70,6 +69,14 @@
70
69
  opacity: 1;
71
70
  }
72
71
 
72
+ .cinecrew-player__controls.is-recording { opacity: 1; }
73
+ .cinecrew-player__controls.is-recording > .cinecrew-player__top-controls,
74
+ .cinecrew-player__controls.is-recording > .cinecrew-player__center-controls,
75
+ .cinecrew-player__controls.is-recording > .cinecrew-player__bottom-controls {
76
+ visibility: hidden;
77
+ pointer-events: none;
78
+ }
79
+
73
80
  .cinecrew-player__top-controls,
74
81
  .cinecrew-player__bottom-controls,
75
82
  .cinecrew-player__center-controls,
@@ -103,8 +110,11 @@
103
110
 
104
111
  .cinecrew-player__top-right-actions {
105
112
  justify-content: flex-end;
113
+ flex: 0 0 auto;
106
114
  }
107
115
 
116
+ .cinecrew-player__top-left-actions { flex: 0 0 auto; }
117
+
108
118
  .cinecrew-player__bottom-controls {
109
119
  width: 100%;
110
120
  flex-direction: column;
@@ -128,6 +138,57 @@
128
138
  justify-content: center;
129
139
  }
130
140
 
141
+ .cinecrew-player__recording-overlay {
142
+ position: absolute;
143
+ top: 10px;
144
+ left: 50%;
145
+ z-index: 5;
146
+ display: flex;
147
+ min-width: 0;
148
+ max-width: calc(100% - 24px);
149
+ box-sizing: border-box;
150
+ align-items: center;
151
+ justify-content: center;
152
+ gap: 8px;
153
+ flex-wrap: wrap;
154
+ padding: 7px 10px;
155
+ border: 1px solid rgba(255,255,255,.22);
156
+ border-radius: 12px;
157
+ background: rgba(0, 0, 0, .68);
158
+ box-shadow: 0 6px 18px rgba(0,0,0,.28);
159
+ transform: translateX(-50%);
160
+ backdrop-filter: blur(8px);
161
+ font-size: .88em;
162
+ }
163
+
164
+ .cinecrew-player__recording-overlay.is-error { border-color: var(--cinecrew-accent); }
165
+ .cinecrew-player__recording-indicator { color: #ff4b63; font-size: .78em; font-weight: 800; letter-spacing: .08em; }
166
+ .cinecrew-player__recording-timer { font-variant-numeric: tabular-nums; font-size: 1.05em; }
167
+ .cinecrew-player__recording-actions { display: flex; gap: 6px; }
168
+ .cinecrew-player__recording-actions button,
169
+ .cinecrew-player__recording-overlay > button {
170
+ border: 1px solid rgba(255,255,255,.2);
171
+ border-radius: 999px;
172
+ padding: 6px 9px;
173
+ color: inherit;
174
+ background: rgba(255,255,255,.1);
175
+ cursor: pointer;
176
+ font: inherit;
177
+ }
178
+ .cinecrew-player__recording-download {
179
+ display: inline-flex;
180
+ align-items: center;
181
+ border: 1px solid rgba(255,255,255,.2);
182
+ border-radius: 999px;
183
+ padding: 6px 9px;
184
+ color: inherit;
185
+ background: rgba(255,255,255,.1);
186
+ text-decoration: none;
187
+ font: inherit;
188
+ }
189
+ .cinecrew-player__recording-actions button:last-child { border-color: #ff4b63; background: rgba(255,75,99,.2); }
190
+ .cinecrew-player__recording-ready { color: #70e3b1; }
191
+
131
192
  .cinecrew-player__seek {
132
193
  flex: 0 0 auto;
133
194
  width: 100%;
@@ -431,7 +492,8 @@
431
492
  grid-row: span 2;
432
493
  place-items: center;
433
494
  border-radius: 9px;
434
- background: rgba(255,255,255,.08);
495
+ border: 1px solid color-mix(in srgb, var(--diagnostic-accent, #fff) 32%, transparent);
496
+ background: color-mix(in srgb, var(--diagnostic-accent, #fff) 14%, transparent);
435
497
  }
436
498
 
437
499
  .cinecrew-player__diagnostic-icon .cinecrew-player__icon { width: 18px; height: 18px; }
@@ -479,6 +541,16 @@
479
541
  gap: 8px;
480
542
  min-height: 0;
481
543
  overflow: auto;
544
+ overscroll-behavior: contain;
545
+ scrollbar-width: thin;
546
+ }
547
+
548
+ .cinecrew-player__older-loading {
549
+ flex: 0 0 auto;
550
+ align-self: center;
551
+ padding: 6px 10px;
552
+ color: var(--cinecrew-accent);
553
+ font-size: .86em;
482
554
  }
483
555
 
484
556
  .cinecrew-player__chat-message,
@@ -527,6 +599,7 @@
527
599
 
528
600
  .cinecrew-player__chat-composer {
529
601
  position: relative;
602
+ container-type: inline-size;
530
603
  display: flex;
531
604
  align-items: center;
532
605
  gap: 7px;
@@ -602,8 +675,9 @@
602
675
 
603
676
  .cinecrew-player__emoji-picker {
604
677
  position: absolute;
605
- right: 0;
606
- bottom: calc(100% + 12px);
678
+ left: 0;
679
+ right: auto;
680
+ bottom: 100%;
607
681
  z-index: 2;
608
682
  display: flex;
609
683
  flex-direction: column;
@@ -617,7 +691,31 @@
617
691
  box-shadow: 0 10px 30px rgba(0, 0, 0, .42);
618
692
  }
619
693
 
620
- .cinecrew-player__chat-composer .cinecrew-player__emoji-search {
694
+ @supports (width: 1cqw) {
695
+ .cinecrew-player__emoji-picker { width: min(340px, 100cqw); }
696
+ }
697
+
698
+ .cinecrew-player__emoji-anchor {
699
+ position: relative;
700
+ display: inline-flex;
701
+ flex: 0 0 34px;
702
+ width: 34px;
703
+ height: 34px;
704
+ align-self: center;
705
+ align-items: center;
706
+ }
707
+
708
+ .cinecrew-player__emoji-anchor > .cinecrew-player__emoji-toggle {
709
+ box-sizing: border-box;
710
+ width: 34px;
711
+ min-width: 34px;
712
+ height: 34px;
713
+ min-height: 34px;
714
+ padding: 0;
715
+ line-height: 1;
716
+ }
717
+
718
+ .cinecrew-player__emoji-picker .cinecrew-player__emoji-search {
621
719
  flex: 0 0 auto;
622
720
  width: 100%;
623
721
  box-sizing: border-box;
@@ -631,7 +729,7 @@
631
729
  font-size: 13px;
632
730
  }
633
731
 
634
- .cinecrew-player__chat-composer .cinecrew-player__emoji-search:focus {
732
+ .cinecrew-player__emoji-picker .cinecrew-player__emoji-search:focus {
635
733
  border-color: var(--cinecrew-accent);
636
734
  }
637
735
 
@@ -652,7 +750,7 @@
652
750
  font: inherit;
653
751
  }
654
752
 
655
- .cinecrew-player__chat-composer .cinecrew-player__emoji-categories button {
753
+ .cinecrew-player__emoji-picker .cinecrew-player__emoji-categories button {
656
754
  display: grid;
657
755
  min-width: 0;
658
756
  min-height: 34px;
@@ -664,8 +762,8 @@
664
762
  font-size: 19px;
665
763
  }
666
764
 
667
- .cinecrew-player__chat-composer .cinecrew-player__emoji-categories button:hover,
668
- .cinecrew-player__chat-composer .cinecrew-player__emoji-categories button.is-active {
765
+ .cinecrew-player__emoji-picker .cinecrew-player__emoji-categories button:hover,
766
+ .cinecrew-player__emoji-picker .cinecrew-player__emoji-categories button.is-active {
669
767
  border-color: var(--cinecrew-accent);
670
768
  background: color-mix(in srgb, var(--cinecrew-accent) 14%, transparent);
671
769
  }
@@ -682,24 +780,27 @@
682
780
  scrollbar-width: thin;
683
781
  }
684
782
 
685
- .cinecrew-player__chat-composer .cinecrew-player__emoji-grid button {
783
+ .cinecrew-player__emoji-picker .cinecrew-player__emoji-grid button {
686
784
  display: grid;
687
785
  width: 100%;
688
786
  min-width: 0;
689
- min-height: 34px;
787
+ min-height: 38px;
690
788
  place-items: center;
691
789
  border: 0;
692
- border-radius: 8px;
790
+ border-radius: 50%;
693
791
  padding: 0;
694
792
  background: transparent;
695
- font-size: 19px;
793
+ font-size: 23px;
794
+ line-height: 1;
795
+ transition: background-color .12s ease, transform .12s ease;
696
796
  }
697
797
 
698
- .cinecrew-player__chat-composer .cinecrew-player__emoji-grid button:hover {
798
+ .cinecrew-player__emoji-picker .cinecrew-player__emoji-grid button:hover {
699
799
  background: rgba(255, 255, 255, .12);
800
+ transform: scale(1.12);
700
801
  }
701
802
 
702
- .cinecrew-player__chat-composer .cinecrew-player__emoji-grid .cinecrew-player__emoji-load-more {
803
+ .cinecrew-player__emoji-picker .cinecrew-player__emoji-grid .cinecrew-player__emoji-load-more {
703
804
  grid-column: 1 / -1;
704
805
  min-height: 34px;
705
806
  border: 1px solid rgba(255, 255, 255, .14);
@@ -752,6 +853,12 @@
752
853
  background: rgba(255,255,255,.1);
753
854
  }
754
855
 
856
+ .cinecrew-player__menu .cinecrew-player__menu-option.is-selected {
857
+ color: var(--cinecrew-accent);
858
+ background: color-mix(in srgb, var(--cinecrew-accent) 18%, transparent);
859
+ font-weight: 700;
860
+ }
861
+
755
862
  .cinecrew-player__panel {
756
863
  position: absolute;
757
864
  inset: 0 0 0 auto;
@@ -811,9 +918,11 @@
811
918
 
812
919
  @media (max-width: 640px) {
813
920
  .cinecrew-player__controls { padding: 10px; }
814
- .cinecrew-player__top-controls { align-items: flex-start; gap: 6px; }
815
- .cinecrew-player__top-left-actions { gap: 4px; }
921
+ .cinecrew-player__top-controls { align-items: center; gap: 6px; flex-wrap: wrap; }
922
+ .cinecrew-player__title { order: 3; flex: 0 0 100%; box-sizing: border-box; padding: 0 4px; text-align: center; }
923
+ .cinecrew-player__top-left-actions { order: 1; gap: 4px; }
816
924
  .cinecrew-player__top-right-actions {
925
+ order: 2;
817
926
  max-width: calc(100% - 128px);
818
927
  flex-wrap: wrap;
819
928
  gap: 4px;
@@ -825,7 +934,6 @@
825
934
  min-height: 34px;
826
935
  padding: 6px 8px;
827
936
  }
828
- .cinecrew-player__title { top: 96px; left: 12px; right: 12px; }
829
937
  .cinecrew-player__bottom-actions { align-items: flex-end; gap: 6px; }
830
938
  .cinecrew-player__bottom-right-actions { max-width: 100%; flex-wrap: wrap; justify-content: flex-end; gap: 4px; }
831
939
  .cinecrew-player__panel { width: min(380px, 92%); }
package/types/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type * as React from 'react';
2
2
 
3
3
  export type AspectRatio = 'FIT' | 'FILL' | 'STRETCH' | 'FILL_SCREEN' | string;
4
+ export interface AspectRatioOption { value: AspectRatio; label?: string }
4
5
  export type PlayerMediaType = 'live' | 'channel' | 'movie' | 'series' | string;
5
6
 
6
7
  export interface PlayerSource {
@@ -57,6 +58,8 @@ export interface PlayerApi {
57
58
  seekBy(seconds: number): void;
58
59
  back(): void;
59
60
  setPlaybackRate(rate: number): void;
61
+ setPanel(panel: 'chat' | 'epg' | 'diagnostics' | null): void;
62
+ closePanel(): void;
60
63
  getVideoElement(): unknown | null;
61
64
  getAudioTracks(): AudioTrack[];
62
65
  enterFullscreen?(): void | Promise<void>;
@@ -77,6 +80,7 @@ export interface PlayerActionContext {
77
80
  video?: unknown | null;
78
81
  }
79
82
 
83
+ /** Notification invoked after the player's built-in action has executed. */
80
84
  export type PlayerAction = (payload?: Record<string, unknown>, context?: PlayerActionContext) => unknown;
81
85
 
82
86
  export interface PlayerActions {
@@ -209,9 +213,14 @@ export interface CineCrewPlayerProps {
209
213
  drawerMode?: PlayerDrawerMode;
210
214
  /** Web CSS or React Native view-style overrides for the chat, EPG, and diagnostics drawer. */
211
215
  drawerStyle?: React.CSSProperties | import('react-native').ViewStyle;
212
- /** Number of chat messages fetched per page; older pages load from the drawer's See more button. Defaults to 50. */
216
+ /** Number of chat messages fetched per page. Older pages load automatically when scrolling to the top. Defaults to 50. */
213
217
  messagePageSize?: number;
218
+ /** Available aspect-ratio choices. Items may be values or labeled { value, label } options. */
219
+ aspectRatios?: Array<AspectRatio | AspectRatioOption>;
220
+ /** Initial aspect-ratio choice. Defaults to FIT. */
221
+ defaultAspectRatio?: AspectRatio;
214
222
  features?: { diagnostics?: boolean; [key: string]: boolean | undefined };
223
+ /** App callbacks invoked after each corresponding built-in action. */
215
224
  actions?: PlayerActions;
216
225
  integrations?: PlayerIntegrations;
217
226
  theme?: PlayerTheme;
@@ -236,6 +245,8 @@ export interface CineCrewPlayerProps {
236
245
  onClose?: () => void;
237
246
  onBack?: () => void;
238
247
  onFullscreen?: (state: { isFullscreen: boolean }) => void;
248
+ /** Invoked after the player applies an aspect ratio selection; actions.onAspectRatioChange takes precedence when both are supplied. */
249
+ onAspectRatioChange?: PlayerAction;
239
250
  onPlayerHostRef?: (node: unknown | null) => void;
240
251
  onInlinePreviewWheel?: (deltaY: number) => void;
241
252
  inlinePreview?: boolean;
@@ -245,6 +256,8 @@ export interface CineCrewPlayerProps {
245
256
  liveChatNonce?: number;
246
257
  onReady?: (playerOrEvent: unknown) => void;
247
258
  onProgress?: (event: unknown) => void;
259
+ /** Called once for each elapsed playback second and after a completed seek/restart with a zero-padded HH:MM:SS position. */
260
+ onProgressBarChange?: (time: string) => void;
248
261
  onPlaying?: (event: unknown) => void;
249
262
  onBuffering?: (buffering: boolean) => void;
250
263
  onError?: (error: Error | Record<string, unknown>) => void;