@moviie/player-expo 0.27.0 → 0.28.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/dist/{chunk-TEDMUQGQ.mjs → chunk-7S3DXFVX.mjs} +3 -3
- package/dist/{chunk-TEDMUQGQ.mjs.map → chunk-7S3DXFVX.mjs.map} +1 -1
- package/dist/index.cjs +100 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.mjs +101 -15
- package/dist/index.mjs.map +1 -1
- package/dist/layout.cjs +1 -1
- package/dist/layout.cjs.map +1 -1
- package/dist/layout.mjs +1 -1
- package/package.json +4 -4
- package/src/components/controls/moviie-skin-chrome-context.tsx +13 -0
- package/src/components/moviie-skin-settings-overlay.tsx +56 -9
- package/src/components/moviie-video-props.ts +3 -0
- package/src/components/moviie-video.tsx +4 -0
- package/src/constants.ts +1 -1
- package/src/hooks/use-moviie-playback.ts +28 -2
- package/src/hooks/use-moviie-player-types.ts +4 -0
- package/src/hooks/use-moviie-player.ts +19 -7
- package/src/hooks/use-moviie-player.web.ts +14 -4
- package/src/lib/resolve-swap-action.ts +19 -3
|
@@ -5,7 +5,7 @@ import * as Application from 'expo-application';
|
|
|
5
5
|
import { jsx } from 'react/jsx-runtime';
|
|
6
6
|
|
|
7
7
|
// src/constants.ts
|
|
8
|
-
var MOVIIE_PLAYER_EXPO_PKG_VERSION = "0.
|
|
8
|
+
var MOVIIE_PLAYER_EXPO_PKG_VERSION = "0.28.0";
|
|
9
9
|
var MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
10
10
|
var MOVIIE_PLAYBACK_REFRESH_MAX_RETRIES = 3;
|
|
11
11
|
var MOVIIE_PLAYBACK_REFRESH_RETRY_BACKOFF_MS = 30 * 1e3;
|
|
@@ -287,5 +287,5 @@ function MoviieProvider({
|
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
export { EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV, EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV, EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN_ENV, MOVIIE_BRANDING_MARKETING_ORIGIN, MOVIIE_BRANDING_UTM_PARAM_CAMPAIGN, MOVIIE_BRANDING_UTM_PARAM_MEDIUM, MOVIIE_BRANDING_UTM_PARAM_SOURCE, MOVIIE_EMBED_BRAND_LETTERMARK_STROKE_WIDTH, MOVIIE_EMBED_BRAND_UTM, MOVIIE_EMBED_BRAND_VIEW_BOX, MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE, MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS, MOVIIE_PLAYBACK_REFRESH_MAX_ON_ERROR, MOVIIE_PLAYBACK_REFRESH_MAX_RETRIES, MOVIIE_PLAYBACK_REFRESH_MAX_TIMER_CHUNK_MS, MOVIIE_PLAYBACK_REFRESH_RETRY_BACKOFF_MS, MOVIIE_PLAYER_EXPO_EMBED_JS_MARKER_ATTR, MOVIIE_PLAYER_EXPO_PKG_VERSION, MOVIIE_REMEMBER_POSITION_DEBOUNCE_MS, MOVIIE_REMEMBER_POSITION_MIN_PERSIST_SECONDS, MOVIIE_REMEMBER_POSITION_STORAGE_PREFIX, MOVIIE_SKIN_BRAND_MARK_ARTBOARD_HEIGHT_PX, MOVIIE_SKIN_BRAND_MARK_ARTBOARD_WIDTH_PX, MOVIIE_SKIN_BRAND_MARK_TARGET_WIDTH_AT_REFERENCE_PT, MOVIIE_SKIN_BUFFERING_INDICATOR_SLOT_PX, MOVIIE_SKIN_BUFFER_UNDERRUN_LEAD_SECONDS, MOVIIE_SKIN_CENTER_CLUSTER_COLUMN_GAP_PX, MOVIIE_SKIN_CENTER_PLAY_ICON_PX, MOVIIE_SKIN_CENTER_PLAY_SCRIM_DIAMETER_AT_REFERENCE_PT, MOVIIE_SKIN_CENTER_SEEK_SCRIM_DIAMETER_AT_REFERENCE_PT, MOVIIE_SKIN_CHROME_CONTROL_PRESSED_OPACITY, MOVIIE_SKIN_CHROME_CONTROL_REST_OPACITY, MOVIIE_SKIN_CHROME_EDGE_GRADIENT_EDGE_SOLID_FADE_END_FRACTION, MOVIIE_SKIN_CHROME_EDGE_GRADIENT_HEIGHT_AT_REFERENCE_PT, MOVIIE_SKIN_CHROME_EDGE_GRADIENT_MIN_CLEAR_MIDDLE_PX, MOVIIE_SKIN_CHROME_FOREGROUND_HEX, MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX, MOVIIE_SKIN_CHROME_GRADIENT_EDGE_ALPHA, MOVIIE_SKIN_CHROME_SCRIM_BLACK_RGBA, MOVIIE_SKIN_CHROME_SVG_GRADIENT_BOTTOM_EDGE_ID, MOVIIE_SKIN_CHROME_SVG_GRADIENT_TOP_EDGE_ID, MOVIIE_SKIN_CLOCK_TEXT_FONT_SIZE_AT_REFERENCE_PT, MOVIIE_SKIN_CONTROLS_AUTO_HIDE_MS, MOVIIE_SKIN_CONTROLS_FADE_MS, MOVIIE_SKIN_CONTROL_ICON_PX, MOVIIE_SKIN_CUSTOM_FULLSCREEN_ENTER_SCALE_START, MOVIIE_SKIN_CUSTOM_FULLSCREEN_HUD_EDGE_BOOST_REFERENCE_PT, MOVIIE_SKIN_CUSTOM_FULLSCREEN_ROTATE_Z_DEGREES, MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_BACKGROUND_HEX, MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_OVERSCAN_PX, MOVIIE_SKIN_CUSTOM_FULLSCREEN_TRANSITION_MS, MOVIIE_SKIN_CUSTOM_FULLSCREEN_VIDEO_CONTENT_FIT, MOVIIE_SKIN_DEFAULT_ACCENT_HEX, MOVIIE_SKIN_FLOATING_FULLSCREEN_ICON_AT_REFERENCE_PT, MOVIIE_SKIN_FLOATING_FULLSCREEN_SCRIM_DIAMETER_AT_REFERENCE_PT, MOVIIE_SKIN_FLOATING_HUD_ABOVE_TIMELINE_GAP_AT_REFERENCE_PT, MOVIIE_SKIN_FLOATING_HUD_BUTTON_GAP_AT_REFERENCE_PT, MOVIIE_SKIN_FLOATING_HUD_CLOCK_CORNER_RADIUS_PX, MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX, MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX, MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT, MOVIIE_SKIN_LAYOUT_SCALE_MAX, MOVIIE_SKIN_LAYOUT_SCALE_MIN, MOVIIE_SKIN_SEEK_ICON_PX, MOVIIE_SKIN_SEEK_JUMP_SECONDS, MOVIIE_SKIN_TIMELINE_BAR_HEIGHT_PX, MOVIIE_SKIN_TIMELINE_BUFFER_LAYER_RGBA, MOVIIE_SKIN_TIMELINE_CHAPTER_SNAP_THRESHOLD_SECONDS, MOVIIE_SKIN_TIMELINE_END_SNAP_EPSILON_SECONDS, MOVIIE_SKIN_TIMELINE_RAIL_BACKGROUND_RGBA, MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_BOTTOM_DP, MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_HORIZONTAL_DP, MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_TOP_DP, MOVIIE_SKIN_TIMELINE_THUMB_BORDER_RGBA, MOVIIE_SKIN_TIMELINE_THUMB_DIAMETER_PX, MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER, MOVIIE_SKIN_TIMELINE_TOUCH_EXPANSION_VERTICAL_DP, MOVIIE_SKIN_TIMELINE_TOUCH_PADDING_VERTICAL_PX, MOVIIE_SKIN_VOLUME_LOW_ICON_THRESHOLD, MOVIIE_SMART_PROGRESS_BAR_HEIGHT_DP, MOVIIE_SMART_PROGRESS_CONFIG, MOVIIE_SMART_PROGRESS_FILL_TRANSITION_MS, MOVIIE_SMART_PROGRESS_Z_INDEX, MOVIIE_VIDEO_DEFAULT_CONTENT_FIT, MOVIIE_VIEWER_TOKEN_SECURE_STORE_KEY, MOVIIE_WATCH_EMBED_JS_PATH, MOVIIE_WATCH_ORIGIN_DEFAULT, MoviieProvider, SecureStoreViewerTokenStore, useMoviieContext, warnOnce };
|
|
290
|
-
//# sourceMappingURL=chunk-
|
|
291
|
-
//# sourceMappingURL=chunk-
|
|
290
|
+
//# sourceMappingURL=chunk-7S3DXFVX.mjs.map
|
|
291
|
+
//# sourceMappingURL=chunk-7S3DXFVX.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/apply-expo-moviie-endpoints.ts","../src/lib/warn-once.ts","../src/secure-store-viewer-token-store.ts","../src/platform/native-application-id.ts","../src/platform/platform-client-info.ts","../src/provider/moviie-provider.tsx"],"names":["MemoryViewerTokenStore"],"mappings":"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","file":"chunk-TEDMUQGQ.mjs","sourcesContent":["export const MOVIIE_PLAYER_EXPO_PKG_VERSION = '0.27.0' as const\n\nexport const MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS = 5 * 60 * 1000\n\n/**\n * Token-refresh retry budget. The scheduled refresh fires once, well before the\n * signed URI expires (`planRefresh` + the server's `refreshAfter` lead). If that\n * single attempt fails (transient network), re-arm a few times with a linear\n * backoff so a blip does not leave the session to die on a CDN 403 at expiry.\n */\nexport const MOVIIE_PLAYBACK_REFRESH_MAX_RETRIES = 3 as const\nexport const MOVIIE_PLAYBACK_REFRESH_RETRY_BACKOFF_MS = 30 * 1000\n\n/**\n * Longest a single refresh timer is allowed to wait before it re-evaluates the\n * schedule against the live wall clock. A signed token can sit 8h out, but RN\n * cannot be trusted to fire one multi-hour `setTimeout` on time (background\n * suspension, throttling, drift). Chunking re-anchors the plan periodically so\n * the refresh stays close to its intended instant even on long sessions.\n */\nexport const MOVIIE_PLAYBACK_REFRESH_MAX_TIMER_CHUNK_MS = 5 * 60 * 1000\n\n/**\n * Hard cap on automatic refetches triggered by a player `error` status per\n * video. The expiry-recovery path (a 403 from an expired token surfaces as a\n * player error) is the ground-truth backstop when the proactive timer misses\n * (clock skew, missed background wake). Bounded so a genuinely broken source\n * cannot loop forever; reset when the embed changes.\n */\nexport const MOVIIE_PLAYBACK_REFRESH_MAX_ON_ERROR = 3 as const\n\n/**\n * Smart Progress curve — mirrors {@link SMART_PROGRESS_CONFIG} on the web embed\n * (`apps/web/src/app/embed/[id]/constants.ts`).\n */\nexport const MOVIIE_SMART_PROGRESS_CONFIG = {\n R1: 0.18,\n P1: 0.62,\n R2: 0.8,\n P2: 0.95,\n P_MAX_BEFORE_END: 0.99,\n} as const\n\n/** Fill animation duration (ms); aligns with web `.moviie-smart-progress-fill` transition. */\nexport const MOVIIE_SMART_PROGRESS_FILL_TRANSITION_MS = 150 as const\n\n/** Absolute bottom bar height (dp) for native Smart Progress strip. */\nexport const MOVIIE_SMART_PROGRESS_BAR_HEIGHT_DP = 12 as const\n\nexport const MOVIIE_SMART_PROGRESS_Z_INDEX = 34 as const\n\n/**\n * SecureStore key prefix for resume position (`{prefix}{embedId}`).\n * Embed IDs are UUIDs from the API.\n */\nexport const MOVIIE_REMEMBER_POSITION_STORAGE_PREFIX = 'moviie.resume_position.' as const\n\n/** Debounce interval before persisting resume position while playing. */\nexport const MOVIIE_REMEMBER_POSITION_DEBOUNCE_MS = 5000 as const\n\n/**\n * Floor (seconds) below which a stop-time position is treated as a transient,\n * not a real checkpoint. Mirrors the `clampResumeTimeSeconds` floor: a paused\n * read this close to 0 — most often a mid-session source swap reloading the\n * item — must not overwrite or clear a good stored resume position.\n */\nexport const MOVIIE_REMEMBER_POSITION_MIN_PERSIST_SECONDS = 0.25 as const\n\n/** Matches embed/web framing defaults when `contentFit` is omitted on `MoviieVideo`. */\nexport const MOVIIE_VIDEO_DEFAULT_CONTENT_FIT = {\n VERTICAL: 'contain',\n HORIZONTAL: 'cover',\n} as const\n\nexport const MOVIIE_BRANDING_MARKETING_ORIGIN = 'https://moviie.ai' as const\n\n/** Origin público da página watch/embed (sem barra final). Override: `EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN`. */\nexport const MOVIIE_WATCH_ORIGIN_DEFAULT = 'https://watch.moviie.ai' as const\n\n/**\n * Variável `EXPO_PUBLIC_*` para override do origin watch/embed em Expo Web (`resolveMoviieWatchOrigin`).\n */\nexport const EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN_ENV = 'EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN' as const\n\n/** Path público do script da API JS do embed (relativo ao watch origin). */\nexport const MOVIIE_WATCH_EMBED_JS_PATH = '/embed.js' as const\n\n/**\n * Atributo único no `<script>` injectado em Expo Web para evitar duplicar `embed.js`\n * quando há vários `MoviieVideo` montados.\n */\nexport const MOVIIE_PLAYER_EXPO_EMBED_JS_MARKER_ATTR = 'data-moviie-player-expo-embed-js' as const\n\n/**\n * Variável `EXPO_PUBLIC_*` que override a base da API Moviie em **dev only**.\n * O Metro inlina qualquer `EXPO_PUBLIC_*` em build time, sem precisar de\n * `expo-constants`. Em produção o SDK usa sempre o default `https://api.moviie.ai/v1`.\n *\n * Exemplo `.env.local`:\n * EXPO_PUBLIC_MOVIIE_API_BASE_URL=http://localhost:3000/api/v1\n */\nexport const EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV = 'EXPO_PUBLIC_MOVIIE_API_BASE_URL' as const\n\n/**\n * Variável `EXPO_PUBLIC_*` que override a base de telemetria em **dev only**.\n * Caso omitida, deriva-se de `{origin}/telemetry/v1` a partir de `apiBaseUrl`.\n */\nexport const EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV = 'EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL' as const\n\nexport const MOVIIE_BRANDING_UTM_PARAM_SOURCE = 'utm_source' as const\nexport const MOVIIE_BRANDING_UTM_PARAM_MEDIUM = 'utm_medium' as const\nexport const MOVIIE_BRANDING_UTM_PARAM_CAMPAIGN = 'utm_campaign' as const\n\nexport const MOVIIE_BRANDING_UTM_SOURCE_VALUE = 'player-expo' as const\nexport const MOVIIE_BRANDING_UTM_MEDIUM_VALUE = 'branding' as const\n\n/** Espelha `PLAYER_EMBED_BRAND_UTM` do embed web (`apps/web/src/app/embed/[id]/constants.ts`). */\nexport const MOVIIE_EMBED_BRAND_UTM = {\n SOURCE: 'moviie_embed_player',\n MEDIUM: 'video_control_bar',\n CAMPAIGN: 'logo_click',\n} as const\n\n/**\n * Default skin accent — the canonical `--cream` token (dark) from\n * `@moviie/design-system`. INLINED (not imported): the published package's\n * `react-native` entry points at this source file, so Metro in a consumer app\n * resolves every import here — and the design-system package is private (not\n * on npm), which made the SDK uninstallable outside the monorepo. The value is\n * locked to the token by `tests/skin-accent-token.test.ts`.\n */\nexport const MOVIIE_SKIN_DEFAULT_ACCENT_HEX = '#ffffe1'\n\n/**\n * Valor legado para a prop `controlsAutoHideMs` / `autoHideMs`: o chrome da skin Moviie já não\n * usa temporizador para ocultar — só ao toque fora ou ações (play, seek).\n */\nexport const MOVIIE_SKIN_CONTROLS_AUTO_HIDE_MS = 3000 as const\n\nexport const MOVIIE_SKIN_CONTROLS_FADE_MS = 240 as const\n\nexport const MOVIIE_SKIN_WATERMARK_OPACITY = 0.7 as const\n\nexport const MOVIIE_SKIN_CONTROL_ICON_PX = 22 as const\n\n/**\n * Largura lógica de referência do layout da skin (ex.: frame Figma / iPhone ~390pt).\n * Dimensões em `MOVIIE_SKIN_*_AT_REFERENCE` / tokens da timeline escalam com `windowWidth`.\n */\nexport const MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT = 390 as const\n\n/** Limite inferior do factor de escala (telefones mais estreitos). */\nexport const MOVIIE_SKIN_LAYOUT_SCALE_MIN = 0.72 as const\n\n/**\n * Limite superior do factor de escala: não aumenta além do design de referência em ecrãs largos.\n */\nexport const MOVIIE_SKIN_LAYOUT_SCALE_MAX = 1 as const\n\n/**\n * Distância do HUD inferior (tempo, marca) às bordas laterais do vídeo e ao padding interno do relógio —\n * valor na largura de referência ({@link MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT}).\n */\nexport const MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX = 6 as const\n\n/**\n * Espaço entre a linha do relógio/marca e o topo da área da timeline — referência.\n * Separado de {@link MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX} para poder encostar ao footer sem afetar margens horizontais.\n * Valor 0 = máximo colado (útil para experimentar layout).\n */\nexport const MOVIIE_SKIN_FLOATING_HUD_ABOVE_TIMELINE_GAP_AT_REFERENCE_PT = 0 as const\n\n/** Hit slop do wordmark e do fullscreen substituto no HUD inferior — px (valor físico independente da escala do layout). */\nexport const MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX = 8 as const\n\n/**\n * Diâmetro da película circular dos botões do HUD inferior (fullscreen, PiP, cast) — referência.\n */\nexport const MOVIIE_SKIN_FLOATING_FULLSCREEN_SCRIM_DIAMETER_AT_REFERENCE_PT = 44 as const\n\n/**\n * Tamanho do ícone dentro dessa película — referência.\n */\nexport const MOVIIE_SKIN_FLOATING_FULLSCREEN_ICON_AT_REFERENCE_PT = 26 as const\n\n/**\n * Espaço entre botões da linha direita do HUD (cast, PiP, fullscreen) — referência.\n * Maior que {@link MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX} para evitar toques acidentais\n * em botões adjacentes.\n */\nexport const MOVIIE_SKIN_FLOATING_HUD_BUTTON_GAP_AT_REFERENCE_PT = 10 as const\n\n/** Raio dos cantos do indicador de tempo — valor na largura de referência. */\nexport const MOVIIE_SKIN_FLOATING_HUD_CLOCK_CORNER_RADIUS_PX = 6 as const\n\n/** Opacidade da película preta detrás dos botões de chrome (0–1). */\nexport const MOVIIE_SKIN_CHROME_SCRIM_BLACK_ALPHA = 0.5 as const\n\n/** Película preta por detrás dos elementos de chrome (timing, ícones). */\nexport const MOVIIE_SKIN_CHROME_SCRIM_BLACK_RGBA =\n `rgba(0,0,0,${MOVIIE_SKIN_CHROME_SCRIM_BLACK_ALPHA})` as const\n\n/** Opacidade dos controlos do chrome no estado normal (repouso). */\nexport const MOVIIE_SKIN_CHROME_CONTROL_REST_OPACITY = 1 as const\n\n/**\n * Opacidade dos controlos do chrome ao premir — feedback visual (seek, play, fullscreen).\n */\nexport const MOVIIE_SKIN_CHROME_CONTROL_PRESSED_OPACITY = 0.72 as const\n\n/** Preto nos stops do degradê vertical da skin (opacidade via `stopOpacity`). */\nexport const MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX = '#000000' as const\n\n/** Opacidade na borda “cheia” do degradê (outro extremo é totalmente transparente). */\nexport const MOVIIE_SKIN_CHROME_GRADIENT_EDGE_ALPHA = 0.62 as const\n\n/**\n * Altura da faixa reservada ao degradê nas bordas — referência (maior = mais “respiro” transparente).\n * O escuro concentra-se junto à borda via {@link MOVIIE_SKIN_CHROME_EDGE_GRADIENT_EDGE_SOLID_FADE_END_FRACTION}.\n * O inferior acrescenta a altura da timeline quando a barra de progresso está visível.\n */\nexport const MOVIIE_SKIN_CHROME_EDGE_GRADIENT_HEIGHT_AT_REFERENCE_PT = 104 as const\n\n/**\n * Ao longo da faixa, fração [0–1] medida a partir da borda escura até estar 100% transparente.\n * Ex.: 0.48 → ~48% da altura da faixa com degradê; o resto é totalmente transparente (valor intermédio entre faixa longa e lábio rente à borda).\n */\nexport const MOVIIE_SKIN_CHROME_EDGE_GRADIENT_EDGE_SOLID_FADE_END_FRACTION = 0.48 as const\n\n/**\n * Altura mínima transparente entre faixa superior e inferior após escalar somas —\n * evita sobreposição das duas faixas (“película” em todo o vídeo).\n */\nexport const MOVIIE_SKIN_CHROME_EDGE_GRADIENT_MIN_CLEAR_MIDDLE_PX = 56 as const\n\n/** IDs estáveis para `LinearGradient` em SVG (skin chrome). */\nexport const MOVIIE_SKIN_CHROME_SVG_GRADIENT_BOTTOM_EDGE_ID =\n 'moviie_skin_chrome_gradient_bottom_edge' as const\n\nexport const MOVIIE_SKIN_CHROME_SVG_GRADIENT_TOP_EDGE_ID =\n 'moviie_skin_chrome_gradient_top_edge' as const\n\n/** Volume normalizado (0–1) abaixo disto usa o ícone `volume-low` como no Vidstack. */\nexport const MOVIIE_SKIN_VOLUME_LOW_ICON_THRESHOLD = 0.45 as const\n\n/** Foreground dos ícones e texto da skin (branco sólido). */\nexport const MOVIIE_SKIN_CHROME_FOREGROUND_HEX = '#ffffff' as const\n\n/**\n * Espelha valores numéricos de `OrientationLock` do pacote `expo-screen-orientation` (SDK 52).\n * Mantidos aqui para funções puras e testes Vitest sem resolver o entry nativo do Expo.\n */\nexport const MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE = {\n LANDSCAPE: 5,\n LANDSCAPE_LEFT: 6,\n LANDSCAPE_RIGHT: 7,\n} as const\n\nexport type MoviieExpoOrientationLockValue =\n (typeof MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE)[keyof typeof MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE]\n\n/** Duração da transição (rotação + escala) do fullscreen JS na skin Moviie. */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_TRANSITION_MS = 420 as const\n\n/**\n * Rotação final em graus no eixo Z (sentido horário no React Native): vídeo + chrome giram juntos.\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_ROTATE_Z_DEGREES = 90 as const\n\n/** Escala inicial ao entrar em fullscreen (anima até 1). Saída anima de 1 até este valor. */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_ENTER_SCALE_START = 0.78 as const\n\n/**\n * `contentFit` no fullscreen rotacionado: preenche a altura útil do palco; barras laterais ficam a preto do palco.\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_VIDEO_CONTENT_FIT = 'contain' as const\n\n/** Fundo do palco em fullscreen JS e placeholder inline durante o modo expandido. */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_BACKGROUND_HEX = '#000000' as const\n\n/**\n * Margem extra (dp/pt) para dentro dos safe area insets no palco fullscreen rotacionado —\n * evita cortar chrome por cantos redondos / overshoot da animação.\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_OVERSCAN_PX = 12 as const\n\n/**\n * Reforço da margem do HUD/timeline em fullscreen rotacionado (escala com {@link MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT}).\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_HUD_EDGE_BOOST_REFERENCE_PT = 14 as const\n\n/** Margem de buffer (s) abaixo da cabeça de reprodução para detetar stalls em HLS. */\nexport const MOVIIE_SKIN_BUFFER_UNDERRUN_LEAD_SECONDS = 0.35 as const\n\nexport const MOVIIE_SKIN_SEEK_JUMP_SECONDS = 10 as const\n\nexport const MOVIIE_SKIN_CENTER_PLAY_ICON_PX = 40 as const\n\n/**\n * Diâmetro da película circular do play/pause central — referência.\n * Entre o círculo compacto (~52) e o layout antigo (~108 na referência).\n */\nexport const MOVIIE_SKIN_CENTER_PLAY_SCRIM_DIAMETER_AT_REFERENCE_PT = 80 as const\n\n/**\n * Diâmetro da película circular dos botões seek (±10 s) junto ao play — referência.\n * Compacto em torno do ícone ({@link MOVIIE_SKIN_SEEK_ICON_PX}); inferior ao play.\n */\nexport const MOVIIE_SKIN_CENTER_SEEK_SCRIM_DIAMETER_AT_REFERENCE_PT = 46 as const\n\n/** Ícone seek ±10 s no cluster central — referência (escala com layout). */\nexport const MOVIIE_SKIN_SEEK_ICON_PX = 28 as const\n\n/** Espaço horizontal entre botões do cluster central — valor na largura de referência. */\nexport const MOVIIE_SKIN_CENTER_CLUSTER_COLUMN_GAP_PX = 12 as const\n\n/** Tamanho do texto do relógio — valor na largura de referência. */\nexport const MOVIIE_SKIN_CLOCK_TEXT_FONT_SIZE_AT_REFERENCE_PT = 12 as const\n\n/** Altura da faixa única da timeline — valor na largura de referência. */\nexport const MOVIIE_SKIN_TIMELINE_BAR_HEIGHT_PX = 3 as const\n\n/** Diâmetro do thumb de scrub — valor na largura de referência. */\nexport const MOVIIE_SKIN_TIMELINE_THUMB_DIAMETER_PX = 14 as const\n\n/** Padding vertical acima da timeline — referência (0 = mínimo para testes de densidade). */\nexport const MOVIIE_SKIN_TIMELINE_TOUCH_PADDING_VERTICAL_PX = 0 as const\n\n/**\n * Padding vertical mínimo (dp lógico) por cima do rail dentro da área do vídeo — bem menor que antes:\n * o alvo tátil prioritário é {@link MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_BOTTOM_DP} por baixo do frame.\n */\nexport const MOVIIE_SKIN_TIMELINE_TOUCH_EXPANSION_VERTICAL_DP = 2 as const\n\n/**\n * Expansão lateral modesta (`View.hitSlop`) — evita faixa enorme dentro do vídeo.\n */\nexport const MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_HORIZONTAL_DP = 3 as const\n\n/**\n * Pouca expansão para cima: apenas cobrir metade superior do thumb / gestos desde logo acima do trilho.\n */\nexport const MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_TOP_DP = 2 as const\n\n/**\n * Expansão inferior dominante — cobre o thumb quando ultrapassa o limite inferior do vídeo\n * (`hitSlop` não ocupa layout dentro do frame; toques contam por baixo da overlay).\n */\nexport const MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_BOTTOM_DP = 14 as const\n\n/** Trilho base da timeline: branco ~30%. */\nexport const MOVIIE_SKIN_TIMELINE_RAIL_BACKGROUND_RGBA = 'rgba(255,255,255,0.3)' as const\n\n/** Camada de buffer sobre o trilho (mesma cor/opacidade que o trilho). */\nexport const MOVIIE_SKIN_TIMELINE_BUFFER_LAYER_RGBA = MOVIIE_SKIN_TIMELINE_RAIL_BACKGROUND_RGBA\n\n/** Contorno do thumb da timeline para contraste sobre vídeo claro. */\nexport const MOVIIE_SKIN_TIMELINE_THUMB_BORDER_RGBA = 'rgba(0,0,0,0.35)' as const\n\n/** Diâmetro do thumb durante scrub (drag) relativamente ao thumb em repouso. */\nexport const MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER = 1.65 as const\n\n/**\n * Segundos antes do fim onde o progresso mostrado fixa em 100% quando não está a reproduzir —\n * o `currentTime` do motor costuma ficar ligeiramente abaixo de `duration` no fim.\n */\nexport const MOVIIE_SKIN_TIMELINE_END_SNAP_EPSILON_SECONDS = 0.15 as const\n\n/**\n * Distância máxima (s) entre a posição de release do scrub e um boundary de capítulo\n * para que o snap automático seja ativado.\n */\nexport const MOVIIE_SKIN_TIMELINE_CHAPTER_SNAP_THRESHOLD_SECONDS = 2 as const\n\n/** Área do `ActivityIndicator` small no overlay de buffering — valor na largura de referência. */\nexport const MOVIIE_SKIN_BUFFERING_INDICATOR_SLOT_PX = 28 as const\n\n/** Largura intrínseca do SVG wordmark (viewBox). */\nexport const MOVIIE_SKIN_BRAND_MARK_ARTBOARD_WIDTH_PX = 173 as const\n\n/** Altura intrínseca do SVG wordmark (viewBox). */\nexport const MOVIIE_SKIN_BRAND_MARK_ARTBOARD_HEIGHT_PX = 46 as const\n\n/**\n * Largura visual alvo do wordmark quando `windowWidth` = {@link MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT}\n * (entre o tamanho compacto antigo e o artboard completo).\n */\nexport const MOVIIE_SKIN_BRAND_MARK_TARGET_WIDTH_AT_REFERENCE_PT = 68 as const\n\n/** ViewBox do SVG wordmark Moviie (173×46). */\nexport const MOVIIE_EMBED_BRAND_VIEW_BOX = '0 0 173 46' as const\n\n/** Espessura do traço das letras “ii” no wordmark (coordenadas do viewBox). */\nexport const MOVIIE_EMBED_BRAND_LETTERMARK_STROKE_WIDTH = 3 as const\n","/**\n * Configura endpoints da API Moviie a partir de **variáveis de ambiente**\n * `EXPO_PUBLIC_MOVIIE_API_BASE_URL` e (raro) `EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL`.\n *\n * **Override é apenas para desenvolvimento local.** Apps em produção usam o\n * default `https://api.moviie.ai/v1`. Por isso este módulo:\n *\n * - Só aplica o override quando `__DEV__ === true` (Metro/Hermes dev mode);\n * - Não depende de `expo-constants` — usa só `process.env.*` que o Metro inlina\n * em build time para qualquer var `EXPO_PUBLIC_*`;\n * - Falha silenciosamente em produção (var inexistente → default do SDK).\n *\n * Vars relevantes (definidas em `.env.local` no consumer):\n * EXPO_PUBLIC_MOVIIE_API_BASE_URL=http://localhost:3000/api/v1\n * EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL=http://localhost:3000/telemetry/v1\n */\nimport { configureMoviieEndpoints } from '@moviie/player-sdk'\n\nimport {\n EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV,\n EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV,\n} from './constants'\n\nfunction normalize(raw: string | undefined): string | undefined {\n if (typeof raw !== 'string') return undefined\n const trimmed = raw.trim()\n return trimmed.length > 0 ? trimmed.replace(/\\/+$/, '') : undefined\n}\n\n// `__DEV__` é definido pelo bundler RN. Em web build (Vite/Next) cai pra `process.env.NODE_ENV`.\nconst devMode =\n typeof __DEV__ !== 'undefined'\n ? __DEV__\n : typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n\nif (devMode) {\n const apiBaseUrl = normalize(process.env[EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV])\n const eventsBaseUrl = normalize(process.env[EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV])\n\n const opts: { apiBaseUrl?: string; eventsBaseUrl?: string } = {}\n if (apiBaseUrl != null) opts.apiBaseUrl = apiBaseUrl\n if (eventsBaseUrl != null) opts.eventsBaseUrl = eventsBaseUrl\n\n if (opts.apiBaseUrl != null || opts.eventsBaseUrl != null) {\n configureMoviieEndpoints(opts)\n }\n}\n","/**\n * Console warning idempotente por chave. Útil para dependências opcionais ausentes:\n * dispara uma única vez por sessão para a mesma chave, evitando ruído no console.\n *\n * Reusável para qualquer feature gated por dep opcional (cast, DRM custom,\n * analytics provider, etc.).\n */\n\nconst FIRED_KEYS = new Set<string>()\n\nexport function warnOnce(key: string, message: string): void {\n if (FIRED_KEYS.has(key)) {\n return\n }\n FIRED_KEYS.add(key)\n // eslint-disable-next-line no-console\n console.warn(message)\n}\n\n/** Limpa o set de chaves disparadas. Use apenas em testes. */\nexport function __resetWarnOnceForTests(): void {\n FIRED_KEYS.clear()\n}\n","import type { ViewerTokenStore } from '@moviie/player-sdk'\nimport { MemoryViewerTokenStore } from '@moviie/player-sdk'\n\nimport { warnOnce } from './lib/warn-once'\n\nexport const MOVIIE_VIEWER_TOKEN_SECURE_STORE_KEY = 'moviie_viewer_token_v1' as const\n\nconst SECURE_STORE_MISSING_WARNING =\n '[@moviie/player-expo] `expo-secure-store` não está instalado — viewer token será mantido apenas em memória (perde ao matar app). ' +\n 'Instala com `pnpm add expo-secure-store` se quiseres persistência entre sessões.'\n\ninterface StoredEnvelope {\n token: string\n expiresAt: number\n}\n\nfunction isStoredEnvelope(value: unknown): value is StoredEnvelope {\n if (!value || typeof value !== 'object') return false\n const v = value as Record<string, unknown>\n return typeof v.token === 'string' && typeof v.expiresAt === 'number'\n}\n\nexport class SecureStoreViewerTokenStore implements ViewerTokenStore {\n private readonly fallback: ViewerTokenStore\n private readonly storageKey: string\n\n constructor(options?: { fallback?: ViewerTokenStore; storageKey?: string }) {\n this.fallback = options?.fallback ?? new MemoryViewerTokenStore()\n this.storageKey = options?.storageKey ?? MOVIIE_VIEWER_TOKEN_SECURE_STORE_KEY\n }\n\n private async loadSecureStore(): Promise<typeof import('expo-secure-store') | null> {\n try {\n return await import('expo-secure-store')\n } catch {\n warnOnce('moviie:expo-secure-store-missing', SECURE_STORE_MISSING_WARNING)\n return null\n }\n }\n\n async get(): Promise<string | null> {\n const SecureStore = await this.loadSecureStore()\n if (!SecureStore) {\n return this.fallback.get()\n }\n try {\n const raw = await SecureStore.getItemAsync(this.storageKey)\n if (!raw) return null\n const parsed: unknown = JSON.parse(raw)\n if (!isStoredEnvelope(parsed)) {\n await SecureStore.deleteItemAsync(this.storageKey).catch(() => {})\n return null\n }\n if (parsed.expiresAt <= Date.now()) {\n await SecureStore.deleteItemAsync(this.storageKey).catch(() => {})\n return null\n }\n return parsed.token\n } catch {\n return this.fallback.get()\n }\n }\n\n async set(token: string, ttlSec: number): Promise<void> {\n const SecureStore = await this.loadSecureStore()\n const envelope: StoredEnvelope = {\n token,\n expiresAt: Date.now() + Math.max(0, ttlSec) * 1000,\n }\n if (!SecureStore) {\n await this.fallback.set(token, ttlSec)\n return\n }\n try {\n await SecureStore.setItemAsync(this.storageKey, JSON.stringify(envelope))\n } catch {\n await this.fallback.set(token, ttlSec)\n }\n }\n}\n","import * as Application from \"expo-application\"\n\nexport function readNativeApplicationId(): string | undefined {\n try {\n const id = Application.applicationId\n return id ?? undefined\n } catch {\n return undefined\n }\n}\n","import { Platform } from \"react-native\"\n\nimport type { MoviieClientInfo } from \"@moviie/player-sdk\"\n\nimport { readNativeApplicationId } from \"./native-application-id\"\n\nlet cached: MoviieClientInfo | null = null\n\nexport function buildPlatformClientInfo(sdkVersion: string): MoviieClientInfo {\n if (cached) {\n return cached\n }\n\n const os = Platform.OS\n const platform: MoviieClientInfo[\"platform\"] =\n os === \"ios\" ? \"ios\" : os === \"android\" ? \"android\" : \"web\"\n\n const bundleId =\n platform === \"web\" ? undefined : readNativeApplicationId()\n\n cached = {\n platform,\n bundleId,\n sdkVersion,\n }\n return cached\n}\n\nexport function resetPlatformClientInfoCache(): void {\n cached = null\n}\n","import {\n createContext,\n useContext,\n useMemo,\n type ReactNode,\n} from \"react\"\n\nimport {\n buildClientHeaders,\n MemoryViewerTokenStore,\n MoviieClient,\n type MoviieClientInfo,\n type ViewerTokenStore,\n} from \"@moviie/player-sdk\"\n\nimport { MOVIIE_PLAYER_EXPO_PKG_VERSION } from \"../constants\"\nimport { buildPlatformClientInfo } from \"../platform/platform-client-info\"\nimport { SecureStoreViewerTokenStore } from \"../secure-store-viewer-token-store\"\n\nexport interface MoviieContextValue {\n client: MoviieClient\n viewerTokenStore: ViewerTokenStore\n publishableKey: string | null\n clientInfo: MoviieClientInfo\n sdkVersion: string\n /** Headers reused by TelemetryClient (Bearer + X-Moviie-Client when aplicável) */\n telemetryHeaders: Record<string, string>\n}\n\nconst MoviieContext = createContext<MoviieContextValue | null>(null)\n\nlet fallbackContext: MoviieContextValue | null = null\n\nfunction getOrCreateFallbackContext(): MoviieContextValue {\n if (!fallbackContext) {\n const sdkVersion = MOVIIE_PLAYER_EXPO_PKG_VERSION\n const clientInfo = buildPlatformClientInfo(sdkVersion)\n const viewerTokenStore = new MemoryViewerTokenStore()\n const client = new MoviieClient({\n publishableKey: undefined,\n clientInfo,\n sdkVersion,\n })\n fallbackContext = {\n client,\n viewerTokenStore,\n publishableKey: null,\n clientInfo,\n sdkVersion,\n telemetryHeaders: buildClientHeaders({\n clientInfo,\n sdkVersion,\n }),\n }\n }\n return fallbackContext\n}\n\nexport function useMoviieContext(): MoviieContextValue {\n const ctx = useContext(MoviieContext)\n return ctx ?? getOrCreateFallbackContext()\n}\n\nexport function MoviieProvider({\n publishableKey,\n children,\n}: {\n publishableKey?: string | null\n children: ReactNode\n}) {\n const value = useMemo((): MoviieContextValue => {\n const sdkVersion = MOVIIE_PLAYER_EXPO_PKG_VERSION\n const clientInfo = buildPlatformClientInfo(sdkVersion)\n const trimmedKey = publishableKey?.trim()\n const viewerTokenStore = new SecureStoreViewerTokenStore()\n const client = new MoviieClient({\n publishableKey: trimmedKey || undefined,\n clientInfo,\n sdkVersion,\n })\n const telemetryHeaders = buildClientHeaders({\n publishableKey: trimmedKey || undefined,\n clientInfo,\n sdkVersion,\n })\n return {\n client,\n viewerTokenStore,\n publishableKey: trimmedKey ?? null,\n clientInfo,\n sdkVersion,\n telemetryHeaders,\n }\n }, [publishableKey])\n\n return (\n <MoviieContext.Provider value={value}>{children}</MoviieContext.Provider>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/apply-expo-moviie-endpoints.ts","../src/lib/warn-once.ts","../src/secure-store-viewer-token-store.ts","../src/platform/native-application-id.ts","../src/platform/platform-client-info.ts","../src/provider/moviie-provider.tsx"],"names":["MemoryViewerTokenStore"],"mappings":"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","file":"chunk-7S3DXFVX.mjs","sourcesContent":["export const MOVIIE_PLAYER_EXPO_PKG_VERSION = '0.28.0' as const\n\nexport const MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS = 5 * 60 * 1000\n\n/**\n * Token-refresh retry budget. The scheduled refresh fires once, well before the\n * signed URI expires (`planRefresh` + the server's `refreshAfter` lead). If that\n * single attempt fails (transient network), re-arm a few times with a linear\n * backoff so a blip does not leave the session to die on a CDN 403 at expiry.\n */\nexport const MOVIIE_PLAYBACK_REFRESH_MAX_RETRIES = 3 as const\nexport const MOVIIE_PLAYBACK_REFRESH_RETRY_BACKOFF_MS = 30 * 1000\n\n/**\n * Longest a single refresh timer is allowed to wait before it re-evaluates the\n * schedule against the live wall clock. A signed token can sit 8h out, but RN\n * cannot be trusted to fire one multi-hour `setTimeout` on time (background\n * suspension, throttling, drift). Chunking re-anchors the plan periodically so\n * the refresh stays close to its intended instant even on long sessions.\n */\nexport const MOVIIE_PLAYBACK_REFRESH_MAX_TIMER_CHUNK_MS = 5 * 60 * 1000\n\n/**\n * Hard cap on automatic refetches triggered by a player `error` status per\n * video. The expiry-recovery path (a 403 from an expired token surfaces as a\n * player error) is the ground-truth backstop when the proactive timer misses\n * (clock skew, missed background wake). Bounded so a genuinely broken source\n * cannot loop forever; reset when the embed changes.\n */\nexport const MOVIIE_PLAYBACK_REFRESH_MAX_ON_ERROR = 3 as const\n\n/**\n * Smart Progress curve — mirrors {@link SMART_PROGRESS_CONFIG} on the web embed\n * (`apps/web/src/app/embed/[id]/constants.ts`).\n */\nexport const MOVIIE_SMART_PROGRESS_CONFIG = {\n R1: 0.18,\n P1: 0.62,\n R2: 0.8,\n P2: 0.95,\n P_MAX_BEFORE_END: 0.99,\n} as const\n\n/** Fill animation duration (ms); aligns with web `.moviie-smart-progress-fill` transition. */\nexport const MOVIIE_SMART_PROGRESS_FILL_TRANSITION_MS = 150 as const\n\n/** Absolute bottom bar height (dp) for native Smart Progress strip. */\nexport const MOVIIE_SMART_PROGRESS_BAR_HEIGHT_DP = 12 as const\n\nexport const MOVIIE_SMART_PROGRESS_Z_INDEX = 34 as const\n\n/**\n * SecureStore key prefix for resume position (`{prefix}{embedId}`).\n * Embed IDs are UUIDs from the API.\n */\nexport const MOVIIE_REMEMBER_POSITION_STORAGE_PREFIX = 'moviie.resume_position.' as const\n\n/** Debounce interval before persisting resume position while playing. */\nexport const MOVIIE_REMEMBER_POSITION_DEBOUNCE_MS = 5000 as const\n\n/**\n * Floor (seconds) below which a stop-time position is treated as a transient,\n * not a real checkpoint. Mirrors the `clampResumeTimeSeconds` floor: a paused\n * read this close to 0 — most often a mid-session source swap reloading the\n * item — must not overwrite or clear a good stored resume position.\n */\nexport const MOVIIE_REMEMBER_POSITION_MIN_PERSIST_SECONDS = 0.25 as const\n\n/** Matches embed/web framing defaults when `contentFit` is omitted on `MoviieVideo`. */\nexport const MOVIIE_VIDEO_DEFAULT_CONTENT_FIT = {\n VERTICAL: 'contain',\n HORIZONTAL: 'cover',\n} as const\n\nexport const MOVIIE_BRANDING_MARKETING_ORIGIN = 'https://moviie.ai' as const\n\n/** Origin público da página watch/embed (sem barra final). Override: `EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN`. */\nexport const MOVIIE_WATCH_ORIGIN_DEFAULT = 'https://watch.moviie.ai' as const\n\n/**\n * Variável `EXPO_PUBLIC_*` para override do origin watch/embed em Expo Web (`resolveMoviieWatchOrigin`).\n */\nexport const EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN_ENV = 'EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN' as const\n\n/** Path público do script da API JS do embed (relativo ao watch origin). */\nexport const MOVIIE_WATCH_EMBED_JS_PATH = '/embed.js' as const\n\n/**\n * Atributo único no `<script>` injectado em Expo Web para evitar duplicar `embed.js`\n * quando há vários `MoviieVideo` montados.\n */\nexport const MOVIIE_PLAYER_EXPO_EMBED_JS_MARKER_ATTR = 'data-moviie-player-expo-embed-js' as const\n\n/**\n * Variável `EXPO_PUBLIC_*` que override a base da API Moviie em **dev only**.\n * O Metro inlina qualquer `EXPO_PUBLIC_*` em build time, sem precisar de\n * `expo-constants`. Em produção o SDK usa sempre o default `https://api.moviie.ai/v1`.\n *\n * Exemplo `.env.local`:\n * EXPO_PUBLIC_MOVIIE_API_BASE_URL=http://localhost:3000/api/v1\n */\nexport const EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV = 'EXPO_PUBLIC_MOVIIE_API_BASE_URL' as const\n\n/**\n * Variável `EXPO_PUBLIC_*` que override a base de telemetria em **dev only**.\n * Caso omitida, deriva-se de `{origin}/telemetry/v1` a partir de `apiBaseUrl`.\n */\nexport const EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV = 'EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL' as const\n\nexport const MOVIIE_BRANDING_UTM_PARAM_SOURCE = 'utm_source' as const\nexport const MOVIIE_BRANDING_UTM_PARAM_MEDIUM = 'utm_medium' as const\nexport const MOVIIE_BRANDING_UTM_PARAM_CAMPAIGN = 'utm_campaign' as const\n\nexport const MOVIIE_BRANDING_UTM_SOURCE_VALUE = 'player-expo' as const\nexport const MOVIIE_BRANDING_UTM_MEDIUM_VALUE = 'branding' as const\n\n/** Espelha `PLAYER_EMBED_BRAND_UTM` do embed web (`apps/web/src/app/embed/[id]/constants.ts`). */\nexport const MOVIIE_EMBED_BRAND_UTM = {\n SOURCE: 'moviie_embed_player',\n MEDIUM: 'video_control_bar',\n CAMPAIGN: 'logo_click',\n} as const\n\n/**\n * Default skin accent — the canonical `--cream` token (dark) from\n * `@moviie/design-system`. INLINED (not imported): the published package's\n * `react-native` entry points at this source file, so Metro in a consumer app\n * resolves every import here — and the design-system package is private (not\n * on npm), which made the SDK uninstallable outside the monorepo. The value is\n * locked to the token by `tests/skin-accent-token.test.ts`.\n */\nexport const MOVIIE_SKIN_DEFAULT_ACCENT_HEX = '#ffffe1'\n\n/**\n * Valor legado para a prop `controlsAutoHideMs` / `autoHideMs`: o chrome da skin Moviie já não\n * usa temporizador para ocultar — só ao toque fora ou ações (play, seek).\n */\nexport const MOVIIE_SKIN_CONTROLS_AUTO_HIDE_MS = 3000 as const\n\nexport const MOVIIE_SKIN_CONTROLS_FADE_MS = 240 as const\n\nexport const MOVIIE_SKIN_WATERMARK_OPACITY = 0.7 as const\n\nexport const MOVIIE_SKIN_CONTROL_ICON_PX = 22 as const\n\n/**\n * Largura lógica de referência do layout da skin (ex.: frame Figma / iPhone ~390pt).\n * Dimensões em `MOVIIE_SKIN_*_AT_REFERENCE` / tokens da timeline escalam com `windowWidth`.\n */\nexport const MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT = 390 as const\n\n/** Limite inferior do factor de escala (telefones mais estreitos). */\nexport const MOVIIE_SKIN_LAYOUT_SCALE_MIN = 0.72 as const\n\n/**\n * Limite superior do factor de escala: não aumenta além do design de referência em ecrãs largos.\n */\nexport const MOVIIE_SKIN_LAYOUT_SCALE_MAX = 1 as const\n\n/**\n * Distância do HUD inferior (tempo, marca) às bordas laterais do vídeo e ao padding interno do relógio —\n * valor na largura de referência ({@link MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT}).\n */\nexport const MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX = 6 as const\n\n/**\n * Espaço entre a linha do relógio/marca e o topo da área da timeline — referência.\n * Separado de {@link MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX} para poder encostar ao footer sem afetar margens horizontais.\n * Valor 0 = máximo colado (útil para experimentar layout).\n */\nexport const MOVIIE_SKIN_FLOATING_HUD_ABOVE_TIMELINE_GAP_AT_REFERENCE_PT = 0 as const\n\n/** Hit slop do wordmark e do fullscreen substituto no HUD inferior — px (valor físico independente da escala do layout). */\nexport const MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX = 8 as const\n\n/**\n * Diâmetro da película circular dos botões do HUD inferior (fullscreen, PiP, cast) — referência.\n */\nexport const MOVIIE_SKIN_FLOATING_FULLSCREEN_SCRIM_DIAMETER_AT_REFERENCE_PT = 44 as const\n\n/**\n * Tamanho do ícone dentro dessa película — referência.\n */\nexport const MOVIIE_SKIN_FLOATING_FULLSCREEN_ICON_AT_REFERENCE_PT = 26 as const\n\n/**\n * Espaço entre botões da linha direita do HUD (cast, PiP, fullscreen) — referência.\n * Maior que {@link MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX} para evitar toques acidentais\n * em botões adjacentes.\n */\nexport const MOVIIE_SKIN_FLOATING_HUD_BUTTON_GAP_AT_REFERENCE_PT = 10 as const\n\n/** Raio dos cantos do indicador de tempo — valor na largura de referência. */\nexport const MOVIIE_SKIN_FLOATING_HUD_CLOCK_CORNER_RADIUS_PX = 6 as const\n\n/** Opacidade da película preta detrás dos botões de chrome (0–1). */\nexport const MOVIIE_SKIN_CHROME_SCRIM_BLACK_ALPHA = 0.5 as const\n\n/** Película preta por detrás dos elementos de chrome (timing, ícones). */\nexport const MOVIIE_SKIN_CHROME_SCRIM_BLACK_RGBA =\n `rgba(0,0,0,${MOVIIE_SKIN_CHROME_SCRIM_BLACK_ALPHA})` as const\n\n/** Opacidade dos controlos do chrome no estado normal (repouso). */\nexport const MOVIIE_SKIN_CHROME_CONTROL_REST_OPACITY = 1 as const\n\n/**\n * Opacidade dos controlos do chrome ao premir — feedback visual (seek, play, fullscreen).\n */\nexport const MOVIIE_SKIN_CHROME_CONTROL_PRESSED_OPACITY = 0.72 as const\n\n/** Preto nos stops do degradê vertical da skin (opacidade via `stopOpacity`). */\nexport const MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX = '#000000' as const\n\n/** Opacidade na borda “cheia” do degradê (outro extremo é totalmente transparente). */\nexport const MOVIIE_SKIN_CHROME_GRADIENT_EDGE_ALPHA = 0.62 as const\n\n/**\n * Altura da faixa reservada ao degradê nas bordas — referência (maior = mais “respiro” transparente).\n * O escuro concentra-se junto à borda via {@link MOVIIE_SKIN_CHROME_EDGE_GRADIENT_EDGE_SOLID_FADE_END_FRACTION}.\n * O inferior acrescenta a altura da timeline quando a barra de progresso está visível.\n */\nexport const MOVIIE_SKIN_CHROME_EDGE_GRADIENT_HEIGHT_AT_REFERENCE_PT = 104 as const\n\n/**\n * Ao longo da faixa, fração [0–1] medida a partir da borda escura até estar 100% transparente.\n * Ex.: 0.48 → ~48% da altura da faixa com degradê; o resto é totalmente transparente (valor intermédio entre faixa longa e lábio rente à borda).\n */\nexport const MOVIIE_SKIN_CHROME_EDGE_GRADIENT_EDGE_SOLID_FADE_END_FRACTION = 0.48 as const\n\n/**\n * Altura mínima transparente entre faixa superior e inferior após escalar somas —\n * evita sobreposição das duas faixas (“película” em todo o vídeo).\n */\nexport const MOVIIE_SKIN_CHROME_EDGE_GRADIENT_MIN_CLEAR_MIDDLE_PX = 56 as const\n\n/** IDs estáveis para `LinearGradient` em SVG (skin chrome). */\nexport const MOVIIE_SKIN_CHROME_SVG_GRADIENT_BOTTOM_EDGE_ID =\n 'moviie_skin_chrome_gradient_bottom_edge' as const\n\nexport const MOVIIE_SKIN_CHROME_SVG_GRADIENT_TOP_EDGE_ID =\n 'moviie_skin_chrome_gradient_top_edge' as const\n\n/** Volume normalizado (0–1) abaixo disto usa o ícone `volume-low` como no Vidstack. */\nexport const MOVIIE_SKIN_VOLUME_LOW_ICON_THRESHOLD = 0.45 as const\n\n/** Foreground dos ícones e texto da skin (branco sólido). */\nexport const MOVIIE_SKIN_CHROME_FOREGROUND_HEX = '#ffffff' as const\n\n/**\n * Espelha valores numéricos de `OrientationLock` do pacote `expo-screen-orientation` (SDK 52).\n * Mantidos aqui para funções puras e testes Vitest sem resolver o entry nativo do Expo.\n */\nexport const MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE = {\n LANDSCAPE: 5,\n LANDSCAPE_LEFT: 6,\n LANDSCAPE_RIGHT: 7,\n} as const\n\nexport type MoviieExpoOrientationLockValue =\n (typeof MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE)[keyof typeof MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE]\n\n/** Duração da transição (rotação + escala) do fullscreen JS na skin Moviie. */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_TRANSITION_MS = 420 as const\n\n/**\n * Rotação final em graus no eixo Z (sentido horário no React Native): vídeo + chrome giram juntos.\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_ROTATE_Z_DEGREES = 90 as const\n\n/** Escala inicial ao entrar em fullscreen (anima até 1). Saída anima de 1 até este valor. */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_ENTER_SCALE_START = 0.78 as const\n\n/**\n * `contentFit` no fullscreen rotacionado: preenche a altura útil do palco; barras laterais ficam a preto do palco.\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_VIDEO_CONTENT_FIT = 'contain' as const\n\n/** Fundo do palco em fullscreen JS e placeholder inline durante o modo expandido. */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_BACKGROUND_HEX = '#000000' as const\n\n/**\n * Margem extra (dp/pt) para dentro dos safe area insets no palco fullscreen rotacionado —\n * evita cortar chrome por cantos redondos / overshoot da animação.\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_OVERSCAN_PX = 12 as const\n\n/**\n * Reforço da margem do HUD/timeline em fullscreen rotacionado (escala com {@link MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT}).\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_HUD_EDGE_BOOST_REFERENCE_PT = 14 as const\n\n/** Margem de buffer (s) abaixo da cabeça de reprodução para detetar stalls em HLS. */\nexport const MOVIIE_SKIN_BUFFER_UNDERRUN_LEAD_SECONDS = 0.35 as const\n\nexport const MOVIIE_SKIN_SEEK_JUMP_SECONDS = 10 as const\n\nexport const MOVIIE_SKIN_CENTER_PLAY_ICON_PX = 40 as const\n\n/**\n * Diâmetro da película circular do play/pause central — referência.\n * Entre o círculo compacto (~52) e o layout antigo (~108 na referência).\n */\nexport const MOVIIE_SKIN_CENTER_PLAY_SCRIM_DIAMETER_AT_REFERENCE_PT = 80 as const\n\n/**\n * Diâmetro da película circular dos botões seek (±10 s) junto ao play — referência.\n * Compacto em torno do ícone ({@link MOVIIE_SKIN_SEEK_ICON_PX}); inferior ao play.\n */\nexport const MOVIIE_SKIN_CENTER_SEEK_SCRIM_DIAMETER_AT_REFERENCE_PT = 46 as const\n\n/** Ícone seek ±10 s no cluster central — referência (escala com layout). */\nexport const MOVIIE_SKIN_SEEK_ICON_PX = 28 as const\n\n/** Espaço horizontal entre botões do cluster central — valor na largura de referência. */\nexport const MOVIIE_SKIN_CENTER_CLUSTER_COLUMN_GAP_PX = 12 as const\n\n/** Tamanho do texto do relógio — valor na largura de referência. */\nexport const MOVIIE_SKIN_CLOCK_TEXT_FONT_SIZE_AT_REFERENCE_PT = 12 as const\n\n/** Altura da faixa única da timeline — valor na largura de referência. */\nexport const MOVIIE_SKIN_TIMELINE_BAR_HEIGHT_PX = 3 as const\n\n/** Diâmetro do thumb de scrub — valor na largura de referência. */\nexport const MOVIIE_SKIN_TIMELINE_THUMB_DIAMETER_PX = 14 as const\n\n/** Padding vertical acima da timeline — referência (0 = mínimo para testes de densidade). */\nexport const MOVIIE_SKIN_TIMELINE_TOUCH_PADDING_VERTICAL_PX = 0 as const\n\n/**\n * Padding vertical mínimo (dp lógico) por cima do rail dentro da área do vídeo — bem menor que antes:\n * o alvo tátil prioritário é {@link MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_BOTTOM_DP} por baixo do frame.\n */\nexport const MOVIIE_SKIN_TIMELINE_TOUCH_EXPANSION_VERTICAL_DP = 2 as const\n\n/**\n * Expansão lateral modesta (`View.hitSlop`) — evita faixa enorme dentro do vídeo.\n */\nexport const MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_HORIZONTAL_DP = 3 as const\n\n/**\n * Pouca expansão para cima: apenas cobrir metade superior do thumb / gestos desde logo acima do trilho.\n */\nexport const MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_TOP_DP = 2 as const\n\n/**\n * Expansão inferior dominante — cobre o thumb quando ultrapassa o limite inferior do vídeo\n * (`hitSlop` não ocupa layout dentro do frame; toques contam por baixo da overlay).\n */\nexport const MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_BOTTOM_DP = 14 as const\n\n/** Trilho base da timeline: branco ~30%. */\nexport const MOVIIE_SKIN_TIMELINE_RAIL_BACKGROUND_RGBA = 'rgba(255,255,255,0.3)' as const\n\n/** Camada de buffer sobre o trilho (mesma cor/opacidade que o trilho). */\nexport const MOVIIE_SKIN_TIMELINE_BUFFER_LAYER_RGBA = MOVIIE_SKIN_TIMELINE_RAIL_BACKGROUND_RGBA\n\n/** Contorno do thumb da timeline para contraste sobre vídeo claro. */\nexport const MOVIIE_SKIN_TIMELINE_THUMB_BORDER_RGBA = 'rgba(0,0,0,0.35)' as const\n\n/** Diâmetro do thumb durante scrub (drag) relativamente ao thumb em repouso. */\nexport const MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER = 1.65 as const\n\n/**\n * Segundos antes do fim onde o progresso mostrado fixa em 100% quando não está a reproduzir —\n * o `currentTime` do motor costuma ficar ligeiramente abaixo de `duration` no fim.\n */\nexport const MOVIIE_SKIN_TIMELINE_END_SNAP_EPSILON_SECONDS = 0.15 as const\n\n/**\n * Distância máxima (s) entre a posição de release do scrub e um boundary de capítulo\n * para que o snap automático seja ativado.\n */\nexport const MOVIIE_SKIN_TIMELINE_CHAPTER_SNAP_THRESHOLD_SECONDS = 2 as const\n\n/** Área do `ActivityIndicator` small no overlay de buffering — valor na largura de referência. */\nexport const MOVIIE_SKIN_BUFFERING_INDICATOR_SLOT_PX = 28 as const\n\n/** Largura intrínseca do SVG wordmark (viewBox). */\nexport const MOVIIE_SKIN_BRAND_MARK_ARTBOARD_WIDTH_PX = 173 as const\n\n/** Altura intrínseca do SVG wordmark (viewBox). */\nexport const MOVIIE_SKIN_BRAND_MARK_ARTBOARD_HEIGHT_PX = 46 as const\n\n/**\n * Largura visual alvo do wordmark quando `windowWidth` = {@link MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT}\n * (entre o tamanho compacto antigo e o artboard completo).\n */\nexport const MOVIIE_SKIN_BRAND_MARK_TARGET_WIDTH_AT_REFERENCE_PT = 68 as const\n\n/** ViewBox do SVG wordmark Moviie (173×46). */\nexport const MOVIIE_EMBED_BRAND_VIEW_BOX = '0 0 173 46' as const\n\n/** Espessura do traço das letras “ii” no wordmark (coordenadas do viewBox). */\nexport const MOVIIE_EMBED_BRAND_LETTERMARK_STROKE_WIDTH = 3 as const\n","/**\n * Configura endpoints da API Moviie a partir de **variáveis de ambiente**\n * `EXPO_PUBLIC_MOVIIE_API_BASE_URL` e (raro) `EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL`.\n *\n * **Override é apenas para desenvolvimento local.** Apps em produção usam o\n * default `https://api.moviie.ai/v1`. Por isso este módulo:\n *\n * - Só aplica o override quando `__DEV__ === true` (Metro/Hermes dev mode);\n * - Não depende de `expo-constants` — usa só `process.env.*` que o Metro inlina\n * em build time para qualquer var `EXPO_PUBLIC_*`;\n * - Falha silenciosamente em produção (var inexistente → default do SDK).\n *\n * Vars relevantes (definidas em `.env.local` no consumer):\n * EXPO_PUBLIC_MOVIIE_API_BASE_URL=http://localhost:3000/api/v1\n * EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL=http://localhost:3000/telemetry/v1\n */\nimport { configureMoviieEndpoints } from '@moviie/player-sdk'\n\nimport {\n EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV,\n EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV,\n} from './constants'\n\nfunction normalize(raw: string | undefined): string | undefined {\n if (typeof raw !== 'string') return undefined\n const trimmed = raw.trim()\n return trimmed.length > 0 ? trimmed.replace(/\\/+$/, '') : undefined\n}\n\n// `__DEV__` é definido pelo bundler RN. Em web build (Vite/Next) cai pra `process.env.NODE_ENV`.\nconst devMode =\n typeof __DEV__ !== 'undefined'\n ? __DEV__\n : typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n\nif (devMode) {\n const apiBaseUrl = normalize(process.env[EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV])\n const eventsBaseUrl = normalize(process.env[EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV])\n\n const opts: { apiBaseUrl?: string; eventsBaseUrl?: string } = {}\n if (apiBaseUrl != null) opts.apiBaseUrl = apiBaseUrl\n if (eventsBaseUrl != null) opts.eventsBaseUrl = eventsBaseUrl\n\n if (opts.apiBaseUrl != null || opts.eventsBaseUrl != null) {\n configureMoviieEndpoints(opts)\n }\n}\n","/**\n * Console warning idempotente por chave. Útil para dependências opcionais ausentes:\n * dispara uma única vez por sessão para a mesma chave, evitando ruído no console.\n *\n * Reusável para qualquer feature gated por dep opcional (cast, DRM custom,\n * analytics provider, etc.).\n */\n\nconst FIRED_KEYS = new Set<string>()\n\nexport function warnOnce(key: string, message: string): void {\n if (FIRED_KEYS.has(key)) {\n return\n }\n FIRED_KEYS.add(key)\n // eslint-disable-next-line no-console\n console.warn(message)\n}\n\n/** Limpa o set de chaves disparadas. Use apenas em testes. */\nexport function __resetWarnOnceForTests(): void {\n FIRED_KEYS.clear()\n}\n","import type { ViewerTokenStore } from '@moviie/player-sdk'\nimport { MemoryViewerTokenStore } from '@moviie/player-sdk'\n\nimport { warnOnce } from './lib/warn-once'\n\nexport const MOVIIE_VIEWER_TOKEN_SECURE_STORE_KEY = 'moviie_viewer_token_v1' as const\n\nconst SECURE_STORE_MISSING_WARNING =\n '[@moviie/player-expo] `expo-secure-store` não está instalado — viewer token será mantido apenas em memória (perde ao matar app). ' +\n 'Instala com `pnpm add expo-secure-store` se quiseres persistência entre sessões.'\n\ninterface StoredEnvelope {\n token: string\n expiresAt: number\n}\n\nfunction isStoredEnvelope(value: unknown): value is StoredEnvelope {\n if (!value || typeof value !== 'object') return false\n const v = value as Record<string, unknown>\n return typeof v.token === 'string' && typeof v.expiresAt === 'number'\n}\n\nexport class SecureStoreViewerTokenStore implements ViewerTokenStore {\n private readonly fallback: ViewerTokenStore\n private readonly storageKey: string\n\n constructor(options?: { fallback?: ViewerTokenStore; storageKey?: string }) {\n this.fallback = options?.fallback ?? new MemoryViewerTokenStore()\n this.storageKey = options?.storageKey ?? MOVIIE_VIEWER_TOKEN_SECURE_STORE_KEY\n }\n\n private async loadSecureStore(): Promise<typeof import('expo-secure-store') | null> {\n try {\n return await import('expo-secure-store')\n } catch {\n warnOnce('moviie:expo-secure-store-missing', SECURE_STORE_MISSING_WARNING)\n return null\n }\n }\n\n async get(): Promise<string | null> {\n const SecureStore = await this.loadSecureStore()\n if (!SecureStore) {\n return this.fallback.get()\n }\n try {\n const raw = await SecureStore.getItemAsync(this.storageKey)\n if (!raw) return null\n const parsed: unknown = JSON.parse(raw)\n if (!isStoredEnvelope(parsed)) {\n await SecureStore.deleteItemAsync(this.storageKey).catch(() => {})\n return null\n }\n if (parsed.expiresAt <= Date.now()) {\n await SecureStore.deleteItemAsync(this.storageKey).catch(() => {})\n return null\n }\n return parsed.token\n } catch {\n return this.fallback.get()\n }\n }\n\n async set(token: string, ttlSec: number): Promise<void> {\n const SecureStore = await this.loadSecureStore()\n const envelope: StoredEnvelope = {\n token,\n expiresAt: Date.now() + Math.max(0, ttlSec) * 1000,\n }\n if (!SecureStore) {\n await this.fallback.set(token, ttlSec)\n return\n }\n try {\n await SecureStore.setItemAsync(this.storageKey, JSON.stringify(envelope))\n } catch {\n await this.fallback.set(token, ttlSec)\n }\n }\n}\n","import * as Application from \"expo-application\"\n\nexport function readNativeApplicationId(): string | undefined {\n try {\n const id = Application.applicationId\n return id ?? undefined\n } catch {\n return undefined\n }\n}\n","import { Platform } from \"react-native\"\n\nimport type { MoviieClientInfo } from \"@moviie/player-sdk\"\n\nimport { readNativeApplicationId } from \"./native-application-id\"\n\nlet cached: MoviieClientInfo | null = null\n\nexport function buildPlatformClientInfo(sdkVersion: string): MoviieClientInfo {\n if (cached) {\n return cached\n }\n\n const os = Platform.OS\n const platform: MoviieClientInfo[\"platform\"] =\n os === \"ios\" ? \"ios\" : os === \"android\" ? \"android\" : \"web\"\n\n const bundleId =\n platform === \"web\" ? undefined : readNativeApplicationId()\n\n cached = {\n platform,\n bundleId,\n sdkVersion,\n }\n return cached\n}\n\nexport function resetPlatformClientInfoCache(): void {\n cached = null\n}\n","import {\n createContext,\n useContext,\n useMemo,\n type ReactNode,\n} from \"react\"\n\nimport {\n buildClientHeaders,\n MemoryViewerTokenStore,\n MoviieClient,\n type MoviieClientInfo,\n type ViewerTokenStore,\n} from \"@moviie/player-sdk\"\n\nimport { MOVIIE_PLAYER_EXPO_PKG_VERSION } from \"../constants\"\nimport { buildPlatformClientInfo } from \"../platform/platform-client-info\"\nimport { SecureStoreViewerTokenStore } from \"../secure-store-viewer-token-store\"\n\nexport interface MoviieContextValue {\n client: MoviieClient\n viewerTokenStore: ViewerTokenStore\n publishableKey: string | null\n clientInfo: MoviieClientInfo\n sdkVersion: string\n /** Headers reused by TelemetryClient (Bearer + X-Moviie-Client when aplicável) */\n telemetryHeaders: Record<string, string>\n}\n\nconst MoviieContext = createContext<MoviieContextValue | null>(null)\n\nlet fallbackContext: MoviieContextValue | null = null\n\nfunction getOrCreateFallbackContext(): MoviieContextValue {\n if (!fallbackContext) {\n const sdkVersion = MOVIIE_PLAYER_EXPO_PKG_VERSION\n const clientInfo = buildPlatformClientInfo(sdkVersion)\n const viewerTokenStore = new MemoryViewerTokenStore()\n const client = new MoviieClient({\n publishableKey: undefined,\n clientInfo,\n sdkVersion,\n })\n fallbackContext = {\n client,\n viewerTokenStore,\n publishableKey: null,\n clientInfo,\n sdkVersion,\n telemetryHeaders: buildClientHeaders({\n clientInfo,\n sdkVersion,\n }),\n }\n }\n return fallbackContext\n}\n\nexport function useMoviieContext(): MoviieContextValue {\n const ctx = useContext(MoviieContext)\n return ctx ?? getOrCreateFallbackContext()\n}\n\nexport function MoviieProvider({\n publishableKey,\n children,\n}: {\n publishableKey?: string | null\n children: ReactNode\n}) {\n const value = useMemo((): MoviieContextValue => {\n const sdkVersion = MOVIIE_PLAYER_EXPO_PKG_VERSION\n const clientInfo = buildPlatformClientInfo(sdkVersion)\n const trimmedKey = publishableKey?.trim()\n const viewerTokenStore = new SecureStoreViewerTokenStore()\n const client = new MoviieClient({\n publishableKey: trimmedKey || undefined,\n clientInfo,\n sdkVersion,\n })\n const telemetryHeaders = buildClientHeaders({\n publishableKey: trimmedKey || undefined,\n clientInfo,\n sdkVersion,\n })\n return {\n client,\n viewerTokenStore,\n publishableKey: trimmedKey ?? null,\n clientInfo,\n sdkVersion,\n telemetryHeaders,\n }\n }, [publishableKey])\n\n return (\n <MoviieContext.Provider value={value}>{children}</MoviieContext.Provider>\n )\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -46,7 +46,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
// src/constants.ts
|
|
49
|
-
var MOVIIE_PLAYER_EXPO_PKG_VERSION = "0.
|
|
49
|
+
var MOVIIE_PLAYER_EXPO_PKG_VERSION = "0.28.0";
|
|
50
50
|
var MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
51
51
|
var MOVIIE_PLAYBACK_REFRESH_MAX_RETRIES = 3;
|
|
52
52
|
var MOVIIE_PLAYBACK_REFRESH_RETRY_BACKOFF_MS = 30 * 1e3;
|
|
@@ -390,6 +390,7 @@ function useMoviiePlayback(args) {
|
|
|
390
390
|
const [retryNonce, setRetryNonce] = React.useState(0);
|
|
391
391
|
const [selectedDubbingLanguage, setSelectedDubbingLanguage] = React.useState(null);
|
|
392
392
|
const [requestedDubbingLanguage, setRequestedDubbingLanguage] = React.useState(null);
|
|
393
|
+
const [selectedVariantId, setSelectedVariantId] = React.useState(null);
|
|
393
394
|
const currentCredentialRef = React.useRef(null);
|
|
394
395
|
React.useEffect(() => {
|
|
395
396
|
currentCredentialRef.current = extractSessionCredential(data?.playback?.uri);
|
|
@@ -442,6 +443,19 @@ function useMoviiePlayback(args) {
|
|
|
442
443
|
},
|
|
443
444
|
[data?.audioTracks]
|
|
444
445
|
);
|
|
446
|
+
const selectVariant = React.useCallback((variantId) => {
|
|
447
|
+
setSelectedVariantId(variantId?.trim() || null);
|
|
448
|
+
}, []);
|
|
449
|
+
const effectiveData = React.useMemo(() => {
|
|
450
|
+
if (!data || !selectedVariantId) return data;
|
|
451
|
+
const variant = data.variants?.find((v) => v.id === selectedVariantId);
|
|
452
|
+
if (!variant) return data;
|
|
453
|
+
return {
|
|
454
|
+
...data,
|
|
455
|
+
playback: { ...data.playback, uri: variant.uri, contentType: "hls" },
|
|
456
|
+
durationSeconds: variant.durationSeconds
|
|
457
|
+
};
|
|
458
|
+
}, [data, selectedVariantId]);
|
|
445
459
|
React.useEffect(() => {
|
|
446
460
|
if (!trimmedEmbedId) {
|
|
447
461
|
return;
|
|
@@ -490,13 +504,15 @@ function useMoviiePlayback(args) {
|
|
|
490
504
|
}, [trimmedEmbedId, client, publishableKey, retryNonce, requestedDubbingLanguage]);
|
|
491
505
|
const error = missingEmbedId ? new Error("Informe um embedId v\xE1lido (UUID p\xFAblico do embed).") : fetchError;
|
|
492
506
|
return {
|
|
493
|
-
data: missingEmbedId ? null :
|
|
507
|
+
data: missingEmbedId ? null : effectiveData,
|
|
494
508
|
error,
|
|
495
509
|
isLoading: missingEmbedId ? false : isLoading,
|
|
496
510
|
retry,
|
|
497
511
|
refreshPlayback,
|
|
498
512
|
selectedDubbingLanguage,
|
|
499
|
-
selectDubbingLanguage
|
|
513
|
+
selectDubbingLanguage,
|
|
514
|
+
selectedVariantId,
|
|
515
|
+
selectVariant
|
|
500
516
|
};
|
|
501
517
|
}
|
|
502
518
|
|
|
@@ -513,15 +529,19 @@ function resolveSwapAction(params) {
|
|
|
513
529
|
const {
|
|
514
530
|
uriChanged,
|
|
515
531
|
isTokenRefresh,
|
|
532
|
+
variantChanged = false,
|
|
533
|
+
nowOnVariant = false,
|
|
516
534
|
liveSeconds,
|
|
517
535
|
liveWasPlaying,
|
|
518
536
|
optionsAutoplay,
|
|
519
537
|
controlsAutoplay
|
|
520
538
|
} = params;
|
|
521
|
-
const shouldPlay = uriChanged && isTokenRefresh && liveWasPlaying != null ? liveWasPlaying : optionsAutoplay !== void 0 ? optionsAutoplay : controlsAutoplay;
|
|
539
|
+
const shouldPlay = uriChanged && (isTokenRefresh || variantChanged) && liveWasPlaying != null ? liveWasPlaying : optionsAutoplay !== void 0 ? optionsAutoplay : controlsAutoplay;
|
|
522
540
|
let restore;
|
|
523
541
|
if (!uriChanged) {
|
|
524
542
|
restore = "none";
|
|
543
|
+
} else if (variantChanged) {
|
|
544
|
+
restore = nowOnVariant ? "none" : "stored";
|
|
525
545
|
} else if (isTokenRefresh) {
|
|
526
546
|
restore = liveSeconds != null && liveSeconds > 0 ? "live" : "none";
|
|
527
547
|
} else {
|
|
@@ -1150,7 +1170,9 @@ function useMoviiePlayer(options) {
|
|
|
1150
1170
|
retry,
|
|
1151
1171
|
refreshPlayback,
|
|
1152
1172
|
selectedDubbingLanguage,
|
|
1153
|
-
selectDubbingLanguage
|
|
1173
|
+
selectDubbingLanguage,
|
|
1174
|
+
selectedVariantId,
|
|
1175
|
+
selectVariant
|
|
1154
1176
|
} = useMoviiePlayback({
|
|
1155
1177
|
embedId: options.embedId
|
|
1156
1178
|
});
|
|
@@ -1175,12 +1197,15 @@ function useMoviiePlayer(options) {
|
|
|
1175
1197
|
useMoviiePlaybackResumePersistence({
|
|
1176
1198
|
durationSeconds: data?.durationSeconds,
|
|
1177
1199
|
embedId: data?.embedId,
|
|
1178
|
-
|
|
1200
|
+
// Don't persist/restore position while on an alternate version (Express): its
|
|
1201
|
+
// different timeline would otherwise corrupt the full video's checkpoint.
|
|
1202
|
+
enabled: rememberEnabled && data != null && selectedVariantId == null,
|
|
1179
1203
|
player
|
|
1180
1204
|
});
|
|
1181
1205
|
const resumeHandledRef = React.useRef(false);
|
|
1182
1206
|
const prevEmbedIdRef = React.useRef(void 0);
|
|
1183
1207
|
const prevUriRef = React.useRef(void 0);
|
|
1208
|
+
const prevVariantIdRef = React.useRef(null);
|
|
1184
1209
|
const errorRefreshCountRef = React.useRef(0);
|
|
1185
1210
|
React.useEffect(() => {
|
|
1186
1211
|
resumeHandledRef.current = false;
|
|
@@ -1195,13 +1220,19 @@ function useMoviiePlayer(options) {
|
|
|
1195
1220
|
const uri = data.playback.uri;
|
|
1196
1221
|
const uriChanged = prevUriRef.current !== uri;
|
|
1197
1222
|
const isTokenRefresh = prevEmbedIdRef.current === data.embedId;
|
|
1223
|
+
const variantChanged = prevVariantIdRef.current !== selectedVariantId;
|
|
1224
|
+
const nowOnVariant = selectedVariantId != null;
|
|
1198
1225
|
prevEmbedIdRef.current = data.embedId;
|
|
1199
1226
|
prevUriRef.current = uri;
|
|
1200
|
-
|
|
1201
|
-
const
|
|
1227
|
+
prevVariantIdRef.current = selectedVariantId;
|
|
1228
|
+
const captureLive = uriChanged && (isTokenRefresh || variantChanged);
|
|
1229
|
+
const liveSeconds = captureLive ? safeReadPlayerProperty(() => player.currentTime, null) : null;
|
|
1230
|
+
const liveWasPlaying = captureLive ? safeReadPlayerProperty(() => player.playing, null) : null;
|
|
1202
1231
|
const action = resolveSwapAction({
|
|
1203
1232
|
uriChanged,
|
|
1204
1233
|
isTokenRefresh,
|
|
1234
|
+
variantChanged,
|
|
1235
|
+
nowOnVariant,
|
|
1205
1236
|
liveSeconds,
|
|
1206
1237
|
liveWasPlaying,
|
|
1207
1238
|
optionsAutoplay: options.autoplay,
|
|
@@ -1265,7 +1296,8 @@ function useMoviiePlayer(options) {
|
|
|
1265
1296
|
options.autoplay,
|
|
1266
1297
|
options.backgroundPlayback,
|
|
1267
1298
|
options.lockScreenNowPlaying,
|
|
1268
|
-
rememberEnabled
|
|
1299
|
+
rememberEnabled,
|
|
1300
|
+
selectedVariantId
|
|
1269
1301
|
]);
|
|
1270
1302
|
React.useEffect(() => {
|
|
1271
1303
|
if (!data) {
|
|
@@ -1318,6 +1350,8 @@ function useMoviiePlayer(options) {
|
|
|
1318
1350
|
retry,
|
|
1319
1351
|
selectedDubbingLanguage,
|
|
1320
1352
|
selectDubbingLanguage,
|
|
1353
|
+
selectedVariantId,
|
|
1354
|
+
selectVariant,
|
|
1321
1355
|
// Feature 183 — playback session id scoping in-player search. Spread into
|
|
1322
1356
|
// <MoviieVideo /> to wire the native search overlay.
|
|
1323
1357
|
searchSessionId
|
|
@@ -2576,7 +2610,9 @@ function MoviieSkinChromeProvider({
|
|
|
2576
2610
|
openCastPicker: openCastPickerProp,
|
|
2577
2611
|
searchSessionId,
|
|
2578
2612
|
selectedDubbingLanguage = null,
|
|
2579
|
-
selectDubbingLanguage: selectDubbingLanguageProp
|
|
2613
|
+
selectDubbingLanguage: selectDubbingLanguageProp,
|
|
2614
|
+
selectedVariantId = null,
|
|
2615
|
+
selectVariant: selectVariantProp
|
|
2580
2616
|
}) {
|
|
2581
2617
|
const noopPictureInPicture = React.useCallback(() => {
|
|
2582
2618
|
}, []);
|
|
@@ -2663,6 +2699,9 @@ function MoviieSkinChromeProvider({
|
|
|
2663
2699
|
const noopSelectDubbingLanguage = React.useCallback((_language) => {
|
|
2664
2700
|
}, []);
|
|
2665
2701
|
const selectDubbingLanguage = selectDubbingLanguageProp ?? noopSelectDubbingLanguage;
|
|
2702
|
+
const noopSelectVariant = React.useCallback((_variantId) => {
|
|
2703
|
+
}, []);
|
|
2704
|
+
const selectVariant = selectVariantProp ?? noopSelectVariant;
|
|
2666
2705
|
const [ebookOpen, setEbookOpen] = React.useState(false);
|
|
2667
2706
|
const openEbook = React.useCallback(() => {
|
|
2668
2707
|
setEbookOpen(true);
|
|
@@ -2804,6 +2843,8 @@ function MoviieSkinChromeProvider({
|
|
|
2804
2843
|
closeSettings,
|
|
2805
2844
|
selectedDubbingLanguage,
|
|
2806
2845
|
selectDubbingLanguage,
|
|
2846
|
+
selectedVariantId,
|
|
2847
|
+
selectVariant,
|
|
2807
2848
|
searchSessionId,
|
|
2808
2849
|
summaryOpen,
|
|
2809
2850
|
openSummary,
|
|
@@ -2859,6 +2900,8 @@ function MoviieSkinChromeProvider({
|
|
|
2859
2900
|
closeSettings,
|
|
2860
2901
|
selectedDubbingLanguage,
|
|
2861
2902
|
selectDubbingLanguage,
|
|
2903
|
+
selectedVariantId,
|
|
2904
|
+
selectVariant,
|
|
2862
2905
|
searchSessionId,
|
|
2863
2906
|
summaryOpen,
|
|
2864
2907
|
openSummary,
|
|
@@ -4231,13 +4274,17 @@ function uniqueSpeedOptions(initialRate) {
|
|
|
4231
4274
|
function formatSpeed(rate) {
|
|
4232
4275
|
return rate === 1 ? "Normal" : `${Number(rate.toFixed(2))}x`;
|
|
4233
4276
|
}
|
|
4277
|
+
function formatVariantDuration(totalSeconds) {
|
|
4278
|
+
const s = Number.isFinite(totalSeconds) && totalSeconds > 0 ? Math.round(totalSeconds) : 0;
|
|
4279
|
+
return s >= 60 ? `${Math.round(s / 60)} min` : `${s}s`;
|
|
4280
|
+
}
|
|
4234
4281
|
function matchSubtitleTrack(available, entry) {
|
|
4235
4282
|
const want = primarySubtag(entry.language);
|
|
4236
4283
|
return available.find((track) => primarySubtag(track.language) === want);
|
|
4237
4284
|
}
|
|
4238
4285
|
function hasConfigurablePlaybackSettings(playback) {
|
|
4239
4286
|
if (!playback.controls.showSettings) return false;
|
|
4240
|
-
return playback.controls.showCaptions && playback.captions.length > 0 || hasSelectableAudioTracks(playback) || playback.controls.showSpeed;
|
|
4287
|
+
return (playback.variants?.length ?? 0) > 0 || playback.controls.showCaptions && playback.captions.length > 0 || hasSelectableAudioTracks(playback) || playback.controls.showSpeed;
|
|
4241
4288
|
}
|
|
4242
4289
|
function usePlayerSettingsSnapshot() {
|
|
4243
4290
|
const { player } = useMoviieSkinChrome();
|
|
@@ -4368,7 +4415,9 @@ function MoviieSkinSettingsOverlay() {
|
|
|
4368
4415
|
playback,
|
|
4369
4416
|
settingsOpen,
|
|
4370
4417
|
selectedDubbingLanguage,
|
|
4371
|
-
selectDubbingLanguage
|
|
4418
|
+
selectDubbingLanguage,
|
|
4419
|
+
selectedVariantId,
|
|
4420
|
+
selectVariant
|
|
4372
4421
|
} = useMoviieSkinChrome();
|
|
4373
4422
|
const [activeMenu, setActiveMenu] = React.useState(null);
|
|
4374
4423
|
const [pendingAudioLanguage, setPendingAudioLanguage] = React.useState(null);
|
|
@@ -4444,23 +4493,26 @@ function MoviieSkinSettingsOverlay() {
|
|
|
4444
4493
|
() => playback.controls.showSpeed ? uniqueSpeedOptions(playback.controls.playbackRate) : [],
|
|
4445
4494
|
[playback.controls.playbackRate, playback.controls.showSpeed]
|
|
4446
4495
|
);
|
|
4496
|
+
const variants = React.useMemo(() => playback.variants ?? [], [playback.variants]);
|
|
4497
|
+
const activeVariantLabel = selectedVariantId == null ? "Completo" : variants.find((v) => v.id === selectedVariantId)?.label ?? "Completo";
|
|
4447
4498
|
React.useEffect(() => {
|
|
4448
4499
|
if (!settingsOpen) {
|
|
4449
4500
|
setActiveMenu(null);
|
|
4450
4501
|
}
|
|
4451
4502
|
}, [settingsOpen]);
|
|
4452
4503
|
React.useEffect(() => {
|
|
4504
|
+
if (activeMenu === "variant" && variants.length === 0) setActiveMenu(null);
|
|
4453
4505
|
if (activeMenu === "captions" && captionOptions.length === 0) setActiveMenu(null);
|
|
4454
4506
|
if (activeMenu === "audio" && audioTracks.length < 2) setActiveMenu(null);
|
|
4455
4507
|
if (activeMenu === "speed" && speedOptions.length === 0) setActiveMenu(null);
|
|
4456
|
-
}, [activeMenu, audioTracks.length, captionOptions.length, speedOptions.length]);
|
|
4508
|
+
}, [activeMenu, audioTracks.length, captionOptions.length, speedOptions.length, variants.length]);
|
|
4457
4509
|
const activeCaptionLabel = activeSubtitleLang == null ? "Desativado" : captionOptions.find(
|
|
4458
4510
|
({ caption }) => primarySubtag(caption.language) === activeSubtitleLang
|
|
4459
4511
|
)?.caption.label ?? "Ativado";
|
|
4460
4512
|
const activeAudioLabel = audioTracks.find((entry, index) => isAudioActive(entry, index))?.label ?? audioTracks[0]?.label ?? "Original";
|
|
4461
4513
|
const activeSpeedLabel = formatSpeed(activeRate);
|
|
4462
4514
|
if (!hasConfigurablePlaybackSettings(playback)) return null;
|
|
4463
|
-
const sheetTitle = activeMenu === "captions" ? "Legendas" : activeMenu === "audio" ? "\xC1udio" : activeMenu === "speed" ? "Velocidade" : "Configura\xE7\xF5es";
|
|
4515
|
+
const sheetTitle = activeMenu === "variant" ? "Vers\xE3o" : activeMenu === "captions" ? "Legendas" : activeMenu === "audio" ? "\xC1udio" : activeMenu === "speed" ? "Velocidade" : "Configura\xE7\xF5es";
|
|
4464
4516
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4465
4517
|
MoviieSkinSheet,
|
|
4466
4518
|
{
|
|
@@ -4470,6 +4522,14 @@ function MoviieSkinSettingsOverlay() {
|
|
|
4470
4522
|
visible: settingsOpen,
|
|
4471
4523
|
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.ScrollView, { style: styles7.menuBody, children: [
|
|
4472
4524
|
activeMenu == null ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles7.sectionBody, children: [
|
|
4525
|
+
variants.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4526
|
+
SettingsMenuRow,
|
|
4527
|
+
{
|
|
4528
|
+
label: "Vers\xE3o",
|
|
4529
|
+
value: activeVariantLabel,
|
|
4530
|
+
onPress: () => setActiveMenu("variant")
|
|
4531
|
+
}
|
|
4532
|
+
) : null,
|
|
4473
4533
|
audioTracks.length >= 2 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4474
4534
|
SettingsMenuRow,
|
|
4475
4535
|
{
|
|
@@ -4495,6 +4555,28 @@ function MoviieSkinSettingsOverlay() {
|
|
|
4495
4555
|
}
|
|
4496
4556
|
) : null
|
|
4497
4557
|
] }) : null,
|
|
4558
|
+
activeMenu === "variant" && variants.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4559
|
+
/* @__PURE__ */ jsxRuntime.jsx(SettingsBackRow, { onPress: () => setActiveMenu(null) }),
|
|
4560
|
+
/* @__PURE__ */ jsxRuntime.jsxs(SettingsSection, { title: "Vers\xE3o", children: [
|
|
4561
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4562
|
+
SettingsRow,
|
|
4563
|
+
{
|
|
4564
|
+
active: selectedVariantId == null,
|
|
4565
|
+
label: "Completo",
|
|
4566
|
+
onPress: () => selectVariant(null)
|
|
4567
|
+
}
|
|
4568
|
+
),
|
|
4569
|
+
variants.map((variant) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4570
|
+
SettingsRow,
|
|
4571
|
+
{
|
|
4572
|
+
active: selectedVariantId === variant.id,
|
|
4573
|
+
label: `${variant.label} \xB7 ${formatVariantDuration(variant.durationSeconds)}`,
|
|
4574
|
+
onPress: () => selectVariant(variant.id)
|
|
4575
|
+
},
|
|
4576
|
+
variant.id
|
|
4577
|
+
))
|
|
4578
|
+
] })
|
|
4579
|
+
] }) : null,
|
|
4498
4580
|
activeMenu === "captions" && captionOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4499
4581
|
/* @__PURE__ */ jsxRuntime.jsx(SettingsBackRow, { onPress: () => setActiveMenu(null) }),
|
|
4500
4582
|
/* @__PURE__ */ jsxRuntime.jsxs(SettingsSection, { title: "Legendas", children: [
|
|
@@ -7364,6 +7446,8 @@ var MoviieVideoImpl = React.forwardRef(
|
|
|
7364
7446
|
searchSessionId = null,
|
|
7365
7447
|
selectedDubbingLanguage = null,
|
|
7366
7448
|
selectDubbingLanguage,
|
|
7449
|
+
selectedVariantId = null,
|
|
7450
|
+
selectVariant,
|
|
7367
7451
|
controlsAutoHideMs,
|
|
7368
7452
|
controlsVisibleByDefault,
|
|
7369
7453
|
pictureInPicture,
|
|
@@ -7767,6 +7851,8 @@ var MoviieVideoImpl = React.forwardRef(
|
|
|
7767
7851
|
player,
|
|
7768
7852
|
selectedDubbingLanguage,
|
|
7769
7853
|
selectDubbingLanguage,
|
|
7854
|
+
selectedVariantId,
|
|
7855
|
+
selectVariant,
|
|
7770
7856
|
searchSessionId,
|
|
7771
7857
|
skinLayoutMetricsWidth: customFullscreen ? skinLayoutMetricsBasisWidth : void 0,
|
|
7772
7858
|
videoViewRef: innerRef,
|