@hanifhan1f/vidstack-react 1.12.17 → 1.12.18
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/dev/chunks/{vidstack-awS6X--9.js → vidstack-CevuS08D.js} +12 -5
- package/dev/chunks/{vidstack-o47ADvk_.js → vidstack-CkRXb9Ia.js} +49 -9
- package/dev/player/vidstack-default-components.js +1 -1
- package/dev/player/vidstack-default-layout.js +1 -1
- package/package.json +1 -1
- package/player/layouts/default.d.ts +17 -0
- package/player/styles/default/layouts/video.css +69 -0
- package/prod/chunks/{vidstack-D15hTbK0.js → vidstack-C4tuISYG.js} +12 -5
- package/prod/chunks/{vidstack-Ce0Qn3e1.js → vidstack-CikQpsuo.js} +49 -9
- package/prod/player/vidstack-default-components.js +1 -1
- package/prod/player/vidstack-default-layout.js +1 -1
- package/server/chunks/{vidstack-CWR0J8Qz.js → vidstack-Ct1NFlBa.js} +49 -9
- package/server/chunks/{vidstack-C6mbdfF1.js → vidstack-DTn72IA8.js} +12 -5
- package/server/player/vidstack-default-components.js +1 -1
- package/server/player/vidstack-default-layout.js +1 -1
- package/dev/chunks/vidstack-BZIhWvGa.js +0 -1371
- package/dev/chunks/vidstack-vz-aZSfo.js +0 -1497
- package/prod/chunks/vidstack-D8qjOk_1.js +0 -1497
- package/prod/chunks/vidstack-WsodkLQg.js +0 -1371
- package/server/chunks/vidstack-2zMSe4ym.js +0 -1371
- package/server/chunks/vidstack-CJLEk6TF.js +0 -1497
|
@@ -1,1497 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
import { useSignal, composeRefs, isBoolean, uppercaseFirstChar, isUndefined, isString, signal, camelToKebabCase, onDispose, scoped, keysOf, effect, isArray, isKeyboardClick, listenEvent, toggleClass, useContext } from './vidstack-D_bWd66h.js';
|
|
5
|
-
import { createComputed, createSignal, MediaAnnouncer, Root, Trigger, Content, GoogleCastButton, Captions, useChapterOptions, Root$1 as Root$5, Root$2 as Root$6, Root$3 as Root$7, useScoped, Root$4 as Root$a, Group, useChapterTitle, createEffect, useActiveTextTrack, ChapterTitle as ChapterTitle$1, Title, Root$5 as Root$b, Track as Track$1, TrackFill as TrackFill$1 } from './vidstack-f6WXkmfP.js';
|
|
6
|
-
import { useColorSchemePreference, useActive, useResizeObserver, useLayoutName, useTransitionActive } from './vidstack-CvWDiSTs.js';
|
|
7
|
-
import { useMediaContext, MuteButton, SeekButton, LiveButton, PlayButton, CaptionButton, appendParamsToURL, PIPButton, FullscreenButton, AirPlayButton, Items, Root$3 as Root$1, Item, Root as Root$2, Img, Root$2 as Root$3, Button, Portal, Track, TrackFill, Thumb, Steps, useMediaPlayer, Root$5 as Root$4, useAudioOptions, useCaptionOptions, Root$4 as Root$8, Preview, Value, Root$1 as Root$9, Chapters, Progress, Thumbnail, ChapterTitle, Time, Gesture } from './vidstack-B-FM4-oZ.js';
|
|
8
|
-
import { useMediaState, isTrackCaptionKind, getDownloadFile, isRemotionSrc, IS_SERVER, useMediaContext as useMediaContext$1, sortVideoQualities, Primitive, mediaContext } from './vidstack-BDiAEW1N.js';
|
|
9
|
-
import { flushSync } from 'react-dom';
|
|
10
|
-
import { RemotionThumbnail, RemotionSliderThumbnail } from './vidstack-D-hQD1eE.js';
|
|
11
|
-
|
|
12
|
-
const DefaultLayoutContext = React.createContext({});
|
|
13
|
-
DefaultLayoutContext.displayName = "DefaultLayoutContext";
|
|
14
|
-
function useDefaultLayoutContext() {
|
|
15
|
-
return React.useContext(DefaultLayoutContext);
|
|
16
|
-
}
|
|
17
|
-
function useDefaultLayoutWord(word) {
|
|
18
|
-
const { translations } = useDefaultLayoutContext();
|
|
19
|
-
return i18n(translations, word);
|
|
20
|
-
}
|
|
21
|
-
function i18n(translations, word) {
|
|
22
|
-
return translations?.[word] ?? word;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function useColorSchemeClass(colorScheme) {
|
|
26
|
-
const systemColorPreference = useColorSchemePreference();
|
|
27
|
-
if (colorScheme === "default") {
|
|
28
|
-
return null;
|
|
29
|
-
} else if (colorScheme === "system") {
|
|
30
|
-
return systemColorPreference;
|
|
31
|
-
} else {
|
|
32
|
-
return colorScheme;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function createDefaultMediaLayout({
|
|
37
|
-
type,
|
|
38
|
-
smLayoutWhen,
|
|
39
|
-
renderLayout
|
|
40
|
-
}) {
|
|
41
|
-
const Layout = React.forwardRef(
|
|
42
|
-
({
|
|
43
|
-
children,
|
|
44
|
-
className,
|
|
45
|
-
disableTimeSlider = false,
|
|
46
|
-
hideQualityBitrate = false,
|
|
47
|
-
icons,
|
|
48
|
-
colorScheme = "system",
|
|
49
|
-
download = null,
|
|
50
|
-
menuContainer = null,
|
|
51
|
-
menuGroup = "bottom",
|
|
52
|
-
noAudioGain = false,
|
|
53
|
-
audioGains = { min: 0, max: 300, step: 25 },
|
|
54
|
-
noGestures = false,
|
|
55
|
-
noKeyboardAnimations = false,
|
|
56
|
-
noModal = false,
|
|
57
|
-
noScrubGesture,
|
|
58
|
-
playbackRates = { min: 0, max: 2, step: 0.25 },
|
|
59
|
-
seekStep = 10,
|
|
60
|
-
episodes = null,
|
|
61
|
-
episodesTitle = "Episodes",
|
|
62
|
-
showMenuDelay,
|
|
63
|
-
showTooltipDelay = 700,
|
|
64
|
-
sliderChaptersMinWidth = 325,
|
|
65
|
-
slots,
|
|
66
|
-
smallLayoutWhen = smLayoutWhen,
|
|
67
|
-
thumbnails = null,
|
|
68
|
-
translations,
|
|
69
|
-
...props
|
|
70
|
-
}, forwardRef) => {
|
|
71
|
-
const media = useMediaContext(), $load = useSignal(media.$props.load), $canLoad = useMediaState("canLoad"), $viewType = useMediaState("viewType"), $streamType = useMediaState("streamType"), $smallWhen = createComputed(() => {
|
|
72
|
-
return isBoolean(smallLayoutWhen) ? smallLayoutWhen : smallLayoutWhen(media.player.state);
|
|
73
|
-
}, [smallLayoutWhen]), userPrefersAnnouncements = createSignal(true), userPrefersKeyboardAnimations = createSignal(true), isMatch = $viewType === type, isSmallLayout = $smallWhen(), isForcedLayout = isBoolean(smallLayoutWhen), isLoadLayout = $load === "play" && !$canLoad, canRender = $canLoad || isForcedLayout || isLoadLayout, colorSchemeClass = useColorSchemeClass(colorScheme), layoutEl = createSignal(null);
|
|
74
|
-
useSignal($smallWhen);
|
|
75
|
-
return /* @__PURE__ */ React.createElement(
|
|
76
|
-
"div",
|
|
77
|
-
{
|
|
78
|
-
...props,
|
|
79
|
-
className: `vds-${type}-layout` + (colorSchemeClass ? ` ${colorSchemeClass}` : "") + (className ? ` ${className}` : ""),
|
|
80
|
-
"data-match": isMatch ? "" : null,
|
|
81
|
-
"data-sm": isSmallLayout ? "" : null,
|
|
82
|
-
"data-lg": !isSmallLayout ? "" : null,
|
|
83
|
-
"data-size": isSmallLayout ? "sm" : "lg",
|
|
84
|
-
"data-no-scrub-gesture": noScrubGesture ? "" : null,
|
|
85
|
-
ref: composeRefs(layoutEl.set, forwardRef)
|
|
86
|
-
},
|
|
87
|
-
canRender && isMatch ? /* @__PURE__ */ React.createElement(
|
|
88
|
-
DefaultLayoutContext.Provider,
|
|
89
|
-
{
|
|
90
|
-
value: {
|
|
91
|
-
disableTimeSlider,
|
|
92
|
-
hideQualityBitrate,
|
|
93
|
-
icons,
|
|
94
|
-
colorScheme,
|
|
95
|
-
download,
|
|
96
|
-
isSmallLayout,
|
|
97
|
-
menuContainer,
|
|
98
|
-
menuGroup,
|
|
99
|
-
noAudioGain,
|
|
100
|
-
audioGains,
|
|
101
|
-
layoutEl,
|
|
102
|
-
noGestures,
|
|
103
|
-
noKeyboardAnimations,
|
|
104
|
-
noModal,
|
|
105
|
-
noScrubGesture,
|
|
106
|
-
showMenuDelay,
|
|
107
|
-
showTooltipDelay,
|
|
108
|
-
sliderChaptersMinWidth,
|
|
109
|
-
slots,
|
|
110
|
-
seekStep,
|
|
111
|
-
episodes,
|
|
112
|
-
episodesTitle,
|
|
113
|
-
playbackRates,
|
|
114
|
-
thumbnails,
|
|
115
|
-
translations,
|
|
116
|
-
userPrefersAnnouncements,
|
|
117
|
-
userPrefersKeyboardAnimations
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
renderLayout({ streamType: $streamType, isSmallLayout, isLoadLayout }),
|
|
121
|
-
children
|
|
122
|
-
) : null
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
);
|
|
126
|
-
Layout.displayName = "DefaultMediaLayout";
|
|
127
|
-
return Layout;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function useDefaultAudioLayoutSlots() {
|
|
131
|
-
return React.useContext(DefaultLayoutContext).slots;
|
|
132
|
-
}
|
|
133
|
-
function useDefaultVideoLayoutSlots() {
|
|
134
|
-
return React.useContext(DefaultLayoutContext).slots;
|
|
135
|
-
}
|
|
136
|
-
function slot(slots, name, defaultValue) {
|
|
137
|
-
const slot2 = slots?.[name], capitalizedName = uppercaseFirstChar(name);
|
|
138
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, slots?.[`before${capitalizedName}`], isUndefined(slot2) ? defaultValue : slot2, slots?.[`after${capitalizedName}`]);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function DefaultAnnouncer() {
|
|
142
|
-
const { userPrefersAnnouncements, translations } = useDefaultLayoutContext(), $userPrefersAnnouncements = useSignal(userPrefersAnnouncements);
|
|
143
|
-
if (!$userPrefersAnnouncements) return null;
|
|
144
|
-
return /* @__PURE__ */ React.createElement(MediaAnnouncer, { translations });
|
|
145
|
-
}
|
|
146
|
-
DefaultAnnouncer.displayName = "DefaultAnnouncer";
|
|
147
|
-
|
|
148
|
-
function DefaultTooltip({ content, placement, children }) {
|
|
149
|
-
const { showTooltipDelay } = useDefaultLayoutContext();
|
|
150
|
-
return /* @__PURE__ */ React.createElement(Root, { showDelay: showTooltipDelay }, /* @__PURE__ */ React.createElement(Trigger, { asChild: true }, children), /* @__PURE__ */ React.createElement(Content, { className: "vds-tooltip-content", placement }, content));
|
|
151
|
-
}
|
|
152
|
-
DefaultTooltip.displayName = "DefaultTooltip";
|
|
153
|
-
|
|
154
|
-
function DefaultPlayButton({ tooltip }) {
|
|
155
|
-
const { icons: Icons } = useDefaultLayoutContext(), playText = useDefaultLayoutWord("Play"), pauseText = useDefaultLayoutWord("Pause"), $paused = useMediaState("paused"), $ended = useMediaState("ended");
|
|
156
|
-
return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: $paused ? playText : pauseText, placement: tooltip }, /* @__PURE__ */ React.createElement(PlayButton, { className: "vds-play-button vds-button", "aria-label": playText }, $ended ? /* @__PURE__ */ React.createElement(Icons.PlayButton.Replay, { className: "vds-icon" }) : $paused ? /* @__PURE__ */ React.createElement(Icons.PlayButton.Play, { className: "vds-icon" }) : /* @__PURE__ */ React.createElement(Icons.PlayButton.Pause, { className: "vds-icon" })));
|
|
157
|
-
}
|
|
158
|
-
DefaultPlayButton.displayName = "DefaultPlayButton";
|
|
159
|
-
const DefaultMuteButton = React.forwardRef(
|
|
160
|
-
({ tooltip }, forwardRef) => {
|
|
161
|
-
const { icons: Icons } = useDefaultLayoutContext(), muteText = useDefaultLayoutWord("Mute"), unmuteText = useDefaultLayoutWord("Unmute"), $muted = useMediaState("muted"), $volume = useMediaState("volume");
|
|
162
|
-
return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: $muted ? unmuteText : muteText, placement: tooltip }, /* @__PURE__ */ React.createElement(MuteButton, { className: "vds-mute-button vds-button", "aria-label": muteText, ref: forwardRef }, $muted || $volume == 0 ? /* @__PURE__ */ React.createElement(Icons.MuteButton.Mute, { className: "vds-icon" }) : $volume < 0.5 ? /* @__PURE__ */ React.createElement(Icons.MuteButton.VolumeLow, { className: "vds-icon" }) : /* @__PURE__ */ React.createElement(Icons.MuteButton.VolumeHigh, { className: "vds-icon" })));
|
|
163
|
-
}
|
|
164
|
-
);
|
|
165
|
-
DefaultMuteButton.displayName = "DefaultMuteButton";
|
|
166
|
-
function DefaultCaptionButton({ tooltip }) {
|
|
167
|
-
const { icons: Icons } = useDefaultLayoutContext(), captionsText = useDefaultLayoutWord("Captions"), onText = useDefaultLayoutWord("Closed-Captions On"), offText = useDefaultLayoutWord("Closed-Captions Off"), $track = useMediaState("textTrack"), isOn = $track && isTrackCaptionKind($track);
|
|
168
|
-
return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: isOn ? onText : offText, placement: tooltip }, /* @__PURE__ */ React.createElement(CaptionButton, { className: "vds-caption-button vds-button", "aria-label": captionsText }, isOn ? /* @__PURE__ */ React.createElement(Icons.CaptionButton.On, { className: "vds-icon" }) : /* @__PURE__ */ React.createElement(Icons.CaptionButton.Off, { className: "vds-icon" })));
|
|
169
|
-
}
|
|
170
|
-
DefaultCaptionButton.displayName = "DefaultCaptionButton";
|
|
171
|
-
function DefaultPIPButton({ tooltip }) {
|
|
172
|
-
const { icons: Icons } = useDefaultLayoutContext(), pipText = useDefaultLayoutWord("PiP"), enterText = useDefaultLayoutWord("Enter PiP"), exitText = useDefaultLayoutWord("Exit PiP"), $pip = useMediaState("pictureInPicture");
|
|
173
|
-
return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: $pip ? exitText : enterText, placement: tooltip }, /* @__PURE__ */ React.createElement(PIPButton, { className: "vds-pip-button vds-button", "aria-label": pipText }, $pip ? /* @__PURE__ */ React.createElement(Icons.PIPButton.Exit, { className: "vds-icon" }) : /* @__PURE__ */ React.createElement(Icons.PIPButton.Enter, { className: "vds-icon" })));
|
|
174
|
-
}
|
|
175
|
-
DefaultPIPButton.displayName = "DefaultPIPButton";
|
|
176
|
-
function DefaultFullscreenButton({ tooltip }) {
|
|
177
|
-
const { icons: Icons } = useDefaultLayoutContext(), fullscreenText = useDefaultLayoutWord("Fullscreen"), enterText = useDefaultLayoutWord("Enter Fullscreen"), exitText = useDefaultLayoutWord("Exit Fullscreen"), $fullscreen = useMediaState("fullscreen");
|
|
178
|
-
return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: $fullscreen ? exitText : enterText, placement: tooltip }, /* @__PURE__ */ React.createElement(FullscreenButton, { className: "vds-fullscreen-button vds-button", "aria-label": fullscreenText }, $fullscreen ? /* @__PURE__ */ React.createElement(Icons.FullscreenButton.Exit, { className: "vds-icon" }) : /* @__PURE__ */ React.createElement(Icons.FullscreenButton.Enter, { className: "vds-icon" })));
|
|
179
|
-
}
|
|
180
|
-
DefaultFullscreenButton.displayName = "DefaultFullscreenButton";
|
|
181
|
-
function DefaultSeekButton({
|
|
182
|
-
backward,
|
|
183
|
-
tooltip
|
|
184
|
-
}) {
|
|
185
|
-
const { icons: Icons, seekStep } = useDefaultLayoutContext(), seekForwardText = useDefaultLayoutWord("Seek Forward"), seekBackwardText = useDefaultLayoutWord("Seek Backward"), seconds = (backward ? -1 : 1) * seekStep, label = seconds >= 0 ? seekForwardText : seekBackwardText;
|
|
186
|
-
return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: label, placement: tooltip }, /* @__PURE__ */ React.createElement(SeekButton, { className: "vds-seek-button vds-button", seconds, "aria-label": label }, seconds >= 0 ? /* @__PURE__ */ React.createElement(Icons.SeekButton.Forward, { className: "vds-icon" }) : /* @__PURE__ */ React.createElement(Icons.SeekButton.Backward, { className: "vds-icon" })));
|
|
187
|
-
}
|
|
188
|
-
DefaultSeekButton.displayName = "DefaultSeekButton";
|
|
189
|
-
function DefaultEpisodeButton({ tooltip, onPress }) {
|
|
190
|
-
const { icons: Icons } = useDefaultLayoutContext(), episodesText = useDefaultLayoutWord("Episodes");
|
|
191
|
-
return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: episodesText, placement: tooltip }, /* @__PURE__ */ React.createElement(
|
|
192
|
-
"button",
|
|
193
|
-
{
|
|
194
|
-
type: "button",
|
|
195
|
-
className: "vds-episode-button vds-button",
|
|
196
|
-
"aria-label": episodesText,
|
|
197
|
-
onPointerUp: (event) => {
|
|
198
|
-
event.stopPropagation();
|
|
199
|
-
onPress?.(event);
|
|
200
|
-
}
|
|
201
|
-
},
|
|
202
|
-
/* @__PURE__ */ React.createElement(Icons.Menu.Chapters, { className: "vds-icon" })
|
|
203
|
-
));
|
|
204
|
-
}
|
|
205
|
-
DefaultEpisodeButton.displayName = "DefaultEpisodeButton";
|
|
206
|
-
function DefaultAirPlayButton({ tooltip }) {
|
|
207
|
-
const { icons: Icons } = useDefaultLayoutContext(), airPlayText = useDefaultLayoutWord("AirPlay"), $state = useMediaState("remotePlaybackState"), stateText = useDefaultLayoutWord(uppercaseFirstChar($state)), label = `${airPlayText} ${stateText}`, Icon = ($state === "connecting" ? Icons.AirPlayButton.Connecting : $state === "connected" ? Icons.AirPlayButton.Connected : null) ?? Icons.AirPlayButton.Default;
|
|
208
|
-
return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: airPlayText, placement: tooltip }, /* @__PURE__ */ React.createElement(AirPlayButton, { className: "vds-airplay-button vds-button", "aria-label": label }, /* @__PURE__ */ React.createElement(Icon, { className: "vds-icon" })));
|
|
209
|
-
}
|
|
210
|
-
DefaultAirPlayButton.displayName = "DefaultAirPlayButton";
|
|
211
|
-
function DefaultGoogleCastButton({ tooltip }) {
|
|
212
|
-
const { icons: Icons } = useDefaultLayoutContext(), googleCastText = useDefaultLayoutWord("Google Cast"), $state = useMediaState("remotePlaybackState"), stateText = useDefaultLayoutWord(uppercaseFirstChar($state)), label = `${googleCastText} ${stateText}`, Icon = ($state === "connecting" ? Icons.GoogleCastButton.Connecting : $state === "connected" ? Icons.GoogleCastButton.Connected : null) ?? Icons.GoogleCastButton.Default;
|
|
213
|
-
return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: googleCastText, placement: tooltip }, /* @__PURE__ */ React.createElement(GoogleCastButton, { className: "vds-google-cast-button vds-button", "aria-label": label }, /* @__PURE__ */ React.createElement(Icon, { className: "vds-icon" })));
|
|
214
|
-
}
|
|
215
|
-
DefaultGoogleCastButton.displayName = "DefaultGoogleCastButton";
|
|
216
|
-
function DefaultLiveButton() {
|
|
217
|
-
const $live = useMediaState("live"), label = useDefaultLayoutWord("Skip To Live"), liveText = useDefaultLayoutWord("LIVE");
|
|
218
|
-
return $live ? /* @__PURE__ */ React.createElement(LiveButton, { className: "vds-live-button", "aria-label": label }, /* @__PURE__ */ React.createElement("span", { className: "vds-live-button-text" }, liveText)) : null;
|
|
219
|
-
}
|
|
220
|
-
DefaultLiveButton.displayName = "DefaultLiveButton";
|
|
221
|
-
function DefaultDownloadButton() {
|
|
222
|
-
const { download, icons: Icons } = useDefaultLayoutContext(), $src = useMediaState("source"), $title = useMediaState("title"), file = getDownloadFile({
|
|
223
|
-
title: $title,
|
|
224
|
-
src: $src,
|
|
225
|
-
download
|
|
226
|
-
}), downloadText = useDefaultLayoutWord("Download");
|
|
227
|
-
return isString(file?.url) ? /* @__PURE__ */ React.createElement(DefaultTooltip, { content: downloadText, placement: "top" }, /* @__PURE__ */ React.createElement(
|
|
228
|
-
"a",
|
|
229
|
-
{
|
|
230
|
-
role: "button",
|
|
231
|
-
className: "vds-download-button vds-button",
|
|
232
|
-
"aria-label": downloadText,
|
|
233
|
-
href: appendParamsToURL(file.url, { download: file.name }),
|
|
234
|
-
download: file.name,
|
|
235
|
-
target: "_blank"
|
|
236
|
-
},
|
|
237
|
-
Icons.DownloadButton ? /* @__PURE__ */ React.createElement(Icons.DownloadButton.Default, { className: "vds-icon" }) : null
|
|
238
|
-
)) : null;
|
|
239
|
-
}
|
|
240
|
-
DefaultDownloadButton.displayName = "DefaultDownloadButton";
|
|
241
|
-
|
|
242
|
-
function DefaultCaptions() {
|
|
243
|
-
const exampleText = useDefaultLayoutWord("Captions look like this");
|
|
244
|
-
return /* @__PURE__ */ React.createElement(Captions, { className: "vds-captions", exampleText });
|
|
245
|
-
}
|
|
246
|
-
DefaultCaptions.displayName = "DefaultCaptions";
|
|
247
|
-
|
|
248
|
-
function DefaultControlsSpacer() {
|
|
249
|
-
return /* @__PURE__ */ React.createElement("div", { className: "vds-controls-spacer" });
|
|
250
|
-
}
|
|
251
|
-
DefaultControlsSpacer.displayName = "DefaultControlsSpacer";
|
|
252
|
-
|
|
253
|
-
function useParentDialogEl() {
|
|
254
|
-
const { layoutEl } = useDefaultLayoutContext(), $layoutEl = useSignal(layoutEl);
|
|
255
|
-
return React.useMemo(() => $layoutEl?.closest("dialog"), [$layoutEl]);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
function DefaultChaptersMenu({ tooltip, placement, portalClass = "" }) {
|
|
259
|
-
const {
|
|
260
|
-
showMenuDelay,
|
|
261
|
-
noModal,
|
|
262
|
-
isSmallLayout,
|
|
263
|
-
icons: Icons,
|
|
264
|
-
menuGroup,
|
|
265
|
-
menuContainer,
|
|
266
|
-
colorScheme
|
|
267
|
-
} = useDefaultLayoutContext(), chaptersText = useDefaultLayoutWord("Chapters"), options = useChapterOptions(), disabled = !options.length, { thumbnails } = useDefaultLayoutContext(), $src = useMediaState("currentSrc"), $viewType = useMediaState("viewType"), $offset = !isSmallLayout && menuGroup === "bottom" && $viewType === "video" ? 26 : 0, $RemotionThumbnail = useSignal(RemotionThumbnail), colorSchemeClass = useColorSchemeClass(colorScheme), [isOpen, setIsOpen] = React.useState(false), dialogEl = useParentDialogEl();
|
|
268
|
-
if (disabled) return null;
|
|
269
|
-
function onOpen() {
|
|
270
|
-
flushSync(() => {
|
|
271
|
-
setIsOpen(true);
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
function onClose() {
|
|
275
|
-
setIsOpen(false);
|
|
276
|
-
}
|
|
277
|
-
const Content = /* @__PURE__ */ React.createElement(
|
|
278
|
-
Items,
|
|
279
|
-
{
|
|
280
|
-
className: "vds-chapters-menu-items vds-menu-items",
|
|
281
|
-
placement,
|
|
282
|
-
offset: $offset
|
|
283
|
-
},
|
|
284
|
-
isOpen ? /* @__PURE__ */ React.createElement(
|
|
285
|
-
Root$1,
|
|
286
|
-
{
|
|
287
|
-
className: "vds-chapters-radio-group vds-radio-group",
|
|
288
|
-
value: options.selectedValue,
|
|
289
|
-
"data-thumbnails": thumbnails ? "" : null
|
|
290
|
-
},
|
|
291
|
-
options.map(
|
|
292
|
-
({ cue, label, value, startTimeText, durationText, select, setProgressVar }) => /* @__PURE__ */ React.createElement(
|
|
293
|
-
Item,
|
|
294
|
-
{
|
|
295
|
-
className: "vds-chapter-radio vds-radio",
|
|
296
|
-
value,
|
|
297
|
-
key: value,
|
|
298
|
-
onSelect: select,
|
|
299
|
-
ref: setProgressVar
|
|
300
|
-
},
|
|
301
|
-
thumbnails ? /* @__PURE__ */ React.createElement(Root$2, { src: thumbnails, className: "vds-thumbnail", time: cue.startTime }, /* @__PURE__ */ React.createElement(Img, null)) : $RemotionThumbnail && isRemotionSrc($src) ? /* @__PURE__ */ React.createElement($RemotionThumbnail, { className: "vds-thumbnail", frame: cue.startTime * $src.fps }) : null,
|
|
302
|
-
/* @__PURE__ */ React.createElement("div", { className: "vds-chapter-radio-content" }, /* @__PURE__ */ React.createElement("span", { className: "vds-chapter-radio-label" }, label), /* @__PURE__ */ React.createElement("span", { className: "vds-chapter-radio-start-time" }, startTimeText), /* @__PURE__ */ React.createElement("span", { className: "vds-chapter-radio-duration" }, durationText))
|
|
303
|
-
)
|
|
304
|
-
)
|
|
305
|
-
) : null
|
|
306
|
-
);
|
|
307
|
-
return /* @__PURE__ */ React.createElement(
|
|
308
|
-
Root$3,
|
|
309
|
-
{
|
|
310
|
-
className: "vds-chapters-menu vds-menu",
|
|
311
|
-
showDelay: showMenuDelay,
|
|
312
|
-
onOpen,
|
|
313
|
-
onClose
|
|
314
|
-
},
|
|
315
|
-
/* @__PURE__ */ React.createElement(DefaultTooltip, { content: chaptersText, placement: tooltip }, /* @__PURE__ */ React.createElement(
|
|
316
|
-
Button,
|
|
317
|
-
{
|
|
318
|
-
className: "vds-menu-button vds-button",
|
|
319
|
-
disabled,
|
|
320
|
-
"aria-label": chaptersText
|
|
321
|
-
},
|
|
322
|
-
/* @__PURE__ */ React.createElement(Icons.Menu.Chapters, { className: "vds-icon" })
|
|
323
|
-
)),
|
|
324
|
-
noModal || !isSmallLayout ? Content : /* @__PURE__ */ React.createElement(
|
|
325
|
-
Portal,
|
|
326
|
-
{
|
|
327
|
-
container: menuContainer ?? dialogEl,
|
|
328
|
-
className: portalClass + (colorSchemeClass ? ` ${colorSchemeClass}` : ""),
|
|
329
|
-
disabled: "fullscreen",
|
|
330
|
-
"data-sm": isSmallLayout ? "" : null,
|
|
331
|
-
"data-lg": !isSmallLayout ? "" : null,
|
|
332
|
-
"data-size": isSmallLayout ? "sm" : "lg"
|
|
333
|
-
},
|
|
334
|
-
Content
|
|
335
|
-
)
|
|
336
|
-
);
|
|
337
|
-
}
|
|
338
|
-
DefaultChaptersMenu.displayName = "DefaultChaptersMenu";
|
|
339
|
-
|
|
340
|
-
const FONT_COLOR_OPTION = {
|
|
341
|
-
type: "color"
|
|
342
|
-
};
|
|
343
|
-
const FONT_FAMILY_OPTION = {
|
|
344
|
-
type: "radio",
|
|
345
|
-
values: {
|
|
346
|
-
"Monospaced Serif": "mono-serif",
|
|
347
|
-
"Proportional Serif": "pro-serif",
|
|
348
|
-
"Monospaced Sans-Serif": "mono-sans",
|
|
349
|
-
"Proportional Sans-Serif": "pro-sans",
|
|
350
|
-
Casual: "casual",
|
|
351
|
-
Cursive: "cursive",
|
|
352
|
-
"Small Capitals": "capitals"
|
|
353
|
-
}
|
|
354
|
-
};
|
|
355
|
-
const FONT_SIZE_OPTION = {
|
|
356
|
-
type: "slider",
|
|
357
|
-
min: 0,
|
|
358
|
-
max: 400,
|
|
359
|
-
step: 25,
|
|
360
|
-
upIcon: null,
|
|
361
|
-
downIcon: null
|
|
362
|
-
};
|
|
363
|
-
const FONT_OPACITY_OPTION = {
|
|
364
|
-
type: "slider",
|
|
365
|
-
min: 0,
|
|
366
|
-
max: 100,
|
|
367
|
-
step: 5,
|
|
368
|
-
upIcon: null,
|
|
369
|
-
downIcon: null
|
|
370
|
-
};
|
|
371
|
-
const FONT_TEXT_SHADOW_OPTION = {
|
|
372
|
-
type: "radio",
|
|
373
|
-
values: ["None", "Drop Shadow", "Raised", "Depressed", "Outline"]
|
|
374
|
-
};
|
|
375
|
-
const FONT_DEFAULTS = {
|
|
376
|
-
fontFamily: "pro-sans",
|
|
377
|
-
fontSize: "100%",
|
|
378
|
-
textColor: "#ffffff",
|
|
379
|
-
textOpacity: "100%",
|
|
380
|
-
textShadow: "none",
|
|
381
|
-
textBg: "#000000",
|
|
382
|
-
textBgOpacity: "100%",
|
|
383
|
-
displayBg: "#000000",
|
|
384
|
-
displayBgOpacity: "0%"
|
|
385
|
-
};
|
|
386
|
-
const FONT_SIGNALS = Object.keys(FONT_DEFAULTS).reduce(
|
|
387
|
-
(prev, type) => ({
|
|
388
|
-
...prev,
|
|
389
|
-
[type]: signal(FONT_DEFAULTS[type])
|
|
390
|
-
}),
|
|
391
|
-
{}
|
|
392
|
-
);
|
|
393
|
-
if (!IS_SERVER) {
|
|
394
|
-
for (const type of Object.keys(FONT_SIGNALS)) {
|
|
395
|
-
const value = localStorage.getItem(`vds-player:${camelToKebabCase(type)}`);
|
|
396
|
-
if (isString(value)) FONT_SIGNALS[type].set(value);
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
function onFontReset() {
|
|
400
|
-
for (const type of Object.keys(FONT_SIGNALS)) {
|
|
401
|
-
const defaultValue = FONT_DEFAULTS[type];
|
|
402
|
-
FONT_SIGNALS[type].set(defaultValue);
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
function hexToRgb(hex) {
|
|
407
|
-
const { style } = new Option();
|
|
408
|
-
style.color = hex;
|
|
409
|
-
return style.color.match(/\((.*?)\)/)[1].replace(/,/g, " ");
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
let isWatchingVars = false, players = /* @__PURE__ */ new Set();
|
|
413
|
-
function updateFontCssVars() {
|
|
414
|
-
if (IS_SERVER) return;
|
|
415
|
-
const { player } = useMediaContext$1();
|
|
416
|
-
players.add(player);
|
|
417
|
-
onDispose(() => players.delete(player));
|
|
418
|
-
if (!isWatchingVars) {
|
|
419
|
-
scoped(() => {
|
|
420
|
-
for (const type of keysOf(FONT_SIGNALS)) {
|
|
421
|
-
const $value = FONT_SIGNALS[type], defaultValue = FONT_DEFAULTS[type], varName = `--media-user-${camelToKebabCase(type)}`, storageKey = `vds-player:${camelToKebabCase(type)}`;
|
|
422
|
-
effect(() => {
|
|
423
|
-
const value = $value(), isDefaultVarValue = value === defaultValue, varValue = !isDefaultVarValue ? getCssVarValue(player, type, value) : null;
|
|
424
|
-
for (const player2 of players) {
|
|
425
|
-
player2.el?.style.setProperty(varName, varValue);
|
|
426
|
-
}
|
|
427
|
-
if (isDefaultVarValue) {
|
|
428
|
-
localStorage.removeItem(storageKey);
|
|
429
|
-
} else {
|
|
430
|
-
localStorage.setItem(storageKey, value);
|
|
431
|
-
}
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
}, null);
|
|
435
|
-
isWatchingVars = true;
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
function getCssVarValue(player, type, value) {
|
|
439
|
-
switch (type) {
|
|
440
|
-
case "fontFamily":
|
|
441
|
-
const fontVariant = value === "capitals" ? "small-caps" : "";
|
|
442
|
-
player.el?.style.setProperty("--media-user-font-variant", fontVariant);
|
|
443
|
-
return getFontFamilyCSSVarValue(value);
|
|
444
|
-
case "fontSize":
|
|
445
|
-
case "textOpacity":
|
|
446
|
-
case "textBgOpacity":
|
|
447
|
-
case "displayBgOpacity":
|
|
448
|
-
return percentToRatio(value);
|
|
449
|
-
case "textColor":
|
|
450
|
-
return `rgb(${hexToRgb(value)} / var(--media-user-text-opacity, 1))`;
|
|
451
|
-
case "textShadow":
|
|
452
|
-
return getTextShadowCssVarValue(value);
|
|
453
|
-
case "textBg":
|
|
454
|
-
return `rgb(${hexToRgb(value)} / var(--media-user-text-bg-opacity, 1))`;
|
|
455
|
-
case "displayBg":
|
|
456
|
-
return `rgb(${hexToRgb(value)} / var(--media-user-display-bg-opacity, 1))`;
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
function percentToRatio(value) {
|
|
460
|
-
return (parseInt(value) / 100).toString();
|
|
461
|
-
}
|
|
462
|
-
function getFontFamilyCSSVarValue(value) {
|
|
463
|
-
switch (value) {
|
|
464
|
-
case "mono-serif":
|
|
465
|
-
return '"Courier New", Courier, "Nimbus Mono L", "Cutive Mono", monospace';
|
|
466
|
-
case "mono-sans":
|
|
467
|
-
return '"Deja Vu Sans Mono", "Lucida Console", Monaco, Consolas, "PT Mono", monospace';
|
|
468
|
-
case "pro-sans":
|
|
469
|
-
return 'Roboto, "Arial Unicode Ms", Arial, Helvetica, Verdana, "PT Sans Caption", sans-serif';
|
|
470
|
-
case "casual":
|
|
471
|
-
return '"Comic Sans MS", Impact, Handlee, fantasy';
|
|
472
|
-
case "cursive":
|
|
473
|
-
return '"Monotype Corsiva", "URW Chancery L", "Apple Chancery", "Dancing Script", cursive';
|
|
474
|
-
case "capitals":
|
|
475
|
-
return '"Arial Unicode Ms", Arial, Helvetica, Verdana, "Marcellus SC", sans-serif + font-variant=small-caps';
|
|
476
|
-
default:
|
|
477
|
-
return '"Times New Roman", Times, Georgia, Cambria, "PT Serif Caption", serif';
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
function getTextShadowCssVarValue(value) {
|
|
481
|
-
switch (value) {
|
|
482
|
-
case "drop shadow":
|
|
483
|
-
return "rgb(34, 34, 34) 1.86389px 1.86389px 2.79583px, rgb(34, 34, 34) 1.86389px 1.86389px 3.72778px, rgb(34, 34, 34) 1.86389px 1.86389px 4.65972px";
|
|
484
|
-
case "raised":
|
|
485
|
-
return "rgb(34, 34, 34) 1px 1px, rgb(34, 34, 34) 2px 2px";
|
|
486
|
-
case "depressed":
|
|
487
|
-
return "rgb(204, 204, 204) 1px 1px, rgb(34, 34, 34) -1px -1px";
|
|
488
|
-
case "outline":
|
|
489
|
-
return "rgb(34, 34, 34) 0px 0px 1.86389px, rgb(34, 34, 34) 0px 0px 1.86389px, rgb(34, 34, 34) 0px 0px 1.86389px, rgb(34, 34, 34) 0px 0px 1.86389px, rgb(34, 34, 34) 0px 0px 1.86389px";
|
|
490
|
-
default:
|
|
491
|
-
return "";
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
function DefaultMenuSection({ label, value, children }) {
|
|
496
|
-
const id = React.useId();
|
|
497
|
-
if (!label) {
|
|
498
|
-
return /* @__PURE__ */ React.createElement("div", { className: "vds-menu-section" }, /* @__PURE__ */ React.createElement("div", { className: "vds-menu-section-body" }, children));
|
|
499
|
-
}
|
|
500
|
-
return /* @__PURE__ */ React.createElement("section", { className: "vds-menu-section", role: "group", "aria-labelledby": id }, /* @__PURE__ */ React.createElement("div", { className: "vds-menu-section-title" }, /* @__PURE__ */ React.createElement("header", { id }, label), value ? /* @__PURE__ */ React.createElement("div", { className: "vds-menu-section-value" }, value) : null), /* @__PURE__ */ React.createElement("div", { className: "vds-menu-section-body" }, children));
|
|
501
|
-
}
|
|
502
|
-
DefaultMenuSection.displayName = "DefaultMenuSection";
|
|
503
|
-
function DefaultMenuButton({ label, hint = "", Icon, disabled = false }) {
|
|
504
|
-
const { icons: Icons } = React.useContext(DefaultLayoutContext);
|
|
505
|
-
return /* @__PURE__ */ React.createElement(Button, { className: "vds-menu-item", disabled }, /* @__PURE__ */ React.createElement(Icons.Menu.ArrowLeft, { className: "vds-menu-close-icon vds-icon" }), Icon ? /* @__PURE__ */ React.createElement(Icon, { className: "vds-menu-item-icon vds-icon" }) : null, /* @__PURE__ */ React.createElement("span", { className: "vds-menu-item-label" }, label), /* @__PURE__ */ React.createElement("span", { className: "vds-menu-item-hint" }, hint), /* @__PURE__ */ React.createElement(Icons.Menu.ArrowRight, { className: "vds-menu-open-icon vds-icon" }));
|
|
506
|
-
}
|
|
507
|
-
DefaultMenuButton.displayName = "DefaultMenuButton";
|
|
508
|
-
function DefaultMenuItem({ label, children }) {
|
|
509
|
-
return /* @__PURE__ */ React.createElement("div", { className: "vds-menu-item" }, /* @__PURE__ */ React.createElement("div", { className: "vds-menu-item-label" }, label), children);
|
|
510
|
-
}
|
|
511
|
-
DefaultMenuItem.displayName = "DefaultMenuItem";
|
|
512
|
-
function DefaultMenuRadioGroup({ value, options, onChange }) {
|
|
513
|
-
const { icons: Icons } = useDefaultLayoutContext();
|
|
514
|
-
return /* @__PURE__ */ React.createElement(Root$1, { className: "vds-radio-group", value, onChange }, options.map((option) => /* @__PURE__ */ React.createElement(Item, { className: "vds-radio", value: option.value, key: option.value }, /* @__PURE__ */ React.createElement(Icons.Menu.RadioCheck, { className: "vds-icon" }), /* @__PURE__ */ React.createElement("span", { className: "vds-radio-label", "data-part": "label" }, option.label))));
|
|
515
|
-
}
|
|
516
|
-
DefaultMenuRadioGroup.displayName = "DefaultMenuRadioGroup";
|
|
517
|
-
function createRadioOptions(entries) {
|
|
518
|
-
return React.useMemo(
|
|
519
|
-
() => isArray(entries) ? entries.map((entry) => ({ label: entry, value: entry.toLowerCase() })) : Object.keys(entries).map((label) => ({ label, value: entries[label] })),
|
|
520
|
-
[entries]
|
|
521
|
-
);
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
function DefaultMenuSliderItem({
|
|
525
|
-
label,
|
|
526
|
-
value,
|
|
527
|
-
UpIcon,
|
|
528
|
-
DownIcon,
|
|
529
|
-
children,
|
|
530
|
-
isMin,
|
|
531
|
-
isMax
|
|
532
|
-
}) {
|
|
533
|
-
const hasTitle = label || value, Content = /* @__PURE__ */ React.createElement(React.Fragment, null, DownIcon ? /* @__PURE__ */ React.createElement(DownIcon, { className: "vds-icon down" }) : null, children, UpIcon ? /* @__PURE__ */ React.createElement(UpIcon, { className: "vds-icon up" }) : null);
|
|
534
|
-
return /* @__PURE__ */ React.createElement(
|
|
535
|
-
"div",
|
|
536
|
-
{
|
|
537
|
-
className: `vds-menu-item vds-menu-slider-item${hasTitle ? " group" : ""}`,
|
|
538
|
-
"data-min": isMin ? "" : null,
|
|
539
|
-
"data-max": isMax ? "" : null
|
|
540
|
-
},
|
|
541
|
-
hasTitle ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "vds-menu-slider-title" }, label ? /* @__PURE__ */ React.createElement("div", null, label) : null, value ? /* @__PURE__ */ React.createElement("div", null, value) : null), /* @__PURE__ */ React.createElement("div", { className: "vds-menu-slider-body" }, Content)) : Content
|
|
542
|
-
);
|
|
543
|
-
}
|
|
544
|
-
DefaultMenuSliderItem.displayName = "DefaultMenuSliderItem";
|
|
545
|
-
function DefaultSliderParts() {
|
|
546
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Track, { className: "vds-slider-track" }), /* @__PURE__ */ React.createElement(TrackFill, { className: "vds-slider-track-fill vds-slider-track" }), /* @__PURE__ */ React.createElement(Thumb, { className: "vds-slider-thumb" }));
|
|
547
|
-
}
|
|
548
|
-
DefaultSliderParts.displayName = "DefaultSliderParts";
|
|
549
|
-
function DefaultSliderSteps() {
|
|
550
|
-
return /* @__PURE__ */ React.createElement(Steps, { className: "vds-slider-steps" }, (step) => /* @__PURE__ */ React.createElement("div", { className: "vds-slider-step", key: String(step) }));
|
|
551
|
-
}
|
|
552
|
-
DefaultSliderSteps.displayName = "DefaultSliderSteps";
|
|
553
|
-
|
|
554
|
-
function DefaultFontMenu() {
|
|
555
|
-
const label = useDefaultLayoutWord("Caption Styles"), $hasCaptions = useMediaState("hasCaptions"), fontSectionLabel = useDefaultLayoutWord("Font"), textSectionLabel = useDefaultLayoutWord("Text"), textBgSectionLabel = useDefaultLayoutWord("Text Background"), displayBgSectionLabel = useDefaultLayoutWord("Display Background");
|
|
556
|
-
if (!$hasCaptions) return null;
|
|
557
|
-
return /* @__PURE__ */ React.createElement(Root$3, { className: "vds-font-menu vds-menu" }, /* @__PURE__ */ React.createElement(DefaultMenuButton, { label }), /* @__PURE__ */ React.createElement(Items, { className: "vds-font-style-items vds-menu-items" }, /* @__PURE__ */ React.createElement(DefaultMenuSection, { label: fontSectionLabel }, /* @__PURE__ */ React.createElement(DefaultFontFamilyMenu, null), /* @__PURE__ */ React.createElement(DefaultFontSizeSlider, null)), /* @__PURE__ */ React.createElement(DefaultMenuSection, { label: textSectionLabel }, /* @__PURE__ */ React.createElement(DefaultTextColorInput, null), /* @__PURE__ */ React.createElement(DefaultTextShadowMenu, null), /* @__PURE__ */ React.createElement(DefaultTextOpacitySlider, null)), /* @__PURE__ */ React.createElement(DefaultMenuSection, { label: textBgSectionLabel }, /* @__PURE__ */ React.createElement(DefaultTextBgInput, null), /* @__PURE__ */ React.createElement(DefaultTextBgOpacitySlider, null)), /* @__PURE__ */ React.createElement(DefaultMenuSection, { label: displayBgSectionLabel }, /* @__PURE__ */ React.createElement(DefaultDisplayBgInput, null), /* @__PURE__ */ React.createElement(DefaultDisplayBgOpacitySlider, null)), /* @__PURE__ */ React.createElement(DefaultMenuSection, null, /* @__PURE__ */ React.createElement(DefaultResetMenuItem, null))));
|
|
558
|
-
}
|
|
559
|
-
DefaultFontMenu.displayName = "DefaultFontMenu";
|
|
560
|
-
function DefaultFontFamilyMenu() {
|
|
561
|
-
return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Family", type: "fontFamily", option: FONT_FAMILY_OPTION });
|
|
562
|
-
}
|
|
563
|
-
DefaultFontFamilyMenu.displayName = "DefaultFontFamilyMenu";
|
|
564
|
-
function DefaultFontSizeSlider() {
|
|
565
|
-
const { icons: Icons } = useDefaultLayoutContext(), option = {
|
|
566
|
-
...FONT_SIZE_OPTION,
|
|
567
|
-
upIcon: Icons.Menu.FontSizeUp,
|
|
568
|
-
downIcon: Icons.Menu.FontSizeDown
|
|
569
|
-
};
|
|
570
|
-
return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Size", type: "fontSize", option });
|
|
571
|
-
}
|
|
572
|
-
DefaultFontSizeSlider.displayName = "DefaultFontSizeSlider";
|
|
573
|
-
function DefaultTextColorInput() {
|
|
574
|
-
return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Color", type: "textColor", option: FONT_COLOR_OPTION });
|
|
575
|
-
}
|
|
576
|
-
DefaultTextColorInput.displayName = "DefaultTextColorInput";
|
|
577
|
-
function DefaultTextOpacitySlider() {
|
|
578
|
-
const { icons: Icons } = useDefaultLayoutContext(), option = {
|
|
579
|
-
...FONT_OPACITY_OPTION,
|
|
580
|
-
upIcon: Icons.Menu.OpacityUp,
|
|
581
|
-
downIcon: Icons.Menu.OpacityDown
|
|
582
|
-
};
|
|
583
|
-
return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Opacity", type: "textOpacity", option });
|
|
584
|
-
}
|
|
585
|
-
DefaultTextOpacitySlider.displayName = "DefaultTextOpacitySlider";
|
|
586
|
-
function DefaultTextShadowMenu() {
|
|
587
|
-
return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Shadow", type: "textShadow", option: FONT_TEXT_SHADOW_OPTION });
|
|
588
|
-
}
|
|
589
|
-
DefaultTextShadowMenu.displayName = "DefaultTextShadowMenu";
|
|
590
|
-
function DefaultTextBgInput() {
|
|
591
|
-
return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Color", type: "textBg", option: FONT_COLOR_OPTION });
|
|
592
|
-
}
|
|
593
|
-
DefaultTextBgInput.displayName = "DefaultTextBgInput";
|
|
594
|
-
function DefaultTextBgOpacitySlider() {
|
|
595
|
-
const { icons: Icons } = useDefaultLayoutContext(), option = {
|
|
596
|
-
...FONT_OPACITY_OPTION,
|
|
597
|
-
upIcon: Icons.Menu.OpacityUp,
|
|
598
|
-
downIcon: Icons.Menu.OpacityDown
|
|
599
|
-
};
|
|
600
|
-
return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Opacity", type: "textBgOpacity", option });
|
|
601
|
-
}
|
|
602
|
-
DefaultTextBgOpacitySlider.displayName = "DefaultTextBgOpacitySlider";
|
|
603
|
-
function DefaultDisplayBgInput() {
|
|
604
|
-
return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Color", type: "displayBg", option: FONT_COLOR_OPTION });
|
|
605
|
-
}
|
|
606
|
-
DefaultDisplayBgInput.displayName = "DefaultDisplayBgInput";
|
|
607
|
-
function DefaultDisplayBgOpacitySlider() {
|
|
608
|
-
const { icons: Icons } = useDefaultLayoutContext(), option = {
|
|
609
|
-
...FONT_OPACITY_OPTION,
|
|
610
|
-
upIcon: Icons.Menu.OpacityUp,
|
|
611
|
-
downIcon: Icons.Menu.OpacityDown
|
|
612
|
-
};
|
|
613
|
-
return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Opacity", type: "displayBgOpacity", option });
|
|
614
|
-
}
|
|
615
|
-
DefaultDisplayBgOpacitySlider.displayName = "DefaultDisplayBgOpacitySlider";
|
|
616
|
-
function DefaultFontSetting({ label, option, type }) {
|
|
617
|
-
const player = useMediaPlayer(), $currentValue = FONT_SIGNALS[type], $value = useSignal($currentValue), translatedLabel = useDefaultLayoutWord(label);
|
|
618
|
-
const notify = React.useCallback(() => {
|
|
619
|
-
player?.dispatchEvent(new Event("vds-font-change"));
|
|
620
|
-
}, [player]);
|
|
621
|
-
const onChange = React.useCallback(
|
|
622
|
-
(newValue) => {
|
|
623
|
-
$currentValue.set(newValue);
|
|
624
|
-
notify();
|
|
625
|
-
},
|
|
626
|
-
[$currentValue, notify]
|
|
627
|
-
);
|
|
628
|
-
if (option.type === "color") {
|
|
629
|
-
let onColorChange2 = function(event) {
|
|
630
|
-
onChange(event.target.value);
|
|
631
|
-
};
|
|
632
|
-
return /* @__PURE__ */ React.createElement(DefaultMenuItem, { label: translatedLabel }, /* @__PURE__ */ React.createElement("input", { className: "vds-color-picker", type: "color", value: $value, onChange: onColorChange2 }));
|
|
633
|
-
}
|
|
634
|
-
if (option.type === "slider") {
|
|
635
|
-
let onSliderValueChange2 = function(value) {
|
|
636
|
-
onChange(value + "%");
|
|
637
|
-
};
|
|
638
|
-
const { min, max, step, upIcon, downIcon } = option;
|
|
639
|
-
return /* @__PURE__ */ React.createElement(
|
|
640
|
-
DefaultMenuSliderItem,
|
|
641
|
-
{
|
|
642
|
-
label: translatedLabel,
|
|
643
|
-
value: $value,
|
|
644
|
-
UpIcon: upIcon,
|
|
645
|
-
DownIcon: downIcon,
|
|
646
|
-
isMin: $value === min + "%",
|
|
647
|
-
isMax: $value === max + "%"
|
|
648
|
-
},
|
|
649
|
-
/* @__PURE__ */ React.createElement(
|
|
650
|
-
Root$4,
|
|
651
|
-
{
|
|
652
|
-
className: "vds-slider",
|
|
653
|
-
min,
|
|
654
|
-
max,
|
|
655
|
-
step,
|
|
656
|
-
keyStep: step,
|
|
657
|
-
value: parseInt($value),
|
|
658
|
-
"aria-label": translatedLabel,
|
|
659
|
-
onValueChange: onSliderValueChange2,
|
|
660
|
-
onDragValueChange: onSliderValueChange2
|
|
661
|
-
},
|
|
662
|
-
/* @__PURE__ */ React.createElement(DefaultSliderParts, null),
|
|
663
|
-
/* @__PURE__ */ React.createElement(DefaultSliderSteps, null)
|
|
664
|
-
)
|
|
665
|
-
);
|
|
666
|
-
}
|
|
667
|
-
if (option.type === "radio") {
|
|
668
|
-
return /* @__PURE__ */ React.createElement(
|
|
669
|
-
DefaultFontRadioGroup,
|
|
670
|
-
{
|
|
671
|
-
id: camelToKebabCase(type),
|
|
672
|
-
label: translatedLabel,
|
|
673
|
-
value: $value,
|
|
674
|
-
values: option.values,
|
|
675
|
-
onChange
|
|
676
|
-
}
|
|
677
|
-
);
|
|
678
|
-
}
|
|
679
|
-
return null;
|
|
680
|
-
}
|
|
681
|
-
DefaultFontSetting.displayName = "DefaultFontSetting";
|
|
682
|
-
function DefaultFontRadioGroup({ id, label, value, values, onChange }) {
|
|
683
|
-
const radioOptions = createRadioOptions(values), { translations } = useDefaultLayoutContext(), hint = React.useMemo(() => {
|
|
684
|
-
const label2 = radioOptions.find((radio) => radio.value === value)?.label || "";
|
|
685
|
-
return i18n(translations, label2);
|
|
686
|
-
}, [value, radioOptions]);
|
|
687
|
-
return /* @__PURE__ */ React.createElement(Root$3, { className: `vds-${id}-menu vds-menu` }, /* @__PURE__ */ React.createElement(DefaultMenuButton, { label, hint }), /* @__PURE__ */ React.createElement(Items, { className: "vds-menu-items" }, /* @__PURE__ */ React.createElement(DefaultMenuRadioGroup, { value, options: radioOptions, onChange })));
|
|
688
|
-
}
|
|
689
|
-
DefaultFontRadioGroup.displayName = "DefaultFontRadioGroup";
|
|
690
|
-
function DefaultResetMenuItem() {
|
|
691
|
-
const resetText = useDefaultLayoutWord("Reset");
|
|
692
|
-
return /* @__PURE__ */ React.createElement("button", { className: "vds-menu-item", role: "menuitem", onClick: onFontReset }, /* @__PURE__ */ React.createElement("span", { className: "vds-menu-item-label" }, resetText));
|
|
693
|
-
}
|
|
694
|
-
DefaultResetMenuItem.displayName = "DefaultResetMenuItem";
|
|
695
|
-
|
|
696
|
-
function DefaultMenuCheckbox({
|
|
697
|
-
label,
|
|
698
|
-
checked,
|
|
699
|
-
storageKey,
|
|
700
|
-
defaultChecked = false,
|
|
701
|
-
onChange
|
|
702
|
-
}) {
|
|
703
|
-
const [isChecked, setIsChecked] = React.useState(defaultChecked), [isActive, setIsActive] = React.useState(false);
|
|
704
|
-
React.useEffect(() => {
|
|
705
|
-
const savedValue = storageKey ? localStorage.getItem(storageKey) : null, checked2 = !!(savedValue ?? defaultChecked);
|
|
706
|
-
setIsChecked(checked2);
|
|
707
|
-
onChange?.(checked2);
|
|
708
|
-
}, []);
|
|
709
|
-
React.useEffect(() => {
|
|
710
|
-
if (isBoolean(checked)) setIsChecked(checked);
|
|
711
|
-
}, [checked]);
|
|
712
|
-
function onPress(event) {
|
|
713
|
-
if (event && "button" in event && event?.button === 1) return;
|
|
714
|
-
const toggledCheck = !isChecked;
|
|
715
|
-
setIsChecked(toggledCheck);
|
|
716
|
-
if (storageKey) localStorage.setItem(storageKey, toggledCheck ? "1" : "");
|
|
717
|
-
onChange?.(toggledCheck, event?.nativeEvent);
|
|
718
|
-
setIsActive(false);
|
|
719
|
-
}
|
|
720
|
-
function onActive(event) {
|
|
721
|
-
if (event.button !== 0) return;
|
|
722
|
-
setIsActive(true);
|
|
723
|
-
}
|
|
724
|
-
function onKeyDown(event) {
|
|
725
|
-
if (isKeyboardClick(event.nativeEvent)) onPress();
|
|
726
|
-
}
|
|
727
|
-
return /* @__PURE__ */ React.createElement(
|
|
728
|
-
"div",
|
|
729
|
-
{
|
|
730
|
-
className: "vds-menu-checkbox",
|
|
731
|
-
role: "menuitemcheckbox",
|
|
732
|
-
tabIndex: 0,
|
|
733
|
-
"aria-label": label,
|
|
734
|
-
"aria-checked": isChecked ? "true" : "false",
|
|
735
|
-
"data-active": isActive ? "" : null,
|
|
736
|
-
onPointerUp: onPress,
|
|
737
|
-
onPointerDown: onActive,
|
|
738
|
-
onKeyDown
|
|
739
|
-
}
|
|
740
|
-
);
|
|
741
|
-
}
|
|
742
|
-
DefaultMenuCheckbox.displayName = "DefaultMenuCheckbox";
|
|
743
|
-
|
|
744
|
-
function DefaultAccessibilityMenu({ slots }) {
|
|
745
|
-
const label = useDefaultLayoutWord("Accessibility"), { icons: Icons } = useDefaultLayoutContext();
|
|
746
|
-
return /* @__PURE__ */ React.createElement(Root$3, { className: "vds-accessibility-menu vds-menu" }, /* @__PURE__ */ React.createElement(DefaultMenuButton, { label, Icon: Icons.Menu.Accessibility }), /* @__PURE__ */ React.createElement(Items, { className: "vds-menu-items" }, slot(slots, "accessibilityMenuItemsStart", null), /* @__PURE__ */ React.createElement(DefaultMenuSection, null, /* @__PURE__ */ React.createElement(DefaultAnnouncementsMenuCheckbox, null), /* @__PURE__ */ React.createElement(DefaultKeyboardAnimationsMenuCheckbox, null)), /* @__PURE__ */ React.createElement(DefaultMenuSection, null, /* @__PURE__ */ React.createElement(DefaultFontMenu, null)), slot(slots, "accessibilityMenuItemsEnd", null)));
|
|
747
|
-
}
|
|
748
|
-
DefaultAccessibilityMenu.displayName = "DefaultAccessibilityMenu";
|
|
749
|
-
function DefaultAnnouncementsMenuCheckbox() {
|
|
750
|
-
const { userPrefersAnnouncements } = useDefaultLayoutContext(), label = useDefaultLayoutWord("Announcements");
|
|
751
|
-
function onChange(checked) {
|
|
752
|
-
userPrefersAnnouncements.set(checked);
|
|
753
|
-
}
|
|
754
|
-
return /* @__PURE__ */ React.createElement(DefaultMenuItem, { label }, /* @__PURE__ */ React.createElement(
|
|
755
|
-
DefaultMenuCheckbox,
|
|
756
|
-
{
|
|
757
|
-
label,
|
|
758
|
-
defaultChecked: true,
|
|
759
|
-
storageKey: "vds-player::announcements",
|
|
760
|
-
onChange
|
|
761
|
-
}
|
|
762
|
-
));
|
|
763
|
-
}
|
|
764
|
-
DefaultAnnouncementsMenuCheckbox.displayName = "DefaultAnnouncementsMenuCheckbox";
|
|
765
|
-
function DefaultKeyboardAnimationsMenuCheckbox() {
|
|
766
|
-
const $viewType = useMediaState("viewType"), { userPrefersKeyboardAnimations, noKeyboardAnimations } = useDefaultLayoutContext(), label = useDefaultLayoutWord("Keyboard Animations");
|
|
767
|
-
if ($viewType !== "video" || noKeyboardAnimations) return null;
|
|
768
|
-
function onChange(checked) {
|
|
769
|
-
userPrefersKeyboardAnimations.set(checked);
|
|
770
|
-
}
|
|
771
|
-
return /* @__PURE__ */ React.createElement(DefaultMenuItem, { label }, /* @__PURE__ */ React.createElement(
|
|
772
|
-
DefaultMenuCheckbox,
|
|
773
|
-
{
|
|
774
|
-
label,
|
|
775
|
-
defaultChecked: true,
|
|
776
|
-
storageKey: "vds-player::keyboard-animations",
|
|
777
|
-
onChange
|
|
778
|
-
}
|
|
779
|
-
));
|
|
780
|
-
}
|
|
781
|
-
DefaultKeyboardAnimationsMenuCheckbox.displayName = "DefaultKeyboardAnimationsMenuCheckbox";
|
|
782
|
-
|
|
783
|
-
function DefaultAudioMenu({ slots }) {
|
|
784
|
-
const label = useDefaultLayoutWord("Audio"), $canSetAudioGain = useMediaState("canSetAudioGain"), $audioTracks = useMediaState("audioTracks"), { noAudioGain, icons: Icons } = useDefaultLayoutContext(), hasGainSlider = $canSetAudioGain && !noAudioGain, $disabled = !hasGainSlider && $audioTracks.length <= 1;
|
|
785
|
-
if ($disabled) return null;
|
|
786
|
-
return /* @__PURE__ */ React.createElement(Root$3, { className: "vds-audio-menu vds-menu" }, /* @__PURE__ */ React.createElement(DefaultMenuButton, { label, Icon: Icons.Menu.Audio }), /* @__PURE__ */ React.createElement(Items, { className: "vds-menu-items" }, slot(slots, "audioMenuItemsStart", null), /* @__PURE__ */ React.createElement(DefaultAudioTracksMenu, null), hasGainSlider ? /* @__PURE__ */ React.createElement(DefaultAudioBoostMenuSection, null) : null, slot(slots, "audioMenuItemsEnd", null)));
|
|
787
|
-
}
|
|
788
|
-
DefaultAudioMenu.displayName = "DefaultAudioMenu";
|
|
789
|
-
function DefaultAudioBoostMenuSection() {
|
|
790
|
-
const $audioGain = useMediaState("audioGain"), label = useDefaultLayoutWord("Boost"), value = Math.round((($audioGain ?? 1) - 1) * 100) + "%", $canSetAudioGain = useMediaState("canSetAudioGain"), { noAudioGain, icons: Icons } = useDefaultLayoutContext(), $disabled = !$canSetAudioGain || noAudioGain, min = useGainMin(), max = useGainMax();
|
|
791
|
-
if ($disabled) return null;
|
|
792
|
-
return /* @__PURE__ */ React.createElement(DefaultMenuSection, { label, value }, /* @__PURE__ */ React.createElement(
|
|
793
|
-
DefaultMenuSliderItem,
|
|
794
|
-
{
|
|
795
|
-
UpIcon: Icons.Menu.AudioBoostUp,
|
|
796
|
-
DownIcon: Icons.Menu.AudioBoostDown,
|
|
797
|
-
isMin: (($audioGain ?? 1) - 1) * 100 <= min,
|
|
798
|
-
isMax: (($audioGain ?? 1) - 1) * 100 === max
|
|
799
|
-
},
|
|
800
|
-
/* @__PURE__ */ React.createElement(DefaultAudioGainSlider, null)
|
|
801
|
-
));
|
|
802
|
-
}
|
|
803
|
-
DefaultAudioBoostMenuSection.displayName = "DefaultAudioBoostMenuSection";
|
|
804
|
-
function useGainMin() {
|
|
805
|
-
const { audioGains } = useDefaultLayoutContext(), min = isArray(audioGains) ? audioGains[0] : audioGains?.min;
|
|
806
|
-
return min ?? 0;
|
|
807
|
-
}
|
|
808
|
-
function useGainMax() {
|
|
809
|
-
const { audioGains } = useDefaultLayoutContext(), max = isArray(audioGains) ? audioGains[audioGains.length - 1] : audioGains?.max;
|
|
810
|
-
return max ?? 300;
|
|
811
|
-
}
|
|
812
|
-
function useGainStep() {
|
|
813
|
-
const { audioGains } = useDefaultLayoutContext(), step = isArray(audioGains) ? audioGains[1] - audioGains[0] : audioGains?.step;
|
|
814
|
-
return step || 25;
|
|
815
|
-
}
|
|
816
|
-
function DefaultAudioGainSlider() {
|
|
817
|
-
const label = useDefaultLayoutWord("Audio Boost"), min = useGainMin(), max = useGainMax(), step = useGainStep();
|
|
818
|
-
return /* @__PURE__ */ React.createElement(
|
|
819
|
-
Root$5,
|
|
820
|
-
{
|
|
821
|
-
className: "vds-audio-gain-slider vds-slider",
|
|
822
|
-
"aria-label": label,
|
|
823
|
-
min,
|
|
824
|
-
max,
|
|
825
|
-
step,
|
|
826
|
-
keyStep: step
|
|
827
|
-
},
|
|
828
|
-
/* @__PURE__ */ React.createElement(DefaultSliderParts, null),
|
|
829
|
-
/* @__PURE__ */ React.createElement(DefaultSliderSteps, null)
|
|
830
|
-
);
|
|
831
|
-
}
|
|
832
|
-
DefaultAudioGainSlider.displayName = "DefaultAudioGainSlider";
|
|
833
|
-
function DefaultAudioTracksMenu() {
|
|
834
|
-
const { icons: Icons } = useDefaultLayoutContext(), label = useDefaultLayoutWord("Track"), defaultText = useDefaultLayoutWord("Default"), $track = useMediaState("audioTrack"), options = useAudioOptions();
|
|
835
|
-
if (options.disabled) return null;
|
|
836
|
-
return /* @__PURE__ */ React.createElement(Root$3, { className: "vds-audio-track-menu vds-menu" }, /* @__PURE__ */ React.createElement(
|
|
837
|
-
DefaultMenuButton,
|
|
838
|
-
{
|
|
839
|
-
label,
|
|
840
|
-
hint: $track?.label ?? defaultText,
|
|
841
|
-
disabled: options.disabled,
|
|
842
|
-
Icon: Icons.Menu.Audio
|
|
843
|
-
}
|
|
844
|
-
), /* @__PURE__ */ React.createElement(Items, { className: "vds-menu-items" }, /* @__PURE__ */ React.createElement(
|
|
845
|
-
Root$1,
|
|
846
|
-
{
|
|
847
|
-
className: "vds-audio-radio-group vds-radio-group",
|
|
848
|
-
value: options.selectedValue
|
|
849
|
-
},
|
|
850
|
-
options.map(({ label: label2, value, select }) => /* @__PURE__ */ React.createElement(
|
|
851
|
-
Item,
|
|
852
|
-
{
|
|
853
|
-
className: "vds-audio-radio vds-radio",
|
|
854
|
-
value,
|
|
855
|
-
onSelect: select,
|
|
856
|
-
key: value
|
|
857
|
-
},
|
|
858
|
-
/* @__PURE__ */ React.createElement(Icons.Menu.RadioCheck, { className: "vds-icon" }),
|
|
859
|
-
/* @__PURE__ */ React.createElement("span", { className: "vds-radio-label" }, label2)
|
|
860
|
-
))
|
|
861
|
-
)));
|
|
862
|
-
}
|
|
863
|
-
DefaultAudioTracksMenu.displayName = "DefaultAudioTracksMenu";
|
|
864
|
-
|
|
865
|
-
function DefaultCaptionMenu({ slots }) {
|
|
866
|
-
const { icons: Icons } = useDefaultLayoutContext(), label = useDefaultLayoutWord("Captions"), offText = useDefaultLayoutWord("Off"), options = useCaptionOptions({ off: offText }), hint = options.selectedTrack?.label ?? offText;
|
|
867
|
-
if (options.disabled) return null;
|
|
868
|
-
return /* @__PURE__ */ React.createElement(Root$3, { className: "vds-captions-menu vds-menu" }, /* @__PURE__ */ React.createElement(
|
|
869
|
-
DefaultMenuButton,
|
|
870
|
-
{
|
|
871
|
-
label,
|
|
872
|
-
hint,
|
|
873
|
-
disabled: options.disabled,
|
|
874
|
-
Icon: Icons.Menu.Captions
|
|
875
|
-
}
|
|
876
|
-
), /* @__PURE__ */ React.createElement(Items, { className: "vds-menu-items" }, slot(slots, "captionsMenuItemsStart", null), /* @__PURE__ */ React.createElement(
|
|
877
|
-
Root$1,
|
|
878
|
-
{
|
|
879
|
-
className: "vds-captions-radio-group vds-radio-group",
|
|
880
|
-
value: options.selectedValue
|
|
881
|
-
},
|
|
882
|
-
options.map(({ label: label2, value, select }) => /* @__PURE__ */ React.createElement(
|
|
883
|
-
Item,
|
|
884
|
-
{
|
|
885
|
-
className: "vds-caption-radio vds-radio",
|
|
886
|
-
value,
|
|
887
|
-
onSelect: select,
|
|
888
|
-
key: value
|
|
889
|
-
},
|
|
890
|
-
/* @__PURE__ */ React.createElement(Icons.Menu.RadioCheck, { className: "vds-icon" }),
|
|
891
|
-
/* @__PURE__ */ React.createElement("span", { className: "vds-radio-label" }, label2)
|
|
892
|
-
))
|
|
893
|
-
), slot(slots, "captionsMenuItemsEnd", null)));
|
|
894
|
-
}
|
|
895
|
-
DefaultCaptionMenu.displayName = "DefaultCaptionMenu";
|
|
896
|
-
|
|
897
|
-
function DefaultPlaybackMenu({ slots }) {
|
|
898
|
-
const label = useDefaultLayoutWord("Playback"), { icons: Icons } = useDefaultLayoutContext();
|
|
899
|
-
return /* @__PURE__ */ React.createElement(Root$3, { className: "vds-playback-menu vds-menu" }, /* @__PURE__ */ React.createElement(DefaultMenuButton, { label, Icon: Icons.Menu.Playback }), /* @__PURE__ */ React.createElement(Items, { className: "vds-menu-items" }, slot(slots, "playbackMenuItemsStart", null), /* @__PURE__ */ React.createElement(DefaultMenuSection, null, slot(slots, "playbackMenuLoop", /* @__PURE__ */ React.createElement(DefaultLoopMenuCheckbox, null))), /* @__PURE__ */ React.createElement(DefaultSpeedMenuSection, null), /* @__PURE__ */ React.createElement(DefaultQualityMenuSection, null), slot(slots, "playbackMenuItemsEnd", null)));
|
|
900
|
-
}
|
|
901
|
-
DefaultPlaybackMenu.displayName = "DefaultPlaybackMenu";
|
|
902
|
-
function DefaultLoopMenuCheckbox() {
|
|
903
|
-
const { remote } = useMediaContext(), label = useDefaultLayoutWord("Loop");
|
|
904
|
-
function onChange(checked, trigger) {
|
|
905
|
-
remote.userPrefersLoopChange(checked, trigger);
|
|
906
|
-
}
|
|
907
|
-
return /* @__PURE__ */ React.createElement(DefaultMenuItem, { label }, /* @__PURE__ */ React.createElement(DefaultMenuCheckbox, { label, storageKey: "vds-player::user-loop", onChange }));
|
|
908
|
-
}
|
|
909
|
-
DefaultLoopMenuCheckbox.displayName = "DefaultLoopMenuCheckbox";
|
|
910
|
-
function DefaultAutoQualityMenuCheckbox() {
|
|
911
|
-
const { remote, qualities } = useMediaContext(), $autoQuality = useMediaState("autoQuality"), label = useDefaultLayoutWord("Auto");
|
|
912
|
-
function onChange(checked, trigger) {
|
|
913
|
-
if (checked) {
|
|
914
|
-
remote.requestAutoQuality(trigger);
|
|
915
|
-
} else {
|
|
916
|
-
remote.changeQuality(qualities.selectedIndex, trigger);
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
return /* @__PURE__ */ React.createElement(DefaultMenuItem, { label }, /* @__PURE__ */ React.createElement(
|
|
920
|
-
DefaultMenuCheckbox,
|
|
921
|
-
{
|
|
922
|
-
label,
|
|
923
|
-
checked: $autoQuality,
|
|
924
|
-
onChange,
|
|
925
|
-
defaultChecked: $autoQuality
|
|
926
|
-
}
|
|
927
|
-
));
|
|
928
|
-
}
|
|
929
|
-
DefaultAutoQualityMenuCheckbox.displayName = "DefaultAutoQualityMenuCheckbox";
|
|
930
|
-
function DefaultQualityMenuSection() {
|
|
931
|
-
const { hideQualityBitrate, icons: Icons } = useDefaultLayoutContext(), $canSetQuality = useMediaState("canSetQuality"), $qualities = useMediaState("qualities"), $quality = useMediaState("quality"), label = useDefaultLayoutWord("Quality"), autoText = useDefaultLayoutWord("Auto"), sortedQualities = React.useMemo(() => sortVideoQualities($qualities), [$qualities]);
|
|
932
|
-
if (!$canSetQuality || $qualities.length <= 1) return null;
|
|
933
|
-
const height = $quality?.height, bitrate = !hideQualityBitrate ? $quality?.bitrate : null, bitrateText = bitrate && bitrate > 0 ? `${(bitrate / 1e6).toFixed(2)} Mbps` : null, value = height ? `${height}p${bitrateText ? ` (${bitrateText})` : ""}` : autoText, isMin = sortedQualities[0] === $quality, isMax = sortedQualities.at(-1) === $quality;
|
|
934
|
-
return /* @__PURE__ */ React.createElement(DefaultMenuSection, { label, value }, /* @__PURE__ */ React.createElement(
|
|
935
|
-
DefaultMenuSliderItem,
|
|
936
|
-
{
|
|
937
|
-
UpIcon: Icons.Menu.QualityUp,
|
|
938
|
-
DownIcon: Icons.Menu.QualityDown,
|
|
939
|
-
isMin,
|
|
940
|
-
isMax
|
|
941
|
-
},
|
|
942
|
-
/* @__PURE__ */ React.createElement(DefaultQualitySlider, null)
|
|
943
|
-
), /* @__PURE__ */ React.createElement(DefaultAutoQualityMenuCheckbox, null));
|
|
944
|
-
}
|
|
945
|
-
DefaultQualityMenuSection.displayName = "DefaultQualityMenuSection";
|
|
946
|
-
function DefaultQualitySlider() {
|
|
947
|
-
const label = useDefaultLayoutWord("Quality");
|
|
948
|
-
return /* @__PURE__ */ React.createElement(Root$7, { className: "vds-quality-slider vds-slider", "aria-label": label }, /* @__PURE__ */ React.createElement(DefaultSliderParts, null), /* @__PURE__ */ React.createElement(DefaultSliderSteps, null));
|
|
949
|
-
}
|
|
950
|
-
DefaultQualitySlider.displayName = "DefaultQualitySlider";
|
|
951
|
-
function DefaultSpeedMenuSection() {
|
|
952
|
-
const { icons: Icons } = useDefaultLayoutContext(), $playbackRate = useMediaState("playbackRate"), $canSetPlaybackRate = useMediaState("canSetPlaybackRate"), label = useDefaultLayoutWord("Speed"), normalText = useDefaultLayoutWord("Normal"), min = useSpeedMin(), max = useSpeedMax(), value = $playbackRate === 1 ? normalText : $playbackRate + "x";
|
|
953
|
-
if (!$canSetPlaybackRate) return null;
|
|
954
|
-
return /* @__PURE__ */ React.createElement(DefaultMenuSection, { label, value }, /* @__PURE__ */ React.createElement(
|
|
955
|
-
DefaultMenuSliderItem,
|
|
956
|
-
{
|
|
957
|
-
UpIcon: Icons.Menu.SpeedUp,
|
|
958
|
-
DownIcon: Icons.Menu.SpeedDown,
|
|
959
|
-
isMin: $playbackRate === min,
|
|
960
|
-
isMax: $playbackRate === max
|
|
961
|
-
},
|
|
962
|
-
/* @__PURE__ */ React.createElement(DefaultSpeedSlider, null)
|
|
963
|
-
));
|
|
964
|
-
}
|
|
965
|
-
function useSpeedMin() {
|
|
966
|
-
const { playbackRates } = useDefaultLayoutContext(), rates = playbackRates;
|
|
967
|
-
return (isArray(rates) ? rates[0] : rates?.min) ?? 0;
|
|
968
|
-
}
|
|
969
|
-
function useSpeedMax() {
|
|
970
|
-
const { playbackRates } = useDefaultLayoutContext(), rates = playbackRates;
|
|
971
|
-
return (isArray(rates) ? rates[rates.length - 1] : rates?.max) ?? 2;
|
|
972
|
-
}
|
|
973
|
-
function useSpeedStep() {
|
|
974
|
-
const { playbackRates } = useDefaultLayoutContext(), rates = playbackRates;
|
|
975
|
-
return (isArray(rates) ? rates[1] - rates[0] : rates?.step) || 0.25;
|
|
976
|
-
}
|
|
977
|
-
function DefaultSpeedSlider() {
|
|
978
|
-
const label = useDefaultLayoutWord("Speed"), min = useSpeedMin(), max = useSpeedMax(), step = useSpeedStep();
|
|
979
|
-
return /* @__PURE__ */ React.createElement(
|
|
980
|
-
Root$6,
|
|
981
|
-
{
|
|
982
|
-
className: "vds-speed-slider vds-slider",
|
|
983
|
-
"aria-label": label,
|
|
984
|
-
min,
|
|
985
|
-
max,
|
|
986
|
-
step,
|
|
987
|
-
keyStep: step
|
|
988
|
-
},
|
|
989
|
-
/* @__PURE__ */ React.createElement(DefaultSliderParts, null),
|
|
990
|
-
/* @__PURE__ */ React.createElement(DefaultSliderSteps, null)
|
|
991
|
-
);
|
|
992
|
-
}
|
|
993
|
-
DefaultSpeedSlider.displayName = "DefaultSpeedSlider";
|
|
994
|
-
|
|
995
|
-
function DefaultSettingsMenu({
|
|
996
|
-
tooltip,
|
|
997
|
-
placement,
|
|
998
|
-
portalClass = "",
|
|
999
|
-
slots
|
|
1000
|
-
}) {
|
|
1001
|
-
const {
|
|
1002
|
-
showMenuDelay,
|
|
1003
|
-
icons: Icons,
|
|
1004
|
-
isSmallLayout,
|
|
1005
|
-
menuContainer,
|
|
1006
|
-
menuGroup,
|
|
1007
|
-
noModal,
|
|
1008
|
-
colorScheme
|
|
1009
|
-
} = useDefaultLayoutContext(), settingsText = useDefaultLayoutWord("Settings"), $viewType = useMediaState("viewType"), $offset = !isSmallLayout && menuGroup === "bottom" && $viewType === "video" ? 26 : 0, colorSchemeClass = useColorSchemeClass(colorScheme), [isOpen, setIsOpen] = React.useState(false), dialogEl = useParentDialogEl();
|
|
1010
|
-
useScoped(updateFontCssVars);
|
|
1011
|
-
function onOpen() {
|
|
1012
|
-
flushSync(() => {
|
|
1013
|
-
setIsOpen(true);
|
|
1014
|
-
});
|
|
1015
|
-
}
|
|
1016
|
-
function onClose() {
|
|
1017
|
-
setIsOpen(false);
|
|
1018
|
-
}
|
|
1019
|
-
const Content = /* @__PURE__ */ React.createElement(
|
|
1020
|
-
Items,
|
|
1021
|
-
{
|
|
1022
|
-
className: "vds-settings-menu-items vds-menu-items",
|
|
1023
|
-
placement,
|
|
1024
|
-
offset: $offset
|
|
1025
|
-
},
|
|
1026
|
-
isOpen ? /* @__PURE__ */ React.createElement(React.Fragment, null, slot(slots, "settingsMenuItemsStart", null), slot(slots, "settingsMenuStartItems", null), /* @__PURE__ */ React.createElement(DefaultPlaybackMenu, { slots }), /* @__PURE__ */ React.createElement(DefaultAccessibilityMenu, { slots }), /* @__PURE__ */ React.createElement(DefaultAudioMenu, { slots }), /* @__PURE__ */ React.createElement(DefaultCaptionMenu, { slots }), slot(slots, "settingsMenuEndItems", null), slot(slots, "settingsMenuItemsEnd", null)) : null
|
|
1027
|
-
);
|
|
1028
|
-
return /* @__PURE__ */ React.createElement(
|
|
1029
|
-
Root$3,
|
|
1030
|
-
{
|
|
1031
|
-
className: "vds-settings-menu vds-menu",
|
|
1032
|
-
showDelay: showMenuDelay,
|
|
1033
|
-
onOpen,
|
|
1034
|
-
onClose
|
|
1035
|
-
},
|
|
1036
|
-
/* @__PURE__ */ React.createElement(DefaultTooltip, { content: settingsText, placement: tooltip }, /* @__PURE__ */ React.createElement(Button, { className: "vds-menu-button vds-button", "aria-label": settingsText }, /* @__PURE__ */ React.createElement(Icons.Menu.Settings, { className: "vds-icon vds-rotate-icon" }))),
|
|
1037
|
-
noModal || !isSmallLayout ? Content : /* @__PURE__ */ React.createElement(
|
|
1038
|
-
Portal,
|
|
1039
|
-
{
|
|
1040
|
-
className: portalClass + (colorSchemeClass ? ` ${colorSchemeClass}` : ""),
|
|
1041
|
-
container: menuContainer ?? dialogEl,
|
|
1042
|
-
disabled: "fullscreen",
|
|
1043
|
-
"data-sm": isSmallLayout ? "" : null,
|
|
1044
|
-
"data-lg": !isSmallLayout ? "" : null,
|
|
1045
|
-
"data-size": isSmallLayout ? "sm" : "lg",
|
|
1046
|
-
"data-view-type": $viewType
|
|
1047
|
-
},
|
|
1048
|
-
Content
|
|
1049
|
-
)
|
|
1050
|
-
);
|
|
1051
|
-
}
|
|
1052
|
-
DefaultSettingsMenu.displayName = "DefaultSettingsMenu";
|
|
1053
|
-
|
|
1054
|
-
function DefaultVolumePopup({ tooltip, orientation, slots }) {
|
|
1055
|
-
const $pointer = useMediaState("pointer"), $muted = useMediaState("muted"), $canSetVolume = useMediaState("canSetVolume"), [rootEl, setRootEl] = React.useState(null), isRootActive = useActive(rootEl), muteButton = slot(slots, "muteButton", /* @__PURE__ */ React.createElement(DefaultMuteButton, { tooltip }));
|
|
1056
|
-
if (!$canSetVolume) {
|
|
1057
|
-
return muteButton;
|
|
1058
|
-
}
|
|
1059
|
-
return $pointer === "coarse" && !$muted ? null : /* @__PURE__ */ React.createElement("div", { className: "vds-volume", "data-active": isRootActive ? "" : null, ref: setRootEl }, muteButton, /* @__PURE__ */ React.createElement("div", { className: "vds-volume-popup" }, slot(slots, "volumeSlider", /* @__PURE__ */ React.createElement(DefaultVolumeSlider, { orientation }))));
|
|
1060
|
-
}
|
|
1061
|
-
DefaultVolumePopup.displayName = "DefaultVolumePopup";
|
|
1062
|
-
function DefaultVolumeSlider(props) {
|
|
1063
|
-
const label = useDefaultLayoutWord("Volume");
|
|
1064
|
-
return /* @__PURE__ */ React.createElement(Root$8, { className: "vds-volume-slider vds-slider", "aria-label": label, ...props }, /* @__PURE__ */ React.createElement(Track, { className: "vds-slider-track" }), /* @__PURE__ */ React.createElement(TrackFill, { className: "vds-slider-track-fill vds-slider-track" }), /* @__PURE__ */ React.createElement(Thumb, { className: "vds-slider-thumb" }), /* @__PURE__ */ React.createElement(Preview, { className: "vds-slider-preview", noClamp: true }, /* @__PURE__ */ React.createElement(Value, { className: "vds-slider-value" })));
|
|
1065
|
-
}
|
|
1066
|
-
DefaultVolumeSlider.displayName = "DefaultVolumeSlider";
|
|
1067
|
-
function DefaultTimeSlider() {
|
|
1068
|
-
const [instance, setInstance] = React.useState(null), [width, setWidth] = React.useState(0), $src = useMediaState("currentSrc"), { thumbnails, sliderChaptersMinWidth, disableTimeSlider, seekStep, noScrubGesture } = useDefaultLayoutContext(), label = useDefaultLayoutWord("Seek"), $RemotionSliderThumbnail = useSignal(RemotionSliderThumbnail);
|
|
1069
|
-
const onResize = React.useCallback(() => {
|
|
1070
|
-
const el = instance?.el;
|
|
1071
|
-
el && setWidth(el.clientWidth);
|
|
1072
|
-
}, [instance]);
|
|
1073
|
-
useResizeObserver(instance?.el, onResize);
|
|
1074
|
-
return /* @__PURE__ */ React.createElement(
|
|
1075
|
-
Root$9,
|
|
1076
|
-
{
|
|
1077
|
-
className: "vds-time-slider vds-slider",
|
|
1078
|
-
"aria-label": label,
|
|
1079
|
-
disabled: disableTimeSlider,
|
|
1080
|
-
noSwipeGesture: noScrubGesture,
|
|
1081
|
-
keyStep: seekStep,
|
|
1082
|
-
ref: setInstance
|
|
1083
|
-
},
|
|
1084
|
-
/* @__PURE__ */ React.createElement(
|
|
1085
|
-
Chapters,
|
|
1086
|
-
{
|
|
1087
|
-
className: "vds-slider-chapters",
|
|
1088
|
-
disabled: width < sliderChaptersMinWidth
|
|
1089
|
-
},
|
|
1090
|
-
(cues, forwardRef) => cues.map((cue) => /* @__PURE__ */ React.createElement("div", { className: "vds-slider-chapter", key: cue.startTime, ref: forwardRef }, /* @__PURE__ */ React.createElement(Track, { className: "vds-slider-track" }), /* @__PURE__ */ React.createElement(TrackFill, { className: "vds-slider-track-fill vds-slider-track" }), /* @__PURE__ */ React.createElement(Progress, { className: "vds-slider-progress vds-slider-track" })))
|
|
1091
|
-
),
|
|
1092
|
-
/* @__PURE__ */ React.createElement(Thumb, { className: "vds-slider-thumb" }),
|
|
1093
|
-
/* @__PURE__ */ React.createElement(Preview, { className: "vds-slider-preview" }, thumbnails ? /* @__PURE__ */ React.createElement(
|
|
1094
|
-
Thumbnail.Root,
|
|
1095
|
-
{
|
|
1096
|
-
src: thumbnails,
|
|
1097
|
-
className: "vds-slider-thumbnail vds-thumbnail"
|
|
1098
|
-
},
|
|
1099
|
-
/* @__PURE__ */ React.createElement(Thumbnail.Img, null)
|
|
1100
|
-
) : $RemotionSliderThumbnail && isRemotionSrc($src) ? /* @__PURE__ */ React.createElement($RemotionSliderThumbnail, { className: "vds-slider-thumbnail vds-thumbnail" }) : null, /* @__PURE__ */ React.createElement(ChapterTitle, { className: "vds-slider-chapter-title" }), /* @__PURE__ */ React.createElement(Value, { className: "vds-slider-value" }))
|
|
1101
|
-
);
|
|
1102
|
-
}
|
|
1103
|
-
DefaultTimeSlider.displayName = "DefaultTimeSlider";
|
|
1104
|
-
|
|
1105
|
-
function DefaultTimeGroup({ slots }) {
|
|
1106
|
-
const $duration = useMediaState("duration");
|
|
1107
|
-
if (!$duration) return null;
|
|
1108
|
-
return /* @__PURE__ */ React.createElement("div", { className: "vds-time-group" }, slot(slots, "currentTime", /* @__PURE__ */ React.createElement(Time, { className: "vds-time", type: "current" })), slot(slots, "timeDivider", /* @__PURE__ */ React.createElement("div", { className: "vds-time-divider" }, "/")), slot(slots, "endTime", /* @__PURE__ */ React.createElement(Time, { className: "vds-time", type: "duration" })));
|
|
1109
|
-
}
|
|
1110
|
-
DefaultTimeGroup.displayName = "DefaultTimeGroup";
|
|
1111
|
-
function DefaultTimeInfo({ slots }) {
|
|
1112
|
-
const $live = useMediaState("live");
|
|
1113
|
-
return $live ? slot(slots, "liveButton", /* @__PURE__ */ React.createElement(DefaultLiveButton, null)) : /* @__PURE__ */ React.createElement(DefaultTimeGroup, { slots });
|
|
1114
|
-
}
|
|
1115
|
-
DefaultTimeInfo.displayName = "DefaultTimeInfo";
|
|
1116
|
-
function DefaultTimeInvert({ slots }) {
|
|
1117
|
-
const $live = useMediaState("live"), $duration = useMediaState("duration");
|
|
1118
|
-
return $live ? slot(slots, "liveButton", /* @__PURE__ */ React.createElement(DefaultLiveButton, null)) : slot(
|
|
1119
|
-
slots,
|
|
1120
|
-
"endTime",
|
|
1121
|
-
$duration ? /* @__PURE__ */ React.createElement(Time, { className: "vds-time", type: "current", toggle: true, remainder: true }) : null
|
|
1122
|
-
);
|
|
1123
|
-
}
|
|
1124
|
-
DefaultTimeInvert.displayName = "DefaultTimeInvert";
|
|
1125
|
-
|
|
1126
|
-
const MediaLayout$1 = createDefaultMediaLayout({
|
|
1127
|
-
type: "audio",
|
|
1128
|
-
smLayoutWhen({ width }) {
|
|
1129
|
-
return width < 576;
|
|
1130
|
-
},
|
|
1131
|
-
renderLayout: () => /* @__PURE__ */ React.createElement(AudioLayout, null)
|
|
1132
|
-
});
|
|
1133
|
-
function DefaultAudioLayout(props) {
|
|
1134
|
-
const [scrubbing, setScrubbing] = React.useState(false), $pointer = useMediaState("pointer");
|
|
1135
|
-
const onStartScrubbing = React.useCallback((event) => {
|
|
1136
|
-
const { target } = event, hasTimeSlider = !!(target instanceof HTMLElement && target.closest(".vds-time-slider"));
|
|
1137
|
-
if (!hasTimeSlider) return;
|
|
1138
|
-
event.nativeEvent.stopImmediatePropagation();
|
|
1139
|
-
setScrubbing(true);
|
|
1140
|
-
}, []);
|
|
1141
|
-
const onStopScrubbing = React.useCallback(() => {
|
|
1142
|
-
setScrubbing(false);
|
|
1143
|
-
}, []);
|
|
1144
|
-
React.useEffect(() => {
|
|
1145
|
-
if (scrubbing) return listenEvent(window, "pointerdown", onStopScrubbing);
|
|
1146
|
-
}, [scrubbing, onStopScrubbing]);
|
|
1147
|
-
return /* @__PURE__ */ React.createElement(
|
|
1148
|
-
MediaLayout$1,
|
|
1149
|
-
{
|
|
1150
|
-
...props,
|
|
1151
|
-
"data-scrubbing": scrubbing ? "" : null,
|
|
1152
|
-
onPointerDown: scrubbing ? (e) => e.stopPropagation() : void 0,
|
|
1153
|
-
onPointerDownCapture: $pointer === "coarse" && !scrubbing ? onStartScrubbing : void 0
|
|
1154
|
-
}
|
|
1155
|
-
);
|
|
1156
|
-
}
|
|
1157
|
-
DefaultAudioLayout.displayName = "DefaultAudioLayout";
|
|
1158
|
-
function AudioLayout() {
|
|
1159
|
-
const slots = useDefaultAudioLayoutSlots();
|
|
1160
|
-
useLayoutName("audio");
|
|
1161
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(DefaultAnnouncer, null), /* @__PURE__ */ React.createElement(DefaultCaptions, null), /* @__PURE__ */ React.createElement(Root$a, { className: "vds-controls" }, /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "seekBackwardButton", /* @__PURE__ */ React.createElement(DefaultSeekButton, { backward: true, tooltip: "top start" })), slot(slots, "playButton", /* @__PURE__ */ React.createElement(DefaultPlayButton, { tooltip: "top center" })), slot(slots, "seekForwardButton", /* @__PURE__ */ React.createElement(DefaultSeekButton, { tooltip: "top center" })), /* @__PURE__ */ React.createElement(DefaultAudioTitle, null), slot(slots, "timeSlider", /* @__PURE__ */ React.createElement(DefaultTimeSlider, null)), /* @__PURE__ */ React.createElement(DefaultTimeInvert, { slots }), /* @__PURE__ */ React.createElement(DefaultVolumePopup, { orientation: "vertical", tooltip: "top", slots }), slot(slots, "captionButton", /* @__PURE__ */ React.createElement(DefaultCaptionButton, { tooltip: "top center" })), slot(slots, "downloadButton", /* @__PURE__ */ React.createElement(DefaultDownloadButton, null)), /* @__PURE__ */ React.createElement(DefaultAudioMenus, { slots }))));
|
|
1162
|
-
}
|
|
1163
|
-
AudioLayout.displayName = "AudioLayout";
|
|
1164
|
-
function DefaultAudioMenus({ slots }) {
|
|
1165
|
-
const { isSmallLayout, noModal } = useDefaultLayoutContext(), placement = noModal ? "top end" : !isSmallLayout ? "top end" : null;
|
|
1166
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, slot(
|
|
1167
|
-
slots,
|
|
1168
|
-
"chaptersMenu",
|
|
1169
|
-
/* @__PURE__ */ React.createElement(DefaultChaptersMenu, { tooltip: "top", placement, portalClass: "vds-audio-layout" })
|
|
1170
|
-
), slot(
|
|
1171
|
-
slots,
|
|
1172
|
-
"settingsMenu",
|
|
1173
|
-
/* @__PURE__ */ React.createElement(
|
|
1174
|
-
DefaultSettingsMenu,
|
|
1175
|
-
{
|
|
1176
|
-
tooltip: "top end",
|
|
1177
|
-
placement,
|
|
1178
|
-
portalClass: "vds-audio-layout",
|
|
1179
|
-
slots
|
|
1180
|
-
}
|
|
1181
|
-
)
|
|
1182
|
-
));
|
|
1183
|
-
}
|
|
1184
|
-
DefaultAudioMenus.displayName = "DefaultAudioMenus";
|
|
1185
|
-
function DefaultAudioTitle() {
|
|
1186
|
-
const [rootEl, setRootEl] = React.useState(null), media = useMediaContext(), { translations } = useDefaultLayoutContext(), [isTextOverflowing, setIsTextOverflowing] = React.useState(false);
|
|
1187
|
-
const isContinued = createComputed(() => {
|
|
1188
|
-
const { started, currentTime } = media.$state;
|
|
1189
|
-
return started() || currentTime() > 0;
|
|
1190
|
-
});
|
|
1191
|
-
const $title = useSignal(
|
|
1192
|
-
createComputed(() => {
|
|
1193
|
-
const { title, ended } = media.$state;
|
|
1194
|
-
if (!title()) return "";
|
|
1195
|
-
const word = ended() ? "Replay" : isContinued() ? "Continue" : "Play";
|
|
1196
|
-
return `${i18n(translations, word)}: ${title()}`;
|
|
1197
|
-
})
|
|
1198
|
-
);
|
|
1199
|
-
const chapterTitle = useChapterTitle(), $isContinued = useSignal(isContinued), $chapterTitle = $isContinued ? chapterTitle : "", isTransitionActive = useTransitionActive(rootEl);
|
|
1200
|
-
React.useEffect(() => {
|
|
1201
|
-
if (isTransitionActive && document.activeElement === document.body) {
|
|
1202
|
-
media.player.el?.focus({ preventScroll: true });
|
|
1203
|
-
}
|
|
1204
|
-
}, []);
|
|
1205
|
-
const onResize = React.useCallback(() => {
|
|
1206
|
-
const el = rootEl, isOverflowing = !!el && !isTransitionActive && el.clientWidth < el.children[0].clientWidth;
|
|
1207
|
-
if (el) toggleClass(el, "vds-marquee", isOverflowing);
|
|
1208
|
-
setIsTextOverflowing(isOverflowing);
|
|
1209
|
-
}, [rootEl, isTransitionActive]);
|
|
1210
|
-
useResizeObserver(rootEl, onResize);
|
|
1211
|
-
return $title ? /* @__PURE__ */ React.createElement("span", { className: "vds-title", title: $title, ref: setRootEl }, /* @__PURE__ */ React.createElement(AudioTitle, { title: $title, chapterTitle: $chapterTitle }), isTextOverflowing && !isTransitionActive ? /* @__PURE__ */ React.createElement(AudioTitle, { title: $title, chapterTitle: $chapterTitle }) : null) : /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null);
|
|
1212
|
-
}
|
|
1213
|
-
DefaultAudioTitle.displayName = "DefaultAudioTitle";
|
|
1214
|
-
function AudioTitle({ title, chapterTitle }) {
|
|
1215
|
-
const slots = useDefaultAudioLayoutSlots();
|
|
1216
|
-
return /* @__PURE__ */ React.createElement("span", { className: "vds-title-text" }, slot(slots, "title", title), slot(slots, "chapterTitle", /* @__PURE__ */ React.createElement("span", { className: "vds-chapter-title" }, chapterTitle)));
|
|
1217
|
-
}
|
|
1218
|
-
AudioTitle.displayName = "AudioTitle";
|
|
1219
|
-
|
|
1220
|
-
const DefaultKeyboardDisplay = React.forwardRef(
|
|
1221
|
-
({ icons: Icons, ...props }, forwardRef) => {
|
|
1222
|
-
const [visible, setVisible] = React.useState(false), [Icon, setIcon] = React.useState(null), [count, setCount] = React.useState(0), $lastKeyboardAction = useMediaState("lastKeyboardAction");
|
|
1223
|
-
React.useEffect(() => {
|
|
1224
|
-
setCount((n) => n + 1);
|
|
1225
|
-
}, [$lastKeyboardAction]);
|
|
1226
|
-
const actionDataAttr = React.useMemo(() => {
|
|
1227
|
-
const action = $lastKeyboardAction?.action;
|
|
1228
|
-
return action && visible ? camelToKebabCase(action) : null;
|
|
1229
|
-
}, [visible, $lastKeyboardAction]);
|
|
1230
|
-
const className = React.useMemo(
|
|
1231
|
-
() => `vds-kb-action${!visible ? " hidden" : ""}${props.className ? ` ${props.className}` : ""}`,
|
|
1232
|
-
[visible]
|
|
1233
|
-
);
|
|
1234
|
-
const $$text = createComputed(getText), $text = useSignal($$text);
|
|
1235
|
-
createEffect(() => {
|
|
1236
|
-
const Icon2 = getIcon(Icons);
|
|
1237
|
-
setIcon(() => Icon2);
|
|
1238
|
-
}, [Icons]);
|
|
1239
|
-
React.useEffect(() => {
|
|
1240
|
-
setVisible(!!$lastKeyboardAction);
|
|
1241
|
-
const id = setTimeout(() => setVisible(false), 500);
|
|
1242
|
-
return () => {
|
|
1243
|
-
setVisible(false);
|
|
1244
|
-
window.clearTimeout(id);
|
|
1245
|
-
};
|
|
1246
|
-
}, [$lastKeyboardAction]);
|
|
1247
|
-
return Icon ? /* @__PURE__ */ React.createElement(
|
|
1248
|
-
Primitive.div,
|
|
1249
|
-
{
|
|
1250
|
-
...props,
|
|
1251
|
-
className,
|
|
1252
|
-
"data-action": actionDataAttr,
|
|
1253
|
-
ref: forwardRef
|
|
1254
|
-
},
|
|
1255
|
-
/* @__PURE__ */ React.createElement("div", { className: "vds-kb-text-wrapper" }, /* @__PURE__ */ React.createElement("div", { className: "vds-kb-text" }, $text)),
|
|
1256
|
-
/* @__PURE__ */ React.createElement("div", { className: "vds-kb-bezel", key: count }, /* @__PURE__ */ React.createElement("div", { className: "vds-kb-icon" }, /* @__PURE__ */ React.createElement(Icon, null)))
|
|
1257
|
-
) : null;
|
|
1258
|
-
}
|
|
1259
|
-
);
|
|
1260
|
-
DefaultKeyboardDisplay.displayName = "DefaultKeyboardDisplay";
|
|
1261
|
-
function getText() {
|
|
1262
|
-
const { $state } = useContext(mediaContext), action = $state.lastKeyboardAction()?.action, audioGain = $state.audioGain() ?? 1;
|
|
1263
|
-
switch (action) {
|
|
1264
|
-
case "toggleMuted":
|
|
1265
|
-
return $state.muted() ? "0%" : getVolumeText($state.volume(), audioGain);
|
|
1266
|
-
case "volumeUp":
|
|
1267
|
-
case "volumeDown":
|
|
1268
|
-
return getVolumeText($state.volume(), audioGain);
|
|
1269
|
-
default:
|
|
1270
|
-
return "";
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
function getVolumeText(volume, gain) {
|
|
1274
|
-
return `${Math.round(volume * gain * 100)}%`;
|
|
1275
|
-
}
|
|
1276
|
-
function getIcon(Icons) {
|
|
1277
|
-
const { $state } = useContext(mediaContext), action = $state.lastKeyboardAction()?.action;
|
|
1278
|
-
switch (action) {
|
|
1279
|
-
case "togglePaused":
|
|
1280
|
-
return !$state.paused() ? Icons.Play : Icons.Pause;
|
|
1281
|
-
case "toggleMuted":
|
|
1282
|
-
return $state.muted() || $state.volume() === 0 ? Icons.Mute : $state.volume() >= 0.5 ? Icons.VolumeUp : Icons.VolumeDown;
|
|
1283
|
-
case "toggleFullscreen":
|
|
1284
|
-
return $state.fullscreen() ? Icons.EnterFullscreen : Icons.ExitFullscreen;
|
|
1285
|
-
case "togglePictureInPicture":
|
|
1286
|
-
return $state.pictureInPicture() ? Icons.EnterPiP : Icons.ExitPiP;
|
|
1287
|
-
case "toggleCaptions":
|
|
1288
|
-
return $state.hasCaptions() ? $state.textTrack() ? Icons.CaptionsOn : Icons.CaptionsOff : null;
|
|
1289
|
-
case "volumeUp":
|
|
1290
|
-
return Icons.VolumeUp;
|
|
1291
|
-
case "volumeDown":
|
|
1292
|
-
return Icons.VolumeDown;
|
|
1293
|
-
case "seekForward":
|
|
1294
|
-
return Icons.SeekForward;
|
|
1295
|
-
case "seekBackward":
|
|
1296
|
-
return Icons.SeekBackward;
|
|
1297
|
-
default:
|
|
1298
|
-
return null;
|
|
1299
|
-
}
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
|
-
function DefaultTitle() {
|
|
1303
|
-
const $started = useMediaState("started"), $title = useMediaState("title"), $hasChapters = useActiveTextTrack("chapters");
|
|
1304
|
-
return $hasChapters && ($started || !$title) ? /* @__PURE__ */ React.createElement(ChapterTitle$1, { className: "vds-chapter-title" }) : /* @__PURE__ */ React.createElement(Title, { className: "vds-chapter-title" });
|
|
1305
|
-
}
|
|
1306
|
-
DefaultTitle.displayName = "DefaultTitle";
|
|
1307
|
-
|
|
1308
|
-
const MediaLayout = createDefaultMediaLayout({
|
|
1309
|
-
type: "video",
|
|
1310
|
-
smLayoutWhen({ width, height }) {
|
|
1311
|
-
return width < 576 || height < 380;
|
|
1312
|
-
},
|
|
1313
|
-
renderLayout(props) {
|
|
1314
|
-
return /* @__PURE__ */ React.createElement(VideoLayout, { ...props });
|
|
1315
|
-
}
|
|
1316
|
-
});
|
|
1317
|
-
function DefaultVideoLayout(props) {
|
|
1318
|
-
return /* @__PURE__ */ React.createElement(MediaLayout, { ...props });
|
|
1319
|
-
}
|
|
1320
|
-
DefaultVideoLayout.displayName = "DefaultVideoLayout";
|
|
1321
|
-
function VideoLayout({ streamType, isLoadLayout, isSmallLayout }) {
|
|
1322
|
-
useLayoutName("video");
|
|
1323
|
-
return isLoadLayout ? /* @__PURE__ */ React.createElement(DefaultVideoLoadLayout, null) : streamType === "unknown" ? /* @__PURE__ */ React.createElement(DefaultBufferingIndicator, null) : isSmallLayout ? /* @__PURE__ */ React.createElement(DefaultVideoSmallLayout, null) : /* @__PURE__ */ React.createElement(DefaultVideoLargeLayout, null);
|
|
1324
|
-
}
|
|
1325
|
-
VideoLayout.displayName = "VideoLayout";
|
|
1326
|
-
function DefaultVideoLargeLayout() {
|
|
1327
|
-
const { menuGroup, episodes, episodesTitle, isSmallLayout } = useDefaultLayoutContext(), baseSlots = useDefaultVideoLayoutSlots(), slots = { ...baseSlots, ...baseSlots?.largeLayout }, $fullscreen = useMediaState("fullscreen"), [episodesOpen, setEpisodesOpen] = React.useState(false), list = episodes ?? [];
|
|
1328
|
-
React.useEffect(() => {
|
|
1329
|
-
if (!$fullscreen) setEpisodesOpen(false);
|
|
1330
|
-
}, [$fullscreen]);
|
|
1331
|
-
const canOpenEpisodes = ($fullscreen || isSmallLayout) && list.length > 0;
|
|
1332
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(DefaultAnnouncer, null), /* @__PURE__ */ React.createElement(DefaultVideoGestures, null), /* @__PURE__ */ React.createElement(DefaultVideoKeyboardDisplay, null), slot(slots, "bufferingIndicator", /* @__PURE__ */ React.createElement(DefaultBufferingIndicator, null)), slot(slots, "captions", /* @__PURE__ */ React.createElement(DefaultCaptions, null)), /* @__PURE__ */ React.createElement(Root$a, { className: "vds-controls" }, /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "topControlsGroupStart", null), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "topControlsGroupCenter", null), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "topControlsGroupEnd", null), menuGroup === "top" && /* @__PURE__ */ React.createElement(DefaultVideoMenus, { slots })), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "centerControlsGroupStart", null), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "centerControlsGroupCenter", null), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "centerControlsGroupEnd", null)), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "timeSlider", /* @__PURE__ */ React.createElement(DefaultTimeSlider, null))), /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "playButton", /* @__PURE__ */ React.createElement(DefaultPlayButton, { tooltip: "top start" })), /* @__PURE__ */ React.createElement(DefaultSeekButton, { backward: true, tooltip: "top" }), /* @__PURE__ */ React.createElement(DefaultSeekButton, { tooltip: "top" }), /* @__PURE__ */ React.createElement(DefaultVolumePopup, { orientation: "horizontal", tooltip: "top", slots }), /* @__PURE__ */ React.createElement(DefaultTimeInfo, { slots }), slot(slots, "chapterTitle", /* @__PURE__ */ React.createElement(DefaultTitle, null)), canOpenEpisodes ? /* @__PURE__ */ React.createElement(DefaultEpisodeButton, { tooltip: "top", onPress: () => setEpisodesOpen((open) => !open) }) : null, slot(slots, "captionButton", /* @__PURE__ */ React.createElement(DefaultCaptionButton, { tooltip: "top" })), menuGroup === "bottom" && /* @__PURE__ */ React.createElement(DefaultVideoMenus, { slots }), slot(slots, "airPlayButton", /* @__PURE__ */ React.createElement(DefaultAirPlayButton, { tooltip: "top" })), slot(slots, "googleCastButton", /* @__PURE__ */ React.createElement(DefaultGoogleCastButton, { tooltip: "top" })), slot(slots, "downloadButton", /* @__PURE__ */ React.createElement(DefaultDownloadButton, null)), slot(slots, "pipButton", /* @__PURE__ */ React.createElement(DefaultPIPButton, { tooltip: "top" })), slot(slots, "fullscreenButton", /* @__PURE__ */ React.createElement(DefaultFullscreenButton, { tooltip: "top end" })))), /* @__PURE__ */ React.createElement(
|
|
1333
|
-
DefaultEpisodesSidebar,
|
|
1334
|
-
{
|
|
1335
|
-
open: episodesOpen,
|
|
1336
|
-
onClose: () => setEpisodesOpen(false),
|
|
1337
|
-
episodes: list,
|
|
1338
|
-
episodesTitle: episodesTitle ?? "Episodes"
|
|
1339
|
-
}
|
|
1340
|
-
));
|
|
1341
|
-
}
|
|
1342
|
-
DefaultVideoLargeLayout.displayName = "DefaultVideoLargeLayout";
|
|
1343
|
-
function DefaultVideoSmallLayout() {
|
|
1344
|
-
const { episodes, episodesTitle, isSmallLayout } = useDefaultLayoutContext(), baseSlots = useDefaultVideoLayoutSlots(), slots = { ...baseSlots, ...baseSlots?.smallLayout }, $fullscreen = useMediaState("fullscreen"), [episodesOpen, setEpisodesOpen] = React.useState(false), list = episodes ?? [];
|
|
1345
|
-
React.useEffect(() => {
|
|
1346
|
-
if (!$fullscreen) setEpisodesOpen(false);
|
|
1347
|
-
}, [$fullscreen]);
|
|
1348
|
-
const canOpenEpisodes = ($fullscreen || isSmallLayout) && list.length > 0;
|
|
1349
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(DefaultAnnouncer, null), /* @__PURE__ */ React.createElement(DefaultVideoGestures, null), /* @__PURE__ */ React.createElement(DefaultVideoKeyboardDisplay, null), slot(slots, "bufferingIndicator", /* @__PURE__ */ React.createElement(DefaultBufferingIndicator, null)), slot(slots, "captions", /* @__PURE__ */ React.createElement(DefaultCaptions, null)), /* @__PURE__ */ React.createElement(Root$a, { className: "vds-controls" }, /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "topControlsGroupStart", null), slot(slots, "airPlayButton", /* @__PURE__ */ React.createElement(DefaultAirPlayButton, { tooltip: "top start" })), slot(slots, "googleCastButton", /* @__PURE__ */ React.createElement(DefaultGoogleCastButton, { tooltip: "top start" })), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "topControlsGroupCenter", null), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "captionButton", /* @__PURE__ */ React.createElement(DefaultCaptionButton, { tooltip: "bottom" })), slot(slots, "downloadButton", /* @__PURE__ */ React.createElement(DefaultDownloadButton, null)), /* @__PURE__ */ React.createElement(DefaultVideoMenus, { slots }), /* @__PURE__ */ React.createElement(DefaultVolumePopup, { orientation: "vertical", tooltip: "bottom end", slots }), slot(slots, "topControlsGroupEnd", null)), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "centerControlsGroupStart", null), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), /* @__PURE__ */ React.createElement(DefaultSeekButton, { backward: true, tooltip: "top" }), slot(slots, "centerControlsGroupCenter", null), slot(slots, "playButton", /* @__PURE__ */ React.createElement(DefaultPlayButton, { tooltip: "top" })), /* @__PURE__ */ React.createElement(DefaultSeekButton, { tooltip: "top" }), canOpenEpisodes ? /* @__PURE__ */ React.createElement(DefaultEpisodeButton, { tooltip: "top", onPress: () => setEpisodesOpen((open) => !open) }) : null, /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "centerControlsGroupEnd", null)), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, /* @__PURE__ */ React.createElement(DefaultTimeInfo, { slots }), slot(slots, "chapterTitle", /* @__PURE__ */ React.createElement(DefaultTitle, null)), slot(slots, "fullscreenButton", /* @__PURE__ */ React.createElement(DefaultFullscreenButton, { tooltip: "top end" }))), /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "timeSlider", /* @__PURE__ */ React.createElement(DefaultTimeSlider, null)))), slot(slots, "startDuration", /* @__PURE__ */ React.createElement(DefaultVideoStartDuration, null)), /* @__PURE__ */ React.createElement(
|
|
1350
|
-
DefaultEpisodesSidebar,
|
|
1351
|
-
{
|
|
1352
|
-
open: episodesOpen,
|
|
1353
|
-
onClose: () => setEpisodesOpen(false),
|
|
1354
|
-
episodes: list,
|
|
1355
|
-
episodesTitle: episodesTitle ?? "Episodes"
|
|
1356
|
-
}
|
|
1357
|
-
));
|
|
1358
|
-
}
|
|
1359
|
-
DefaultVideoSmallLayout.displayName = "DefaultVideoSmallLayout";
|
|
1360
|
-
function DefaultVideoStartDuration() {
|
|
1361
|
-
const $duration = useMediaState("duration");
|
|
1362
|
-
if ($duration === 0) return null;
|
|
1363
|
-
return /* @__PURE__ */ React.createElement("div", { className: "vds-start-duration" }, /* @__PURE__ */ React.createElement(Time, { className: "vds-time", type: "duration" }));
|
|
1364
|
-
}
|
|
1365
|
-
DefaultVideoStartDuration.displayName = "DefaultVideoStartDuration";
|
|
1366
|
-
function DefaultVideoGestures() {
|
|
1367
|
-
const { noGestures } = useDefaultLayoutContext();
|
|
1368
|
-
if (noGestures) return null;
|
|
1369
|
-
return /* @__PURE__ */ React.createElement("div", { className: "vds-gestures" }, /* @__PURE__ */ React.createElement(Gesture, { className: "vds-gesture", event: "pointerup", action: "toggle:paused" }), /* @__PURE__ */ React.createElement(Gesture, { className: "vds-gesture", event: "pointerup", action: "toggle:controls" }), /* @__PURE__ */ React.createElement(Gesture, { className: "vds-gesture", event: "dblpointerup", action: "toggle:fullscreen" }), /* @__PURE__ */ React.createElement(Gesture, { className: "vds-gesture", event: "dblpointerup", action: "seek:-10" }), /* @__PURE__ */ React.createElement(Gesture, { className: "vds-gesture", event: "dblpointerup", action: "seek:10" }));
|
|
1370
|
-
}
|
|
1371
|
-
DefaultVideoGestures.displayName = "DefaultVideoGestures";
|
|
1372
|
-
function DefaultBufferingIndicator() {
|
|
1373
|
-
return /* @__PURE__ */ React.createElement("div", { className: "vds-buffering-indicator" }, /* @__PURE__ */ React.createElement(Root$b, { className: "vds-buffering-spinner" }, /* @__PURE__ */ React.createElement(Track$1, { className: "vds-buffering-track" }), /* @__PURE__ */ React.createElement(TrackFill$1, { className: "vds-buffering-track-fill" })));
|
|
1374
|
-
}
|
|
1375
|
-
DefaultBufferingIndicator.displayName = "DefaultBufferingIndicator";
|
|
1376
|
-
function DefaultVideoMenus({ slots }) {
|
|
1377
|
-
const { isSmallLayout, noModal, menuGroup } = useDefaultLayoutContext(), side = menuGroup === "top" || isSmallLayout ? "bottom" : "top", tooltip = `${side} end`, placement = noModal ? `${side} end` : !isSmallLayout ? `${side} end` : null;
|
|
1378
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, slot(
|
|
1379
|
-
slots,
|
|
1380
|
-
"chaptersMenu",
|
|
1381
|
-
/* @__PURE__ */ React.createElement(
|
|
1382
|
-
DefaultChaptersMenu,
|
|
1383
|
-
{
|
|
1384
|
-
tooltip,
|
|
1385
|
-
placement,
|
|
1386
|
-
portalClass: "vds-video-layout"
|
|
1387
|
-
}
|
|
1388
|
-
)
|
|
1389
|
-
), slot(
|
|
1390
|
-
slots,
|
|
1391
|
-
"settingsMenu",
|
|
1392
|
-
/* @__PURE__ */ React.createElement(
|
|
1393
|
-
DefaultSettingsMenu,
|
|
1394
|
-
{
|
|
1395
|
-
tooltip,
|
|
1396
|
-
placement,
|
|
1397
|
-
portalClass: "vds-video-layout",
|
|
1398
|
-
slots
|
|
1399
|
-
}
|
|
1400
|
-
)
|
|
1401
|
-
));
|
|
1402
|
-
}
|
|
1403
|
-
DefaultVideoMenus.displayName = "DefaultVideoMenus";
|
|
1404
|
-
function DefaultEpisodesSidebar({
|
|
1405
|
-
open,
|
|
1406
|
-
onClose,
|
|
1407
|
-
episodes,
|
|
1408
|
-
episodesTitle
|
|
1409
|
-
}) {
|
|
1410
|
-
const $fullscreen = useMediaState("fullscreen"), { isSmallLayout } = useDefaultLayoutContext();
|
|
1411
|
-
if (!$fullscreen && !isSmallLayout || episodes.length === 0) return null;
|
|
1412
|
-
return /* @__PURE__ */ React.createElement(
|
|
1413
|
-
"div",
|
|
1414
|
-
{
|
|
1415
|
-
className: "vds-episodes-backdrop",
|
|
1416
|
-
"data-open": open ? "true" : "false",
|
|
1417
|
-
onPointerUp: (event) => {
|
|
1418
|
-
if (event.target === event.currentTarget) onClose();
|
|
1419
|
-
}
|
|
1420
|
-
},
|
|
1421
|
-
/* @__PURE__ */ React.createElement(
|
|
1422
|
-
"aside",
|
|
1423
|
-
{
|
|
1424
|
-
className: "vds-episodes-panel",
|
|
1425
|
-
"data-open": open ? "true" : "false",
|
|
1426
|
-
onKeyDown: (event) => {
|
|
1427
|
-
if (event.key === "Escape") onClose();
|
|
1428
|
-
}
|
|
1429
|
-
},
|
|
1430
|
-
/* @__PURE__ */ React.createElement("header", { className: "vds-episodes-panel-header" }, /* @__PURE__ */ React.createElement("h3", { className: "vds-episodes-panel-title" }, episodesTitle), /* @__PURE__ */ React.createElement(
|
|
1431
|
-
"button",
|
|
1432
|
-
{
|
|
1433
|
-
type: "button",
|
|
1434
|
-
className: "vds-episodes-close-btn",
|
|
1435
|
-
"aria-label": "Close episodes",
|
|
1436
|
-
onPointerUp: (event) => {
|
|
1437
|
-
event.stopPropagation();
|
|
1438
|
-
onClose();
|
|
1439
|
-
}
|
|
1440
|
-
},
|
|
1441
|
-
/* @__PURE__ */ React.createElement("span", { "aria-hidden": "true" }, "x")
|
|
1442
|
-
)),
|
|
1443
|
-
/* @__PURE__ */ React.createElement("div", { className: "vds-episodes-list", role: "list" }, episodes.map((episode, index) => {
|
|
1444
|
-
const episodeName = episode.episodeTitle || `Episode ${episode.episodeNumber ?? index + 1}`, runtimeText = Number.isFinite(episode.runtime) ? `${episode.runtime}m` : null, seasonEpLabel = episode.seasonNumber != null && episode.episodeNumber != null ? `S${String(episode.seasonNumber).padStart(2, "0")} \xB7 E${String(episode.episodeNumber).padStart(2, "0")}` : episodeName;
|
|
1445
|
-
const onEpisodeSelect = (event) => {
|
|
1446
|
-
event.stopPropagation();
|
|
1447
|
-
event.currentTarget.dispatchEvent(
|
|
1448
|
-
new CustomEvent("vds-episode-select", {
|
|
1449
|
-
bubbles: true,
|
|
1450
|
-
composed: true,
|
|
1451
|
-
detail: { episode, index }
|
|
1452
|
-
})
|
|
1453
|
-
);
|
|
1454
|
-
onClose();
|
|
1455
|
-
};
|
|
1456
|
-
return /* @__PURE__ */ React.createElement(
|
|
1457
|
-
"article",
|
|
1458
|
-
{
|
|
1459
|
-
key: `${episode.episodeNumber ?? index}-${episode.title ?? ""}`,
|
|
1460
|
-
className: "vds-episode-item",
|
|
1461
|
-
role: "button",
|
|
1462
|
-
tabIndex: 0,
|
|
1463
|
-
"aria-label": episode.title || episodeName,
|
|
1464
|
-
onPointerUp: onEpisodeSelect,
|
|
1465
|
-
onKeyDown: (event) => {
|
|
1466
|
-
if (event.key === "Enter" || event.key === " ") onEpisodeSelect(event);
|
|
1467
|
-
}
|
|
1468
|
-
},
|
|
1469
|
-
/* @__PURE__ */ React.createElement("div", { className: "vds-episode-thumb-wrap" }, episode.thumbnail ? /* @__PURE__ */ React.createElement(
|
|
1470
|
-
"img",
|
|
1471
|
-
{
|
|
1472
|
-
className: "vds-episode-thumb",
|
|
1473
|
-
src: episode.thumbnail,
|
|
1474
|
-
alt: episode.title || episodeName,
|
|
1475
|
-
loading: "lazy",
|
|
1476
|
-
decoding: "async"
|
|
1477
|
-
}
|
|
1478
|
-
) : /* @__PURE__ */ React.createElement("div", { className: "vds-episode-thumb vds-episode-thumb-placeholder" })),
|
|
1479
|
-
/* @__PURE__ */ React.createElement("div", { className: "vds-episode-body" }, /* @__PURE__ */ React.createElement("div", { className: "vds-episode-meta-row" }, /* @__PURE__ */ React.createElement("span", { className: "vds-episode-label" }, seasonEpLabel), runtimeText ? /* @__PURE__ */ React.createElement("span", { className: "vds-episode-runtime" }, runtimeText) : null), /* @__PURE__ */ React.createElement("h4", { className: "vds-episode-title", title: episode.title || "" }, episode.title || "-"), /* @__PURE__ */ React.createElement("p", { className: "vds-episode-subtitle", title: episodeName }, episodeName), episode.overview ? /* @__PURE__ */ React.createElement("p", { className: "vds-episode-desc", title: episode.overview }, episode.overview) : null)
|
|
1480
|
-
);
|
|
1481
|
-
}))
|
|
1482
|
-
)
|
|
1483
|
-
);
|
|
1484
|
-
}
|
|
1485
|
-
function DefaultVideoLoadLayout() {
|
|
1486
|
-
const { isSmallLayout } = useDefaultLayoutContext(), baseSlots = useDefaultVideoLayoutSlots(), slots = { ...baseSlots, ...baseSlots?.[isSmallLayout ? "smallLayout" : "largeLayout"] };
|
|
1487
|
-
return /* @__PURE__ */ React.createElement("div", { className: "vds-load-container" }, slot(slots, "bufferingIndicator", /* @__PURE__ */ React.createElement(DefaultBufferingIndicator, null)), slot(slots, "loadButton", /* @__PURE__ */ React.createElement(DefaultPlayButton, { tooltip: "top" })));
|
|
1488
|
-
}
|
|
1489
|
-
DefaultVideoLoadLayout.displayName = "DefaultVideoLoadLayout";
|
|
1490
|
-
function DefaultVideoKeyboardDisplay() {
|
|
1491
|
-
const { noKeyboardAnimations, icons, userPrefersKeyboardAnimations } = useDefaultLayoutContext(), $userPrefersKeyboardAnimations = useSignal(userPrefersKeyboardAnimations), disabled = noKeyboardAnimations || !$userPrefersKeyboardAnimations;
|
|
1492
|
-
if (disabled || !icons.KeyboardDisplay) return null;
|
|
1493
|
-
return /* @__PURE__ */ React.createElement(DefaultKeyboardDisplay, { icons: icons.KeyboardDisplay });
|
|
1494
|
-
}
|
|
1495
|
-
DefaultVideoKeyboardDisplay.displayName = "DefaultVideoKeyboardDisplay";
|
|
1496
|
-
|
|
1497
|
-
export { DefaultAudioLayout, DefaultBufferingIndicator, DefaultKeyboardDisplay, DefaultLayoutContext, DefaultMenuButton, DefaultMenuCheckbox, DefaultMenuItem, DefaultMenuRadioGroup, DefaultMenuSection, DefaultMenuSliderItem, DefaultSliderParts, DefaultSliderSteps, DefaultTooltip, DefaultVideoGestures, DefaultVideoLargeLayout, DefaultVideoLayout, DefaultVideoSmallLayout, createRadioOptions, i18n, useDefaultLayoutContext, useDefaultLayoutWord };
|