@moviie/player-expo 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +230 -0
- package/app.plugin.cjs +3 -0
- package/dist/cast.cjs +100 -0
- package/dist/cast.cjs.map +1 -0
- package/dist/cast.d.cts +15 -0
- package/dist/cast.d.ts +15 -0
- package/dist/cast.mjs +92 -0
- package/dist/cast.mjs.map +1 -0
- package/dist/chunk-67DJ7NOB.mjs +294 -0
- package/dist/chunk-67DJ7NOB.mjs.map +1 -0
- package/dist/chunk-7U2LKIGU.mjs +12 -0
- package/dist/chunk-7U2LKIGU.mjs.map +1 -0
- package/dist/chunk-BJTO5JO5.mjs +10 -0
- package/dist/chunk-BJTO5JO5.mjs.map +1 -0
- package/dist/index.cjs +3934 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +450 -0
- package/dist/index.d.ts +450 -0
- package/dist/index.mjs +3571 -0
- package/dist/index.mjs.map +1 -0
- package/dist/layout.cjs +217 -0
- package/dist/layout.cjs.map +1 -0
- package/dist/layout.d.cts +20 -0
- package/dist/layout.d.ts +20 -0
- package/dist/layout.mjs +4 -0
- package/dist/layout.mjs.map +1 -0
- package/dist/moviie-cast-adapter-DmSU2u3j.d.cts +53 -0
- package/dist/moviie-cast-adapter-DmSU2u3j.d.ts +53 -0
- package/dist/plugin/with-moviie.cjs +88 -0
- package/dist/plugin/with-moviie.cjs.map +1 -0
- package/dist/plugin/with-moviie.d.cts +52 -0
- package/dist/plugin/with-moviie.d.ts +52 -0
- package/dist/plugin/with-moviie.mjs +76 -0
- package/dist/plugin/with-moviie.mjs.map +1 -0
- package/package.json +134 -0
- package/plugin/validate-options.ts +31 -0
- package/plugin/with-moviie-types.ts +21 -0
- package/plugin/with-moviie.ts +84 -0
- package/src/apply-expo-moviie-endpoints.ts +47 -0
- package/src/cast/google-cast-adapter.ts +111 -0
- package/src/cast/index.ts +12 -0
- package/src/components/controls/moviie-bottom-timeline.tsx +477 -0
- package/src/components/controls/moviie-cast-buttons.tsx +96 -0
- package/src/components/controls/moviie-chrome-edge-gradients.tsx +162 -0
- package/src/components/controls/moviie-controls.tsx +585 -0
- package/src/components/controls/moviie-skin-chrome-context.tsx +374 -0
- package/src/components/controls/moviie-skin-smart-progress.tsx +157 -0
- package/src/components/icons/embed-media-icons.tsx +282 -0
- package/src/components/icons/moviie-embed-brand-mark.tsx +58 -0
- package/src/components/moviie-error-boundary.tsx +80 -0
- package/src/components/moviie-player-error-shell.tsx +143 -0
- package/src/components/moviie-player-loading-shell.tsx +59 -0
- package/src/components/moviie-skin-custom-fullscreen-modal.tsx +232 -0
- package/src/components/moviie-video-props.ts +134 -0
- package/src/components/moviie-video.tsx +568 -0
- package/src/components/moviie-video.web.tsx +167 -0
- package/src/components/overlays/moviie-watermark.tsx +53 -0
- package/src/constants.ts +374 -0
- package/src/hooks/use-moviie-event.ts +103 -0
- package/src/hooks/use-moviie-playback-ended.ts +14 -0
- package/src/hooks/use-moviie-playback-resume-persistence.ts +76 -0
- package/src/hooks/use-moviie-playback.ts +99 -0
- package/src/hooks/use-moviie-player-types.ts +55 -0
- package/src/hooks/use-moviie-player.ts +236 -0
- package/src/hooks/use-moviie-player.web.ts +57 -0
- package/src/hooks/use-moviie-telemetry.ts +133 -0
- package/src/index.ts +90 -0
- package/src/layout.ts +4 -0
- package/src/lib/add-moviie-playback-ended-listener.ts +16 -0
- package/src/lib/build-moviie-branding-marketing-url.ts +14 -0
- package/src/lib/build-moviie-embed-brand-home-url.ts +16 -0
- package/src/lib/build-moviie-skin-layout-metrics.ts +166 -0
- package/src/lib/build-moviie-video-presentation.ts +42 -0
- package/src/lib/build-moviie-watch-embed-url.ts +30 -0
- package/src/lib/cast-adapter-registry.ts +13 -0
- package/src/lib/clamp-unit-interval.ts +3 -0
- package/src/lib/compute-custom-fullscreen-stage-dimensions.ts +39 -0
- package/src/lib/compute-moviie-playback-ended.ts +31 -0
- package/src/lib/compute-playback-buffering.ts +41 -0
- package/src/lib/compute-playback-progress-ratio.ts +33 -0
- package/src/lib/compute-timeline-scrub-commit-time.ts +40 -0
- package/src/lib/custom-fullscreen-native-orientation.ts +88 -0
- package/src/lib/format-playback-clock.ts +27 -0
- package/src/lib/jsx-native-bridge.ts +45 -0
- package/src/lib/map-smart-progress-display-ratio.ts +43 -0
- package/src/lib/moviie-cast-adapter.ts +53 -0
- package/src/lib/moviie-error-display.ts +149 -0
- package/src/lib/moviie-shell-tokens.ts +27 -0
- package/src/lib/moviie-telemetry-callbacks.ts +76 -0
- package/src/lib/optional-status-bar.ts +48 -0
- package/src/lib/partition-moviie-video-host-style.ts +54 -0
- package/src/lib/remember-playback-position-storage.ts +98 -0
- package/src/lib/resolve-moviie-skin-layout-scale.ts +17 -0
- package/src/lib/resolve-orientation-lock-for-rotate-z-deg.ts +21 -0
- package/src/lib/resolve-skin-accent-color.ts +10 -0
- package/src/lib/resolve-web-embed-iframe-src.ts +17 -0
- package/src/lib/warn-once.ts +23 -0
- package/src/platform/native-application-id.ts +10 -0
- package/src/platform/platform-client-info.ts +31 -0
- package/src/playback/fetch-playback-fresh.ts +27 -0
- package/src/playback/playback-memory-cache.ts +52 -0
- package/src/provider/moviie-provider.tsx +99 -0
- package/src/secure-store-viewer-token-store.ts +80 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,3571 @@
|
|
|
1
|
+
import { MOVIIE_SMART_PROGRESS_Z_INDEX, MOVIIE_SMART_PROGRESS_BAR_HEIGHT_DP, MOVIIE_SKIN_CUSTOM_FULLSCREEN_ENTER_SCALE_START, MOVIIE_SKIN_CUSTOM_FULLSCREEN_TRANSITION_MS, MOVIIE_SKIN_CUSTOM_FULLSCREEN_ROTATE_Z_DEGREES, MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_BACKGROUND_HEX, MOVIIE_SKIN_CHROME_CONTROL_PRESSED_OPACITY, warnOnce, MOVIIE_PLAYBACK_PROFILE, MOVIIE_VIDEO_DEFAULT_CONTENT_FIT, MOVIIE_SKIN_CUSTOM_FULLSCREEN_VIDEO_CONTENT_FIT, MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_OVERSCAN_PX, MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE, MOVIIE_SKIN_CHROME_FOREGROUND_HEX, MOVIIE_SKIN_CONTROLS_FADE_MS, MOVIIE_SKIN_SEEK_JUMP_SECONDS, MOVIIE_SKIN_CHROME_SCRIM_BLACK_RGBA, MOVIIE_SKIN_TIMELINE_END_SNAP_EPSILON_SECONDS, MOVIIE_SKIN_CHROME_SVG_GRADIENT_TOP_EDGE_ID, MOVIIE_SKIN_CHROME_GRADIENT_EDGE_ALPHA, MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX, MOVIIE_SKIN_CHROME_SVG_GRADIENT_BOTTOM_EDGE_ID, MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX, MOVIIE_SKIN_TOP_ICON_CAST_VISUAL_SCALE, MOVIIE_SKIN_TOP_ICON_PIP_VISUAL_SCALE, MOVIIE_SKIN_TOP_ICON_FULLSCREEN_VISUAL_SCALE, MOVIIE_EMBED_BRAND_VIEW_BOX, MOVIIE_EMBED_BRAND_LETTERMARK_STROKE_WIDTH, MOVIIE_SMART_PROGRESS_FILL_TRANSITION_MS, MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER, MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_HORIZONTAL_DP, MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_BOTTOM_DP, MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_TOP_DP, MOVIIE_SKIN_BUFFER_UNDERRUN_LEAD_SECONDS, MOVIIE_SKIN_CHROME_EDGE_GRADIENT_MIN_CLEAR_MIDDLE_PX, MOVIIE_SKIN_CHROME_EDGE_GRADIENT_EDGE_SOLID_FADE_END_FRACTION, MOVIIE_SKIN_CHROME_CONTROL_REST_OPACITY, MOVIIE_BRANDING_MARKETING_ORIGIN, MOVIIE_BRANDING_UTM_PARAM_SOURCE, MOVIIE_EMBED_BRAND_UTM, MOVIIE_BRANDING_UTM_PARAM_MEDIUM, MOVIIE_BRANDING_UTM_PARAM_CAMPAIGN, MOVIIE_SKIN_DEFAULT_ACCENT_HEX, MOVIIE_SMART_PROGRESS_CONFIG, MOVIIE_SKIN_TIMELINE_BUFFER_LAYER_RGBA, MOVIIE_SKIN_TIMELINE_RAIL_BACKGROUND_RGBA, MOVIIE_SKIN_TIMELINE_THUMB_BORDER_RGBA, MOVIIE_SKIN_TIMELINE_TOUCH_EXPANSION_VERTICAL_DP, MOVIIE_SKIN_TIMELINE_CHAPTER_SNAP_THRESHOLD_SECONDS, MOVIIE_SKIN_BRAND_MARK_ARTBOARD_HEIGHT_PX, MOVIIE_SKIN_BRAND_MARK_ARTBOARD_WIDTH_PX, MOVIIE_SKIN_CUSTOM_FULLSCREEN_HUD_EDGE_BOOST_REFERENCE_PT, useMoviieContext, MOVIIE_WATCH_ORIGIN_DEFAULT, MOVIIE_SKIN_LAYOUT_SCALE_MAX, MOVIIE_SKIN_LAYOUT_SCALE_MIN, MOVIIE_SKIN_BRAND_MARK_TARGET_WIDTH_AT_REFERENCE_PT, MOVIIE_SKIN_TIMELINE_THUMB_DIAMETER_PX, MOVIIE_SKIN_TIMELINE_BAR_HEIGHT_PX, MOVIIE_SKIN_TIMELINE_TOUCH_PADDING_VERTICAL_PX, MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX, MOVIIE_SKIN_FLOATING_HUD_BUTTON_GAP_AT_REFERENCE_PT, MOVIIE_SKIN_FLOATING_FULLSCREEN_TOP_ICON_AT_REFERENCE_PT, MOVIIE_SKIN_FLOATING_FULLSCREEN_ICON_AT_REFERENCE_PT, MOVIIE_SKIN_FLOATING_FULLSCREEN_SCRIM_DIAMETER_AT_REFERENCE_PT, MOVIIE_SKIN_CHROME_EDGE_GRADIENT_HEIGHT_AT_REFERENCE_PT, MOVIIE_SKIN_BUFFERING_INDICATOR_SLOT_PX, MOVIIE_SKIN_CLOCK_TEXT_FONT_SIZE_AT_REFERENCE_PT, MOVIIE_SKIN_CENTER_PLAY_SCRIM_DIAMETER_AT_REFERENCE_PT, MOVIIE_SKIN_CENTER_CLUSTER_COLUMN_GAP_PX, MOVIIE_SKIN_CENTER_PLAY_ICON_PX, MOVIIE_SKIN_CENTER_SEEK_SCRIM_DIAMETER_AT_REFERENCE_PT, MOVIIE_SKIN_SEEK_ICON_PX, MOVIIE_SKIN_CONTROL_ICON_PX, MOVIIE_SKIN_FLOATING_HUD_CLOCK_CORNER_RADIUS_PX, MOVIIE_SKIN_FLOATING_HUD_ABOVE_TIMELINE_GAP_AT_REFERENCE_PT, MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT, MOVIIE_REMEMBER_POSITION_DEBOUNCE_MS, MOVIIE_REMEMBER_POSITION_STORAGE_PREFIX, MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS } from './chunk-67DJ7NOB.mjs';
|
|
2
|
+
export { EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV, EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV, EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN_ENV, MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS, MOVIIE_PLAYBACK_PROFILE, MOVIIE_PLAYER_EXPO_EMBED_JS_MARKER_ATTR, MOVIIE_PLAYER_EXPO_PKG_VERSION, MOVIIE_REMEMBER_POSITION_DEBOUNCE_MS, MOVIIE_REMEMBER_POSITION_STORAGE_PREFIX, MOVIIE_SKIN_CONTROLS_AUTO_HIDE_MS, MOVIIE_SKIN_CONTROL_ICON_PX, MOVIIE_SKIN_DEFAULT_ACCENT_HEX, MOVIIE_SKIN_TIMELINE_END_SNAP_EPSILON_SECONDS, MOVIIE_SKIN_VOLUME_LOW_ICON_THRESHOLD, MOVIIE_VIDEO_DEFAULT_CONTENT_FIT, MOVIIE_VIEWER_TOKEN_SECURE_STORE_KEY, MOVIIE_WATCH_EMBED_JS_PATH, MOVIIE_WATCH_ORIGIN_DEFAULT, MoviieProvider, SecureStoreViewerTokenStore, useMoviieContext } from './chunk-67DJ7NOB.mjs';
|
|
3
|
+
import { getRegisteredCastAdapter } from './chunk-7U2LKIGU.mjs';
|
|
4
|
+
import { __require } from './chunk-BJTO5JO5.mjs';
|
|
5
|
+
import { MoviieAuthError, MoviieNotFoundError, MoviieBundleBlockedError, MoviieReferrerBlockedError, MoviieSubscriptionInactiveError, MoviieNetworkError, MoviieRateLimitError, deriveTelemetryEventsBaseUrlFromBootstrapUrl, TelemetryClient, PLAYBACK_EVENT_TYPE } from '@moviie/player-sdk';
|
|
6
|
+
export * from '@moviie/player-sdk';
|
|
7
|
+
import React, { createContext, forwardRef, useRef, useMemo, useCallback, useImperativeHandle, useEffect, useState, createElement, useContext } from 'react';
|
|
8
|
+
import { isPictureInPictureSupported, VideoView, useVideoPlayer } from 'expo-video';
|
|
9
|
+
import { Animated, StyleSheet, Platform, useWindowDimensions, View, Modal, Pressable, Text, Image, ActivityIndicator, Linking, Easing as Easing$1, AppState } from 'react-native';
|
|
10
|
+
import { PLAYER_API_EVENTS } from '@moviie/player-types';
|
|
11
|
+
export { PLAYER_API_EVENTS, PLAYER_API_METHODS, PLAYER_API_PROPERTIES } from '@moviie/player-types';
|
|
12
|
+
import AnimatedReanimated, { useSharedValue, withTiming, runOnJS, useAnimatedStyle, Easing, useDerivedValue } from 'react-native-reanimated';
|
|
13
|
+
import RNSvg, { Defs as Defs$1, LinearGradient as LinearGradient$1, Stop as Stop$1, Rect as Rect$1, Path as Path$1 } from 'react-native-svg';
|
|
14
|
+
import { useSafeAreaInsets, SafeAreaProvider } from 'react-native-safe-area-context';
|
|
15
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
16
|
+
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
17
|
+
import { getOrientationLockAsync, lockAsync, OrientationLock, unlockAsync } from 'expo-screen-orientation';
|
|
18
|
+
|
|
19
|
+
// src/playback/playback-memory-cache.ts
|
|
20
|
+
var playbackCache = /* @__PURE__ */ new Map();
|
|
21
|
+
function cacheKey(scope, embedId) {
|
|
22
|
+
return `${scope ?? "__anon__"}::${embedId}`;
|
|
23
|
+
}
|
|
24
|
+
function resolveEntryExpiry(data) {
|
|
25
|
+
const now = Date.now();
|
|
26
|
+
const fallback = now + MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS;
|
|
27
|
+
const serverExpiry = data.playback?.expiresAt;
|
|
28
|
+
if (!serverExpiry) return fallback;
|
|
29
|
+
const parsed = Date.parse(serverExpiry);
|
|
30
|
+
if (!Number.isFinite(parsed)) return fallback;
|
|
31
|
+
return Math.min(fallback, parsed);
|
|
32
|
+
}
|
|
33
|
+
function readPlaybackCache(scope, embedId) {
|
|
34
|
+
const key = cacheKey(scope, embedId);
|
|
35
|
+
const hit = playbackCache.get(key);
|
|
36
|
+
if (!hit || hit.expiresAt <= Date.now()) {
|
|
37
|
+
playbackCache.delete(key);
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return hit.data;
|
|
41
|
+
}
|
|
42
|
+
function writePlaybackCache(scope, embedId, data) {
|
|
43
|
+
playbackCache.set(cacheKey(scope, embedId), {
|
|
44
|
+
data,
|
|
45
|
+
expiresAt: resolveEntryExpiry(data)
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/playback/fetch-playback-fresh.ts
|
|
50
|
+
async function fetchPlaybackFreshWriteCache(scope, embedId, signal, getPlayback) {
|
|
51
|
+
try {
|
|
52
|
+
const data = await getPlayback(embedId, signal);
|
|
53
|
+
writePlaybackCache(scope, embedId, data);
|
|
54
|
+
return { ok: true, data };
|
|
55
|
+
} catch (unknownError) {
|
|
56
|
+
const error = unknownError instanceof Error ? unknownError : new Error(String(unknownError));
|
|
57
|
+
return { ok: false, error };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/hooks/use-moviie-playback.ts
|
|
62
|
+
function useMoviiePlayback(args) {
|
|
63
|
+
const trimmedEmbedId = args.embedId?.trim();
|
|
64
|
+
const missingEmbedId = !trimmedEmbedId;
|
|
65
|
+
const { client, publishableKey } = useMoviieContext();
|
|
66
|
+
const [data, setData] = useState(null);
|
|
67
|
+
const [fetchError, setFetchError] = useState(null);
|
|
68
|
+
const [isLoading, setIsLoading] = useState(!missingEmbedId);
|
|
69
|
+
const [retryNonce, setRetryNonce] = useState(0);
|
|
70
|
+
const retry = useCallback(() => {
|
|
71
|
+
setRetryNonce((n) => n + 1);
|
|
72
|
+
}, []);
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (!trimmedEmbedId) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const embedKey = trimmedEmbedId;
|
|
78
|
+
const controller = new AbortController();
|
|
79
|
+
let cancelled = false;
|
|
80
|
+
async function load() {
|
|
81
|
+
setIsLoading(true);
|
|
82
|
+
setFetchError(null);
|
|
83
|
+
try {
|
|
84
|
+
const cached = readPlaybackCache(publishableKey, embedKey);
|
|
85
|
+
if (cached && !controller.signal.aborted) {
|
|
86
|
+
setData(cached);
|
|
87
|
+
}
|
|
88
|
+
const outcome = await fetchPlaybackFreshWriteCache(
|
|
89
|
+
publishableKey,
|
|
90
|
+
embedKey,
|
|
91
|
+
controller.signal,
|
|
92
|
+
(id, sig) => client.getPlayback(id, sig)
|
|
93
|
+
);
|
|
94
|
+
if (cancelled || controller.signal.aborted) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (outcome.ok) {
|
|
98
|
+
setData(outcome.data);
|
|
99
|
+
} else {
|
|
100
|
+
setFetchError(outcome.error);
|
|
101
|
+
setData(readPlaybackCache(publishableKey, embedKey));
|
|
102
|
+
}
|
|
103
|
+
} finally {
|
|
104
|
+
if (!cancelled && !controller.signal.aborted) {
|
|
105
|
+
setIsLoading(false);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
void load();
|
|
110
|
+
return () => {
|
|
111
|
+
cancelled = true;
|
|
112
|
+
controller.abort();
|
|
113
|
+
};
|
|
114
|
+
}, [trimmedEmbedId, client, publishableKey, retryNonce]);
|
|
115
|
+
const error = missingEmbedId ? new Error("Informe um embedId v\xE1lido (UUID p\xFAblico do embed).") : fetchError;
|
|
116
|
+
return {
|
|
117
|
+
data: missingEmbedId ? null : data,
|
|
118
|
+
error,
|
|
119
|
+
isLoading: missingEmbedId ? false : isLoading,
|
|
120
|
+
retry
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function useMoviieTelemetry(player, playback, eventsBaseUrl, defaultHeaders, viewerTokenStore) {
|
|
124
|
+
const hasStartedPlaybackRef = useRef(false);
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
if (!playback?.telemetry.bootstrapUrl) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const telemetry = new TelemetryClient({
|
|
130
|
+
eventsBaseUrl,
|
|
131
|
+
defaultHeaders,
|
|
132
|
+
viewerTokenStore,
|
|
133
|
+
getPositionSeconds: () => player.currentTime
|
|
134
|
+
});
|
|
135
|
+
let disposed = false;
|
|
136
|
+
const subs = [];
|
|
137
|
+
void (async () => {
|
|
138
|
+
try {
|
|
139
|
+
await telemetry.bootstrap({
|
|
140
|
+
bootstrapUrl: playback.telemetry.bootstrapUrl
|
|
141
|
+
});
|
|
142
|
+
if (disposed) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
await telemetry.recordEvent({
|
|
146
|
+
eventType: PLAYBACK_EVENT_TYPE.SESSION_START,
|
|
147
|
+
positionSeconds: 0
|
|
148
|
+
});
|
|
149
|
+
} catch {
|
|
150
|
+
}
|
|
151
|
+
})();
|
|
152
|
+
subs.push(
|
|
153
|
+
player.addListener("playingChange", ({ isPlaying }) => {
|
|
154
|
+
telemetry.updatePosition(Math.max(0, player.currentTime));
|
|
155
|
+
if (isPlaying) {
|
|
156
|
+
void telemetry.recordEvent({
|
|
157
|
+
eventType: hasStartedPlaybackRef.current ? PLAYBACK_EVENT_TYPE.RESUME : PLAYBACK_EVENT_TYPE.PLAY_START,
|
|
158
|
+
positionSeconds: Math.floor(Math.max(0, player.currentTime))
|
|
159
|
+
});
|
|
160
|
+
hasStartedPlaybackRef.current = true;
|
|
161
|
+
telemetry.startHeartbeats();
|
|
162
|
+
} else {
|
|
163
|
+
void telemetry.recordEvent({
|
|
164
|
+
eventType: PLAYBACK_EVENT_TYPE.PAUSE,
|
|
165
|
+
positionSeconds: Math.floor(Math.max(0, player.currentTime))
|
|
166
|
+
});
|
|
167
|
+
telemetry.stopHeartbeats();
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
);
|
|
171
|
+
subs.push(
|
|
172
|
+
player.addListener("playToEnd", () => {
|
|
173
|
+
telemetry.updatePosition(Math.max(0, player.currentTime));
|
|
174
|
+
void telemetry.recordEvent({
|
|
175
|
+
eventType: PLAYBACK_EVENT_TYPE.ENDED,
|
|
176
|
+
positionSeconds: Math.floor(Math.max(0, player.duration))
|
|
177
|
+
});
|
|
178
|
+
telemetry.stopHeartbeats();
|
|
179
|
+
})
|
|
180
|
+
);
|
|
181
|
+
subs.push(
|
|
182
|
+
player.addListener("statusChange", ({ status }) => {
|
|
183
|
+
if (status === "error") {
|
|
184
|
+
void telemetry.recordEvent({
|
|
185
|
+
eventType: PLAYBACK_EVENT_TYPE.ERROR,
|
|
186
|
+
positionSeconds: Math.floor(Math.max(0, player.currentTime)),
|
|
187
|
+
errorCode: "player_status_error"
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
);
|
|
192
|
+
subs.push(
|
|
193
|
+
player.addListener("timeUpdate", ({ currentTime }) => {
|
|
194
|
+
telemetry.updatePosition(Math.max(0, currentTime));
|
|
195
|
+
})
|
|
196
|
+
);
|
|
197
|
+
const appStateSub = AppState.addEventListener(
|
|
198
|
+
"change",
|
|
199
|
+
(next) => {
|
|
200
|
+
if (next === "active") {
|
|
201
|
+
telemetry.resumeHeartbeats();
|
|
202
|
+
} else {
|
|
203
|
+
telemetry.pauseHeartbeats();
|
|
204
|
+
void telemetry.flush();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
return () => {
|
|
209
|
+
disposed = true;
|
|
210
|
+
hasStartedPlaybackRef.current = false;
|
|
211
|
+
subs.forEach((s) => {
|
|
212
|
+
s.remove();
|
|
213
|
+
});
|
|
214
|
+
appStateSub.remove();
|
|
215
|
+
void telemetry.destroy();
|
|
216
|
+
};
|
|
217
|
+
}, [
|
|
218
|
+
player,
|
|
219
|
+
playback?.embedId,
|
|
220
|
+
playback?.telemetry.bootstrapUrl,
|
|
221
|
+
eventsBaseUrl,
|
|
222
|
+
defaultHeaders,
|
|
223
|
+
viewerTokenStore
|
|
224
|
+
]);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// src/lib/remember-playback-position-storage.ts
|
|
228
|
+
var RESUME_SECURE_STORE_MISSING_WARNING = "[@moviie/player-expo] `expo-secure-store` n\xE3o est\xE1 instalado \u2014 resume position n\xE3o ser\xE1 persistido. Instala com `pnpm add expo-secure-store` se quiseres retomar onde o utilizador parou.";
|
|
229
|
+
var SECURE_STORE_KEY_SAFE_PATTERN = /^[A-Za-z0-9._-]+$/;
|
|
230
|
+
function isSecureStoreSafeEmbedId(embedId) {
|
|
231
|
+
return SECURE_STORE_KEY_SAFE_PATTERN.test(embedId);
|
|
232
|
+
}
|
|
233
|
+
function rememberPlaybackPositionStorageKey(embedId) {
|
|
234
|
+
return `${MOVIIE_REMEMBER_POSITION_STORAGE_PREFIX}${embedId}`;
|
|
235
|
+
}
|
|
236
|
+
function parseStoredResumeSeconds(raw) {
|
|
237
|
+
if (raw == null || raw === "") {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
const n = Number(raw);
|
|
241
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
return n;
|
|
245
|
+
}
|
|
246
|
+
function clampResumeTimeSeconds(seconds, durationSeconds) {
|
|
247
|
+
if (seconds == null || !Number.isFinite(seconds) || seconds < 0.25) {
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
if (durationSeconds != null && Number.isFinite(durationSeconds) && durationSeconds > 0) {
|
|
251
|
+
if (seconds >= durationSeconds - 1) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
return Math.min(seconds, durationSeconds - 0.25);
|
|
255
|
+
}
|
|
256
|
+
return seconds;
|
|
257
|
+
}
|
|
258
|
+
async function loadSecureStore() {
|
|
259
|
+
try {
|
|
260
|
+
return await import('expo-secure-store');
|
|
261
|
+
} catch {
|
|
262
|
+
warnOnce("moviie:expo-secure-store-missing-resume", RESUME_SECURE_STORE_MISSING_WARNING);
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async function readStoredResumeSeconds(embedId) {
|
|
267
|
+
if (!isSecureStoreSafeEmbedId(embedId)) {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
const SecureStore = await loadSecureStore();
|
|
271
|
+
if (!SecureStore) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
try {
|
|
275
|
+
const raw = await SecureStore.getItemAsync(rememberPlaybackPositionStorageKey(embedId));
|
|
276
|
+
return parseStoredResumeSeconds(raw);
|
|
277
|
+
} catch {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
async function writeStoredResumeSeconds(embedId, seconds) {
|
|
282
|
+
if (!isSecureStoreSafeEmbedId(embedId)) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const SecureStore = await loadSecureStore();
|
|
286
|
+
if (!SecureStore) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
try {
|
|
290
|
+
await SecureStore.setItemAsync(rememberPlaybackPositionStorageKey(embedId), String(seconds));
|
|
291
|
+
} catch {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
async function clearStoredResumeSeconds(embedId) {
|
|
296
|
+
if (!isSecureStoreSafeEmbedId(embedId)) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
const SecureStore = await loadSecureStore();
|
|
300
|
+
if (!SecureStore) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
try {
|
|
304
|
+
await SecureStore.deleteItemAsync(rememberPlaybackPositionStorageKey(embedId));
|
|
305
|
+
} catch {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// src/hooks/use-moviie-playback-resume-persistence.ts
|
|
311
|
+
function useMoviiePlaybackResumePersistence(options) {
|
|
312
|
+
const { player, embedId, durationSeconds, enabled } = options;
|
|
313
|
+
const debounceTimerRef = useRef(null);
|
|
314
|
+
useEffect(() => {
|
|
315
|
+
if (!enabled || embedId == null || embedId === "") {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const clearDebounce = () => {
|
|
319
|
+
if (debounceTimerRef.current != null) {
|
|
320
|
+
clearTimeout(debounceTimerRef.current);
|
|
321
|
+
debounceTimerRef.current = null;
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
const persistNow = (seconds) => {
|
|
325
|
+
const clamped = clampResumeTimeSeconds(seconds, durationSeconds);
|
|
326
|
+
if (clamped == null) {
|
|
327
|
+
void clearStoredResumeSeconds(embedId);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
void writeStoredResumeSeconds(embedId, clamped);
|
|
331
|
+
};
|
|
332
|
+
const schedulePersist = (seconds) => {
|
|
333
|
+
clearDebounce();
|
|
334
|
+
debounceTimerRef.current = setTimeout(() => {
|
|
335
|
+
debounceTimerRef.current = null;
|
|
336
|
+
persistNow(seconds);
|
|
337
|
+
}, MOVIIE_REMEMBER_POSITION_DEBOUNCE_MS);
|
|
338
|
+
};
|
|
339
|
+
const subTime = player.addListener("timeUpdate", ({ currentTime }) => {
|
|
340
|
+
if (player.playing) {
|
|
341
|
+
schedulePersist(currentTime);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
const subPlaying = player.addListener("playingChange", ({ isPlaying }) => {
|
|
345
|
+
if (!isPlaying) {
|
|
346
|
+
clearDebounce();
|
|
347
|
+
persistNow(player.currentTime);
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
const subEnd = player.addListener("playToEnd", () => {
|
|
351
|
+
clearDebounce();
|
|
352
|
+
void clearStoredResumeSeconds(embedId);
|
|
353
|
+
});
|
|
354
|
+
return () => {
|
|
355
|
+
clearDebounce();
|
|
356
|
+
subTime.remove();
|
|
357
|
+
subPlaying.remove();
|
|
358
|
+
subEnd.remove();
|
|
359
|
+
};
|
|
360
|
+
}, [durationSeconds, embedId, enabled, player]);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// src/lib/build-moviie-video-presentation.ts
|
|
364
|
+
function buildMoviieVideoPresentationProps(args) {
|
|
365
|
+
const allowsPictureInPicture = args.pictureInPicture !== void 0 ? args.pictureInPicture : args.showPip;
|
|
366
|
+
return {
|
|
367
|
+
allowsPictureInPicture,
|
|
368
|
+
startsPictureInPictureAutomatically: args.pictureInPictureAutoStart ?? false,
|
|
369
|
+
requiresLinearPlayback: args.profile === MOVIIE_PLAYBACK_PROFILE.VSL
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// src/hooks/use-moviie-player.ts
|
|
374
|
+
var PLAYBACK_REQUEST_HEADER_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
375
|
+
"authorization",
|
|
376
|
+
"referer",
|
|
377
|
+
"user-agent",
|
|
378
|
+
"x-moviie-playback-token",
|
|
379
|
+
"x-moviie-signature",
|
|
380
|
+
"x-playback-token"
|
|
381
|
+
]);
|
|
382
|
+
function filterPlaybackRequestHeaders(raw) {
|
|
383
|
+
if (!raw) return void 0;
|
|
384
|
+
const safe = {};
|
|
385
|
+
for (const [name, value] of Object.entries(raw)) {
|
|
386
|
+
if (typeof name !== "string" || typeof value !== "string") continue;
|
|
387
|
+
if (!PLAYBACK_REQUEST_HEADER_ALLOWLIST.has(name.toLowerCase())) continue;
|
|
388
|
+
if (/[\r\n]/.test(value)) continue;
|
|
389
|
+
safe[name] = value;
|
|
390
|
+
}
|
|
391
|
+
return Object.keys(safe).length > 0 ? safe : void 0;
|
|
392
|
+
}
|
|
393
|
+
function buildVideoSource(data) {
|
|
394
|
+
const headers = filterPlaybackRequestHeaders(data.playback.requestHeaders);
|
|
395
|
+
const base = {
|
|
396
|
+
uri: data.playback.uri,
|
|
397
|
+
metadata: {
|
|
398
|
+
title: data.title,
|
|
399
|
+
artist: data.branding.organizationName ?? void 0,
|
|
400
|
+
artwork: data.posterUrl ?? void 0
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
if (headers) {
|
|
404
|
+
return { ...base, headers };
|
|
405
|
+
}
|
|
406
|
+
return base;
|
|
407
|
+
}
|
|
408
|
+
function configurePlaybackDefaults(player, data) {
|
|
409
|
+
const c = data.controls;
|
|
410
|
+
player.loop = c.loop;
|
|
411
|
+
player.muted = c.muted;
|
|
412
|
+
player.timeUpdateEventInterval = 1;
|
|
413
|
+
}
|
|
414
|
+
function applyNativePlaybackPresentation(player, opts) {
|
|
415
|
+
player.staysActiveInBackground = opts.backgroundPlayback ?? false;
|
|
416
|
+
player.showNowPlayingNotification = opts.lockScreenNowPlaying ?? false;
|
|
417
|
+
}
|
|
418
|
+
function syncPlaybackIntent(player, shouldPlay) {
|
|
419
|
+
if (shouldPlay) {
|
|
420
|
+
player.play();
|
|
421
|
+
} else {
|
|
422
|
+
player.pause();
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
var EMPTY_PRESENTATION = buildMoviieVideoPresentationProps({
|
|
426
|
+
profile: "",
|
|
427
|
+
showPip: false
|
|
428
|
+
});
|
|
429
|
+
function useMoviiePlayer(options) {
|
|
430
|
+
const ctx = useMoviieContext();
|
|
431
|
+
const { data, error, isLoading, retry } = useMoviiePlayback({
|
|
432
|
+
embedId: options.embedId
|
|
433
|
+
});
|
|
434
|
+
const rememberEnabled = useMemo(() => {
|
|
435
|
+
if (options.rememberPosition === false) {
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
if (options.rememberPosition === true) {
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
return data?.controls.rememberPosition === true;
|
|
442
|
+
}, [data?.controls.rememberPosition, options.rememberPosition]);
|
|
443
|
+
const player = useVideoPlayer(null, (initialPlayer) => {
|
|
444
|
+
initialPlayer.timeUpdateEventInterval = 1;
|
|
445
|
+
});
|
|
446
|
+
useMoviiePlaybackResumePersistence({
|
|
447
|
+
durationSeconds: data?.durationSeconds,
|
|
448
|
+
embedId: data?.embedId,
|
|
449
|
+
enabled: rememberEnabled && data != null,
|
|
450
|
+
player
|
|
451
|
+
});
|
|
452
|
+
const resumeHandledRef = useRef(false);
|
|
453
|
+
useEffect(() => {
|
|
454
|
+
resumeHandledRef.current = false;
|
|
455
|
+
}, [data?.embedId, data?.playback.uri]);
|
|
456
|
+
useEffect(() => {
|
|
457
|
+
if (!data) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const src = buildVideoSource(data);
|
|
461
|
+
const shouldPlay = options.autoplay !== void 0 ? options.autoplay : data.controls.autoplay;
|
|
462
|
+
player.replace(src);
|
|
463
|
+
configurePlaybackDefaults(player, data);
|
|
464
|
+
applyNativePlaybackPresentation(player, {
|
|
465
|
+
backgroundPlayback: options.backgroundPlayback,
|
|
466
|
+
lockScreenNowPlaying: options.lockScreenNowPlaying
|
|
467
|
+
});
|
|
468
|
+
const restoreAndSync = async () => {
|
|
469
|
+
if (player.status !== "readyToPlay") {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
if (!resumeHandledRef.current) {
|
|
473
|
+
resumeHandledRef.current = true;
|
|
474
|
+
if (rememberEnabled) {
|
|
475
|
+
const stored = await readStoredResumeSeconds(data.embedId);
|
|
476
|
+
const clamped = clampResumeTimeSeconds(stored, data.durationSeconds);
|
|
477
|
+
if (clamped != null) {
|
|
478
|
+
player.currentTime = clamped;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
syncPlaybackIntent(player, shouldPlay);
|
|
483
|
+
};
|
|
484
|
+
const sub = player.addListener("statusChange", (payload) => {
|
|
485
|
+
if (payload.status === "readyToPlay") {
|
|
486
|
+
void restoreAndSync();
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
void restoreAndSync();
|
|
490
|
+
return () => {
|
|
491
|
+
sub.remove();
|
|
492
|
+
};
|
|
493
|
+
}, [
|
|
494
|
+
data,
|
|
495
|
+
player,
|
|
496
|
+
options.autoplay,
|
|
497
|
+
options.backgroundPlayback,
|
|
498
|
+
options.lockScreenNowPlaying,
|
|
499
|
+
rememberEnabled
|
|
500
|
+
]);
|
|
501
|
+
const videoPresentation = useMemo(() => {
|
|
502
|
+
if (!data) {
|
|
503
|
+
return EMPTY_PRESENTATION;
|
|
504
|
+
}
|
|
505
|
+
return buildMoviieVideoPresentationProps({
|
|
506
|
+
pictureInPicture: options.pictureInPicture,
|
|
507
|
+
pictureInPictureAutoStart: options.pictureInPictureAutoStart,
|
|
508
|
+
profile: data.profile,
|
|
509
|
+
showPip: data.controls.showPip
|
|
510
|
+
});
|
|
511
|
+
}, [
|
|
512
|
+
data,
|
|
513
|
+
options.pictureInPicture,
|
|
514
|
+
options.pictureInPictureAutoStart
|
|
515
|
+
]);
|
|
516
|
+
const eventsBaseUrl = data?.telemetry.bootstrapUrl != null ? deriveTelemetryEventsBaseUrlFromBootstrapUrl(data.telemetry.bootstrapUrl) ?? ctx.client.getEventsBaseUrl() : ctx.client.getEventsBaseUrl();
|
|
517
|
+
useMoviieTelemetry(
|
|
518
|
+
player,
|
|
519
|
+
data,
|
|
520
|
+
eventsBaseUrl,
|
|
521
|
+
ctx.telemetryHeaders,
|
|
522
|
+
ctx.viewerTokenStore
|
|
523
|
+
);
|
|
524
|
+
return {
|
|
525
|
+
player,
|
|
526
|
+
playback: data,
|
|
527
|
+
error,
|
|
528
|
+
isLoading,
|
|
529
|
+
videoPresentation,
|
|
530
|
+
retry
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
function useMoviieEvent(player, eventName, handler) {
|
|
534
|
+
useEffect(() => {
|
|
535
|
+
if (!player) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
if (eventName === PLAYER_API_EVENTS.TIME_UPDATE) {
|
|
539
|
+
const previousInterval = player.timeUpdateEventInterval;
|
|
540
|
+
if (player.timeUpdateEventInterval <= 0) {
|
|
541
|
+
player.timeUpdateEventInterval = 0.25;
|
|
542
|
+
}
|
|
543
|
+
const sub = player.addListener("timeUpdate", () => {
|
|
544
|
+
handler();
|
|
545
|
+
});
|
|
546
|
+
return () => {
|
|
547
|
+
sub.remove();
|
|
548
|
+
player.timeUpdateEventInterval = previousInterval;
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
if (eventName === PLAYER_API_EVENTS.PLAY) {
|
|
552
|
+
const sub = player.addListener("playingChange", ({ isPlaying }) => {
|
|
553
|
+
if (isPlaying) {
|
|
554
|
+
handler();
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
return () => {
|
|
558
|
+
sub.remove();
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
if (eventName === PLAYER_API_EVENTS.PAUSE) {
|
|
562
|
+
const sub = player.addListener("playingChange", ({ isPlaying }) => {
|
|
563
|
+
if (!isPlaying) {
|
|
564
|
+
handler();
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
return () => {
|
|
568
|
+
sub.remove();
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
if (eventName === PLAYER_API_EVENTS.ENDED) {
|
|
572
|
+
const sub = player.addListener("playToEnd", () => {
|
|
573
|
+
handler();
|
|
574
|
+
});
|
|
575
|
+
return () => {
|
|
576
|
+
sub.remove();
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
if (eventName === PLAYER_API_EVENTS.DURATION_CHANGE) {
|
|
580
|
+
const sub = player.addListener("sourceChange", () => {
|
|
581
|
+
handler();
|
|
582
|
+
});
|
|
583
|
+
return () => {
|
|
584
|
+
sub.remove();
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
if (eventName === PLAYER_API_EVENTS.VOLUME_CHANGE) {
|
|
588
|
+
const sub = player.addListener("volumeChange", () => {
|
|
589
|
+
handler();
|
|
590
|
+
});
|
|
591
|
+
return () => {
|
|
592
|
+
sub.remove();
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
if (eventName === PLAYER_API_EVENTS.READY) {
|
|
596
|
+
const sub = player.addListener("statusChange", ({ status }) => {
|
|
597
|
+
if (status === "readyToPlay") {
|
|
598
|
+
handler();
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
return () => {
|
|
602
|
+
sub.remove();
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
606
|
+
console.warn(
|
|
607
|
+
`[@moviie/player-expo] useMoviieEvent: "${eventName}" n\xE3o tem mapeamento para expo-video nesta vers\xE3o`
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
return void 0;
|
|
611
|
+
}, [player, eventName, handler]);
|
|
612
|
+
}
|
|
613
|
+
function useMoviiePlaybackEnded(player, onEnded) {
|
|
614
|
+
useMoviieEvent(player, PLAYER_API_EVENTS.ENDED, onEnded);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// src/lib/compute-moviie-playback-ended.ts
|
|
618
|
+
function computeMoviiePlaybackEnded(args) {
|
|
619
|
+
if (args.loop) {
|
|
620
|
+
return false;
|
|
621
|
+
}
|
|
622
|
+
if (args.isLive) {
|
|
623
|
+
return false;
|
|
624
|
+
}
|
|
625
|
+
if (args.playing) {
|
|
626
|
+
return false;
|
|
627
|
+
}
|
|
628
|
+
if (!Number.isFinite(args.duration) || args.duration <= 0) {
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
631
|
+
if (!Number.isFinite(args.currentTime)) {
|
|
632
|
+
return false;
|
|
633
|
+
}
|
|
634
|
+
return args.currentTime >= args.duration - MOVIIE_SKIN_TIMELINE_END_SNAP_EPSILON_SECONDS;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// src/lib/add-moviie-playback-ended-listener.ts
|
|
638
|
+
function addMoviiePlaybackEndedListener(player, onEnded) {
|
|
639
|
+
const sub = player.addListener("playToEnd", onEnded);
|
|
640
|
+
return { remove: () => sub.remove() };
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// src/lib/build-moviie-watch-embed-url.ts
|
|
644
|
+
function normalizeWatchOrigin(origin) {
|
|
645
|
+
return origin.trim().replace(/\/+$/, "");
|
|
646
|
+
}
|
|
647
|
+
function buildMoviieWatchEmbedUrl(embedId, watchOrigin) {
|
|
648
|
+
const base = normalizeWatchOrigin(watchOrigin);
|
|
649
|
+
const id = embedId.trim();
|
|
650
|
+
return `${base}/embed/${encodeURIComponent(id)}`;
|
|
651
|
+
}
|
|
652
|
+
function resolveMoviieWatchOrigin() {
|
|
653
|
+
try {
|
|
654
|
+
const raw = typeof process !== "undefined" ? process.env.EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN?.trim() : void 0;
|
|
655
|
+
if (raw) {
|
|
656
|
+
return normalizeWatchOrigin(raw);
|
|
657
|
+
}
|
|
658
|
+
} catch {
|
|
659
|
+
}
|
|
660
|
+
return MOVIIE_WATCH_ORIGIN_DEFAULT;
|
|
661
|
+
}
|
|
662
|
+
var Svg = RNSvg;
|
|
663
|
+
var jsx_native_bridge_default = Svg;
|
|
664
|
+
var Path = Path$1;
|
|
665
|
+
var Defs = Defs$1;
|
|
666
|
+
var LinearGradient = LinearGradient$1;
|
|
667
|
+
var Rect = Rect$1;
|
|
668
|
+
var Stop = Stop$1;
|
|
669
|
+
var AnimatedView = Animated.View;
|
|
670
|
+
var ReanimatedView = AnimatedReanimated.View;
|
|
671
|
+
|
|
672
|
+
// src/lib/moviie-telemetry-callbacks.ts
|
|
673
|
+
function safeInvokeMoviieTelemetry(callback, ...args) {
|
|
674
|
+
if (callback == null) {
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
try {
|
|
678
|
+
callback(...args);
|
|
679
|
+
} catch (err) {
|
|
680
|
+
console.warn("[@moviie/player-expo] telemetry callback threw \u2014 ignorado", err);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// src/lib/moviie-shell-tokens.ts
|
|
685
|
+
var MOVIIE_SHELL_BACKGROUND_HEX = "#0a0a0a";
|
|
686
|
+
var MOVIIE_SHELL_RADIAL_INNER_HEX = "#1a1a1a";
|
|
687
|
+
var MOVIIE_SHELL_HEADING_HEX = "#f8fafc";
|
|
688
|
+
var MOVIIE_SHELL_DESCRIPTION_HEX = "#e5e7eb";
|
|
689
|
+
var MOVIIE_SHELL_ERROR_CODE_HEX = "#4b5563";
|
|
690
|
+
var MOVIIE_SHELL_BUTTON_BG_HEX = "#0a0a0a";
|
|
691
|
+
var MOVIIE_SHELL_BUTTON_BORDER_RGBA = "rgba(255,255,255,0.15)";
|
|
692
|
+
var MOVIIE_SHELL_BUTTON_LABEL_HEX = "#f8fafc";
|
|
693
|
+
var MOVIIE_SHELL_HEADING_FONT_SIZE_PX = 22;
|
|
694
|
+
var MOVIIE_SHELL_DESCRIPTION_FONT_SIZE_PX = 14;
|
|
695
|
+
var MOVIIE_SHELL_BUTTON_LABEL_FONT_SIZE_PX = 14;
|
|
696
|
+
var MOVIIE_SHELL_CONTENT_MAX_WIDTH_PX = 280;
|
|
697
|
+
var MOVIIE_SHELL_BUTTON_PADDING_H_PX = 22;
|
|
698
|
+
var MOVIIE_SHELL_BUTTON_PADDING_V_PX = 12;
|
|
699
|
+
var MOVIIE_SHELL_BUTTON_RADIUS_PX = 9999;
|
|
700
|
+
var MOVIIE_SHELL_CROSSFADE_DURATION_MS = 240;
|
|
701
|
+
var MOVIIE_SHELL_DEFAULT_ASPECT_RATIO = 16 / 9;
|
|
702
|
+
var MOVIIE_DASHBOARD_URL = "https://app.moviie.ai";
|
|
703
|
+
|
|
704
|
+
// src/lib/partition-moviie-video-host-style.ts
|
|
705
|
+
var VIDEO_SURFACE_STYLE_KEYS = /* @__PURE__ */ new Set([
|
|
706
|
+
"backgroundColor",
|
|
707
|
+
"borderRadius",
|
|
708
|
+
"borderTopLeftRadius",
|
|
709
|
+
"borderTopRightRadius",
|
|
710
|
+
"borderBottomLeftRadius",
|
|
711
|
+
"borderBottomRightRadius",
|
|
712
|
+
"borderCurve",
|
|
713
|
+
"borderWidth",
|
|
714
|
+
"borderColor"
|
|
715
|
+
]);
|
|
716
|
+
function partitionMoviieVideoHostStyle(flatStyle) {
|
|
717
|
+
if (flatStyle == null || Object.keys(flatStyle).length === 0) {
|
|
718
|
+
return { columnStyle: void 0, surfaceStyle: void 0 };
|
|
719
|
+
}
|
|
720
|
+
const flat = flatStyle;
|
|
721
|
+
const column = {};
|
|
722
|
+
const surface = {};
|
|
723
|
+
for (const key of Object.keys(flat)) {
|
|
724
|
+
const value = flat[key];
|
|
725
|
+
if (value === void 0) {
|
|
726
|
+
continue;
|
|
727
|
+
}
|
|
728
|
+
if (VIDEO_SURFACE_STYLE_KEYS.has(key)) {
|
|
729
|
+
surface[key] = value;
|
|
730
|
+
} else {
|
|
731
|
+
column[key] = value;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
return {
|
|
735
|
+
columnStyle: Object.keys(column).length > 0 ? column : void 0,
|
|
736
|
+
surfaceStyle: Object.keys(surface).length > 0 ? surface : void 0
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
// src/lib/compute-custom-fullscreen-stage-dimensions.ts
|
|
741
|
+
function computeCustomFullscreenStageDimensions(args) {
|
|
742
|
+
const pad = args.stageOverscanPx;
|
|
743
|
+
const usableW = Math.max(
|
|
744
|
+
0,
|
|
745
|
+
args.windowWidth - args.safeInsets.left - args.safeInsets.right - 2 * pad
|
|
746
|
+
);
|
|
747
|
+
const usableH = Math.max(
|
|
748
|
+
0,
|
|
749
|
+
args.windowHeight - args.safeInsets.top - args.safeInsets.bottom - 2 * pad
|
|
750
|
+
);
|
|
751
|
+
const longSide = Math.max(usableW, usableH);
|
|
752
|
+
const shortSide = Math.min(usableW, usableH);
|
|
753
|
+
return {
|
|
754
|
+
longSide,
|
|
755
|
+
shortSide,
|
|
756
|
+
layoutMetricsBasisWidth: longSide
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
// src/lib/format-playback-clock.ts
|
|
761
|
+
function pad2(value) {
|
|
762
|
+
return String(Math.floor(value)).padStart(2, "0");
|
|
763
|
+
}
|
|
764
|
+
function formatSegment(totalSeconds) {
|
|
765
|
+
if (!Number.isFinite(totalSeconds) || totalSeconds < 0) {
|
|
766
|
+
return "0:00";
|
|
767
|
+
}
|
|
768
|
+
const seconds = totalSeconds % 60;
|
|
769
|
+
const minutes = Math.floor(totalSeconds / 60) % 60;
|
|
770
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
771
|
+
if (hours > 0) {
|
|
772
|
+
return `${hours}:${pad2(minutes)}:${pad2(seconds)}`;
|
|
773
|
+
}
|
|
774
|
+
return `${Math.floor(minutes)}:${pad2(seconds)}`;
|
|
775
|
+
}
|
|
776
|
+
function formatPlaybackClock(currentSeconds, durationSeconds) {
|
|
777
|
+
const current = formatSegment(currentSeconds);
|
|
778
|
+
if (!Number.isFinite(durationSeconds) || durationSeconds <= 0) {
|
|
779
|
+
return current;
|
|
780
|
+
}
|
|
781
|
+
return `${current} / ${formatSegment(durationSeconds)}`;
|
|
782
|
+
}
|
|
783
|
+
var MOVIIE_EMBED_MEDIA_ICON_VIEW_BOX = "0 0 32 32";
|
|
784
|
+
function IconShell({
|
|
785
|
+
size,
|
|
786
|
+
children
|
|
787
|
+
}) {
|
|
788
|
+
const pixels = size ?? 22;
|
|
789
|
+
return /* @__PURE__ */ jsx(
|
|
790
|
+
jsx_native_bridge_default,
|
|
791
|
+
{
|
|
792
|
+
accessibilityElementsHidden: true,
|
|
793
|
+
height: pixels,
|
|
794
|
+
importantForAccessibility: "no",
|
|
795
|
+
viewBox: MOVIIE_EMBED_MEDIA_ICON_VIEW_BOX,
|
|
796
|
+
width: pixels,
|
|
797
|
+
children
|
|
798
|
+
}
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
function EmbedMediaIconPlay(props) {
|
|
802
|
+
return /* @__PURE__ */ jsx(IconShell, { size: props.size, children: /* @__PURE__ */ jsx(
|
|
803
|
+
Path,
|
|
804
|
+
{
|
|
805
|
+
d: "M10.6667 6.6548C10.6667 6.10764 11.2894 5.79346 11.7295 6.11862L24.377 15.4634C24.7377 15.7298 24.7377 16.2692 24.3771 16.5357L11.7295 25.8813C11.2895 26.2065 10.6667 25.8923 10.6667 25.3451L10.6667 6.6548Z",
|
|
806
|
+
fill: props.color
|
|
807
|
+
}
|
|
808
|
+
) });
|
|
809
|
+
}
|
|
810
|
+
function EmbedMediaIconPause(props) {
|
|
811
|
+
return /* @__PURE__ */ jsxs(IconShell, { size: props.size, children: [
|
|
812
|
+
/* @__PURE__ */ jsx(
|
|
813
|
+
Path,
|
|
814
|
+
{
|
|
815
|
+
d: "M8.66667 6.66667C8.29848 6.66667 8 6.96514 8 7.33333V24.6667C8 25.0349 8.29848 25.3333 8.66667 25.3333H12.6667C13.0349 25.3333 13.3333 25.0349 13.3333 24.6667V7.33333C13.3333 6.96514 13.0349 6.66667 12.6667 6.66667H8.66667Z",
|
|
816
|
+
fill: props.color
|
|
817
|
+
}
|
|
818
|
+
),
|
|
819
|
+
/* @__PURE__ */ jsx(
|
|
820
|
+
Path,
|
|
821
|
+
{
|
|
822
|
+
d: "M19.3333 6.66667C18.9651 6.66667 18.6667 6.96514 18.6667 7.33333V24.6667C18.6667 25.0349 18.9651 25.3333 19.3333 25.3333H23.3333C23.7015 25.3333 24 25.0349 24 24.6667V7.33333C24 6.96514 23.7015 6.66667 23.3333 6.66667H19.3333Z",
|
|
823
|
+
fill: props.color
|
|
824
|
+
}
|
|
825
|
+
)
|
|
826
|
+
] });
|
|
827
|
+
}
|
|
828
|
+
function EmbedMediaIconReplay(props) {
|
|
829
|
+
return /* @__PURE__ */ jsx(IconShell, { size: props.size, children: /* @__PURE__ */ jsx(
|
|
830
|
+
Path,
|
|
831
|
+
{
|
|
832
|
+
d: "M15.6038 12.2147C16.0439 12.5399 16.6667 12.2257 16.6667 11.6786V10.1789C16.6667 10.1001 16.7351 10.0384 16.8134 10.0479C20.1116 10.4494 22.6667 13.2593 22.6667 16.6659C22.6667 20.3481 19.6817 23.3332 15.9995 23.3332C12.542 23.3332 9.69927 20.7014 9.36509 17.332C9.32875 16.9655 9.03371 16.6662 8.66548 16.6662L6.66655 16.6666C6.29841 16.6666 5.99769 16.966 6.02187 17.3334C6.36494 22.5454 10.7012 26.6667 16 26.6667C21.5228 26.6667 26 22.1895 26 16.6667C26 11.4103 21.9444 7.10112 16.7916 6.69757C16.7216 6.69209 16.6667 6.63396 16.6667 6.56372V4.98824C16.6667 4.44106 16.0439 4.12689 15.6038 4.45206L11.0765 7.79738C10.7159 8.06387 10.7159 8.60326 11.0766 8.86973L15.6038 12.2147Z",
|
|
833
|
+
fill: props.color
|
|
834
|
+
}
|
|
835
|
+
) });
|
|
836
|
+
}
|
|
837
|
+
function EmbedMediaIconSeekBackward10(props) {
|
|
838
|
+
const fill = props.color;
|
|
839
|
+
return /* @__PURE__ */ jsxs(IconShell, { size: props.size, children: [
|
|
840
|
+
/* @__PURE__ */ jsx(
|
|
841
|
+
Path,
|
|
842
|
+
{
|
|
843
|
+
d: "M16.6667 10.3452C16.6667 10.8924 16.0439 11.2066 15.6038 10.8814L11.0766 7.5364C10.7159 7.26993 10.7159 6.73054 11.0766 6.46405L15.6038 3.11873C16.0439 2.79356 16.6667 3.10773 16.6667 3.6549V5.22682C16.6667 5.29746 16.7223 5.35579 16.7927 5.36066C22.6821 5.76757 27.3333 10.674 27.3333 16.6667C27.3333 22.9259 22.2592 28 16 28C9.96483 28 5.03145 23.2827 4.68601 17.3341C4.66466 16.9665 4.96518 16.6673 5.33339 16.6673H7.3334C7.70157 16.6673 7.99714 16.9668 8.02743 17.3337C8.36638 21.4399 11.8064 24.6667 16 24.6667C20.4183 24.6667 24 21.085 24 16.6667C24 12.5225 20.8483 9.11428 16.8113 8.70739C16.7337 8.69957 16.6667 8.76096 16.6667 8.83893V10.3452Z",
|
|
844
|
+
fill
|
|
845
|
+
}
|
|
846
|
+
),
|
|
847
|
+
/* @__PURE__ */ jsx(
|
|
848
|
+
Path,
|
|
849
|
+
{
|
|
850
|
+
clipRule: "evenodd",
|
|
851
|
+
d: "M17.0879 19.679C17.4553 19.9195 17.8928 20.0398 18.4004 20.0398C18.9099 20.0398 19.3474 19.9205 19.7129 19.6818C20.0803 19.4413 20.3635 19.0938 20.5623 18.6392C20.7612 18.1847 20.8606 17.6373 20.8606 16.9972C20.8625 16.3608 20.764 15.8192 20.5652 15.3722C20.3663 14.9252 20.0822 14.5853 19.7129 14.3523C19.3455 14.1175 18.908 14 18.4004 14C17.8928 14 17.4553 14.1175 17.0879 14.3523C16.7224 14.5853 16.4402 14.9252 16.2413 15.3722C16.0443 15.8173 15.9449 16.3589 15.943 16.9972C15.9411 17.6354 16.0396 18.1818 16.2385 18.6364C16.4373 19.089 16.7205 19.4366 17.0879 19.679ZM19.1362 18.4262C18.9487 18.7349 18.7034 18.8892 18.4004 18.8892C18.1996 18.8892 18.0226 18.8211 17.8691 18.6847C17.7157 18.5464 17.5964 18.3372 17.5112 18.0568C17.4279 17.7765 17.3871 17.4233 17.389 16.9972C17.3909 16.3684 17.4847 15.9025 17.6703 15.5995C17.8559 15.2945 18.0993 15.1421 18.4004 15.1421C18.603 15.1421 18.7801 15.2093 18.9316 15.3438C19.0832 15.4782 19.2015 15.6828 19.2868 15.9574C19.372 16.2301 19.4146 16.5767 19.4146 16.9972C19.4165 17.6392 19.3237 18.1156 19.1362 18.4262Z",
|
|
852
|
+
fill,
|
|
853
|
+
fillRule: "evenodd"
|
|
854
|
+
}
|
|
855
|
+
),
|
|
856
|
+
/* @__PURE__ */ jsx(
|
|
857
|
+
Path,
|
|
858
|
+
{
|
|
859
|
+
d: "M13.7746 19.8978C13.8482 19.8978 13.9079 19.8381 13.9079 19.7644V14.2129C13.9079 14.1393 13.8482 14.0796 13.7746 14.0796H12.642C12.6171 14.0796 12.5927 14.0865 12.5716 14.0997L11.2322 14.9325C11.1931 14.9568 11.1693 14.9996 11.1693 15.0457V15.9497C11.1693 16.0539 11.2833 16.1178 11.3722 16.0635L12.464 15.396C12.4682 15.3934 12.473 15.3921 12.4779 15.3921C12.4926 15.3921 12.5045 15.404 12.5045 15.4187V19.7644C12.5045 19.8381 12.5642 19.8978 12.6378 19.8978H13.7746Z",
|
|
860
|
+
fill
|
|
861
|
+
}
|
|
862
|
+
)
|
|
863
|
+
] });
|
|
864
|
+
}
|
|
865
|
+
function EmbedMediaIconSeekForward10(props) {
|
|
866
|
+
const fill = props.color;
|
|
867
|
+
return /* @__PURE__ */ jsxs(IconShell, { size: props.size, children: [
|
|
868
|
+
/* @__PURE__ */ jsx(
|
|
869
|
+
Path,
|
|
870
|
+
{
|
|
871
|
+
d: "M15.3333 10.3452C15.3333 10.8924 15.9561 11.2066 16.3962 10.8814L20.9234 7.5364C21.2841 7.26993 21.2841 6.73054 20.9235 6.46405L16.3962 3.11873C15.9561 2.79356 15.3333 3.10773 15.3333 3.6549V5.22682C15.3333 5.29746 15.2778 5.35579 15.2073 5.36066C9.31791 5.76757 4.66667 10.674 4.66667 16.6667C4.66667 22.9259 9.74078 28 16 28C22.0352 28 26.9686 23.2827 27.314 17.3341C27.3354 16.9665 27.0348 16.6673 26.6666 16.6673H24.6666C24.2984 16.6673 24.0029 16.9668 23.9726 17.3337C23.6336 21.4399 20.1937 24.6667 16 24.6667C11.5817 24.6667 8 21.085 8 16.6667C8 12.5225 11.1517 9.11428 15.1887 8.70739C15.2663 8.69957 15.3333 8.76096 15.3333 8.83893V10.3452Z",
|
|
872
|
+
fill
|
|
873
|
+
}
|
|
874
|
+
),
|
|
875
|
+
/* @__PURE__ */ jsx(
|
|
876
|
+
Path,
|
|
877
|
+
{
|
|
878
|
+
clipRule: "evenodd",
|
|
879
|
+
d: "M17.0879 19.679C17.4553 19.9195 17.8928 20.0398 18.4004 20.0398C18.9099 20.0398 19.3474 19.9205 19.7129 19.6818C20.0803 19.4413 20.3635 19.0938 20.5623 18.6392C20.7612 18.1847 20.8606 17.6373 20.8606 16.9972C20.8625 16.3608 20.764 15.8192 20.5652 15.3722C20.3663 14.9252 20.0822 14.5853 19.7129 14.3523C19.3455 14.1175 18.908 14 18.4004 14C17.8928 14 17.4553 14.1175 17.0879 14.3523C16.7224 14.5853 16.4402 14.9252 16.2413 15.3722C16.0443 15.8173 15.9449 16.3589 15.943 16.9972C15.9411 17.6354 16.0396 18.1818 16.2385 18.6364C16.4373 19.089 16.7205 19.4366 17.0879 19.679ZM19.1362 18.4262C18.9487 18.7349 18.7034 18.8892 18.4004 18.8892C18.1996 18.8892 18.0225 18.8211 17.8691 18.6847C17.7157 18.5464 17.5964 18.3372 17.5112 18.0568C17.4278 17.7765 17.3871 17.4233 17.389 16.9972C17.3909 16.3684 17.4847 15.9025 17.6703 15.5995C17.8559 15.2945 18.0992 15.1421 18.4004 15.1421C18.603 15.1421 18.7801 15.2093 18.9316 15.3438C19.0831 15.4782 19.2015 15.6828 19.2867 15.9574C19.372 16.2301 19.4146 16.5767 19.4146 16.9972C19.4165 17.6392 19.3237 18.1156 19.1362 18.4262Z",
|
|
880
|
+
fill,
|
|
881
|
+
fillRule: "evenodd"
|
|
882
|
+
}
|
|
883
|
+
),
|
|
884
|
+
/* @__PURE__ */ jsx(
|
|
885
|
+
Path,
|
|
886
|
+
{
|
|
887
|
+
d: "M13.7746 19.8978C13.8482 19.8978 13.9079 19.8381 13.9079 19.7644V14.2129C13.9079 14.1393 13.8482 14.0796 13.7746 14.0796H12.642C12.6171 14.0796 12.5927 14.0865 12.5716 14.0997L11.2322 14.9325C11.1931 14.9568 11.1693 14.9996 11.1693 15.0457V15.9497C11.1693 16.0539 11.2833 16.1178 11.3722 16.0635L12.464 15.396C12.4682 15.3934 12.473 15.3921 12.4779 15.3921C12.4926 15.3921 12.5045 15.404 12.5045 15.4187V19.7644C12.5045 19.8381 12.5642 19.8978 12.6378 19.8978H13.7746Z",
|
|
888
|
+
fill
|
|
889
|
+
}
|
|
890
|
+
)
|
|
891
|
+
] });
|
|
892
|
+
}
|
|
893
|
+
function EmbedMediaIconFullscreen(props) {
|
|
894
|
+
return /* @__PURE__ */ jsxs(IconShell, { size: props.size, children: [
|
|
895
|
+
/* @__PURE__ */ jsx(
|
|
896
|
+
Path,
|
|
897
|
+
{
|
|
898
|
+
d: "M25.3299 7.26517C25.2958 6.929 25.0119 6.66666 24.6667 6.66666H19.3334C18.9652 6.66666 18.6667 6.96514 18.6667 7.33333V9.33333C18.6667 9.70152 18.9652 10 19.3334 10L21.8667 10C21.9403 10 22 10.0597 22 10.1333V12.6667C22 13.0349 22.2985 13.3333 22.6667 13.3333H24.6667C25.0349 13.3333 25.3334 13.0349 25.3334 12.6667V7.33333C25.3334 7.31032 25.3322 7.28758 25.3299 7.26517Z",
|
|
899
|
+
fill: props.color
|
|
900
|
+
}
|
|
901
|
+
),
|
|
902
|
+
/* @__PURE__ */ jsx(
|
|
903
|
+
Path,
|
|
904
|
+
{
|
|
905
|
+
d: "M22 21.8667C22 21.9403 21.9403 22 21.8667 22L19.3334 22C18.9652 22 18.6667 22.2985 18.6667 22.6667V24.6667C18.6667 25.0349 18.9652 25.3333 19.3334 25.3333L24.6667 25.3333C25.0349 25.3333 25.3334 25.0349 25.3334 24.6667V19.3333C25.3334 18.9651 25.0349 18.6667 24.6667 18.6667H22.6667C22.2985 18.6667 22 18.9651 22 19.3333V21.8667Z",
|
|
906
|
+
fill: props.color
|
|
907
|
+
}
|
|
908
|
+
),
|
|
909
|
+
/* @__PURE__ */ jsx(
|
|
910
|
+
Path,
|
|
911
|
+
{
|
|
912
|
+
d: "M12.6667 22H10.1334C10.0597 22 10 21.9403 10 21.8667V19.3333C10 18.9651 9.70154 18.6667 9.33335 18.6667H7.33335C6.96516 18.6667 6.66669 18.9651 6.66669 19.3333V24.6667C6.66669 25.0349 6.96516 25.3333 7.33335 25.3333H12.6667C13.0349 25.3333 13.3334 25.0349 13.3334 24.6667V22.6667C13.3334 22.2985 13.0349 22 12.6667 22Z",
|
|
913
|
+
fill: props.color
|
|
914
|
+
}
|
|
915
|
+
),
|
|
916
|
+
/* @__PURE__ */ jsx(
|
|
917
|
+
Path,
|
|
918
|
+
{
|
|
919
|
+
d: "M10 12.6667V10.1333C10 10.0597 10.0597 10 10.1334 10L12.6667 10C13.0349 10 13.3334 9.70152 13.3334 9.33333V7.33333C13.3334 6.96514 13.0349 6.66666 12.6667 6.66666H7.33335C6.96516 6.66666 6.66669 6.96514 6.66669 7.33333V12.6667C6.66669 13.0349 6.96516 13.3333 7.33335 13.3333H9.33335C9.70154 13.3333 10 13.0349 10 12.6667Z",
|
|
920
|
+
fill: props.color
|
|
921
|
+
}
|
|
922
|
+
)
|
|
923
|
+
] });
|
|
924
|
+
}
|
|
925
|
+
function EmbedMediaIconFullscreenExit(props) {
|
|
926
|
+
return /* @__PURE__ */ jsxs(IconShell, { size: props.size, children: [
|
|
927
|
+
/* @__PURE__ */ jsx(
|
|
928
|
+
Path,
|
|
929
|
+
{
|
|
930
|
+
d: "M19.3334 13.3333C18.9652 13.3333 18.6667 13.0349 18.6667 12.6667L18.6667 7.33333C18.6667 6.96514 18.9652 6.66666 19.3334 6.66666H21.3334C21.7015 6.66666 22 6.96514 22 7.33333V9.86666C22 9.9403 22.0597 10 22.1334 10L24.6667 10C25.0349 10 25.3334 10.2985 25.3334 10.6667V12.6667C25.3334 13.0349 25.0349 13.3333 24.6667 13.3333L19.3334 13.3333Z",
|
|
931
|
+
fill: props.color
|
|
932
|
+
}
|
|
933
|
+
),
|
|
934
|
+
/* @__PURE__ */ jsx(
|
|
935
|
+
Path,
|
|
936
|
+
{
|
|
937
|
+
d: "M13.3334 19.3333C13.3334 18.9651 13.0349 18.6667 12.6667 18.6667H7.33335C6.96516 18.6667 6.66669 18.9651 6.66669 19.3333V21.3333C6.66669 21.7015 6.96516 22 7.33335 22H9.86669C9.94032 22 10 22.0597 10 22.1333L10 24.6667C10 25.0349 10.2985 25.3333 10.6667 25.3333H12.6667C13.0349 25.3333 13.3334 25.0349 13.3334 24.6667L13.3334 19.3333Z",
|
|
938
|
+
fill: props.color
|
|
939
|
+
}
|
|
940
|
+
),
|
|
941
|
+
/* @__PURE__ */ jsx(
|
|
942
|
+
Path,
|
|
943
|
+
{
|
|
944
|
+
d: "M18.6667 24.6667C18.6667 25.0349 18.9652 25.3333 19.3334 25.3333H21.3334C21.7015 25.3333 22 25.0349 22 24.6667V22.1333C22 22.0597 22.0597 22 22.1334 22H24.6667C25.0349 22 25.3334 21.7015 25.3334 21.3333V19.3333C25.3334 18.9651 25.0349 18.6667 24.6667 18.6667L19.3334 18.6667C18.9652 18.6667 18.6667 18.9651 18.6667 19.3333L18.6667 24.6667Z",
|
|
945
|
+
fill: props.color
|
|
946
|
+
}
|
|
947
|
+
),
|
|
948
|
+
/* @__PURE__ */ jsx(
|
|
949
|
+
Path,
|
|
950
|
+
{
|
|
951
|
+
d: "M10.6667 13.3333H12.6667C13.0349 13.3333 13.3334 13.0349 13.3334 12.6667L13.3334 10.6667V7.33333C13.3334 6.96514 13.0349 6.66666 12.6667 6.66666H10.6667C10.2985 6.66666 10 6.96514 10 7.33333L10 9.86666C10 9.9403 9.94033 10 9.86669 10L7.33335 10C6.96516 10 6.66669 10.2985 6.66669 10.6667V12.6667C6.66669 13.0349 6.96516 13.3333 7.33335 13.3333L10.6667 13.3333Z",
|
|
952
|
+
fill: props.color
|
|
953
|
+
}
|
|
954
|
+
)
|
|
955
|
+
] });
|
|
956
|
+
}
|
|
957
|
+
function EmbedMediaIconPictureInPicture(props) {
|
|
958
|
+
const pixels = props.size ?? 22;
|
|
959
|
+
return /* @__PURE__ */ jsx(
|
|
960
|
+
jsx_native_bridge_default,
|
|
961
|
+
{
|
|
962
|
+
accessibilityElementsHidden: true,
|
|
963
|
+
height: pixels,
|
|
964
|
+
importantForAccessibility: "no",
|
|
965
|
+
viewBox: "0 0 24 24",
|
|
966
|
+
width: pixels,
|
|
967
|
+
children: /* @__PURE__ */ jsx(
|
|
968
|
+
Path,
|
|
969
|
+
{
|
|
970
|
+
d: "M19 7h-8v6h8V7zm0-2c1.1 0 2 .9 2 2v6c0 1.1-.9 2-2 2h-8c-1.1 0-2-.9-2-2V7c0-1.1.9-2 2-2h8zM5 5v14h14v-2H7V5H5z",
|
|
971
|
+
fill: props.color
|
|
972
|
+
}
|
|
973
|
+
)
|
|
974
|
+
}
|
|
975
|
+
);
|
|
976
|
+
}
|
|
977
|
+
function EmbedMediaIconCast(props) {
|
|
978
|
+
const pixels = props.size ?? 22;
|
|
979
|
+
return /* @__PURE__ */ jsx(
|
|
980
|
+
jsx_native_bridge_default,
|
|
981
|
+
{
|
|
982
|
+
accessibilityElementsHidden: true,
|
|
983
|
+
height: pixels,
|
|
984
|
+
importantForAccessibility: "no",
|
|
985
|
+
viewBox: "0 0 24 24",
|
|
986
|
+
width: pixels,
|
|
987
|
+
children: /* @__PURE__ */ jsx(
|
|
988
|
+
Path,
|
|
989
|
+
{
|
|
990
|
+
d: "M21 3H3c-1.1 0-2 .9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM1 18v3h3c0-1.66-1.34-3-3-3zm0-4v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm0-4v2c4.97 0 9 4.03 9 9h2c0-6.08-4.93-11-11-11z",
|
|
991
|
+
fill: props.color
|
|
992
|
+
}
|
|
993
|
+
)
|
|
994
|
+
}
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
function EmbedMediaIconCastConnected(props) {
|
|
998
|
+
const pixels = props.size ?? 22;
|
|
999
|
+
return /* @__PURE__ */ jsx(
|
|
1000
|
+
jsx_native_bridge_default,
|
|
1001
|
+
{
|
|
1002
|
+
accessibilityElementsHidden: true,
|
|
1003
|
+
height: pixels,
|
|
1004
|
+
importantForAccessibility: "no",
|
|
1005
|
+
viewBox: "0 0 24 24",
|
|
1006
|
+
width: pixels,
|
|
1007
|
+
children: /* @__PURE__ */ jsx(
|
|
1008
|
+
Path,
|
|
1009
|
+
{
|
|
1010
|
+
d: "M1 18v3h3c0-1.66-1.34-3-3-3zm0-4v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm18-7H5v1.63c3.96 1.28 7.09 4.41 8.37 8.37H19V7zM1 10v2c4.97 0 9 4.03 9 9h2c0-6.08-4.93-11-11-11zm20-7H3c-1.1 0-2 .9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z",
|
|
1011
|
+
fill: props.color
|
|
1012
|
+
}
|
|
1013
|
+
)
|
|
1014
|
+
}
|
|
1015
|
+
);
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
// src/lib/build-moviie-embed-brand-home-url.ts
|
|
1019
|
+
function buildMoviieEmbedBrandHomeUrl() {
|
|
1020
|
+
const url = new URL(`${MOVIIE_BRANDING_MARKETING_ORIGIN}/`);
|
|
1021
|
+
url.searchParams.set(MOVIIE_BRANDING_UTM_PARAM_SOURCE, MOVIIE_EMBED_BRAND_UTM.SOURCE);
|
|
1022
|
+
url.searchParams.set(MOVIIE_BRANDING_UTM_PARAM_MEDIUM, MOVIIE_EMBED_BRAND_UTM.MEDIUM);
|
|
1023
|
+
url.searchParams.set(MOVIIE_BRANDING_UTM_PARAM_CAMPAIGN, MOVIIE_EMBED_BRAND_UTM.CAMPAIGN);
|
|
1024
|
+
return url.toString();
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
// src/lib/resolve-moviie-skin-layout-scale.ts
|
|
1028
|
+
function clampBetween(value, min, max) {
|
|
1029
|
+
return Math.min(Math.max(value, min), max);
|
|
1030
|
+
}
|
|
1031
|
+
function resolveMoviieSkinLayoutScale(windowWidth) {
|
|
1032
|
+
if (!Number.isFinite(windowWidth) || windowWidth <= 0) {
|
|
1033
|
+
return 1;
|
|
1034
|
+
}
|
|
1035
|
+
const raw = windowWidth / MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT;
|
|
1036
|
+
return clampBetween(raw, MOVIIE_SKIN_LAYOUT_SCALE_MIN, MOVIIE_SKIN_LAYOUT_SCALE_MAX);
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
// src/lib/build-moviie-skin-layout-metrics.ts
|
|
1040
|
+
function scaleSkinLayoutDp(layoutScale, baseAtReference) {
|
|
1041
|
+
return baseAtReference * layoutScale;
|
|
1042
|
+
}
|
|
1043
|
+
function buildMoviieSkinLayoutMetrics(windowWidth, options) {
|
|
1044
|
+
const layoutScale = resolveMoviieSkinLayoutScale(windowWidth);
|
|
1045
|
+
const brandMarkWidthPx = scaleSkinLayoutDp(
|
|
1046
|
+
layoutScale,
|
|
1047
|
+
MOVIIE_SKIN_BRAND_MARK_TARGET_WIDTH_AT_REFERENCE_PT
|
|
1048
|
+
);
|
|
1049
|
+
const brandMarkHeightPx = brandMarkWidthPx * (MOVIIE_SKIN_BRAND_MARK_ARTBOARD_HEIGHT_PX / MOVIIE_SKIN_BRAND_MARK_ARTBOARD_WIDTH_PX);
|
|
1050
|
+
const timelineThumbDiameterPx = scaleSkinLayoutDp(
|
|
1051
|
+
layoutScale,
|
|
1052
|
+
MOVIIE_SKIN_TIMELINE_THUMB_DIAMETER_PX
|
|
1053
|
+
);
|
|
1054
|
+
const timelineBarHeightPx = scaleSkinLayoutDp(layoutScale, MOVIIE_SKIN_TIMELINE_BAR_HEIGHT_PX);
|
|
1055
|
+
const timelineThumbBottomInsetPx = timelineBarHeightPx / 2 - timelineThumbDiameterPx / 2;
|
|
1056
|
+
const timelineTouchPaddingVerticalPx = scaleSkinLayoutDp(
|
|
1057
|
+
layoutScale,
|
|
1058
|
+
MOVIIE_SKIN_TIMELINE_TOUCH_PADDING_VERTICAL_PX
|
|
1059
|
+
);
|
|
1060
|
+
const fullscreenHudBoostPx = options?.fullscreenHudProtection === true ? scaleSkinLayoutDp(layoutScale, MOVIIE_SKIN_CUSTOM_FULLSCREEN_HUD_EDGE_BOOST_REFERENCE_PT) : 0;
|
|
1061
|
+
const hudEdgeInsetPx = scaleSkinLayoutDp(layoutScale, MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX) + fullscreenHudBoostPx;
|
|
1062
|
+
return {
|
|
1063
|
+
layoutScale,
|
|
1064
|
+
brandMarkWidthPx,
|
|
1065
|
+
brandMarkHeightPx,
|
|
1066
|
+
hudEdgeInsetPx,
|
|
1067
|
+
floatingHudAboveTimelineGapPx: scaleSkinLayoutDp(
|
|
1068
|
+
layoutScale,
|
|
1069
|
+
MOVIIE_SKIN_FLOATING_HUD_ABOVE_TIMELINE_GAP_AT_REFERENCE_PT
|
|
1070
|
+
),
|
|
1071
|
+
hudClockCornerRadiusPx: scaleSkinLayoutDp(
|
|
1072
|
+
layoutScale,
|
|
1073
|
+
MOVIIE_SKIN_FLOATING_HUD_CLOCK_CORNER_RADIUS_PX
|
|
1074
|
+
),
|
|
1075
|
+
controlIconPx: scaleSkinLayoutDp(layoutScale, MOVIIE_SKIN_CONTROL_ICON_PX),
|
|
1076
|
+
seekIconPx: scaleSkinLayoutDp(layoutScale, MOVIIE_SKIN_SEEK_ICON_PX),
|
|
1077
|
+
seekScrimOuterDiameterPx: scaleSkinLayoutDp(
|
|
1078
|
+
layoutScale,
|
|
1079
|
+
MOVIIE_SKIN_CENTER_SEEK_SCRIM_DIAMETER_AT_REFERENCE_PT
|
|
1080
|
+
),
|
|
1081
|
+
centerPlayIconPx: scaleSkinLayoutDp(layoutScale, MOVIIE_SKIN_CENTER_PLAY_ICON_PX),
|
|
1082
|
+
centerClusterColumnGapPx: scaleSkinLayoutDp(
|
|
1083
|
+
layoutScale,
|
|
1084
|
+
MOVIIE_SKIN_CENTER_CLUSTER_COLUMN_GAP_PX
|
|
1085
|
+
),
|
|
1086
|
+
playScrimOuterDiameterPx: scaleSkinLayoutDp(
|
|
1087
|
+
layoutScale,
|
|
1088
|
+
MOVIIE_SKIN_CENTER_PLAY_SCRIM_DIAMETER_AT_REFERENCE_PT
|
|
1089
|
+
),
|
|
1090
|
+
clockTextFontSizePx: scaleSkinLayoutDp(
|
|
1091
|
+
layoutScale,
|
|
1092
|
+
MOVIIE_SKIN_CLOCK_TEXT_FONT_SIZE_AT_REFERENCE_PT
|
|
1093
|
+
),
|
|
1094
|
+
timelineThumbDiameterPx,
|
|
1095
|
+
timelineTouchPaddingVerticalPx,
|
|
1096
|
+
timelineBarHeightPx,
|
|
1097
|
+
timelineThumbBottomInsetPx,
|
|
1098
|
+
timelineStackHeightChromeVisiblePx: timelineTouchPaddingVerticalPx + timelineThumbDiameterPx,
|
|
1099
|
+
bufferingIndicatorSlotPx: scaleSkinLayoutDp(
|
|
1100
|
+
layoutScale,
|
|
1101
|
+
MOVIIE_SKIN_BUFFERING_INDICATOR_SLOT_PX
|
|
1102
|
+
),
|
|
1103
|
+
chromeEdgeGradientHeightPx: scaleSkinLayoutDp(
|
|
1104
|
+
layoutScale,
|
|
1105
|
+
MOVIIE_SKIN_CHROME_EDGE_GRADIENT_HEIGHT_AT_REFERENCE_PT
|
|
1106
|
+
),
|
|
1107
|
+
floatingHudFullscreenScrimDiameterPx: scaleSkinLayoutDp(
|
|
1108
|
+
layoutScale,
|
|
1109
|
+
MOVIIE_SKIN_FLOATING_FULLSCREEN_SCRIM_DIAMETER_AT_REFERENCE_PT
|
|
1110
|
+
),
|
|
1111
|
+
floatingHudFullscreenIconPx: scaleSkinLayoutDp(
|
|
1112
|
+
layoutScale,
|
|
1113
|
+
MOVIIE_SKIN_FLOATING_FULLSCREEN_ICON_AT_REFERENCE_PT
|
|
1114
|
+
),
|
|
1115
|
+
floatingHudFullscreenTopIconPx: scaleSkinLayoutDp(
|
|
1116
|
+
layoutScale,
|
|
1117
|
+
MOVIIE_SKIN_FLOATING_FULLSCREEN_TOP_ICON_AT_REFERENCE_PT
|
|
1118
|
+
),
|
|
1119
|
+
floatingHudButtonGapPx: scaleSkinLayoutDp(
|
|
1120
|
+
layoutScale,
|
|
1121
|
+
MOVIIE_SKIN_FLOATING_HUD_BUTTON_GAP_AT_REFERENCE_PT
|
|
1122
|
+
)
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
// src/lib/compute-playback-buffering.ts
|
|
1127
|
+
var PLAYER_STATUS_LOADING = "loading";
|
|
1128
|
+
function computePlaybackBuffering(state) {
|
|
1129
|
+
if (computeMoviiePlaybackEnded({
|
|
1130
|
+
playing: state.playing,
|
|
1131
|
+
currentTime: state.currentTime,
|
|
1132
|
+
duration: state.duration,
|
|
1133
|
+
isLive: state.isLive,
|
|
1134
|
+
loop: state.loop
|
|
1135
|
+
})) {
|
|
1136
|
+
return false;
|
|
1137
|
+
}
|
|
1138
|
+
if (state.status === PLAYER_STATUS_LOADING) {
|
|
1139
|
+
return true;
|
|
1140
|
+
}
|
|
1141
|
+
if (state.playing && Number.isFinite(state.duration) && state.duration > 0 && state.bufferedPosition >= 0 && state.currentTime > 0.08 && state.bufferedPosition < state.currentTime + MOVIIE_SKIN_BUFFER_UNDERRUN_LEAD_SECONDS) {
|
|
1142
|
+
return true;
|
|
1143
|
+
}
|
|
1144
|
+
return false;
|
|
1145
|
+
}
|
|
1146
|
+
function usePlaybackUiSync(player) {
|
|
1147
|
+
const [snapshot, setSnapshot] = useState({
|
|
1148
|
+
bufferedPosition: player.bufferedPosition,
|
|
1149
|
+
currentTime: player.currentTime,
|
|
1150
|
+
duration: player.duration,
|
|
1151
|
+
playing: player.playing,
|
|
1152
|
+
status: player.status
|
|
1153
|
+
});
|
|
1154
|
+
useEffect(() => {
|
|
1155
|
+
const subscriptions = [
|
|
1156
|
+
player.addListener("timeUpdate", ({ currentTime }) => {
|
|
1157
|
+
setSnapshot((previous) => ({
|
|
1158
|
+
...previous,
|
|
1159
|
+
bufferedPosition: player.bufferedPosition,
|
|
1160
|
+
currentTime,
|
|
1161
|
+
duration: player.duration,
|
|
1162
|
+
status: player.status
|
|
1163
|
+
}));
|
|
1164
|
+
}),
|
|
1165
|
+
player.addListener("playingChange", ({ isPlaying }) => {
|
|
1166
|
+
setSnapshot((previous) => ({
|
|
1167
|
+
...previous,
|
|
1168
|
+
playing: isPlaying,
|
|
1169
|
+
bufferedPosition: player.bufferedPosition,
|
|
1170
|
+
status: player.status
|
|
1171
|
+
}));
|
|
1172
|
+
}),
|
|
1173
|
+
player.addListener("sourceChange", () => {
|
|
1174
|
+
setSnapshot({
|
|
1175
|
+
bufferedPosition: player.bufferedPosition,
|
|
1176
|
+
currentTime: player.currentTime,
|
|
1177
|
+
duration: player.duration,
|
|
1178
|
+
playing: player.playing,
|
|
1179
|
+
status: player.status
|
|
1180
|
+
});
|
|
1181
|
+
}),
|
|
1182
|
+
player.addListener("statusChange", ({ status }) => {
|
|
1183
|
+
setSnapshot((previous) => ({
|
|
1184
|
+
...previous,
|
|
1185
|
+
bufferedPosition: player.bufferedPosition,
|
|
1186
|
+
status
|
|
1187
|
+
}));
|
|
1188
|
+
}),
|
|
1189
|
+
player.addListener("playToEnd", () => {
|
|
1190
|
+
setSnapshot((previous) => ({
|
|
1191
|
+
...previous,
|
|
1192
|
+
playing: false,
|
|
1193
|
+
bufferedPosition: player.bufferedPosition,
|
|
1194
|
+
currentTime: player.currentTime,
|
|
1195
|
+
duration: player.duration,
|
|
1196
|
+
status: player.status
|
|
1197
|
+
}));
|
|
1198
|
+
})
|
|
1199
|
+
];
|
|
1200
|
+
return () => {
|
|
1201
|
+
for (const sub of subscriptions) {
|
|
1202
|
+
sub.remove();
|
|
1203
|
+
}
|
|
1204
|
+
};
|
|
1205
|
+
}, [player]);
|
|
1206
|
+
return snapshot;
|
|
1207
|
+
}
|
|
1208
|
+
var MoviieSkinChromeContext = createContext(
|
|
1209
|
+
null
|
|
1210
|
+
);
|
|
1211
|
+
function useMoviieSkinChrome() {
|
|
1212
|
+
const ctx = useContext(MoviieSkinChromeContext);
|
|
1213
|
+
if (ctx == null) {
|
|
1214
|
+
throw new Error("useMoviieSkinChrome must be used within MoviieSkinChromeProvider");
|
|
1215
|
+
}
|
|
1216
|
+
return ctx;
|
|
1217
|
+
}
|
|
1218
|
+
function MoviieSkinChromeProvider({
|
|
1219
|
+
children,
|
|
1220
|
+
player,
|
|
1221
|
+
playback,
|
|
1222
|
+
videoViewRef,
|
|
1223
|
+
customFullscreen = false,
|
|
1224
|
+
skinLayoutMetricsWidth,
|
|
1225
|
+
onRequestEnterCustomFullscreen,
|
|
1226
|
+
onRequestExitCustomFullscreenAnimated,
|
|
1227
|
+
autoHideMs: _unusedAutoHideMs,
|
|
1228
|
+
visibleByDefault = true,
|
|
1229
|
+
pictureInPictureControlEnabled = false,
|
|
1230
|
+
pictureInPictureActive = false,
|
|
1231
|
+
togglePictureInPicture: togglePictureInPictureProp,
|
|
1232
|
+
castControlEnabled = false,
|
|
1233
|
+
castConnected = false,
|
|
1234
|
+
openCastPicker: openCastPickerProp
|
|
1235
|
+
}) {
|
|
1236
|
+
const noopPictureInPicture = useCallback(() => {
|
|
1237
|
+
}, []);
|
|
1238
|
+
const togglePictureInPicture = togglePictureInPictureProp ?? noopPictureInPicture;
|
|
1239
|
+
const noopOpenCastPicker = useCallback(() => {
|
|
1240
|
+
}, []);
|
|
1241
|
+
const openCastPicker = openCastPickerProp ?? noopOpenCastPicker;
|
|
1242
|
+
const { width: windowWidth } = useWindowDimensions();
|
|
1243
|
+
const layoutBasisWidth = skinLayoutMetricsWidth ?? windowWidth;
|
|
1244
|
+
const layout = useMemo(
|
|
1245
|
+
() => buildMoviieSkinLayoutMetrics(layoutBasisWidth, {
|
|
1246
|
+
fullscreenHudProtection: customFullscreen
|
|
1247
|
+
}),
|
|
1248
|
+
[customFullscreen, layoutBasisWidth]
|
|
1249
|
+
);
|
|
1250
|
+
const ui = usePlaybackUiSync(player);
|
|
1251
|
+
const [chromeVisible, setChromeVisible] = useState(visibleByDefault);
|
|
1252
|
+
const [timelineScrubClockSeconds, setTimelineScrubClockSeconds] = useState(null);
|
|
1253
|
+
const playbackEndedForChrome = useMemo(
|
|
1254
|
+
() => computeMoviiePlaybackEnded({
|
|
1255
|
+
playing: ui.playing,
|
|
1256
|
+
currentTime: ui.currentTime,
|
|
1257
|
+
duration: ui.duration,
|
|
1258
|
+
isLive: player.isLive,
|
|
1259
|
+
loop: player.loop
|
|
1260
|
+
}),
|
|
1261
|
+
[ui.playing, ui.currentTime, ui.duration, player.isLive, player.loop]
|
|
1262
|
+
);
|
|
1263
|
+
useEffect(() => {
|
|
1264
|
+
if (playbackEndedForChrome) {
|
|
1265
|
+
setChromeVisible(true);
|
|
1266
|
+
}
|
|
1267
|
+
}, [playbackEndedForChrome]);
|
|
1268
|
+
const chromeOpacity = useRef(new Animated.Value(visibleByDefault ? 1 : 0)).current;
|
|
1269
|
+
useEffect(() => {
|
|
1270
|
+
Animated.timing(chromeOpacity, {
|
|
1271
|
+
duration: MOVIIE_SKIN_CONTROLS_FADE_MS,
|
|
1272
|
+
easing: Easing$1.out(Easing$1.quad),
|
|
1273
|
+
toValue: chromeVisible ? 1 : 0,
|
|
1274
|
+
useNativeDriver: true
|
|
1275
|
+
}).start();
|
|
1276
|
+
}, [chromeOpacity, chromeVisible]);
|
|
1277
|
+
const bumpChromeInteraction = useCallback(() => {
|
|
1278
|
+
setChromeVisible(true);
|
|
1279
|
+
}, []);
|
|
1280
|
+
const dismissChrome = useCallback(() => {
|
|
1281
|
+
setChromeVisible(false);
|
|
1282
|
+
}, []);
|
|
1283
|
+
const togglePlay = useCallback(() => {
|
|
1284
|
+
if (player.playing) {
|
|
1285
|
+
player.pause();
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1288
|
+
if (computeMoviiePlaybackEnded({
|
|
1289
|
+
playing: false,
|
|
1290
|
+
currentTime: player.currentTime,
|
|
1291
|
+
duration: player.duration,
|
|
1292
|
+
isLive: player.isLive,
|
|
1293
|
+
loop: player.loop
|
|
1294
|
+
})) {
|
|
1295
|
+
player.currentTime = 0;
|
|
1296
|
+
}
|
|
1297
|
+
player.play();
|
|
1298
|
+
setChromeVisible(false);
|
|
1299
|
+
}, [player]);
|
|
1300
|
+
const seekBack = useCallback(() => {
|
|
1301
|
+
void player.seekBy(-MOVIIE_SKIN_SEEK_JUMP_SECONDS);
|
|
1302
|
+
setChromeVisible(false);
|
|
1303
|
+
}, [player]);
|
|
1304
|
+
const seekForward = useCallback(() => {
|
|
1305
|
+
void player.seekBy(MOVIIE_SKIN_SEEK_JUMP_SECONDS);
|
|
1306
|
+
setChromeVisible(false);
|
|
1307
|
+
}, [player]);
|
|
1308
|
+
const toggleFullscreen = useCallback(() => {
|
|
1309
|
+
if (customFullscreen) {
|
|
1310
|
+
onRequestExitCustomFullscreenAnimated?.();
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
setChromeVisible(false);
|
|
1314
|
+
if (onRequestEnterCustomFullscreen != null) {
|
|
1315
|
+
onRequestEnterCustomFullscreen();
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
void videoViewRef.current?.enterFullscreen?.().catch(() => void 0);
|
|
1319
|
+
}, [
|
|
1320
|
+
customFullscreen,
|
|
1321
|
+
onRequestEnterCustomFullscreen,
|
|
1322
|
+
onRequestExitCustomFullscreenAnimated,
|
|
1323
|
+
videoViewRef
|
|
1324
|
+
]);
|
|
1325
|
+
const isBuffering = useMemo(
|
|
1326
|
+
() => computePlaybackBuffering({
|
|
1327
|
+
...ui,
|
|
1328
|
+
isLive: player.isLive,
|
|
1329
|
+
loop: player.loop
|
|
1330
|
+
}),
|
|
1331
|
+
[ui, player.isLive, player.loop]
|
|
1332
|
+
);
|
|
1333
|
+
const value = useMemo(
|
|
1334
|
+
() => ({
|
|
1335
|
+
playback,
|
|
1336
|
+
player,
|
|
1337
|
+
videoViewRef,
|
|
1338
|
+
chromeVisible,
|
|
1339
|
+
chromeOpacity,
|
|
1340
|
+
timelineScrubClockSeconds,
|
|
1341
|
+
setTimelineScrubClockSeconds,
|
|
1342
|
+
bumpChromeInteraction,
|
|
1343
|
+
dismissChrome,
|
|
1344
|
+
ui,
|
|
1345
|
+
isBuffering,
|
|
1346
|
+
layout,
|
|
1347
|
+
togglePlay,
|
|
1348
|
+
seekBack,
|
|
1349
|
+
seekForward,
|
|
1350
|
+
toggleFullscreen,
|
|
1351
|
+
isCustomFullscreen: customFullscreen,
|
|
1352
|
+
pictureInPictureActive,
|
|
1353
|
+
pictureInPictureControlEnabled,
|
|
1354
|
+
togglePictureInPicture,
|
|
1355
|
+
castControlEnabled,
|
|
1356
|
+
castConnected,
|
|
1357
|
+
openCastPicker
|
|
1358
|
+
}),
|
|
1359
|
+
[
|
|
1360
|
+
playback,
|
|
1361
|
+
player,
|
|
1362
|
+
videoViewRef,
|
|
1363
|
+
chromeVisible,
|
|
1364
|
+
chromeOpacity,
|
|
1365
|
+
timelineScrubClockSeconds,
|
|
1366
|
+
setTimelineScrubClockSeconds,
|
|
1367
|
+
bumpChromeInteraction,
|
|
1368
|
+
dismissChrome,
|
|
1369
|
+
ui,
|
|
1370
|
+
isBuffering,
|
|
1371
|
+
layout,
|
|
1372
|
+
togglePlay,
|
|
1373
|
+
seekBack,
|
|
1374
|
+
seekForward,
|
|
1375
|
+
toggleFullscreen,
|
|
1376
|
+
customFullscreen,
|
|
1377
|
+
pictureInPictureActive,
|
|
1378
|
+
pictureInPictureControlEnabled,
|
|
1379
|
+
togglePictureInPicture,
|
|
1380
|
+
castControlEnabled,
|
|
1381
|
+
castConnected,
|
|
1382
|
+
openCastPicker
|
|
1383
|
+
]
|
|
1384
|
+
);
|
|
1385
|
+
return /* @__PURE__ */ jsx(MoviieSkinChromeContext.Provider, { value, children });
|
|
1386
|
+
}
|
|
1387
|
+
function MoviieEmbedBrandMark() {
|
|
1388
|
+
const { layout } = useMoviieSkinChrome();
|
|
1389
|
+
const fg = MOVIIE_SKIN_CHROME_FOREGROUND_HEX;
|
|
1390
|
+
const openMarketingSite = useCallback(() => {
|
|
1391
|
+
void Linking.openURL(buildMoviieEmbedBrandHomeUrl());
|
|
1392
|
+
}, []);
|
|
1393
|
+
return /* @__PURE__ */ jsx(
|
|
1394
|
+
Pressable,
|
|
1395
|
+
{
|
|
1396
|
+
accessibilityHint: "Abre o site da Moviie no navegador",
|
|
1397
|
+
accessibilityLabel: "Moviie \u2014 p\xE1gina inicial",
|
|
1398
|
+
accessibilityRole: "link",
|
|
1399
|
+
hitSlop: MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX,
|
|
1400
|
+
onPress: openMarketingSite,
|
|
1401
|
+
children: /* @__PURE__ */ jsxs(
|
|
1402
|
+
jsx_native_bridge_default,
|
|
1403
|
+
{
|
|
1404
|
+
accessibilityElementsHidden: true,
|
|
1405
|
+
height: layout.brandMarkHeightPx,
|
|
1406
|
+
importantForAccessibility: "no",
|
|
1407
|
+
viewBox: MOVIIE_EMBED_BRAND_VIEW_BOX,
|
|
1408
|
+
width: layout.brandMarkWidthPx,
|
|
1409
|
+
children: [
|
|
1410
|
+
/* @__PURE__ */ jsx(
|
|
1411
|
+
Path,
|
|
1412
|
+
{
|
|
1413
|
+
d: "M6.066 43.725H0V0h6.066L21.8 36.77 37.533 0h6.192v43.725H37.66V26.43c0-8.165.063-11.128.38-14.212L24.706 43.725h-5.813L5.623 12.337c.317 2.117.443 6.593.443 12.7z",
|
|
1414
|
+
fill: fg
|
|
1415
|
+
}
|
|
1416
|
+
),
|
|
1417
|
+
/* @__PURE__ */ jsx(
|
|
1418
|
+
Path,
|
|
1419
|
+
{
|
|
1420
|
+
d: "M47.527 29.467c0-9.494 6.454-16.16 15.239-16.16 8.725 0 15.179 6.666 15.179 16.16s-6.454 16.16-15.179 16.16c-8.785 0-15.239-6.666-15.239-16.16m5.678 0c0 6.413 3.884 10.878 9.561 10.878 5.617 0 9.562-4.465 9.562-10.878S68.383 18.59 62.766 18.59c-5.677 0-9.561 4.465-9.561 10.878M159.227 45.626c-8.737 0-14.744-6.526-14.744-16.065 0-9.601 5.886-16.253 14.501-16.253 8.434 0 13.955 6.024 13.955 15.124v2.196l-22.934.063c.424 6.464 3.701 10.04 9.343 10.04 4.43 0 7.342-1.882 8.313-5.396H173c-1.456 6.589-6.431 10.291-13.773 10.291m-.243-27.36c-4.975 0-8.13 3.074-8.858 8.471h17.11c0-5.083-3.216-8.472-8.252-8.472",
|
|
1421
|
+
fill: fg
|
|
1422
|
+
}
|
|
1423
|
+
),
|
|
1424
|
+
/* @__PURE__ */ jsx(
|
|
1425
|
+
Path,
|
|
1426
|
+
{
|
|
1427
|
+
d: "m140.681 15.209-12.313 28.516h-4.794l12.313-28.516zm-14.384 0-12.312 28.516h-4.811l12.313-28.516zm-39.363 0 6.553 16.138c1.06 2.768 1.927 5.221 2.42 7.006l.944-.007c.49-1.892 1.476-4.393 2.539-6.988l6.68-16.15h5.054L98.799 43.726h-5.15L81.747 15.21z",
|
|
1428
|
+
fill: "none",
|
|
1429
|
+
stroke: fg,
|
|
1430
|
+
strokeLinejoin: "bevel",
|
|
1431
|
+
strokeWidth: MOVIIE_EMBED_BRAND_LETTERMARK_STROKE_WIDTH
|
|
1432
|
+
}
|
|
1433
|
+
)
|
|
1434
|
+
]
|
|
1435
|
+
}
|
|
1436
|
+
)
|
|
1437
|
+
}
|
|
1438
|
+
);
|
|
1439
|
+
}
|
|
1440
|
+
function pressOpacity(pressed) {
|
|
1441
|
+
return {
|
|
1442
|
+
opacity: pressed ? MOVIIE_SKIN_CHROME_CONTROL_PRESSED_OPACITY : MOVIIE_SKIN_CHROME_CONTROL_REST_OPACITY
|
|
1443
|
+
};
|
|
1444
|
+
}
|
|
1445
|
+
function ScrimPad(props) {
|
|
1446
|
+
return /* @__PURE__ */ jsx(
|
|
1447
|
+
Pressable,
|
|
1448
|
+
{
|
|
1449
|
+
accessibilityLabel: props.accessibilityLabel,
|
|
1450
|
+
accessibilityRole: "button",
|
|
1451
|
+
accessibilityState: { selected: props.selected },
|
|
1452
|
+
hitSlop: props.hitSlop,
|
|
1453
|
+
onPress: props.onPress,
|
|
1454
|
+
style: (state) => [props.chromeScrimBaseStyle, props.style, pressOpacity(state.pressed)],
|
|
1455
|
+
children: props.children
|
|
1456
|
+
}
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
function MoviieSkinCastCircleButton(props) {
|
|
1460
|
+
const Icon = props.castConnected ? EmbedMediaIconCastConnected : EmbedMediaIconCast;
|
|
1461
|
+
return /* @__PURE__ */ jsx(
|
|
1462
|
+
ScrimPad,
|
|
1463
|
+
{
|
|
1464
|
+
accessibilityLabel: props.castConnected ? "Encerrar transmiss\xE3o" : "Transmitir",
|
|
1465
|
+
chromeScrimBaseStyle: props.chromeScrimBaseStyle,
|
|
1466
|
+
hitSlop: MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX,
|
|
1467
|
+
onPress: props.onPress,
|
|
1468
|
+
selected: props.castConnected,
|
|
1469
|
+
style: props.circleScrimStyle,
|
|
1470
|
+
children: /* @__PURE__ */ jsx(
|
|
1471
|
+
Icon,
|
|
1472
|
+
{
|
|
1473
|
+
color: MOVIIE_SKIN_CHROME_FOREGROUND_HEX,
|
|
1474
|
+
size: props.layout.floatingHudFullscreenIconPx
|
|
1475
|
+
}
|
|
1476
|
+
)
|
|
1477
|
+
}
|
|
1478
|
+
);
|
|
1479
|
+
}
|
|
1480
|
+
function MoviieSkinCastTopBareButton(props) {
|
|
1481
|
+
const Icon = props.castConnected ? EmbedMediaIconCastConnected : EmbedMediaIconCast;
|
|
1482
|
+
return /* @__PURE__ */ jsx(
|
|
1483
|
+
Pressable,
|
|
1484
|
+
{
|
|
1485
|
+
accessibilityLabel: props.castConnected ? "Encerrar transmiss\xE3o" : "Transmitir",
|
|
1486
|
+
accessibilityRole: "button",
|
|
1487
|
+
accessibilityState: { selected: props.castConnected },
|
|
1488
|
+
hitSlop: MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX,
|
|
1489
|
+
onPress: props.onPress,
|
|
1490
|
+
style: (state) => pressOpacity(state.pressed),
|
|
1491
|
+
children: /* @__PURE__ */ jsx(View, { children: /* @__PURE__ */ jsx(
|
|
1492
|
+
Icon,
|
|
1493
|
+
{
|
|
1494
|
+
color: MOVIIE_SKIN_CHROME_FOREGROUND_HEX,
|
|
1495
|
+
size: props.layout.floatingHudFullscreenTopIconPx * MOVIIE_SKIN_TOP_ICON_CAST_VISUAL_SCALE
|
|
1496
|
+
}
|
|
1497
|
+
) })
|
|
1498
|
+
}
|
|
1499
|
+
);
|
|
1500
|
+
}
|
|
1501
|
+
function MoviieSkinChromeEdgeGradients(props) {
|
|
1502
|
+
const [hostWidth, setHostWidth] = useState(0);
|
|
1503
|
+
const [hostHeight, setHostHeight] = useState(0);
|
|
1504
|
+
const onHostLayout = useCallback((event) => {
|
|
1505
|
+
const { height, width } = event.nativeEvent.layout;
|
|
1506
|
+
setHostWidth(width);
|
|
1507
|
+
setHostHeight(height);
|
|
1508
|
+
}, []);
|
|
1509
|
+
const rawTopPx = props.layout.chromeEdgeGradientHeightPx;
|
|
1510
|
+
const rawBottomPx = props.layout.chromeEdgeGradientHeightPx + (props.showProgress ? props.layout.timelineStackHeightChromeVisiblePx : 0);
|
|
1511
|
+
const { effBottomPx, effTopPx, svgWidthPx } = useMemo(() => {
|
|
1512
|
+
if (hostWidth <= 0 || hostHeight <= 0) {
|
|
1513
|
+
return { effBottomPx: 0, effTopPx: 0, svgWidthPx: 0 };
|
|
1514
|
+
}
|
|
1515
|
+
const svgWidthPx2 = hostWidth;
|
|
1516
|
+
const maxTotalPx = Math.max(
|
|
1517
|
+
0,
|
|
1518
|
+
hostHeight - MOVIIE_SKIN_CHROME_EDGE_GRADIENT_MIN_CLEAR_MIDDLE_PX
|
|
1519
|
+
);
|
|
1520
|
+
const rawSum = rawTopPx + rawBottomPx;
|
|
1521
|
+
const scale = rawSum > maxTotalPx && maxTotalPx > 0 && rawSum > 0 ? maxTotalPx / rawSum : 1;
|
|
1522
|
+
return {
|
|
1523
|
+
effBottomPx: rawBottomPx * scale,
|
|
1524
|
+
effTopPx: rawTopPx * scale,
|
|
1525
|
+
svgWidthPx: svgWidthPx2
|
|
1526
|
+
};
|
|
1527
|
+
}, [hostHeight, hostWidth, rawBottomPx, rawTopPx]);
|
|
1528
|
+
const topFillUrl = `url(#${MOVIIE_SKIN_CHROME_SVG_GRADIENT_TOP_EDGE_ID})`;
|
|
1529
|
+
const bottomFillUrl = `url(#${MOVIIE_SKIN_CHROME_SVG_GRADIENT_BOTTOM_EDGE_ID})`;
|
|
1530
|
+
const layoutReady = hostWidth > 0 && hostHeight > 0 && svgWidthPx > 0;
|
|
1531
|
+
const fadeEndOffset = String(MOVIIE_SKIN_CHROME_EDGE_GRADIENT_EDGE_SOLID_FADE_END_FRACTION);
|
|
1532
|
+
return /* @__PURE__ */ jsxs(
|
|
1533
|
+
View,
|
|
1534
|
+
{
|
|
1535
|
+
accessibilityElementsHidden: true,
|
|
1536
|
+
importantForAccessibility: "no-hide-descendants",
|
|
1537
|
+
onLayout: onHostLayout,
|
|
1538
|
+
pointerEvents: "none",
|
|
1539
|
+
style: StyleSheet.absoluteFillObject,
|
|
1540
|
+
testID: "moviie-chrome-edge-gradients",
|
|
1541
|
+
children: [
|
|
1542
|
+
layoutReady && effTopPx > 0 ? /* @__PURE__ */ jsx(
|
|
1543
|
+
View,
|
|
1544
|
+
{
|
|
1545
|
+
accessibilityElementsHidden: true,
|
|
1546
|
+
importantForAccessibility: "no-hide-descendants",
|
|
1547
|
+
pointerEvents: "none",
|
|
1548
|
+
style: {
|
|
1549
|
+
height: effTopPx,
|
|
1550
|
+
left: 0,
|
|
1551
|
+
overflow: "hidden",
|
|
1552
|
+
position: "absolute",
|
|
1553
|
+
top: 0,
|
|
1554
|
+
width: hostWidth
|
|
1555
|
+
},
|
|
1556
|
+
children: /* @__PURE__ */ jsxs(jsx_native_bridge_default, { accessibilityElementsHidden: true, height: effTopPx, width: svgWidthPx, children: [
|
|
1557
|
+
/* @__PURE__ */ jsx(Defs, { children: /* @__PURE__ */ jsxs(
|
|
1558
|
+
LinearGradient,
|
|
1559
|
+
{
|
|
1560
|
+
gradientUnits: "objectBoundingBox",
|
|
1561
|
+
id: MOVIIE_SKIN_CHROME_SVG_GRADIENT_TOP_EDGE_ID,
|
|
1562
|
+
x1: "0",
|
|
1563
|
+
x2: "0",
|
|
1564
|
+
y1: "0",
|
|
1565
|
+
y2: "1",
|
|
1566
|
+
children: [
|
|
1567
|
+
/* @__PURE__ */ jsx(
|
|
1568
|
+
Stop,
|
|
1569
|
+
{
|
|
1570
|
+
offset: "0",
|
|
1571
|
+
stopColor: MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX,
|
|
1572
|
+
stopOpacity: MOVIIE_SKIN_CHROME_GRADIENT_EDGE_ALPHA
|
|
1573
|
+
}
|
|
1574
|
+
),
|
|
1575
|
+
/* @__PURE__ */ jsx(
|
|
1576
|
+
Stop,
|
|
1577
|
+
{
|
|
1578
|
+
offset: fadeEndOffset,
|
|
1579
|
+
stopColor: MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX,
|
|
1580
|
+
stopOpacity: 0
|
|
1581
|
+
}
|
|
1582
|
+
),
|
|
1583
|
+
/* @__PURE__ */ jsx(Stop, { offset: "1", stopColor: MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX, stopOpacity: 0 })
|
|
1584
|
+
]
|
|
1585
|
+
}
|
|
1586
|
+
) }),
|
|
1587
|
+
/* @__PURE__ */ jsx(Rect, { fill: topFillUrl, height: effTopPx, width: svgWidthPx })
|
|
1588
|
+
] })
|
|
1589
|
+
}
|
|
1590
|
+
) : null,
|
|
1591
|
+
layoutReady && effBottomPx > 0 ? /* @__PURE__ */ jsx(
|
|
1592
|
+
View,
|
|
1593
|
+
{
|
|
1594
|
+
accessibilityElementsHidden: true,
|
|
1595
|
+
importantForAccessibility: "no-hide-descendants",
|
|
1596
|
+
pointerEvents: "none",
|
|
1597
|
+
style: {
|
|
1598
|
+
bottom: 0,
|
|
1599
|
+
height: effBottomPx,
|
|
1600
|
+
left: 0,
|
|
1601
|
+
overflow: "hidden",
|
|
1602
|
+
position: "absolute",
|
|
1603
|
+
width: hostWidth
|
|
1604
|
+
},
|
|
1605
|
+
children: /* @__PURE__ */ jsxs(jsx_native_bridge_default, { accessibilityElementsHidden: true, height: effBottomPx, width: svgWidthPx, children: [
|
|
1606
|
+
/* @__PURE__ */ jsx(Defs, { children: /* @__PURE__ */ jsxs(
|
|
1607
|
+
LinearGradient,
|
|
1608
|
+
{
|
|
1609
|
+
gradientUnits: "objectBoundingBox",
|
|
1610
|
+
id: MOVIIE_SKIN_CHROME_SVG_GRADIENT_BOTTOM_EDGE_ID,
|
|
1611
|
+
x1: "0",
|
|
1612
|
+
x2: "0",
|
|
1613
|
+
y1: "1",
|
|
1614
|
+
y2: "0",
|
|
1615
|
+
children: [
|
|
1616
|
+
/* @__PURE__ */ jsx(
|
|
1617
|
+
Stop,
|
|
1618
|
+
{
|
|
1619
|
+
offset: "0",
|
|
1620
|
+
stopColor: MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX,
|
|
1621
|
+
stopOpacity: MOVIIE_SKIN_CHROME_GRADIENT_EDGE_ALPHA
|
|
1622
|
+
}
|
|
1623
|
+
),
|
|
1624
|
+
/* @__PURE__ */ jsx(
|
|
1625
|
+
Stop,
|
|
1626
|
+
{
|
|
1627
|
+
offset: fadeEndOffset,
|
|
1628
|
+
stopColor: MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX,
|
|
1629
|
+
stopOpacity: 0
|
|
1630
|
+
}
|
|
1631
|
+
),
|
|
1632
|
+
/* @__PURE__ */ jsx(Stop, { offset: "1", stopColor: MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX, stopOpacity: 0 })
|
|
1633
|
+
]
|
|
1634
|
+
}
|
|
1635
|
+
) }),
|
|
1636
|
+
/* @__PURE__ */ jsx(Rect, { fill: bottomFillUrl, height: effBottomPx, width: svgWidthPx })
|
|
1637
|
+
] })
|
|
1638
|
+
}
|
|
1639
|
+
) : null
|
|
1640
|
+
]
|
|
1641
|
+
}
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
// src/lib/clamp-unit-interval.ts
|
|
1646
|
+
function clampUnitInterval(value) {
|
|
1647
|
+
return Math.min(1, Math.max(0, value));
|
|
1648
|
+
}
|
|
1649
|
+
|
|
1650
|
+
// src/lib/compute-playback-progress-ratio.ts
|
|
1651
|
+
function computePlaybackProgressRatio(state) {
|
|
1652
|
+
if (!state.durationOk || !Number.isFinite(state.currentTime) || !Number.isFinite(state.duration) || state.duration <= 0) {
|
|
1653
|
+
return 0;
|
|
1654
|
+
}
|
|
1655
|
+
const raw = state.currentTime / state.duration;
|
|
1656
|
+
if (raw >= 1) {
|
|
1657
|
+
return 1;
|
|
1658
|
+
}
|
|
1659
|
+
const snapToEndWhilePaused = !state.playing && state.currentTime >= state.duration - MOVIIE_SKIN_TIMELINE_END_SNAP_EPSILON_SECONDS;
|
|
1660
|
+
const ratio = snapToEndWhilePaused ? 1 : raw;
|
|
1661
|
+
return clampUnitInterval(ratio);
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
// src/lib/compute-timeline-scrub-commit-time.ts
|
|
1665
|
+
function computeTimelineScrubCommitTime(params) {
|
|
1666
|
+
const {
|
|
1667
|
+
ratio,
|
|
1668
|
+
durationSeconds,
|
|
1669
|
+
chapters,
|
|
1670
|
+
snapThresholdSeconds = MOVIIE_SKIN_TIMELINE_CHAPTER_SNAP_THRESHOLD_SECONDS
|
|
1671
|
+
} = params;
|
|
1672
|
+
const rawTime = ratio * durationSeconds;
|
|
1673
|
+
let nearest = null;
|
|
1674
|
+
let nearestDist = Infinity;
|
|
1675
|
+
for (const chapter of chapters) {
|
|
1676
|
+
const dist = Math.abs(chapter.startTimeSeconds - rawTime);
|
|
1677
|
+
if (dist < nearestDist) {
|
|
1678
|
+
nearestDist = dist;
|
|
1679
|
+
nearest = chapter.startTimeSeconds;
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
return nearest !== null && nearestDist <= snapThresholdSeconds ? nearest : rawTime;
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
// src/lib/resolve-skin-accent-color.ts
|
|
1686
|
+
var HEX_COLOR_REGEX = /^#[0-9A-Fa-f]{6}$/;
|
|
1687
|
+
function resolveSkinAccentColor(primaryColor) {
|
|
1688
|
+
if (primaryColor != null && HEX_COLOR_REGEX.test(primaryColor)) {
|
|
1689
|
+
return primaryColor;
|
|
1690
|
+
}
|
|
1691
|
+
return MOVIIE_SKIN_DEFAULT_ACCENT_HEX;
|
|
1692
|
+
}
|
|
1693
|
+
function createMoviieSkinBottomTimelineStyles(layout) {
|
|
1694
|
+
return StyleSheet.create({
|
|
1695
|
+
root: {
|
|
1696
|
+
bottom: 0,
|
|
1697
|
+
left: 0,
|
|
1698
|
+
overflow: "visible",
|
|
1699
|
+
pointerEvents: "box-none",
|
|
1700
|
+
position: "absolute",
|
|
1701
|
+
right: 0,
|
|
1702
|
+
zIndex: 24
|
|
1703
|
+
},
|
|
1704
|
+
touchExpansion: {
|
|
1705
|
+
overflow: "visible",
|
|
1706
|
+
paddingBottom: 0,
|
|
1707
|
+
paddingTop: layout.timelineTouchPaddingVerticalPx + MOVIIE_SKIN_TIMELINE_TOUCH_EXPANSION_VERTICAL_DP,
|
|
1708
|
+
position: "relative"
|
|
1709
|
+
},
|
|
1710
|
+
trackStack: {
|
|
1711
|
+
overflow: "visible",
|
|
1712
|
+
width: "100%"
|
|
1713
|
+
},
|
|
1714
|
+
thumbBase: {
|
|
1715
|
+
borderColor: MOVIIE_SKIN_TIMELINE_THUMB_BORDER_RGBA,
|
|
1716
|
+
borderWidth: 1,
|
|
1717
|
+
elevation: 8,
|
|
1718
|
+
position: "absolute",
|
|
1719
|
+
zIndex: 10
|
|
1720
|
+
},
|
|
1721
|
+
unifiedBarSlot: {
|
|
1722
|
+
overflow: "visible",
|
|
1723
|
+
position: "relative",
|
|
1724
|
+
width: "100%"
|
|
1725
|
+
},
|
|
1726
|
+
railLayer: {
|
|
1727
|
+
backgroundColor: MOVIIE_SKIN_TIMELINE_RAIL_BACKGROUND_RGBA,
|
|
1728
|
+
bottom: 0,
|
|
1729
|
+
height: layout.timelineBarHeightPx,
|
|
1730
|
+
left: 0,
|
|
1731
|
+
position: "absolute",
|
|
1732
|
+
right: 0,
|
|
1733
|
+
zIndex: 0
|
|
1734
|
+
},
|
|
1735
|
+
bufferLayer: {
|
|
1736
|
+
backgroundColor: MOVIIE_SKIN_TIMELINE_BUFFER_LAYER_RGBA,
|
|
1737
|
+
bottom: 0,
|
|
1738
|
+
height: layout.timelineBarHeightPx,
|
|
1739
|
+
left: 0,
|
|
1740
|
+
position: "absolute",
|
|
1741
|
+
zIndex: 1
|
|
1742
|
+
},
|
|
1743
|
+
progressLayer: {
|
|
1744
|
+
bottom: 0,
|
|
1745
|
+
height: layout.timelineBarHeightPx,
|
|
1746
|
+
left: 0,
|
|
1747
|
+
position: "absolute",
|
|
1748
|
+
zIndex: 2
|
|
1749
|
+
}
|
|
1750
|
+
});
|
|
1751
|
+
}
|
|
1752
|
+
function MoviieSkinBottomTimeline() {
|
|
1753
|
+
const {
|
|
1754
|
+
playback,
|
|
1755
|
+
chromeVisible,
|
|
1756
|
+
layout,
|
|
1757
|
+
player,
|
|
1758
|
+
setTimelineScrubClockSeconds,
|
|
1759
|
+
ui
|
|
1760
|
+
} = useMoviieSkinChrome();
|
|
1761
|
+
const styles6 = useMemo(
|
|
1762
|
+
() => createMoviieSkinBottomTimelineStyles(layout),
|
|
1763
|
+
[layout]
|
|
1764
|
+
);
|
|
1765
|
+
const { controls } = playback;
|
|
1766
|
+
const accent = resolveSkinAccentColor(playback.branding.primaryColor);
|
|
1767
|
+
const foreground = MOVIIE_SKIN_CHROME_FOREGROUND_HEX;
|
|
1768
|
+
const durationOk = controls.showProgress && Number.isFinite(ui.duration) && ui.duration > 0 && !player.isLive;
|
|
1769
|
+
const progressRatioLive = computePlaybackProgressRatio({
|
|
1770
|
+
currentTime: ui.currentTime,
|
|
1771
|
+
duration: ui.duration,
|
|
1772
|
+
durationOk,
|
|
1773
|
+
playing: ui.playing
|
|
1774
|
+
});
|
|
1775
|
+
const bufferRatioLive = durationOk && Number.isFinite(ui.bufferedPosition) && ui.bufferedPosition >= 0 ? clampUnitInterval(ui.bufferedPosition / ui.duration) : 0;
|
|
1776
|
+
const isDraggingSV = useSharedValue(false);
|
|
1777
|
+
const awaitingUnlockSV = useSharedValue(false);
|
|
1778
|
+
const scrubRatioSV = useSharedValue(0);
|
|
1779
|
+
const progressRatioSV = useSharedValue(progressRatioLive);
|
|
1780
|
+
const bufferRatioSV = useSharedValue(bufferRatioLive);
|
|
1781
|
+
const trackWidthSV = useSharedValue(0);
|
|
1782
|
+
const durationSV = useSharedValue(ui.duration);
|
|
1783
|
+
const chromeVisibleSV = useSharedValue(chromeVisible);
|
|
1784
|
+
const timelineAccentEngagedSV = useSharedValue(false);
|
|
1785
|
+
const thumbBaseDiamSV = useSharedValue(layout.timelineThumbDiameterPx);
|
|
1786
|
+
const barHeightSV = useSharedValue(layout.timelineBarHeightPx);
|
|
1787
|
+
const isDraggingRef = useRef(false);
|
|
1788
|
+
const shouldResumeRef = useRef(false);
|
|
1789
|
+
const progressRatioLiveRef = useRef(progressRatioLive);
|
|
1790
|
+
progressRatioLiveRef.current = progressRatioLive;
|
|
1791
|
+
const chaptersRef = useRef(playback.chapters);
|
|
1792
|
+
chaptersRef.current = playback.chapters;
|
|
1793
|
+
const chromeVisibleRef = useRef(chromeVisible);
|
|
1794
|
+
chromeVisibleRef.current = chromeVisible;
|
|
1795
|
+
useEffect(() => {
|
|
1796
|
+
if (!isDraggingRef.current) {
|
|
1797
|
+
progressRatioSV.value = progressRatioLive;
|
|
1798
|
+
}
|
|
1799
|
+
}, [progressRatioLive, progressRatioSV]);
|
|
1800
|
+
useEffect(() => {
|
|
1801
|
+
bufferRatioSV.value = bufferRatioLive;
|
|
1802
|
+
}, [bufferRatioLive, bufferRatioSV]);
|
|
1803
|
+
useEffect(() => {
|
|
1804
|
+
durationSV.value = ui.duration;
|
|
1805
|
+
}, [ui.duration, durationSV]);
|
|
1806
|
+
useEffect(() => {
|
|
1807
|
+
thumbBaseDiamSV.value = layout.timelineThumbDiameterPx;
|
|
1808
|
+
barHeightSV.value = layout.timelineBarHeightPx;
|
|
1809
|
+
}, [
|
|
1810
|
+
layout.timelineThumbDiameterPx,
|
|
1811
|
+
layout.timelineBarHeightPx,
|
|
1812
|
+
thumbBaseDiamSV,
|
|
1813
|
+
barHeightSV
|
|
1814
|
+
]);
|
|
1815
|
+
useEffect(() => {
|
|
1816
|
+
chromeVisibleSV.value = chromeVisible;
|
|
1817
|
+
if (chromeVisible) {
|
|
1818
|
+
timelineAccentEngagedSV.value = false;
|
|
1819
|
+
awaitingUnlockSV.value = false;
|
|
1820
|
+
}
|
|
1821
|
+
}, [
|
|
1822
|
+
chromeVisible,
|
|
1823
|
+
chromeVisibleSV,
|
|
1824
|
+
timelineAccentEngagedSV,
|
|
1825
|
+
awaitingUnlockSV
|
|
1826
|
+
]);
|
|
1827
|
+
useEffect(() => {
|
|
1828
|
+
const sub = player.addListener("statusChange", ({ status }) => {
|
|
1829
|
+
if (shouldResumeRef.current && status === "readyToPlay" && !isDraggingRef.current) {
|
|
1830
|
+
player.play();
|
|
1831
|
+
}
|
|
1832
|
+
});
|
|
1833
|
+
return () => sub.remove();
|
|
1834
|
+
}, [player]);
|
|
1835
|
+
useEffect(() => {
|
|
1836
|
+
const sub = player.addListener("playingChange", ({ isPlaying }) => {
|
|
1837
|
+
if (isPlaying && !isDraggingRef.current) {
|
|
1838
|
+
shouldResumeRef.current = false;
|
|
1839
|
+
}
|
|
1840
|
+
});
|
|
1841
|
+
return () => sub.remove();
|
|
1842
|
+
}, [player]);
|
|
1843
|
+
const effectiveRatioSV = useDerivedValue(
|
|
1844
|
+
() => isDraggingSV.value ? scrubRatioSV.value : progressRatioSV.value
|
|
1845
|
+
);
|
|
1846
|
+
const showAccentSV = useDerivedValue(
|
|
1847
|
+
() => chromeVisibleSV.value || isDraggingSV.value || timelineAccentEngagedSV.value
|
|
1848
|
+
);
|
|
1849
|
+
const showThumbSV = useDerivedValue(
|
|
1850
|
+
() => chromeVisibleSV.value || isDraggingSV.value || timelineAccentEngagedSV.value
|
|
1851
|
+
);
|
|
1852
|
+
const thumbDiamSV = useDerivedValue(
|
|
1853
|
+
() => isDraggingSV.value ? Math.round(
|
|
1854
|
+
thumbBaseDiamSV.value * MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER
|
|
1855
|
+
) : thumbBaseDiamSV.value
|
|
1856
|
+
);
|
|
1857
|
+
const progressBarStyle = useAnimatedStyle(() => ({
|
|
1858
|
+
backgroundColor: showAccentSV.value ? accent : foreground,
|
|
1859
|
+
width: `${effectiveRatioSV.value * 100}%`
|
|
1860
|
+
}));
|
|
1861
|
+
const bufferBarStyle = useAnimatedStyle(() => ({
|
|
1862
|
+
width: `${bufferRatioSV.value * 100}%`
|
|
1863
|
+
}));
|
|
1864
|
+
const thumbStyle = useAnimatedStyle(() => {
|
|
1865
|
+
if (!showThumbSV.value) {
|
|
1866
|
+
return { opacity: 0 };
|
|
1867
|
+
}
|
|
1868
|
+
const diameter = thumbDiamSV.value;
|
|
1869
|
+
const radius = diameter / 2;
|
|
1870
|
+
const w = trackWidthSV.value;
|
|
1871
|
+
const left = w > 0 ? Math.min(w - diameter, Math.max(0, effectiveRatioSV.value * w - radius)) : 0;
|
|
1872
|
+
const bh = barHeightSV.value;
|
|
1873
|
+
return {
|
|
1874
|
+
opacity: 1,
|
|
1875
|
+
backgroundColor: showAccentSV.value ? accent : foreground,
|
|
1876
|
+
left,
|
|
1877
|
+
width: diameter,
|
|
1878
|
+
height: diameter,
|
|
1879
|
+
borderRadius: radius,
|
|
1880
|
+
bottom: bh / 2 - radius
|
|
1881
|
+
};
|
|
1882
|
+
});
|
|
1883
|
+
const onScrubBegin = useCallback(() => {
|
|
1884
|
+
isDraggingRef.current = true;
|
|
1885
|
+
if (!shouldResumeRef.current) {
|
|
1886
|
+
shouldResumeRef.current = player.playing;
|
|
1887
|
+
}
|
|
1888
|
+
}, [player]);
|
|
1889
|
+
const onScrubUpdate = useCallback(
|
|
1890
|
+
(ratio) => {
|
|
1891
|
+
setTimelineScrubClockSeconds(ratio * durationSV.value);
|
|
1892
|
+
},
|
|
1893
|
+
[setTimelineScrubClockSeconds, durationSV]
|
|
1894
|
+
);
|
|
1895
|
+
const onScrubCommit = useCallback(
|
|
1896
|
+
(ratio) => {
|
|
1897
|
+
isDraggingRef.current = false;
|
|
1898
|
+
setTimelineScrubClockSeconds(null);
|
|
1899
|
+
const dur = durationSV.value;
|
|
1900
|
+
if (!Number.isFinite(dur) || dur <= 0) return;
|
|
1901
|
+
const targetTime = computeTimelineScrubCommitTime({
|
|
1902
|
+
ratio,
|
|
1903
|
+
durationSeconds: dur,
|
|
1904
|
+
chapters: chaptersRef.current
|
|
1905
|
+
});
|
|
1906
|
+
player.currentTime = targetTime;
|
|
1907
|
+
if (shouldResumeRef.current) {
|
|
1908
|
+
player.play();
|
|
1909
|
+
}
|
|
1910
|
+
},
|
|
1911
|
+
[setTimelineScrubClockSeconds, player, durationSV]
|
|
1912
|
+
);
|
|
1913
|
+
const onScrubCancel = useCallback(() => {
|
|
1914
|
+
isDraggingRef.current = false;
|
|
1915
|
+
setTimelineScrubClockSeconds(null);
|
|
1916
|
+
progressRatioSV.value = progressRatioLiveRef.current;
|
|
1917
|
+
}, [setTimelineScrubClockSeconds, progressRatioSV]);
|
|
1918
|
+
const onAccentEngage = useCallback(() => {
|
|
1919
|
+
timelineAccentEngagedSV.value = true;
|
|
1920
|
+
}, [timelineAccentEngagedSV]);
|
|
1921
|
+
const onAccentDisengageCancel = useCallback(() => {
|
|
1922
|
+
timelineAccentEngagedSV.value = false;
|
|
1923
|
+
}, [timelineAccentEngagedSV]);
|
|
1924
|
+
const panGesture = useMemo(
|
|
1925
|
+
() => Gesture.Pan().activeOffsetX([-8, 8]).failOffsetY([-15, 15]).enabled(durationOk).onBegin(() => {
|
|
1926
|
+
"worklet";
|
|
1927
|
+
if (!chromeVisibleSV.value && !timelineAccentEngagedSV.value) {
|
|
1928
|
+
awaitingUnlockSV.value = true;
|
|
1929
|
+
runOnJS(onAccentEngage)();
|
|
1930
|
+
}
|
|
1931
|
+
}).onStart((e) => {
|
|
1932
|
+
"worklet";
|
|
1933
|
+
if (awaitingUnlockSV.value) {
|
|
1934
|
+
return;
|
|
1935
|
+
}
|
|
1936
|
+
isDraggingSV.value = true;
|
|
1937
|
+
runOnJS(onScrubBegin)();
|
|
1938
|
+
const w = trackWidthSV.value;
|
|
1939
|
+
if (w <= 0) return;
|
|
1940
|
+
const ratio = Math.max(0, Math.min(1, e.x / w));
|
|
1941
|
+
scrubRatioSV.value = ratio;
|
|
1942
|
+
runOnJS(onScrubUpdate)(ratio);
|
|
1943
|
+
}).onUpdate((e) => {
|
|
1944
|
+
"worklet";
|
|
1945
|
+
const w = trackWidthSV.value;
|
|
1946
|
+
if (w <= 0) return;
|
|
1947
|
+
const ratio = Math.max(0, Math.min(1, e.x / w));
|
|
1948
|
+
if (awaitingUnlockSV.value) {
|
|
1949
|
+
awaitingUnlockSV.value = false;
|
|
1950
|
+
isDraggingSV.value = true;
|
|
1951
|
+
runOnJS(onScrubBegin)();
|
|
1952
|
+
}
|
|
1953
|
+
if (!isDraggingSV.value) return;
|
|
1954
|
+
scrubRatioSV.value = ratio;
|
|
1955
|
+
runOnJS(onScrubUpdate)(ratio);
|
|
1956
|
+
}).onEnd(() => {
|
|
1957
|
+
"worklet";
|
|
1958
|
+
if (awaitingUnlockSV.value) {
|
|
1959
|
+
awaitingUnlockSV.value = false;
|
|
1960
|
+
runOnJS(onAccentDisengageCancel)();
|
|
1961
|
+
return;
|
|
1962
|
+
}
|
|
1963
|
+
if (!isDraggingSV.value) return;
|
|
1964
|
+
const committed = scrubRatioSV.value;
|
|
1965
|
+
progressRatioSV.value = committed;
|
|
1966
|
+
isDraggingSV.value = false;
|
|
1967
|
+
scrubRatioSV.value = 0;
|
|
1968
|
+
runOnJS(onScrubCommit)(committed);
|
|
1969
|
+
}).onFinalize(() => {
|
|
1970
|
+
"worklet";
|
|
1971
|
+
if (awaitingUnlockSV.value) {
|
|
1972
|
+
awaitingUnlockSV.value = false;
|
|
1973
|
+
runOnJS(onAccentDisengageCancel)();
|
|
1974
|
+
return;
|
|
1975
|
+
}
|
|
1976
|
+
if (isDraggingSV.value) {
|
|
1977
|
+
isDraggingSV.value = false;
|
|
1978
|
+
scrubRatioSV.value = 0;
|
|
1979
|
+
runOnJS(onScrubCancel)();
|
|
1980
|
+
}
|
|
1981
|
+
}),
|
|
1982
|
+
[
|
|
1983
|
+
durationOk,
|
|
1984
|
+
isDraggingSV,
|
|
1985
|
+
awaitingUnlockSV,
|
|
1986
|
+
scrubRatioSV,
|
|
1987
|
+
progressRatioSV,
|
|
1988
|
+
trackWidthSV,
|
|
1989
|
+
chromeVisibleSV,
|
|
1990
|
+
timelineAccentEngagedSV,
|
|
1991
|
+
onAccentEngage,
|
|
1992
|
+
onAccentDisengageCancel,
|
|
1993
|
+
onScrubBegin,
|
|
1994
|
+
onScrubUpdate,
|
|
1995
|
+
onScrubCommit,
|
|
1996
|
+
onScrubCancel
|
|
1997
|
+
]
|
|
1998
|
+
);
|
|
1999
|
+
const onTrackLayout = useCallback(
|
|
2000
|
+
(event) => {
|
|
2001
|
+
trackWidthSV.value = event.nativeEvent.layout.width;
|
|
2002
|
+
},
|
|
2003
|
+
[trackWidthSV]
|
|
2004
|
+
);
|
|
2005
|
+
if (!durationOk) {
|
|
2006
|
+
return null;
|
|
2007
|
+
}
|
|
2008
|
+
const unifiedSlotHeightPx = Math.max(
|
|
2009
|
+
layout.timelineThumbDiameterPx,
|
|
2010
|
+
Math.round(
|
|
2011
|
+
layout.timelineThumbDiameterPx * MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER
|
|
2012
|
+
)
|
|
2013
|
+
);
|
|
2014
|
+
const scrubHitSlop = {
|
|
2015
|
+
top: MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_TOP_DP,
|
|
2016
|
+
bottom: MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_BOTTOM_DP,
|
|
2017
|
+
left: MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_HORIZONTAL_DP,
|
|
2018
|
+
right: MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_HORIZONTAL_DP
|
|
2019
|
+
};
|
|
2020
|
+
return /* @__PURE__ */ jsx(View, { pointerEvents: "box-none", style: styles6.root, children: /* @__PURE__ */ jsx(GestureDetector, { gesture: panGesture, children: /* @__PURE__ */ jsx(View, { hitSlop: scrubHitSlop, pointerEvents: "auto", style: styles6.touchExpansion, children: /* @__PURE__ */ jsx(View, { style: styles6.trackStack, children: /* @__PURE__ */ jsxs(
|
|
2021
|
+
View,
|
|
2022
|
+
{
|
|
2023
|
+
accessibilityRole: "progressbar",
|
|
2024
|
+
accessibilityValue: {
|
|
2025
|
+
max: 1,
|
|
2026
|
+
min: 0,
|
|
2027
|
+
now: progressRatioLive
|
|
2028
|
+
},
|
|
2029
|
+
collapsable: false,
|
|
2030
|
+
style: [styles6.unifiedBarSlot, { height: unifiedSlotHeightPx }],
|
|
2031
|
+
onLayout: onTrackLayout,
|
|
2032
|
+
children: [
|
|
2033
|
+
/* @__PURE__ */ jsx(View, { style: styles6.railLayer }),
|
|
2034
|
+
/* @__PURE__ */ jsx(ReanimatedView, { style: [styles6.bufferLayer, bufferBarStyle] }),
|
|
2035
|
+
/* @__PURE__ */ jsx(ReanimatedView, { style: [styles6.progressLayer, progressBarStyle] }),
|
|
2036
|
+
/* @__PURE__ */ jsx(ReanimatedView, { style: [styles6.thumbBase, thumbStyle] })
|
|
2037
|
+
]
|
|
2038
|
+
}
|
|
2039
|
+
) }) }) }) });
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
// src/lib/map-smart-progress-display-ratio.ts
|
|
2043
|
+
function easeOutQuad(t) {
|
|
2044
|
+
return t * (2 - t);
|
|
2045
|
+
}
|
|
2046
|
+
function easeInQuad(t) {
|
|
2047
|
+
return t * t;
|
|
2048
|
+
}
|
|
2049
|
+
function mapSmartProgressRawRatio(realUnitInterval) {
|
|
2050
|
+
const r = Math.min(1, Math.max(0, realUnitInterval));
|
|
2051
|
+
const {
|
|
2052
|
+
R1,
|
|
2053
|
+
P1,
|
|
2054
|
+
R2,
|
|
2055
|
+
P2,
|
|
2056
|
+
P_MAX_BEFORE_END: pMax
|
|
2057
|
+
} = MOVIIE_SMART_PROGRESS_CONFIG;
|
|
2058
|
+
if (r <= 0) {
|
|
2059
|
+
return 0;
|
|
2060
|
+
}
|
|
2061
|
+
if (r >= 1) {
|
|
2062
|
+
return pMax;
|
|
2063
|
+
}
|
|
2064
|
+
if (r <= R1) {
|
|
2065
|
+
return P1 * easeOutQuad(r / R1);
|
|
2066
|
+
}
|
|
2067
|
+
if (r <= R2) {
|
|
2068
|
+
const t2 = (r - R1) / (R2 - R1);
|
|
2069
|
+
return P1 + (P2 - P1) * t2;
|
|
2070
|
+
}
|
|
2071
|
+
const t = (r - R2) / (1 - R2);
|
|
2072
|
+
return P2 + (pMax - P2) * easeInQuad(t);
|
|
2073
|
+
}
|
|
2074
|
+
var styles = StyleSheet.create({
|
|
2075
|
+
container: {
|
|
2076
|
+
bottom: 0,
|
|
2077
|
+
height: MOVIIE_SMART_PROGRESS_BAR_HEIGHT_DP,
|
|
2078
|
+
left: 0,
|
|
2079
|
+
overflow: "hidden",
|
|
2080
|
+
position: "absolute",
|
|
2081
|
+
right: 0,
|
|
2082
|
+
zIndex: MOVIIE_SMART_PROGRESS_Z_INDEX
|
|
2083
|
+
},
|
|
2084
|
+
fill: {
|
|
2085
|
+
bottom: 0,
|
|
2086
|
+
height: "100%",
|
|
2087
|
+
left: 0,
|
|
2088
|
+
position: "absolute",
|
|
2089
|
+
top: 0
|
|
2090
|
+
}
|
|
2091
|
+
});
|
|
2092
|
+
function MoviieSkinSmartProgress() {
|
|
2093
|
+
const { playback, player, timelineScrubClockSeconds, ui } = useMoviieSkinChrome();
|
|
2094
|
+
const accent = resolveSkinAccentColor(playback.branding.primaryColor);
|
|
2095
|
+
const durationOk = playback.smartProgressEnabled && Number.isFinite(ui.duration) && ui.duration > 0 && !player.isLive;
|
|
2096
|
+
const [barVisible, setBarVisible] = useState(() => !player.muted);
|
|
2097
|
+
const hasUserInteractedRef = useRef(!player.muted);
|
|
2098
|
+
const lastDisplayedRef = useRef(0);
|
|
2099
|
+
const progressAnim = useRef(new Animated.Value(0)).current;
|
|
2100
|
+
const syncMutedVisibility = useCallback(() => {
|
|
2101
|
+
const muted = player.muted;
|
|
2102
|
+
if (!muted) {
|
|
2103
|
+
hasUserInteractedRef.current = true;
|
|
2104
|
+
setBarVisible(true);
|
|
2105
|
+
return;
|
|
2106
|
+
}
|
|
2107
|
+
if (!hasUserInteractedRef.current) {
|
|
2108
|
+
setBarVisible(false);
|
|
2109
|
+
}
|
|
2110
|
+
}, [player]);
|
|
2111
|
+
useEffect(() => {
|
|
2112
|
+
syncMutedVisibility();
|
|
2113
|
+
const subMuted = player.addListener("mutedChange", syncMutedVisibility);
|
|
2114
|
+
const subVolume = player.addListener("volumeChange", syncMutedVisibility);
|
|
2115
|
+
return () => {
|
|
2116
|
+
subMuted.remove();
|
|
2117
|
+
subVolume.remove();
|
|
2118
|
+
};
|
|
2119
|
+
}, [player, syncMutedVisibility]);
|
|
2120
|
+
useEffect(() => {
|
|
2121
|
+
lastDisplayedRef.current = 0;
|
|
2122
|
+
progressAnim.setValue(0);
|
|
2123
|
+
}, [playback.embedId, progressAnim]);
|
|
2124
|
+
useEffect(() => {
|
|
2125
|
+
if (!durationOk || !barVisible) {
|
|
2126
|
+
return;
|
|
2127
|
+
}
|
|
2128
|
+
const scrubbing = timelineScrubClockSeconds != null;
|
|
2129
|
+
const clockSeconds = scrubbing ? timelineScrubClockSeconds : ui.currentTime;
|
|
2130
|
+
const realRatio = computePlaybackProgressRatio({
|
|
2131
|
+
currentTime: clockSeconds,
|
|
2132
|
+
duration: ui.duration,
|
|
2133
|
+
durationOk: true,
|
|
2134
|
+
playing: ui.playing
|
|
2135
|
+
});
|
|
2136
|
+
const mapped = mapSmartProgressRawRatio(realRatio);
|
|
2137
|
+
const next = scrubbing ? mapped : Math.max(mapped, lastDisplayedRef.current);
|
|
2138
|
+
lastDisplayedRef.current = next;
|
|
2139
|
+
Animated.timing(progressAnim, {
|
|
2140
|
+
duration: MOVIIE_SMART_PROGRESS_FILL_TRANSITION_MS,
|
|
2141
|
+
toValue: next,
|
|
2142
|
+
useNativeDriver: false
|
|
2143
|
+
}).start();
|
|
2144
|
+
}, [
|
|
2145
|
+
barVisible,
|
|
2146
|
+
durationOk,
|
|
2147
|
+
progressAnim,
|
|
2148
|
+
timelineScrubClockSeconds,
|
|
2149
|
+
ui.currentTime,
|
|
2150
|
+
ui.duration,
|
|
2151
|
+
ui.playing
|
|
2152
|
+
]);
|
|
2153
|
+
useEffect(() => {
|
|
2154
|
+
if (!durationOk || !barVisible) {
|
|
2155
|
+
return;
|
|
2156
|
+
}
|
|
2157
|
+
const sub = player.addListener("playToEnd", () => {
|
|
2158
|
+
lastDisplayedRef.current = 1;
|
|
2159
|
+
Animated.timing(progressAnim, {
|
|
2160
|
+
duration: MOVIIE_SMART_PROGRESS_FILL_TRANSITION_MS,
|
|
2161
|
+
toValue: 1,
|
|
2162
|
+
useNativeDriver: false
|
|
2163
|
+
}).start();
|
|
2164
|
+
});
|
|
2165
|
+
return () => sub.remove();
|
|
2166
|
+
}, [barVisible, durationOk, player, progressAnim]);
|
|
2167
|
+
if (!playback.smartProgressEnabled || !durationOk) {
|
|
2168
|
+
return null;
|
|
2169
|
+
}
|
|
2170
|
+
if (!barVisible) {
|
|
2171
|
+
return null;
|
|
2172
|
+
}
|
|
2173
|
+
const widthInterpolated = progressAnim.interpolate({
|
|
2174
|
+
extrapolate: "clamp",
|
|
2175
|
+
inputRange: [0, 1],
|
|
2176
|
+
outputRange: ["0%", "100%"]
|
|
2177
|
+
});
|
|
2178
|
+
return /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: styles.container, children: /* @__PURE__ */ jsx(
|
|
2179
|
+
Animated.View,
|
|
2180
|
+
{
|
|
2181
|
+
style: [
|
|
2182
|
+
styles.fill,
|
|
2183
|
+
{
|
|
2184
|
+
backgroundColor: accent,
|
|
2185
|
+
width: widthInterpolated
|
|
2186
|
+
}
|
|
2187
|
+
]
|
|
2188
|
+
}
|
|
2189
|
+
) });
|
|
2190
|
+
}
|
|
2191
|
+
function resolveChromeControlPressOpacityStyle(pressed) {
|
|
2192
|
+
return {
|
|
2193
|
+
opacity: pressed ? MOVIIE_SKIN_CHROME_CONTROL_PRESSED_OPACITY : MOVIIE_SKIN_CHROME_CONTROL_REST_OPACITY
|
|
2194
|
+
};
|
|
2195
|
+
}
|
|
2196
|
+
function createMoviieSkinOverlayStyles(layout) {
|
|
2197
|
+
return StyleSheet.create({
|
|
2198
|
+
chromeScrimBase: {
|
|
2199
|
+
backgroundColor: MOVIIE_SKIN_CHROME_SCRIM_BLACK_RGBA
|
|
2200
|
+
},
|
|
2201
|
+
floatingHud: {
|
|
2202
|
+
bottom: 0,
|
|
2203
|
+
left: 0,
|
|
2204
|
+
pointerEvents: "box-none",
|
|
2205
|
+
position: "absolute",
|
|
2206
|
+
right: 0
|
|
2207
|
+
},
|
|
2208
|
+
floatingHudInner: {
|
|
2209
|
+
alignItems: "center",
|
|
2210
|
+
flexDirection: "row",
|
|
2211
|
+
justifyContent: "space-between",
|
|
2212
|
+
paddingBottom: layout.floatingHudAboveTimelineGapPx,
|
|
2213
|
+
paddingHorizontal: layout.hudEdgeInsetPx
|
|
2214
|
+
},
|
|
2215
|
+
floatingLeftSpacer: {
|
|
2216
|
+
flex: 1
|
|
2217
|
+
},
|
|
2218
|
+
floatingRight: {
|
|
2219
|
+
alignItems: "center",
|
|
2220
|
+
columnGap: layout.floatingHudButtonGapPx,
|
|
2221
|
+
flexDirection: "row",
|
|
2222
|
+
flexShrink: 0
|
|
2223
|
+
},
|
|
2224
|
+
clockScrim: {
|
|
2225
|
+
borderRadius: layout.hudClockCornerRadiusPx,
|
|
2226
|
+
overflow: "hidden",
|
|
2227
|
+
paddingHorizontal: layout.hudEdgeInsetPx,
|
|
2228
|
+
paddingVertical: layout.hudEdgeInsetPx
|
|
2229
|
+
},
|
|
2230
|
+
clockText: {
|
|
2231
|
+
color: MOVIIE_SKIN_CHROME_FOREGROUND_HEX,
|
|
2232
|
+
fontSize: layout.clockTextFontSizePx,
|
|
2233
|
+
fontVariant: ["tabular-nums"]
|
|
2234
|
+
},
|
|
2235
|
+
centerCluster: {
|
|
2236
|
+
...StyleSheet.absoluteFillObject,
|
|
2237
|
+
alignItems: "center",
|
|
2238
|
+
justifyContent: "center",
|
|
2239
|
+
pointerEvents: "box-none"
|
|
2240
|
+
},
|
|
2241
|
+
centerClusterRow: {
|
|
2242
|
+
alignItems: "center",
|
|
2243
|
+
columnGap: layout.centerClusterColumnGapPx,
|
|
2244
|
+
flexDirection: "row",
|
|
2245
|
+
justifyContent: "center"
|
|
2246
|
+
},
|
|
2247
|
+
seekCircularScrim: {
|
|
2248
|
+
alignItems: "center",
|
|
2249
|
+
borderRadius: layout.seekScrimOuterDiameterPx / 2,
|
|
2250
|
+
height: layout.seekScrimOuterDiameterPx,
|
|
2251
|
+
justifyContent: "center",
|
|
2252
|
+
overflow: "hidden",
|
|
2253
|
+
width: layout.seekScrimOuterDiameterPx
|
|
2254
|
+
},
|
|
2255
|
+
playScrim: {
|
|
2256
|
+
alignItems: "center",
|
|
2257
|
+
borderRadius: layout.playScrimOuterDiameterPx / 2,
|
|
2258
|
+
height: layout.playScrimOuterDiameterPx,
|
|
2259
|
+
justifyContent: "center",
|
|
2260
|
+
overflow: "hidden",
|
|
2261
|
+
width: layout.playScrimOuterDiameterPx
|
|
2262
|
+
},
|
|
2263
|
+
playPlaceholder: {
|
|
2264
|
+
height: layout.playScrimOuterDiameterPx,
|
|
2265
|
+
width: layout.playScrimOuterDiameterPx
|
|
2266
|
+
},
|
|
2267
|
+
fullscreenHudCircleScrim: {
|
|
2268
|
+
alignItems: "center",
|
|
2269
|
+
borderRadius: layout.floatingHudFullscreenScrimDiameterPx / 2,
|
|
2270
|
+
height: layout.floatingHudFullscreenScrimDiameterPx,
|
|
2271
|
+
justifyContent: "center",
|
|
2272
|
+
overflow: "hidden",
|
|
2273
|
+
width: layout.floatingHudFullscreenScrimDiameterPx
|
|
2274
|
+
},
|
|
2275
|
+
topFullscreenCorner: {
|
|
2276
|
+
alignItems: "center",
|
|
2277
|
+
columnGap: layout.floatingHudButtonGapPx,
|
|
2278
|
+
flexDirection: "row",
|
|
2279
|
+
pointerEvents: "box-none",
|
|
2280
|
+
position: "absolute",
|
|
2281
|
+
right: layout.hudEdgeInsetPx,
|
|
2282
|
+
top: layout.hudEdgeInsetPx,
|
|
2283
|
+
zIndex: 8
|
|
2284
|
+
}
|
|
2285
|
+
});
|
|
2286
|
+
}
|
|
2287
|
+
function ChromeScrimPad(props) {
|
|
2288
|
+
const padStyle = [props.chromeScrimBaseStyle, props.style];
|
|
2289
|
+
if (props.onPress != null) {
|
|
2290
|
+
return /* @__PURE__ */ jsx(
|
|
2291
|
+
Pressable,
|
|
2292
|
+
{
|
|
2293
|
+
accessibilityLabel: props.accessibilityLabel,
|
|
2294
|
+
accessibilityRole: props.accessibilityRole ?? "button",
|
|
2295
|
+
hitSlop: props.hitSlop,
|
|
2296
|
+
onPress: props.onPress,
|
|
2297
|
+
style: (state) => [
|
|
2298
|
+
props.chromeScrimBaseStyle,
|
|
2299
|
+
props.style,
|
|
2300
|
+
resolveChromeControlPressOpacityStyle(state.pressed)
|
|
2301
|
+
],
|
|
2302
|
+
children: props.children
|
|
2303
|
+
}
|
|
2304
|
+
);
|
|
2305
|
+
}
|
|
2306
|
+
return /* @__PURE__ */ jsx(View, { style: padStyle, children: props.children });
|
|
2307
|
+
}
|
|
2308
|
+
function MoviieSkinPictureInPictureCircleButton(props) {
|
|
2309
|
+
return /* @__PURE__ */ jsx(
|
|
2310
|
+
ChromeScrimPad,
|
|
2311
|
+
{
|
|
2312
|
+
accessibilityLabel: props.pictureInPictureActive ? "Fechar imagem no imagem" : "Imagem no imagem",
|
|
2313
|
+
chromeScrimBaseStyle: props.styles.chromeScrimBase,
|
|
2314
|
+
hitSlop: MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX,
|
|
2315
|
+
onPress: props.onPress,
|
|
2316
|
+
style: props.styles.fullscreenHudCircleScrim,
|
|
2317
|
+
children: /* @__PURE__ */ jsx(
|
|
2318
|
+
EmbedMediaIconPictureInPicture,
|
|
2319
|
+
{
|
|
2320
|
+
color: MOVIIE_SKIN_CHROME_FOREGROUND_HEX,
|
|
2321
|
+
size: props.layout.floatingHudFullscreenIconPx
|
|
2322
|
+
}
|
|
2323
|
+
)
|
|
2324
|
+
}
|
|
2325
|
+
);
|
|
2326
|
+
}
|
|
2327
|
+
function MoviieSkinPictureInPictureTopBareButton(props) {
|
|
2328
|
+
return /* @__PURE__ */ jsx(
|
|
2329
|
+
Pressable,
|
|
2330
|
+
{
|
|
2331
|
+
accessibilityLabel: props.pictureInPictureActive ? "Fechar imagem no imagem" : "Imagem no imagem",
|
|
2332
|
+
accessibilityRole: "button",
|
|
2333
|
+
hitSlop: MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX,
|
|
2334
|
+
onPress: props.onPress,
|
|
2335
|
+
style: (state) => resolveChromeControlPressOpacityStyle(state.pressed),
|
|
2336
|
+
children: /* @__PURE__ */ jsx(
|
|
2337
|
+
EmbedMediaIconPictureInPicture,
|
|
2338
|
+
{
|
|
2339
|
+
color: MOVIIE_SKIN_CHROME_FOREGROUND_HEX,
|
|
2340
|
+
size: props.layout.floatingHudFullscreenTopIconPx * MOVIIE_SKIN_TOP_ICON_PIP_VISUAL_SCALE
|
|
2341
|
+
}
|
|
2342
|
+
)
|
|
2343
|
+
}
|
|
2344
|
+
);
|
|
2345
|
+
}
|
|
2346
|
+
function MoviieSkinFullscreenCircleButton(props) {
|
|
2347
|
+
return /* @__PURE__ */ jsx(
|
|
2348
|
+
ChromeScrimPad,
|
|
2349
|
+
{
|
|
2350
|
+
accessibilityLabel: props.isFullscreen ? "Sair de ecr\xE3 inteiro" : "Ecr\xE3 inteiro",
|
|
2351
|
+
chromeScrimBaseStyle: props.styles.chromeScrimBase,
|
|
2352
|
+
hitSlop: MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX,
|
|
2353
|
+
onPress: props.onPress,
|
|
2354
|
+
style: props.styles.fullscreenHudCircleScrim,
|
|
2355
|
+
children: props.isFullscreen ? /* @__PURE__ */ jsx(
|
|
2356
|
+
EmbedMediaIconFullscreenExit,
|
|
2357
|
+
{
|
|
2358
|
+
color: MOVIIE_SKIN_CHROME_FOREGROUND_HEX,
|
|
2359
|
+
size: props.layout.floatingHudFullscreenIconPx
|
|
2360
|
+
}
|
|
2361
|
+
) : /* @__PURE__ */ jsx(
|
|
2362
|
+
EmbedMediaIconFullscreen,
|
|
2363
|
+
{
|
|
2364
|
+
color: MOVIIE_SKIN_CHROME_FOREGROUND_HEX,
|
|
2365
|
+
size: props.layout.floatingHudFullscreenIconPx
|
|
2366
|
+
}
|
|
2367
|
+
)
|
|
2368
|
+
}
|
|
2369
|
+
);
|
|
2370
|
+
}
|
|
2371
|
+
function MoviieSkinFullscreenTopBareButton(props) {
|
|
2372
|
+
const size = props.layout.floatingHudFullscreenTopIconPx * MOVIIE_SKIN_TOP_ICON_FULLSCREEN_VISUAL_SCALE;
|
|
2373
|
+
return /* @__PURE__ */ jsx(
|
|
2374
|
+
Pressable,
|
|
2375
|
+
{
|
|
2376
|
+
accessibilityLabel: props.isFullscreen ? "Sair de ecr\xE3 inteiro" : "Ecr\xE3 inteiro",
|
|
2377
|
+
accessibilityRole: "button",
|
|
2378
|
+
hitSlop: MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX,
|
|
2379
|
+
onPress: props.onPress,
|
|
2380
|
+
style: (state) => resolveChromeControlPressOpacityStyle(state.pressed),
|
|
2381
|
+
children: props.isFullscreen ? /* @__PURE__ */ jsx(EmbedMediaIconFullscreenExit, { color: MOVIIE_SKIN_CHROME_FOREGROUND_HEX, size }) : /* @__PURE__ */ jsx(EmbedMediaIconFullscreen, { color: MOVIIE_SKIN_CHROME_FOREGROUND_HEX, size })
|
|
2382
|
+
}
|
|
2383
|
+
);
|
|
2384
|
+
}
|
|
2385
|
+
function MoviieSkinBufferingIndicator() {
|
|
2386
|
+
const { isBuffering, layout } = useMoviieSkinChrome();
|
|
2387
|
+
const bufferingHudStyle = useMemo(
|
|
2388
|
+
() => ({
|
|
2389
|
+
alignItems: "center",
|
|
2390
|
+
height: layout.bufferingIndicatorSlotPx,
|
|
2391
|
+
justifyContent: "center",
|
|
2392
|
+
left: layout.hudEdgeInsetPx,
|
|
2393
|
+
position: "absolute",
|
|
2394
|
+
top: layout.hudEdgeInsetPx,
|
|
2395
|
+
width: layout.bufferingIndicatorSlotPx,
|
|
2396
|
+
zIndex: 16
|
|
2397
|
+
}),
|
|
2398
|
+
[layout]
|
|
2399
|
+
);
|
|
2400
|
+
if (!isBuffering) {
|
|
2401
|
+
return null;
|
|
2402
|
+
}
|
|
2403
|
+
return /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: bufferingHudStyle, children: /* @__PURE__ */ jsx(
|
|
2404
|
+
ActivityIndicator,
|
|
2405
|
+
{
|
|
2406
|
+
accessibilityLabel: "A carregar v\xEDdeo",
|
|
2407
|
+
color: MOVIIE_SKIN_CHROME_FOREGROUND_HEX,
|
|
2408
|
+
size: "small"
|
|
2409
|
+
}
|
|
2410
|
+
) });
|
|
2411
|
+
}
|
|
2412
|
+
function MoviieSkinVideoOverlay() {
|
|
2413
|
+
const {
|
|
2414
|
+
chromeOpacity,
|
|
2415
|
+
chromeVisible,
|
|
2416
|
+
bumpChromeInteraction,
|
|
2417
|
+
castConnected,
|
|
2418
|
+
castControlEnabled,
|
|
2419
|
+
dismissChrome,
|
|
2420
|
+
isCustomFullscreen,
|
|
2421
|
+
openCastPicker,
|
|
2422
|
+
pictureInPictureActive,
|
|
2423
|
+
pictureInPictureControlEnabled,
|
|
2424
|
+
toggleFullscreen,
|
|
2425
|
+
togglePictureInPicture,
|
|
2426
|
+
layout,
|
|
2427
|
+
playback,
|
|
2428
|
+
player,
|
|
2429
|
+
seekBack,
|
|
2430
|
+
seekForward,
|
|
2431
|
+
timelineScrubClockSeconds,
|
|
2432
|
+
togglePlay,
|
|
2433
|
+
ui
|
|
2434
|
+
} = useMoviieSkinChrome();
|
|
2435
|
+
const handlePictureInPicturePress = useCallback(() => {
|
|
2436
|
+
togglePictureInPicture();
|
|
2437
|
+
dismissChrome();
|
|
2438
|
+
}, [togglePictureInPicture, dismissChrome]);
|
|
2439
|
+
const handleCastPress = useCallback(() => {
|
|
2440
|
+
dismissChrome();
|
|
2441
|
+
setTimeout(() => openCastPicker(), 150);
|
|
2442
|
+
}, [openCastPicker, dismissChrome]);
|
|
2443
|
+
const styles6 = useMemo(() => createMoviieSkinOverlayStyles(layout), [layout]);
|
|
2444
|
+
const { controls } = playback;
|
|
2445
|
+
const fg = MOVIIE_SKIN_CHROME_FOREGROUND_HEX;
|
|
2446
|
+
const clockDisplaySeconds = timelineScrubClockSeconds ?? ui.currentTime;
|
|
2447
|
+
const playbackEndedForUi = useMemo(
|
|
2448
|
+
() => computeMoviiePlaybackEnded({
|
|
2449
|
+
playing: ui.playing,
|
|
2450
|
+
currentTime: clockDisplaySeconds,
|
|
2451
|
+
duration: ui.duration,
|
|
2452
|
+
isLive: player.isLive,
|
|
2453
|
+
loop: player.loop
|
|
2454
|
+
}),
|
|
2455
|
+
[ui.playing, clockDisplaySeconds, ui.duration, player.isLive, player.loop]
|
|
2456
|
+
);
|
|
2457
|
+
const { centerSeekBackwardEnabled, centerSeekForwardEnabled } = useMemo(() => {
|
|
2458
|
+
const alignSeekButtonsWithPlay = controls.showPlay && !player.isLive;
|
|
2459
|
+
const hideSeekClusterAtEnd = playbackEndedForUi;
|
|
2460
|
+
return {
|
|
2461
|
+
centerSeekBackwardEnabled: !hideSeekClusterAtEnd && (controls.seekBackwardEnabled || alignSeekButtonsWithPlay),
|
|
2462
|
+
centerSeekForwardEnabled: !hideSeekClusterAtEnd && (controls.seekForwardEnabled || alignSeekButtonsWithPlay)
|
|
2463
|
+
};
|
|
2464
|
+
}, [
|
|
2465
|
+
controls.seekBackwardEnabled,
|
|
2466
|
+
controls.seekForwardEnabled,
|
|
2467
|
+
controls.showPlay,
|
|
2468
|
+
player.isLive,
|
|
2469
|
+
playbackEndedForUi
|
|
2470
|
+
]);
|
|
2471
|
+
const centerPlayShowsReplay = playbackEndedForUi;
|
|
2472
|
+
const centerPlayAccessibilityLabel = ui.playing ? "Pausar" : centerPlayShowsReplay ? "Come\xE7ar novamente" : "Reproduzir";
|
|
2473
|
+
const clockLabel = controls.showCurrentTime || controls.showDuration ? formatPlaybackClock(clockDisplaySeconds, ui.duration) : null;
|
|
2474
|
+
const showSeekCluster = centerSeekBackwardEnabled || centerSeekForwardEnabled || controls.showPlay;
|
|
2475
|
+
const seekSlot = layout.seekScrimOuterDiameterPx;
|
|
2476
|
+
const showPictureInPictureTrailing = pictureInPictureControlEnabled;
|
|
2477
|
+
const showCastTrailing = castControlEnabled;
|
|
2478
|
+
const hasFloatingHudTrailing = playback.branding.showWatermark || !playback.branding.showWatermark && (controls.showFullscreen || showPictureInPictureTrailing || showCastTrailing);
|
|
2479
|
+
const showFloatingHud = clockLabel != null || hasFloatingHudTrailing;
|
|
2480
|
+
const showFullscreenBottomTrailing = controls.showFullscreen && !playback.branding.showWatermark;
|
|
2481
|
+
const showTopCornerChrome = playback.branding.showWatermark && (controls.showFullscreen || showPictureInPictureTrailing || showCastTrailing);
|
|
2482
|
+
return /* @__PURE__ */ jsxs(View, { pointerEvents: "box-none", style: StyleSheet.absoluteFillObject, children: [
|
|
2483
|
+
/* @__PURE__ */ jsx(
|
|
2484
|
+
Pressable,
|
|
2485
|
+
{
|
|
2486
|
+
accessibilityLabel: chromeVisible ? "\xC1rea do v\xEDdeo \u2014 toque para esconder os controles" : "Mostrar controles do v\xEDdeo",
|
|
2487
|
+
accessibilityRole: "button",
|
|
2488
|
+
onPress: chromeVisible ? dismissChrome : bumpChromeInteraction,
|
|
2489
|
+
style: [StyleSheet.absoluteFillObject, { zIndex: 0 }]
|
|
2490
|
+
}
|
|
2491
|
+
),
|
|
2492
|
+
/* @__PURE__ */ jsxs(
|
|
2493
|
+
AnimatedView,
|
|
2494
|
+
{
|
|
2495
|
+
pointerEvents: !chromeVisible ? "none" : "box-none",
|
|
2496
|
+
style: [
|
|
2497
|
+
StyleSheet.absoluteFillObject,
|
|
2498
|
+
{
|
|
2499
|
+
opacity: chromeOpacity,
|
|
2500
|
+
zIndex: 2
|
|
2501
|
+
}
|
|
2502
|
+
],
|
|
2503
|
+
children: [
|
|
2504
|
+
/* @__PURE__ */ jsx(MoviieSkinChromeEdgeGradients, { layout, showProgress: controls.showProgress }),
|
|
2505
|
+
showTopCornerChrome ? /* @__PURE__ */ jsxs(View, { pointerEvents: "box-none", style: styles6.topFullscreenCorner, children: [
|
|
2506
|
+
showCastTrailing ? /* @__PURE__ */ jsx(
|
|
2507
|
+
MoviieSkinCastTopBareButton,
|
|
2508
|
+
{
|
|
2509
|
+
castConnected,
|
|
2510
|
+
layout,
|
|
2511
|
+
onPress: handleCastPress
|
|
2512
|
+
}
|
|
2513
|
+
) : null,
|
|
2514
|
+
showPictureInPictureTrailing ? /* @__PURE__ */ jsx(
|
|
2515
|
+
MoviieSkinPictureInPictureTopBareButton,
|
|
2516
|
+
{
|
|
2517
|
+
layout,
|
|
2518
|
+
pictureInPictureActive,
|
|
2519
|
+
onPress: handlePictureInPicturePress
|
|
2520
|
+
}
|
|
2521
|
+
) : null,
|
|
2522
|
+
controls.showFullscreen ? /* @__PURE__ */ jsx(
|
|
2523
|
+
MoviieSkinFullscreenTopBareButton,
|
|
2524
|
+
{
|
|
2525
|
+
isFullscreen: isCustomFullscreen,
|
|
2526
|
+
layout,
|
|
2527
|
+
onPress: toggleFullscreen
|
|
2528
|
+
}
|
|
2529
|
+
) : null
|
|
2530
|
+
] }) : null,
|
|
2531
|
+
showFloatingHud ? /* @__PURE__ */ jsx(
|
|
2532
|
+
View,
|
|
2533
|
+
{
|
|
2534
|
+
pointerEvents: "box-none",
|
|
2535
|
+
style: [
|
|
2536
|
+
styles6.floatingHud,
|
|
2537
|
+
controls.showProgress ? { bottom: layout.timelineStackHeightChromeVisiblePx } : null
|
|
2538
|
+
],
|
|
2539
|
+
children: /* @__PURE__ */ jsxs(View, { style: styles6.floatingHudInner, children: [
|
|
2540
|
+
clockLabel ? /* @__PURE__ */ jsx(
|
|
2541
|
+
ChromeScrimPad,
|
|
2542
|
+
{
|
|
2543
|
+
chromeScrimBaseStyle: styles6.chromeScrimBase,
|
|
2544
|
+
style: styles6.clockScrim,
|
|
2545
|
+
children: /* @__PURE__ */ jsx(Text, { accessibilityLabel: `Tempo ${clockLabel}`, style: styles6.clockText, children: clockLabel })
|
|
2546
|
+
}
|
|
2547
|
+
) : /* @__PURE__ */ jsx(View, { style: styles6.floatingLeftSpacer }),
|
|
2548
|
+
/* @__PURE__ */ jsx(View, { style: styles6.floatingRight, children: playback.branding.showWatermark ? /* @__PURE__ */ jsx(MoviieEmbedBrandMark, {}) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2549
|
+
showCastTrailing ? /* @__PURE__ */ jsx(
|
|
2550
|
+
MoviieSkinCastCircleButton,
|
|
2551
|
+
{
|
|
2552
|
+
castConnected,
|
|
2553
|
+
chromeScrimBaseStyle: styles6.chromeScrimBase,
|
|
2554
|
+
circleScrimStyle: styles6.fullscreenHudCircleScrim,
|
|
2555
|
+
layout,
|
|
2556
|
+
onPress: handleCastPress
|
|
2557
|
+
}
|
|
2558
|
+
) : null,
|
|
2559
|
+
showPictureInPictureTrailing ? /* @__PURE__ */ jsx(
|
|
2560
|
+
MoviieSkinPictureInPictureCircleButton,
|
|
2561
|
+
{
|
|
2562
|
+
layout,
|
|
2563
|
+
pictureInPictureActive,
|
|
2564
|
+
onPress: handlePictureInPicturePress,
|
|
2565
|
+
styles: styles6
|
|
2566
|
+
}
|
|
2567
|
+
) : null,
|
|
2568
|
+
showFullscreenBottomTrailing ? /* @__PURE__ */ jsx(
|
|
2569
|
+
MoviieSkinFullscreenCircleButton,
|
|
2570
|
+
{
|
|
2571
|
+
isFullscreen: isCustomFullscreen,
|
|
2572
|
+
layout,
|
|
2573
|
+
onPress: toggleFullscreen,
|
|
2574
|
+
styles: styles6
|
|
2575
|
+
}
|
|
2576
|
+
) : null
|
|
2577
|
+
] }) })
|
|
2578
|
+
] })
|
|
2579
|
+
}
|
|
2580
|
+
) : null,
|
|
2581
|
+
showSeekCluster ? /* @__PURE__ */ jsx(View, { pointerEvents: "box-none", style: styles6.centerCluster, children: /* @__PURE__ */ jsxs(View, { style: styles6.centerClusterRow, children: [
|
|
2582
|
+
centerSeekBackwardEnabled ? /* @__PURE__ */ jsx(
|
|
2583
|
+
ChromeScrimPad,
|
|
2584
|
+
{
|
|
2585
|
+
accessibilityLabel: "Retroceder 10 segundos",
|
|
2586
|
+
chromeScrimBaseStyle: styles6.chromeScrimBase,
|
|
2587
|
+
onPress: seekBack,
|
|
2588
|
+
style: styles6.seekCircularScrim,
|
|
2589
|
+
children: /* @__PURE__ */ jsx(EmbedMediaIconSeekBackward10, { color: fg, size: layout.seekIconPx })
|
|
2590
|
+
}
|
|
2591
|
+
) : /* @__PURE__ */ jsx(View, { style: { height: seekSlot, width: seekSlot } }),
|
|
2592
|
+
controls.showPlay ? /* @__PURE__ */ jsx(
|
|
2593
|
+
ChromeScrimPad,
|
|
2594
|
+
{
|
|
2595
|
+
accessibilityLabel: centerPlayAccessibilityLabel,
|
|
2596
|
+
chromeScrimBaseStyle: styles6.chromeScrimBase,
|
|
2597
|
+
onPress: togglePlay,
|
|
2598
|
+
style: styles6.playScrim,
|
|
2599
|
+
children: ui.playing ? /* @__PURE__ */ jsx(EmbedMediaIconPause, { color: fg, size: layout.centerPlayIconPx }) : centerPlayShowsReplay ? /* @__PURE__ */ jsx(EmbedMediaIconReplay, { color: fg, size: layout.centerPlayIconPx }) : /* @__PURE__ */ jsx(EmbedMediaIconPlay, { color: fg, size: layout.centerPlayIconPx })
|
|
2600
|
+
}
|
|
2601
|
+
) : /* @__PURE__ */ jsx(View, { style: styles6.playPlaceholder }),
|
|
2602
|
+
centerSeekForwardEnabled ? /* @__PURE__ */ jsx(
|
|
2603
|
+
ChromeScrimPad,
|
|
2604
|
+
{
|
|
2605
|
+
accessibilityLabel: "Avan\xE7ar 10 segundos",
|
|
2606
|
+
chromeScrimBaseStyle: styles6.chromeScrimBase,
|
|
2607
|
+
onPress: seekForward,
|
|
2608
|
+
style: styles6.seekCircularScrim,
|
|
2609
|
+
children: /* @__PURE__ */ jsx(EmbedMediaIconSeekForward10, { color: fg, size: layout.seekIconPx })
|
|
2610
|
+
}
|
|
2611
|
+
) : /* @__PURE__ */ jsx(View, { style: { height: seekSlot, width: seekSlot } })
|
|
2612
|
+
] }) }) : null
|
|
2613
|
+
]
|
|
2614
|
+
}
|
|
2615
|
+
),
|
|
2616
|
+
/* @__PURE__ */ jsx(MoviieSkinBufferingIndicator, {}),
|
|
2617
|
+
/* @__PURE__ */ jsx(MoviieSkinSmartProgress, {}),
|
|
2618
|
+
/* @__PURE__ */ jsx(MoviieSkinBottomTimeline, {})
|
|
2619
|
+
] });
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2622
|
+
// src/lib/optional-status-bar.ts
|
|
2623
|
+
var cachedModule;
|
|
2624
|
+
function loadModule() {
|
|
2625
|
+
if (cachedModule !== void 0) {
|
|
2626
|
+
return cachedModule;
|
|
2627
|
+
}
|
|
2628
|
+
try {
|
|
2629
|
+
cachedModule = __require("expo-status-bar");
|
|
2630
|
+
} catch {
|
|
2631
|
+
cachedModule = null;
|
|
2632
|
+
warnOnce(
|
|
2633
|
+
"moviie:expo-status-bar-missing",
|
|
2634
|
+
"[@moviie/player-expo] `expo-status-bar` n\xE3o est\xE1 instalado. Status bar n\xE3o ser\xE1 ocultada em fullscreen JS. Instala com `pnpm add expo-status-bar` se quiser este comportamento."
|
|
2635
|
+
);
|
|
2636
|
+
}
|
|
2637
|
+
return cachedModule;
|
|
2638
|
+
}
|
|
2639
|
+
function moviieSetStatusBarHidden(hidden, animation = "fade") {
|
|
2640
|
+
const mod = loadModule();
|
|
2641
|
+
if (mod == null) return;
|
|
2642
|
+
try {
|
|
2643
|
+
mod.setStatusBarHidden(hidden, animation);
|
|
2644
|
+
} catch {
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
async function restoreOrientationLockPolicy(previousLock) {
|
|
2648
|
+
try {
|
|
2649
|
+
if (previousLock === void 0 || previousLock === OrientationLock.DEFAULT || previousLock === OrientationLock.UNKNOWN) {
|
|
2650
|
+
await unlockAsync();
|
|
2651
|
+
return;
|
|
2652
|
+
}
|
|
2653
|
+
await lockAsync(previousLock);
|
|
2654
|
+
} catch {
|
|
2655
|
+
try {
|
|
2656
|
+
await unlockAsync();
|
|
2657
|
+
} catch {
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
}
|
|
2661
|
+
function subscribeCustomFullscreenNativeOrientation(targetLock) {
|
|
2662
|
+
if (Platform.OS === "web") {
|
|
2663
|
+
return { finish: async () => {
|
|
2664
|
+
} };
|
|
2665
|
+
}
|
|
2666
|
+
let cancelled = false;
|
|
2667
|
+
let locked = false;
|
|
2668
|
+
let previousLock;
|
|
2669
|
+
const setup = (async () => {
|
|
2670
|
+
try {
|
|
2671
|
+
previousLock = await getOrientationLockAsync();
|
|
2672
|
+
if (cancelled) {
|
|
2673
|
+
return;
|
|
2674
|
+
}
|
|
2675
|
+
await lockAsync(targetLock);
|
|
2676
|
+
if (cancelled) {
|
|
2677
|
+
await restoreOrientationLockPolicy(previousLock);
|
|
2678
|
+
return;
|
|
2679
|
+
}
|
|
2680
|
+
locked = true;
|
|
2681
|
+
} catch {
|
|
2682
|
+
}
|
|
2683
|
+
})();
|
|
2684
|
+
let finishPromise = null;
|
|
2685
|
+
return {
|
|
2686
|
+
finish: () => {
|
|
2687
|
+
if (finishPromise != null) {
|
|
2688
|
+
return finishPromise;
|
|
2689
|
+
}
|
|
2690
|
+
cancelled = true;
|
|
2691
|
+
finishPromise = (async () => {
|
|
2692
|
+
await setup;
|
|
2693
|
+
if (locked) {
|
|
2694
|
+
locked = false;
|
|
2695
|
+
await restoreOrientationLockPolicy(previousLock);
|
|
2696
|
+
}
|
|
2697
|
+
})();
|
|
2698
|
+
return finishPromise;
|
|
2699
|
+
}
|
|
2700
|
+
};
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
// src/lib/resolve-orientation-lock-for-rotate-z-deg.ts
|
|
2704
|
+
function resolveOrientationLockValueForRotateZDeg(rotateZDeg) {
|
|
2705
|
+
const normalized = (rotateZDeg % 360 + 360) % 360;
|
|
2706
|
+
if (normalized === 90) {
|
|
2707
|
+
return MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE.LANDSCAPE_RIGHT;
|
|
2708
|
+
}
|
|
2709
|
+
if (normalized === 270) {
|
|
2710
|
+
return MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE.LANDSCAPE_LEFT;
|
|
2711
|
+
}
|
|
2712
|
+
return MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE.LANDSCAPE;
|
|
2713
|
+
}
|
|
2714
|
+
var CUSTOM_FULLSCREEN_TIMING = {
|
|
2715
|
+
duration: MOVIIE_SKIN_CUSTOM_FULLSCREEN_TRANSITION_MS
|
|
2716
|
+
};
|
|
2717
|
+
var CUSTOM_FULLSCREEN_USE_JS_STAGE_ROTATION = Platform.OS === "web";
|
|
2718
|
+
var MoviieSkinCustomFullscreenModalInner = forwardRef(function MoviieSkinCustomFullscreenModalInner2(props, ref) {
|
|
2719
|
+
const orientationFinishRef = useRef(null);
|
|
2720
|
+
const insets = useSafeAreaInsets();
|
|
2721
|
+
const { height: winH, width: winW } = useWindowDimensions();
|
|
2722
|
+
const { longSide, shortSide } = useMemo(
|
|
2723
|
+
() => computeCustomFullscreenStageDimensions({
|
|
2724
|
+
windowHeight: winH,
|
|
2725
|
+
safeInsets: insets,
|
|
2726
|
+
stageOverscanPx: MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_OVERSCAN_PX,
|
|
2727
|
+
windowWidth: winW
|
|
2728
|
+
}),
|
|
2729
|
+
[winW, winH, insets.bottom, insets.left, insets.right, insets.top]
|
|
2730
|
+
);
|
|
2731
|
+
const rotateZDeg = useSharedValue(0);
|
|
2732
|
+
const scale = useSharedValue(1);
|
|
2733
|
+
const emitExitComplete = useCallback(() => {
|
|
2734
|
+
props.onExitComplete();
|
|
2735
|
+
}, [props.onExitComplete]);
|
|
2736
|
+
const completeExitAfterNativeOrientationRestore = useCallback(() => {
|
|
2737
|
+
void (async () => {
|
|
2738
|
+
await orientationFinishRef.current?.();
|
|
2739
|
+
emitExitComplete();
|
|
2740
|
+
})();
|
|
2741
|
+
}, [emitExitComplete]);
|
|
2742
|
+
const animateExit = useCallback(() => {
|
|
2743
|
+
scale.value = withTiming(
|
|
2744
|
+
MOVIIE_SKIN_CUSTOM_FULLSCREEN_ENTER_SCALE_START,
|
|
2745
|
+
CUSTOM_FULLSCREEN_TIMING,
|
|
2746
|
+
(finishedScale) => {
|
|
2747
|
+
if (!CUSTOM_FULLSCREEN_USE_JS_STAGE_ROTATION && finishedScale) {
|
|
2748
|
+
runOnJS(completeExitAfterNativeOrientationRestore)();
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
);
|
|
2752
|
+
if (CUSTOM_FULLSCREEN_USE_JS_STAGE_ROTATION) {
|
|
2753
|
+
rotateZDeg.value = withTiming(0, CUSTOM_FULLSCREEN_TIMING, (finished) => {
|
|
2754
|
+
if (finished) {
|
|
2755
|
+
runOnJS(emitExitComplete)();
|
|
2756
|
+
}
|
|
2757
|
+
});
|
|
2758
|
+
return;
|
|
2759
|
+
}
|
|
2760
|
+
rotateZDeg.value = 0;
|
|
2761
|
+
}, [completeExitAfterNativeOrientationRestore, emitExitComplete, rotateZDeg, scale]);
|
|
2762
|
+
useImperativeHandle(ref, () => ({ animateExit }), [animateExit]);
|
|
2763
|
+
useEffect(() => {
|
|
2764
|
+
if (!props.visible) {
|
|
2765
|
+
return;
|
|
2766
|
+
}
|
|
2767
|
+
rotateZDeg.value = 0;
|
|
2768
|
+
scale.value = MOVIIE_SKIN_CUSTOM_FULLSCREEN_ENTER_SCALE_START;
|
|
2769
|
+
if (CUSTOM_FULLSCREEN_USE_JS_STAGE_ROTATION) {
|
|
2770
|
+
rotateZDeg.value = withTiming(
|
|
2771
|
+
MOVIIE_SKIN_CUSTOM_FULLSCREEN_ROTATE_Z_DEGREES,
|
|
2772
|
+
CUSTOM_FULLSCREEN_TIMING
|
|
2773
|
+
);
|
|
2774
|
+
}
|
|
2775
|
+
scale.value = withTiming(1, CUSTOM_FULLSCREEN_TIMING);
|
|
2776
|
+
}, [props.visible, rotateZDeg, scale]);
|
|
2777
|
+
useEffect(() => {
|
|
2778
|
+
if (!props.visible) {
|
|
2779
|
+
return;
|
|
2780
|
+
}
|
|
2781
|
+
moviieSetStatusBarHidden(true, "fade");
|
|
2782
|
+
return () => {
|
|
2783
|
+
moviieSetStatusBarHidden(false, "fade");
|
|
2784
|
+
};
|
|
2785
|
+
}, [props.visible]);
|
|
2786
|
+
useEffect(() => {
|
|
2787
|
+
if (!props.visible || CUSTOM_FULLSCREEN_USE_JS_STAGE_ROTATION) {
|
|
2788
|
+
orientationFinishRef.current = null;
|
|
2789
|
+
return;
|
|
2790
|
+
}
|
|
2791
|
+
const targetLock = resolveOrientationLockValueForRotateZDeg(
|
|
2792
|
+
MOVIIE_SKIN_CUSTOM_FULLSCREEN_ROTATE_Z_DEGREES
|
|
2793
|
+
);
|
|
2794
|
+
const sub = subscribeCustomFullscreenNativeOrientation(targetLock);
|
|
2795
|
+
orientationFinishRef.current = () => sub.finish();
|
|
2796
|
+
return () => {
|
|
2797
|
+
orientationFinishRef.current = null;
|
|
2798
|
+
void sub.finish();
|
|
2799
|
+
};
|
|
2800
|
+
}, [props.visible]);
|
|
2801
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
2802
|
+
if (CUSTOM_FULLSCREEN_USE_JS_STAGE_ROTATION) {
|
|
2803
|
+
return {
|
|
2804
|
+
transform: [{ rotateZ: `${rotateZDeg.value}deg` }, { scale: scale.value }]
|
|
2805
|
+
};
|
|
2806
|
+
}
|
|
2807
|
+
return {
|
|
2808
|
+
transform: [{ scale: scale.value }]
|
|
2809
|
+
};
|
|
2810
|
+
});
|
|
2811
|
+
const stageStaticStyle = useMemo(
|
|
2812
|
+
() => ({
|
|
2813
|
+
height: shortSide,
|
|
2814
|
+
width: longSide
|
|
2815
|
+
}),
|
|
2816
|
+
[longSide, shortSide]
|
|
2817
|
+
);
|
|
2818
|
+
return /* @__PURE__ */ jsx(
|
|
2819
|
+
View,
|
|
2820
|
+
{
|
|
2821
|
+
style: [styles2.root, { backgroundColor: MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_BACKGROUND_HEX }],
|
|
2822
|
+
children: /* @__PURE__ */ jsx(View, { style: styles2.centerSheet, children: /* @__PURE__ */ jsx(ReanimatedView, { style: [styles2.rotatingStage, stageStaticStyle, animatedStyle], children: props.children }) })
|
|
2823
|
+
}
|
|
2824
|
+
);
|
|
2825
|
+
});
|
|
2826
|
+
var MoviieSkinCustomFullscreenModal = forwardRef(function MoviieSkinCustomFullscreenModal2(props, ref) {
|
|
2827
|
+
return /* @__PURE__ */ jsx(
|
|
2828
|
+
Modal,
|
|
2829
|
+
{
|
|
2830
|
+
animationType: "none",
|
|
2831
|
+
hardwareAccelerated: Platform.OS === "android",
|
|
2832
|
+
onRequestClose: () => {
|
|
2833
|
+
if (ref != null && typeof ref !== "function") {
|
|
2834
|
+
ref.current?.animateExit();
|
|
2835
|
+
}
|
|
2836
|
+
},
|
|
2837
|
+
presentationStyle: "fullScreen",
|
|
2838
|
+
statusBarTranslucent: Platform.OS === "android",
|
|
2839
|
+
supportedOrientations: [
|
|
2840
|
+
"portrait",
|
|
2841
|
+
"portrait-upside-down",
|
|
2842
|
+
"landscape",
|
|
2843
|
+
"landscape-left",
|
|
2844
|
+
"landscape-right"
|
|
2845
|
+
],
|
|
2846
|
+
visible: props.visible,
|
|
2847
|
+
children: /* @__PURE__ */ jsx(SafeAreaProvider, { children: /* @__PURE__ */ jsx(MoviieSkinCustomFullscreenModalInner, { ref, ...props }) })
|
|
2848
|
+
}
|
|
2849
|
+
);
|
|
2850
|
+
});
|
|
2851
|
+
var styles2 = StyleSheet.create({
|
|
2852
|
+
root: {
|
|
2853
|
+
flex: 1
|
|
2854
|
+
},
|
|
2855
|
+
centerSheet: {
|
|
2856
|
+
alignItems: "center",
|
|
2857
|
+
flex: 1,
|
|
2858
|
+
justifyContent: "center",
|
|
2859
|
+
overflow: "visible"
|
|
2860
|
+
},
|
|
2861
|
+
rotatingStage: {
|
|
2862
|
+
position: "relative"
|
|
2863
|
+
}
|
|
2864
|
+
});
|
|
2865
|
+
var ERROR_NUMERIC_CODE = {
|
|
2866
|
+
auth: "E1001",
|
|
2867
|
+
not_found: "E1002",
|
|
2868
|
+
bundle_blocked: "E1003",
|
|
2869
|
+
referrer_blocked: "E1004",
|
|
2870
|
+
subscription_inactive: "E1005",
|
|
2871
|
+
network: "E2001",
|
|
2872
|
+
rate_limit: "E2002",
|
|
2873
|
+
unknown: "E9999"
|
|
2874
|
+
};
|
|
2875
|
+
function resolveErrorCode(error) {
|
|
2876
|
+
if (error instanceof MoviieAuthError) return "auth";
|
|
2877
|
+
if (error instanceof MoviieNotFoundError) return "not_found";
|
|
2878
|
+
if (error instanceof MoviieBundleBlockedError) return "bundle_blocked";
|
|
2879
|
+
if (error instanceof MoviieReferrerBlockedError) return "referrer_blocked";
|
|
2880
|
+
if (error instanceof MoviieSubscriptionInactiveError) return "subscription_inactive";
|
|
2881
|
+
if (error instanceof MoviieNetworkError) return "network";
|
|
2882
|
+
if (error instanceof MoviieRateLimitError) return "rate_limit";
|
|
2883
|
+
const code = error.code;
|
|
2884
|
+
if (typeof code === "string") {
|
|
2885
|
+
const known = [
|
|
2886
|
+
"auth",
|
|
2887
|
+
"not_found",
|
|
2888
|
+
"bundle_blocked",
|
|
2889
|
+
"referrer_blocked",
|
|
2890
|
+
"subscription_inactive",
|
|
2891
|
+
"network",
|
|
2892
|
+
"rate_limit"
|
|
2893
|
+
];
|
|
2894
|
+
if (known.includes(code)) {
|
|
2895
|
+
return code;
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
return "unknown";
|
|
2899
|
+
}
|
|
2900
|
+
function getErrorDisplay(error) {
|
|
2901
|
+
const code = resolveErrorCode(error);
|
|
2902
|
+
switch (code) {
|
|
2903
|
+
case "auth":
|
|
2904
|
+
return {
|
|
2905
|
+
code,
|
|
2906
|
+
numericCode: ERROR_NUMERIC_CODE[code],
|
|
2907
|
+
heading: "Configura\xE7\xE3o inv\xE1lida",
|
|
2908
|
+
description: "Verifique a chave public\xE1vel do SDK.",
|
|
2909
|
+
ctaLabel: "Acessar Moviie",
|
|
2910
|
+
ctaKind: "external",
|
|
2911
|
+
externalUrl: MOVIIE_DASHBOARD_URL
|
|
2912
|
+
};
|
|
2913
|
+
case "not_found":
|
|
2914
|
+
return {
|
|
2915
|
+
code,
|
|
2916
|
+
numericCode: ERROR_NUMERIC_CODE[code],
|
|
2917
|
+
heading: "Reprodu\xE7\xE3o indispon\xEDvel",
|
|
2918
|
+
description: "N\xE3o conseguimos encontrar este v\xEDdeo.",
|
|
2919
|
+
ctaLabel: "Acessar Moviie",
|
|
2920
|
+
ctaKind: "external",
|
|
2921
|
+
externalUrl: MOVIIE_DASHBOARD_URL
|
|
2922
|
+
};
|
|
2923
|
+
case "bundle_blocked":
|
|
2924
|
+
return {
|
|
2925
|
+
code,
|
|
2926
|
+
numericCode: ERROR_NUMERIC_CODE[code],
|
|
2927
|
+
heading: "Aplicativo n\xE3o autorizado",
|
|
2928
|
+
description: "Este aplicativo n\xE3o est\xE1 autorizado a reproduzir este v\xEDdeo.",
|
|
2929
|
+
ctaLabel: "Ajustar permiss\xF5es",
|
|
2930
|
+
ctaKind: "external",
|
|
2931
|
+
externalUrl: MOVIIE_DASHBOARD_URL
|
|
2932
|
+
};
|
|
2933
|
+
case "referrer_blocked":
|
|
2934
|
+
return {
|
|
2935
|
+
code,
|
|
2936
|
+
numericCode: ERROR_NUMERIC_CODE[code],
|
|
2937
|
+
heading: "Origem n\xE3o autorizada",
|
|
2938
|
+
description: "Origem n\xE3o autorizada para reprodu\xE7\xE3o.",
|
|
2939
|
+
ctaLabel: "Acessar Moviie",
|
|
2940
|
+
ctaKind: "external",
|
|
2941
|
+
externalUrl: MOVIIE_DASHBOARD_URL
|
|
2942
|
+
};
|
|
2943
|
+
case "subscription_inactive":
|
|
2944
|
+
return {
|
|
2945
|
+
code,
|
|
2946
|
+
numericCode: ERROR_NUMERIC_CODE[code],
|
|
2947
|
+
heading: "Reprodu\xE7\xE3o temporariamente indispon\xEDvel",
|
|
2948
|
+
description: "Acesse a Moviie para continuar assistindo.",
|
|
2949
|
+
ctaLabel: "Ir para a Moviie",
|
|
2950
|
+
ctaKind: "external",
|
|
2951
|
+
externalUrl: MOVIIE_DASHBOARD_URL
|
|
2952
|
+
};
|
|
2953
|
+
case "network":
|
|
2954
|
+
return {
|
|
2955
|
+
code,
|
|
2956
|
+
numericCode: ERROR_NUMERIC_CODE[code],
|
|
2957
|
+
heading: "Erro de conex\xE3o",
|
|
2958
|
+
description: "Verifique sua conex\xE3o e tente novamente.",
|
|
2959
|
+
ctaLabel: "Tentar de novo",
|
|
2960
|
+
ctaKind: "retry",
|
|
2961
|
+
externalUrl: null
|
|
2962
|
+
};
|
|
2963
|
+
case "rate_limit":
|
|
2964
|
+
return {
|
|
2965
|
+
code,
|
|
2966
|
+
numericCode: ERROR_NUMERIC_CODE[code],
|
|
2967
|
+
heading: "Muitas solicita\xE7\xF5es",
|
|
2968
|
+
description: "Aguarde alguns instantes e tente novamente.",
|
|
2969
|
+
ctaLabel: "Tentar de novo",
|
|
2970
|
+
ctaKind: "retry",
|
|
2971
|
+
externalUrl: null
|
|
2972
|
+
};
|
|
2973
|
+
case "unknown":
|
|
2974
|
+
default:
|
|
2975
|
+
return {
|
|
2976
|
+
code: "unknown",
|
|
2977
|
+
numericCode: ERROR_NUMERIC_CODE["unknown"],
|
|
2978
|
+
heading: "Erro tempor\xE1rio",
|
|
2979
|
+
description: "Tente novamente em instantes.",
|
|
2980
|
+
ctaLabel: "Tentar de novo",
|
|
2981
|
+
ctaKind: "retry",
|
|
2982
|
+
externalUrl: null
|
|
2983
|
+
};
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
function MoviiePlayerErrorShell({
|
|
2987
|
+
error,
|
|
2988
|
+
onRetry
|
|
2989
|
+
}) {
|
|
2990
|
+
const display = getErrorDisplay(error);
|
|
2991
|
+
const handlePress = useCallback(() => {
|
|
2992
|
+
if (display.ctaKind === "retry") {
|
|
2993
|
+
onRetry?.();
|
|
2994
|
+
return;
|
|
2995
|
+
}
|
|
2996
|
+
if (display.ctaKind === "external" && display.externalUrl) {
|
|
2997
|
+
void Linking.openURL(display.externalUrl).catch(() => {
|
|
2998
|
+
});
|
|
2999
|
+
}
|
|
3000
|
+
}, [display, onRetry]);
|
|
3001
|
+
const showCta = display.ctaLabel != null && display.ctaKind !== "none";
|
|
3002
|
+
return /* @__PURE__ */ jsxs(View, { style: styles3.root, accessibilityRole: "alert", children: [
|
|
3003
|
+
/* @__PURE__ */ jsx(View, { style: styles3.radialGlow }),
|
|
3004
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.errorCode, selectable: true, children: display.numericCode }),
|
|
3005
|
+
/* @__PURE__ */ jsxs(View, { style: styles3.content, children: [
|
|
3006
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.heading, numberOfLines: 2, children: display.heading }),
|
|
3007
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.description, numberOfLines: 4, children: display.description }),
|
|
3008
|
+
showCta ? /* @__PURE__ */ jsx(
|
|
3009
|
+
Pressable,
|
|
3010
|
+
{
|
|
3011
|
+
accessibilityRole: "button",
|
|
3012
|
+
accessibilityLabel: display.ctaLabel ?? void 0,
|
|
3013
|
+
onPress: handlePress,
|
|
3014
|
+
style: ({ pressed }) => [styles3.button, pressed ? styles3.buttonPressed : null],
|
|
3015
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.buttonLabel, children: display.ctaLabel })
|
|
3016
|
+
}
|
|
3017
|
+
) : null
|
|
3018
|
+
] })
|
|
3019
|
+
] });
|
|
3020
|
+
}
|
|
3021
|
+
var styles3 = StyleSheet.create({
|
|
3022
|
+
root: {
|
|
3023
|
+
...StyleSheet.absoluteFillObject,
|
|
3024
|
+
backgroundColor: MOVIIE_SHELL_BACKGROUND_HEX,
|
|
3025
|
+
overflow: "hidden",
|
|
3026
|
+
alignItems: "center",
|
|
3027
|
+
justifyContent: "center"
|
|
3028
|
+
},
|
|
3029
|
+
/** Simulates radial gradient: dark outer, lighter center. */
|
|
3030
|
+
radialGlow: {
|
|
3031
|
+
position: "absolute",
|
|
3032
|
+
width: "150%",
|
|
3033
|
+
aspectRatio: 1,
|
|
3034
|
+
borderRadius: 9999,
|
|
3035
|
+
backgroundColor: MOVIIE_SHELL_RADIAL_INNER_HEX
|
|
3036
|
+
},
|
|
3037
|
+
content: {
|
|
3038
|
+
...StyleSheet.absoluteFillObject,
|
|
3039
|
+
alignItems: "center",
|
|
3040
|
+
justifyContent: "center",
|
|
3041
|
+
paddingHorizontal: 24,
|
|
3042
|
+
gap: 10
|
|
3043
|
+
},
|
|
3044
|
+
heading: {
|
|
3045
|
+
color: MOVIIE_SHELL_HEADING_HEX,
|
|
3046
|
+
fontSize: MOVIIE_SHELL_HEADING_FONT_SIZE_PX,
|
|
3047
|
+
fontWeight: "600",
|
|
3048
|
+
textAlign: "center",
|
|
3049
|
+
maxWidth: MOVIIE_SHELL_CONTENT_MAX_WIDTH_PX
|
|
3050
|
+
},
|
|
3051
|
+
description: {
|
|
3052
|
+
color: MOVIIE_SHELL_DESCRIPTION_HEX,
|
|
3053
|
+
fontSize: MOVIIE_SHELL_DESCRIPTION_FONT_SIZE_PX,
|
|
3054
|
+
lineHeight: 20,
|
|
3055
|
+
textAlign: "center",
|
|
3056
|
+
maxWidth: MOVIIE_SHELL_CONTENT_MAX_WIDTH_PX
|
|
3057
|
+
},
|
|
3058
|
+
errorCode: {
|
|
3059
|
+
position: "absolute",
|
|
3060
|
+
bottom: 8,
|
|
3061
|
+
right: 10,
|
|
3062
|
+
color: MOVIIE_SHELL_ERROR_CODE_HEX,
|
|
3063
|
+
fontSize: 10,
|
|
3064
|
+
fontFamily: "Menlo",
|
|
3065
|
+
opacity: 0.45,
|
|
3066
|
+
zIndex: 2
|
|
3067
|
+
},
|
|
3068
|
+
button: {
|
|
3069
|
+
marginTop: 6,
|
|
3070
|
+
paddingVertical: MOVIIE_SHELL_BUTTON_PADDING_V_PX,
|
|
3071
|
+
paddingHorizontal: MOVIIE_SHELL_BUTTON_PADDING_H_PX,
|
|
3072
|
+
backgroundColor: MOVIIE_SHELL_BUTTON_BG_HEX,
|
|
3073
|
+
borderColor: MOVIIE_SHELL_BUTTON_BORDER_RGBA,
|
|
3074
|
+
borderWidth: StyleSheet.hairlineWidth * 2,
|
|
3075
|
+
borderRadius: MOVIIE_SHELL_BUTTON_RADIUS_PX
|
|
3076
|
+
},
|
|
3077
|
+
buttonPressed: {
|
|
3078
|
+
opacity: MOVIIE_SKIN_CHROME_CONTROL_PRESSED_OPACITY
|
|
3079
|
+
},
|
|
3080
|
+
buttonLabel: {
|
|
3081
|
+
color: MOVIIE_SHELL_BUTTON_LABEL_HEX,
|
|
3082
|
+
fontSize: MOVIIE_SHELL_BUTTON_LABEL_FONT_SIZE_PX,
|
|
3083
|
+
fontWeight: "600",
|
|
3084
|
+
textAlign: "center"
|
|
3085
|
+
}
|
|
3086
|
+
});
|
|
3087
|
+
function MoviiePlayerLoadingShell({
|
|
3088
|
+
posterUrl,
|
|
3089
|
+
primaryColor
|
|
3090
|
+
}) {
|
|
3091
|
+
const accent = resolveSkinAccentColor(primaryColor ?? null);
|
|
3092
|
+
return /* @__PURE__ */ jsxs(View, { style: styles4.root, accessibilityRole: "progressbar", accessibilityLabel: "Carregando v\xEDdeo", children: [
|
|
3093
|
+
/* @__PURE__ */ jsx(View, { style: styles4.radialGlow }),
|
|
3094
|
+
posterUrl ? /* @__PURE__ */ jsx(Image, { source: { uri: posterUrl }, style: styles4.poster, resizeMode: "cover" }) : null,
|
|
3095
|
+
/* @__PURE__ */ jsx(View, { style: styles4.center, children: /* @__PURE__ */ jsx(ActivityIndicator, { size: "large", color: accent }) })
|
|
3096
|
+
] });
|
|
3097
|
+
}
|
|
3098
|
+
var styles4 = StyleSheet.create({
|
|
3099
|
+
root: {
|
|
3100
|
+
...StyleSheet.absoluteFillObject,
|
|
3101
|
+
backgroundColor: MOVIIE_SHELL_BACKGROUND_HEX,
|
|
3102
|
+
overflow: "hidden",
|
|
3103
|
+
alignItems: "center",
|
|
3104
|
+
justifyContent: "center"
|
|
3105
|
+
},
|
|
3106
|
+
/** Simulates radial gradient: dark outer, lighter center. */
|
|
3107
|
+
radialGlow: {
|
|
3108
|
+
position: "absolute",
|
|
3109
|
+
width: "150%",
|
|
3110
|
+
aspectRatio: 1,
|
|
3111
|
+
borderRadius: 9999,
|
|
3112
|
+
backgroundColor: MOVIIE_SHELL_RADIAL_INNER_HEX
|
|
3113
|
+
},
|
|
3114
|
+
poster: {
|
|
3115
|
+
...StyleSheet.absoluteFillObject,
|
|
3116
|
+
opacity: 0.35
|
|
3117
|
+
},
|
|
3118
|
+
center: {
|
|
3119
|
+
...StyleSheet.absoluteFillObject,
|
|
3120
|
+
alignItems: "center",
|
|
3121
|
+
justifyContent: "center"
|
|
3122
|
+
}
|
|
3123
|
+
});
|
|
3124
|
+
function assignForwardedRef(forwarded, instance) {
|
|
3125
|
+
if (typeof forwarded === "function") {
|
|
3126
|
+
forwarded(instance);
|
|
3127
|
+
return;
|
|
3128
|
+
}
|
|
3129
|
+
if (forwarded) {
|
|
3130
|
+
forwarded.current = instance;
|
|
3131
|
+
}
|
|
3132
|
+
}
|
|
3133
|
+
var HostVideoView = VideoView;
|
|
3134
|
+
var CROSSFADE_TIMING = {
|
|
3135
|
+
duration: MOVIIE_SHELL_CROSSFADE_DURATION_MS,
|
|
3136
|
+
easing: Easing.out(Easing.quad)
|
|
3137
|
+
};
|
|
3138
|
+
var MoviieVideo = forwardRef(
|
|
3139
|
+
function MoviieVideo2(props, ref) {
|
|
3140
|
+
return /* @__PURE__ */ jsx(SafeAreaProvider, { children: /* @__PURE__ */ jsx(MoviieVideoImpl, { ref, ...props }) });
|
|
3141
|
+
}
|
|
3142
|
+
);
|
|
3143
|
+
var MoviieVideoImpl = forwardRef(
|
|
3144
|
+
function MoviieVideoImpl2(props, forwardedRef) {
|
|
3145
|
+
const {
|
|
3146
|
+
player,
|
|
3147
|
+
nativeControls,
|
|
3148
|
+
native = false,
|
|
3149
|
+
playback = null,
|
|
3150
|
+
controlsAutoHideMs,
|
|
3151
|
+
controlsVisibleByDefault,
|
|
3152
|
+
pictureInPicture,
|
|
3153
|
+
pictureInPictureAutoStart,
|
|
3154
|
+
allowsPictureInPicture: passthroughAllowsPictureInPicture,
|
|
3155
|
+
startsPictureInPictureAutomatically: passthroughStartsPictureInPictureAutomatically,
|
|
3156
|
+
requiresLinearPlayback: passthroughRequiresLinearPlayback,
|
|
3157
|
+
onPictureInPictureStart: userOnPictureInPictureStart,
|
|
3158
|
+
onPictureInPictureStop: userOnPictureInPictureStop,
|
|
3159
|
+
children,
|
|
3160
|
+
style,
|
|
3161
|
+
contentFit,
|
|
3162
|
+
error = null,
|
|
3163
|
+
isLoading = false,
|
|
3164
|
+
aspectRatio,
|
|
3165
|
+
onRetry,
|
|
3166
|
+
retry,
|
|
3167
|
+
castAdapter: castAdapterProp,
|
|
3168
|
+
cast,
|
|
3169
|
+
onTelemetryError,
|
|
3170
|
+
onTelemetryEvent,
|
|
3171
|
+
...videoRest
|
|
3172
|
+
} = props;
|
|
3173
|
+
const castAdapter = castAdapterProp ?? getRegisteredCastAdapter();
|
|
3174
|
+
const lastReportedErrorRef = useRef(null);
|
|
3175
|
+
useEffect(() => {
|
|
3176
|
+
if (error == null) {
|
|
3177
|
+
lastReportedErrorRef.current = null;
|
|
3178
|
+
return;
|
|
3179
|
+
}
|
|
3180
|
+
if (lastReportedErrorRef.current === error) {
|
|
3181
|
+
return;
|
|
3182
|
+
}
|
|
3183
|
+
lastReportedErrorRef.current = error;
|
|
3184
|
+
safeInvokeMoviieTelemetry(onTelemetryError, error, {
|
|
3185
|
+
phase: "playback_fetch"
|
|
3186
|
+
});
|
|
3187
|
+
}, [error, onTelemetryError]);
|
|
3188
|
+
const useMoviieChrome = !native;
|
|
3189
|
+
const shellState = playback != null ? "ready" : error != null ? "error" : "loading";
|
|
3190
|
+
const loadingOpacity = useSharedValue(shellState === "loading" ? 1 : 0);
|
|
3191
|
+
const errorOpacity = useSharedValue(shellState === "error" ? 1 : 0);
|
|
3192
|
+
const playerOpacity = useSharedValue(shellState === "ready" ? 1 : 0);
|
|
3193
|
+
useEffect(() => {
|
|
3194
|
+
loadingOpacity.value = withTiming(shellState === "loading" ? 1 : 0, CROSSFADE_TIMING);
|
|
3195
|
+
errorOpacity.value = withTiming(shellState === "error" ? 1 : 0, CROSSFADE_TIMING);
|
|
3196
|
+
playerOpacity.value = withTiming(shellState === "ready" ? 1 : 0, CROSSFADE_TIMING);
|
|
3197
|
+
}, [shellState, loadingOpacity, errorOpacity, playerOpacity]);
|
|
3198
|
+
const loadingAnimatedStyle = useAnimatedStyle(() => ({
|
|
3199
|
+
opacity: loadingOpacity.value
|
|
3200
|
+
}));
|
|
3201
|
+
const errorAnimatedStyle = useAnimatedStyle(() => ({
|
|
3202
|
+
opacity: errorOpacity.value
|
|
3203
|
+
}));
|
|
3204
|
+
const playerAnimatedStyle = useAnimatedStyle(() => ({
|
|
3205
|
+
opacity: playerOpacity.value
|
|
3206
|
+
}));
|
|
3207
|
+
const effectiveOnRetry = useMemo(() => {
|
|
3208
|
+
if (onRetry) return onRetry;
|
|
3209
|
+
if (retry) return retry;
|
|
3210
|
+
return void 0;
|
|
3211
|
+
}, [onRetry, retry]);
|
|
3212
|
+
const nativePresentationVideoProps = useMemo(() => {
|
|
3213
|
+
if (playback != null) {
|
|
3214
|
+
const embedBaseline = buildMoviieVideoPresentationProps({
|
|
3215
|
+
pictureInPicture,
|
|
3216
|
+
pictureInPictureAutoStart,
|
|
3217
|
+
profile: playback.profile,
|
|
3218
|
+
showPip: playback.controls.showPip
|
|
3219
|
+
});
|
|
3220
|
+
return {
|
|
3221
|
+
allowsPictureInPicture: passthroughAllowsPictureInPicture ?? embedBaseline.allowsPictureInPicture,
|
|
3222
|
+
startsPictureInPictureAutomatically: passthroughStartsPictureInPictureAutomatically ?? embedBaseline.startsPictureInPictureAutomatically,
|
|
3223
|
+
requiresLinearPlayback: passthroughRequiresLinearPlayback ?? embedBaseline.requiresLinearPlayback
|
|
3224
|
+
};
|
|
3225
|
+
}
|
|
3226
|
+
return {
|
|
3227
|
+
allowsPictureInPicture: passthroughAllowsPictureInPicture ?? false,
|
|
3228
|
+
startsPictureInPictureAutomatically: passthroughStartsPictureInPictureAutomatically ?? false,
|
|
3229
|
+
requiresLinearPlayback: passthroughRequiresLinearPlayback ?? false
|
|
3230
|
+
};
|
|
3231
|
+
}, [
|
|
3232
|
+
playback,
|
|
3233
|
+
pictureInPicture,
|
|
3234
|
+
pictureInPictureAutoStart,
|
|
3235
|
+
passthroughAllowsPictureInPicture,
|
|
3236
|
+
passthroughStartsPictureInPictureAutomatically,
|
|
3237
|
+
passthroughRequiresLinearPlayback
|
|
3238
|
+
]);
|
|
3239
|
+
const pipControlEnabled = useMemo(() => {
|
|
3240
|
+
if (!playback || !useMoviieChrome) {
|
|
3241
|
+
return false;
|
|
3242
|
+
}
|
|
3243
|
+
return isPictureInPictureSupported() && nativePresentationVideoProps.allowsPictureInPicture;
|
|
3244
|
+
}, [playback, useMoviieChrome, nativePresentationVideoProps.allowsPictureInPicture]);
|
|
3245
|
+
const innerRef = useRef(null);
|
|
3246
|
+
const fullscreenModalRef = useRef(null);
|
|
3247
|
+
const [customFullscreen, setCustomFullscreen] = useState(false);
|
|
3248
|
+
const [pipActive, setPipActive] = useState(false);
|
|
3249
|
+
const [castState, setCastState] = useState(
|
|
3250
|
+
() => castAdapter?.isAvailable() ? castAdapter.getState() : "unavailable"
|
|
3251
|
+
);
|
|
3252
|
+
const castDesired = useMemo(() => {
|
|
3253
|
+
if (!playback || !useMoviieChrome) return false;
|
|
3254
|
+
if (cast === false) return false;
|
|
3255
|
+
if (cast === true) return true;
|
|
3256
|
+
return playback.controls.chromecast === true;
|
|
3257
|
+
}, [cast, playback, useMoviieChrome]);
|
|
3258
|
+
const castControlEnabled = useMemo(() => {
|
|
3259
|
+
if (!castDesired) return false;
|
|
3260
|
+
return castAdapter?.isAvailable() === true;
|
|
3261
|
+
}, [castAdapter, castDesired]);
|
|
3262
|
+
const castConnected = castState === "connected";
|
|
3263
|
+
const openCastPicker = useCallback(() => {
|
|
3264
|
+
void castAdapter?.showDevicePicker().catch(() => {
|
|
3265
|
+
});
|
|
3266
|
+
}, [castAdapter]);
|
|
3267
|
+
useEffect(() => {
|
|
3268
|
+
if (!castAdapter?.isAvailable()) {
|
|
3269
|
+
setCastState("unavailable");
|
|
3270
|
+
return;
|
|
3271
|
+
}
|
|
3272
|
+
setCastState(castAdapter.getState());
|
|
3273
|
+
const unsubscribe = castAdapter.subscribe((next) => {
|
|
3274
|
+
setCastState(next);
|
|
3275
|
+
});
|
|
3276
|
+
return () => {
|
|
3277
|
+
unsubscribe();
|
|
3278
|
+
};
|
|
3279
|
+
}, [castAdapter]);
|
|
3280
|
+
useEffect(() => {
|
|
3281
|
+
if (castDesired && (!castAdapter || !castAdapter.isAvailable())) {
|
|
3282
|
+
warnOnce(
|
|
3283
|
+
"moviie-cast-missing-adapter",
|
|
3284
|
+
'[@moviie/player-expo] O embed habilita Chromecast mas a lib n\xE3o est\xE1 dispon\xEDvel. Instale `react-native-google-cast` e adicione `import "@moviie/player-expo/cast"` no seu _layout.tsx (ver docs/player-expo/cast). Para desligar explicitamente, passe `cast={false}` em <MoviieVideo />.'
|
|
3285
|
+
);
|
|
3286
|
+
}
|
|
3287
|
+
}, [castDesired, castAdapter]);
|
|
3288
|
+
useEffect(() => {
|
|
3289
|
+
if (!castAdapter?.isAvailable() || !playback || !player) return;
|
|
3290
|
+
if (castState !== "connected") return;
|
|
3291
|
+
const startSeconds = player.currentTime ?? 0;
|
|
3292
|
+
void castAdapter.loadMedia({
|
|
3293
|
+
uri: playback.playback.uri,
|
|
3294
|
+
title: playback.title,
|
|
3295
|
+
posterUrl: playback.posterUrl,
|
|
3296
|
+
durationSeconds: playback.durationSeconds ?? null,
|
|
3297
|
+
startSeconds
|
|
3298
|
+
}).then(() => {
|
|
3299
|
+
try {
|
|
3300
|
+
player.pause();
|
|
3301
|
+
} catch {
|
|
3302
|
+
}
|
|
3303
|
+
}).catch(() => {
|
|
3304
|
+
});
|
|
3305
|
+
}, [castAdapter, castState, playback, player]);
|
|
3306
|
+
const { width: winW, height: winH } = useWindowDimensions();
|
|
3307
|
+
const safeAreaInsets = useSafeAreaInsets();
|
|
3308
|
+
const fullscreenStageLayout = useMemo(
|
|
3309
|
+
() => computeCustomFullscreenStageDimensions({
|
|
3310
|
+
windowHeight: winH,
|
|
3311
|
+
safeInsets: safeAreaInsets,
|
|
3312
|
+
stageOverscanPx: MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_OVERSCAN_PX,
|
|
3313
|
+
windowWidth: winW
|
|
3314
|
+
}),
|
|
3315
|
+
[
|
|
3316
|
+
winW,
|
|
3317
|
+
winH,
|
|
3318
|
+
safeAreaInsets.bottom,
|
|
3319
|
+
safeAreaInsets.left,
|
|
3320
|
+
safeAreaInsets.right,
|
|
3321
|
+
safeAreaInsets.top
|
|
3322
|
+
]
|
|
3323
|
+
);
|
|
3324
|
+
useEffect(() => {
|
|
3325
|
+
setPipActive(false);
|
|
3326
|
+
}, [playback?.embedId]);
|
|
3327
|
+
const handleNativePictureInPictureStart = useCallback(() => {
|
|
3328
|
+
if (useMoviieChrome && playback != null) {
|
|
3329
|
+
setPipActive(true);
|
|
3330
|
+
}
|
|
3331
|
+
userOnPictureInPictureStart?.();
|
|
3332
|
+
}, [playback, useMoviieChrome, userOnPictureInPictureStart]);
|
|
3333
|
+
const handleNativePictureInPictureStop = useCallback(() => {
|
|
3334
|
+
if (useMoviieChrome && playback != null) {
|
|
3335
|
+
setPipActive(false);
|
|
3336
|
+
}
|
|
3337
|
+
userOnPictureInPictureStop?.();
|
|
3338
|
+
}, [playback, useMoviieChrome, userOnPictureInPictureStop]);
|
|
3339
|
+
const togglePictureInPicture = useCallback(async () => {
|
|
3340
|
+
const surface = innerRef.current;
|
|
3341
|
+
if (!surface?.startPictureInPicture) {
|
|
3342
|
+
return;
|
|
3343
|
+
}
|
|
3344
|
+
try {
|
|
3345
|
+
if (pipActive) {
|
|
3346
|
+
await surface.stopPictureInPicture?.();
|
|
3347
|
+
} else {
|
|
3348
|
+
await surface.startPictureInPicture();
|
|
3349
|
+
}
|
|
3350
|
+
} catch {
|
|
3351
|
+
}
|
|
3352
|
+
}, [pipActive]);
|
|
3353
|
+
const requestExitCustomFullscreenAnimated = useCallback(() => {
|
|
3354
|
+
fullscreenModalRef.current?.animateExit();
|
|
3355
|
+
}, []);
|
|
3356
|
+
const setRefs = useCallback(
|
|
3357
|
+
(node) => {
|
|
3358
|
+
innerRef.current = node;
|
|
3359
|
+
assignForwardedRef(forwardedRef, node);
|
|
3360
|
+
},
|
|
3361
|
+
[forwardedRef]
|
|
3362
|
+
);
|
|
3363
|
+
const resolvedNativeControlsDefault = native ? playback?.profile === MOVIIE_PLAYBACK_PROFILE.VSL ? false : true : false;
|
|
3364
|
+
const effectiveNativeControls = nativeControls ?? resolvedNativeControlsDefault;
|
|
3365
|
+
const intrinsicAspectRatio = playback?.videoWidthPx != null && playback?.videoHeightPx != null && playback.videoWidthPx > 0 && playback.videoHeightPx > 0 ? playback.videoWidthPx / playback.videoHeightPx : null;
|
|
3366
|
+
const effectiveAspectRatio = intrinsicAspectRatio ?? aspectRatio ?? MOVIIE_SHELL_DEFAULT_ASPECT_RATIO;
|
|
3367
|
+
const effectiveContentFit = contentFit ?? (playback != null ? playback.isVertical ? MOVIIE_VIDEO_DEFAULT_CONTENT_FIT.VERTICAL : MOVIIE_VIDEO_DEFAULT_CONTENT_FIT.HORIZONTAL : void 0);
|
|
3368
|
+
const { columnStyle, surfaceStyle } = partitionMoviieVideoHostStyle(StyleSheet.flatten(style));
|
|
3369
|
+
const stageContainerStyle = [
|
|
3370
|
+
styles5.videoStage,
|
|
3371
|
+
{
|
|
3372
|
+
width: "100%",
|
|
3373
|
+
aspectRatio: effectiveAspectRatio,
|
|
3374
|
+
alignSelf: "stretch",
|
|
3375
|
+
flex: 0
|
|
3376
|
+
},
|
|
3377
|
+
surfaceStyle,
|
|
3378
|
+
useMoviieChrome && playback ? styles5.videoStageClipNone : null
|
|
3379
|
+
];
|
|
3380
|
+
const inlineVideoAndOverlay = player != null ? useMoviieChrome && playback ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3381
|
+
createElement(HostVideoView, {
|
|
3382
|
+
...videoRest,
|
|
3383
|
+
...nativePresentationVideoProps,
|
|
3384
|
+
ref: setRefs,
|
|
3385
|
+
player,
|
|
3386
|
+
nativeControls: effectiveNativeControls,
|
|
3387
|
+
onPictureInPictureStart: handleNativePictureInPictureStart,
|
|
3388
|
+
onPictureInPictureStop: handleNativePictureInPictureStop,
|
|
3389
|
+
...effectiveContentFit != null ? { contentFit: effectiveContentFit } : {},
|
|
3390
|
+
style: styles5.videoFill
|
|
3391
|
+
}),
|
|
3392
|
+
/* @__PURE__ */ jsx(MoviieSkinVideoOverlay, {})
|
|
3393
|
+
] }) : createElement(HostVideoView, {
|
|
3394
|
+
...videoRest,
|
|
3395
|
+
...nativePresentationVideoProps,
|
|
3396
|
+
ref: setRefs,
|
|
3397
|
+
player,
|
|
3398
|
+
nativeControls: effectiveNativeControls,
|
|
3399
|
+
onPictureInPictureStart: handleNativePictureInPictureStart,
|
|
3400
|
+
onPictureInPictureStop: handleNativePictureInPictureStop,
|
|
3401
|
+
...effectiveContentFit != null ? { contentFit: effectiveContentFit } : {},
|
|
3402
|
+
style: styles5.videoFill
|
|
3403
|
+
}) : null;
|
|
3404
|
+
const renderInlineStage = (active) => {
|
|
3405
|
+
if (!playback || !useMoviieChrome) {
|
|
3406
|
+
return inlineVideoAndOverlay;
|
|
3407
|
+
}
|
|
3408
|
+
if (!customFullscreen) {
|
|
3409
|
+
return inlineVideoAndOverlay;
|
|
3410
|
+
}
|
|
3411
|
+
return /* @__PURE__ */ jsx(
|
|
3412
|
+
View,
|
|
3413
|
+
{
|
|
3414
|
+
style: [
|
|
3415
|
+
styles5.videoFill,
|
|
3416
|
+
{
|
|
3417
|
+
backgroundColor: MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_BACKGROUND_HEX
|
|
3418
|
+
}
|
|
3419
|
+
]
|
|
3420
|
+
}
|
|
3421
|
+
);
|
|
3422
|
+
};
|
|
3423
|
+
const stageContent = /* @__PURE__ */ jsxs(View, { style: stageContainerStyle, children: [
|
|
3424
|
+
/* @__PURE__ */ jsx(
|
|
3425
|
+
ReanimatedView,
|
|
3426
|
+
{
|
|
3427
|
+
style: [StyleSheet.absoluteFillObject, loadingAnimatedStyle, styles5.shellLayer],
|
|
3428
|
+
pointerEvents: shellState === "loading" ? "auto" : "none",
|
|
3429
|
+
children: shellState === "loading" || loadingOpacity.value > 0 ? /* @__PURE__ */ jsx(
|
|
3430
|
+
MoviiePlayerLoadingShell,
|
|
3431
|
+
{
|
|
3432
|
+
posterUrl: playback?.posterUrl ?? null,
|
|
3433
|
+
primaryColor: playback?.branding.primaryColor ?? null
|
|
3434
|
+
}
|
|
3435
|
+
) : null
|
|
3436
|
+
}
|
|
3437
|
+
),
|
|
3438
|
+
/* @__PURE__ */ jsx(
|
|
3439
|
+
ReanimatedView,
|
|
3440
|
+
{
|
|
3441
|
+
style: [StyleSheet.absoluteFillObject, errorAnimatedStyle, styles5.shellLayer],
|
|
3442
|
+
pointerEvents: shellState === "error" ? "auto" : "none",
|
|
3443
|
+
children: error ? /* @__PURE__ */ jsx(MoviiePlayerErrorShell, { error, onRetry: effectiveOnRetry }) : null
|
|
3444
|
+
}
|
|
3445
|
+
),
|
|
3446
|
+
/* @__PURE__ */ jsx(
|
|
3447
|
+
ReanimatedView,
|
|
3448
|
+
{
|
|
3449
|
+
style: [StyleSheet.absoluteFillObject, playerAnimatedStyle],
|
|
3450
|
+
pointerEvents: shellState === "ready" ? "auto" : "none",
|
|
3451
|
+
children: renderInlineStage()
|
|
3452
|
+
}
|
|
3453
|
+
)
|
|
3454
|
+
] });
|
|
3455
|
+
if (useMoviieChrome && playback && player) {
|
|
3456
|
+
return /* @__PURE__ */ jsx(
|
|
3457
|
+
MoviieSkinChromeProvider,
|
|
3458
|
+
{
|
|
3459
|
+
autoHideMs: controlsAutoHideMs,
|
|
3460
|
+
customFullscreen,
|
|
3461
|
+
pictureInPictureActive: pipActive,
|
|
3462
|
+
pictureInPictureControlEnabled: pipControlEnabled,
|
|
3463
|
+
togglePictureInPicture,
|
|
3464
|
+
castControlEnabled,
|
|
3465
|
+
castConnected,
|
|
3466
|
+
openCastPicker,
|
|
3467
|
+
onRequestEnterCustomFullscreen: () => setCustomFullscreen(true),
|
|
3468
|
+
onRequestExitCustomFullscreenAnimated: requestExitCustomFullscreenAnimated,
|
|
3469
|
+
playback,
|
|
3470
|
+
player,
|
|
3471
|
+
skinLayoutMetricsWidth: customFullscreen ? fullscreenStageLayout.layoutMetricsBasisWidth : void 0,
|
|
3472
|
+
videoViewRef: innerRef,
|
|
3473
|
+
visibleByDefault: controlsVisibleByDefault,
|
|
3474
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3475
|
+
/* @__PURE__ */ jsxs(View, { style: [styles5.column, columnStyle], children: [
|
|
3476
|
+
stageContent,
|
|
3477
|
+
children
|
|
3478
|
+
] }),
|
|
3479
|
+
/* @__PURE__ */ jsx(
|
|
3480
|
+
MoviieSkinCustomFullscreenModal,
|
|
3481
|
+
{
|
|
3482
|
+
ref: fullscreenModalRef,
|
|
3483
|
+
visible: customFullscreen,
|
|
3484
|
+
onExitComplete: () => setCustomFullscreen(false),
|
|
3485
|
+
children: /* @__PURE__ */ jsxs(View, { style: styles5.fullscreenStage, children: [
|
|
3486
|
+
createElement(HostVideoView, {
|
|
3487
|
+
...videoRest,
|
|
3488
|
+
...nativePresentationVideoProps,
|
|
3489
|
+
ref: setRefs,
|
|
3490
|
+
player,
|
|
3491
|
+
nativeControls: effectiveNativeControls,
|
|
3492
|
+
onPictureInPictureStart: handleNativePictureInPictureStart,
|
|
3493
|
+
onPictureInPictureStop: handleNativePictureInPictureStop,
|
|
3494
|
+
contentFit: MOVIIE_SKIN_CUSTOM_FULLSCREEN_VIDEO_CONTENT_FIT,
|
|
3495
|
+
style: StyleSheet.absoluteFillObject
|
|
3496
|
+
}),
|
|
3497
|
+
/* @__PURE__ */ jsx(MoviieSkinVideoOverlay, {})
|
|
3498
|
+
] })
|
|
3499
|
+
}
|
|
3500
|
+
)
|
|
3501
|
+
] })
|
|
3502
|
+
}
|
|
3503
|
+
);
|
|
3504
|
+
}
|
|
3505
|
+
return /* @__PURE__ */ jsxs(View, { style: [styles5.column, columnStyle], children: [
|
|
3506
|
+
stageContent,
|
|
3507
|
+
children,
|
|
3508
|
+
castAdapter?.renderAndroidProxy?.()
|
|
3509
|
+
] });
|
|
3510
|
+
}
|
|
3511
|
+
);
|
|
3512
|
+
var styles5 = StyleSheet.create({
|
|
3513
|
+
column: {
|
|
3514
|
+
alignSelf: "stretch",
|
|
3515
|
+
width: "100%"
|
|
3516
|
+
},
|
|
3517
|
+
videoStage: {
|
|
3518
|
+
overflow: "hidden",
|
|
3519
|
+
position: "relative",
|
|
3520
|
+
width: "100%"
|
|
3521
|
+
},
|
|
3522
|
+
videoStageClipNone: {
|
|
3523
|
+
overflow: "visible"
|
|
3524
|
+
},
|
|
3525
|
+
videoFill: {
|
|
3526
|
+
flex: 1,
|
|
3527
|
+
width: "100%",
|
|
3528
|
+
alignSelf: "stretch"
|
|
3529
|
+
},
|
|
3530
|
+
fullscreenStage: {
|
|
3531
|
+
flex: 1,
|
|
3532
|
+
position: "relative",
|
|
3533
|
+
width: "100%"
|
|
3534
|
+
},
|
|
3535
|
+
shellLayer: {
|
|
3536
|
+
zIndex: 1
|
|
3537
|
+
}
|
|
3538
|
+
});
|
|
3539
|
+
var MoviieErrorBoundary = class extends React.Component {
|
|
3540
|
+
state = { error: null };
|
|
3541
|
+
static getDerivedStateFromError(error) {
|
|
3542
|
+
return { error };
|
|
3543
|
+
}
|
|
3544
|
+
componentDidCatch(error, info) {
|
|
3545
|
+
if (this.props.onError != null) {
|
|
3546
|
+
try {
|
|
3547
|
+
this.props.onError(error, info);
|
|
3548
|
+
} catch {
|
|
3549
|
+
}
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
reset = () => {
|
|
3553
|
+
this.setState({ error: null });
|
|
3554
|
+
};
|
|
3555
|
+
render() {
|
|
3556
|
+
if (this.state.error != null) {
|
|
3557
|
+
if (this.props.fallback != null) {
|
|
3558
|
+
return this.props.fallback({
|
|
3559
|
+
error: this.state.error,
|
|
3560
|
+
reset: this.reset
|
|
3561
|
+
});
|
|
3562
|
+
}
|
|
3563
|
+
return null;
|
|
3564
|
+
}
|
|
3565
|
+
return this.props.children;
|
|
3566
|
+
}
|
|
3567
|
+
};
|
|
3568
|
+
|
|
3569
|
+
export { MoviieErrorBoundary, MoviieVideo, addMoviiePlaybackEndedListener, buildMoviieVideoPresentationProps, buildMoviieWatchEmbedUrl, computeMoviiePlaybackEnded, normalizeWatchOrigin, resolveMoviieWatchOrigin, useMoviieEvent, useMoviiePlayback, useMoviiePlaybackEnded, useMoviiePlayer };
|
|
3570
|
+
//# sourceMappingURL=index.mjs.map
|
|
3571
|
+
//# sourceMappingURL=index.mjs.map
|