import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { type DataDetectorTypes, Dimensions, StyleSheet } from 'react-native'; import WebView, { type WebViewMessageEvent } from 'react-native-webview'; import WebviewVimeoPlayerController from './module/WebviewVimeoPlayerController'; import { INTERNAL_SET_CONTROLLER_INSTANCE } from './symbol'; import type { VimeoViewProps } from './types'; import type { CommandResult, ReadyResult } from './types/message'; import type { VimeoPlayerEventMap } from './types/vimeo'; import { webviewScripts } from './utils/webviewScripts'; import VimeoViewWrapper from './VimeoViewWrapper'; const { width: screenWidth } = Dimensions.get('window'); function VimeoView({ player, height = 200, width = screenWidth, style, webViewProps, webViewStyle }: VimeoViewProps) { const webViewRef = useRef(null); const playerRef = useRef(null); const [isReady, setIsReady] = useState(false); const dataDetectorTypes = useMemo(() => ['none'] as DataDetectorTypes[], []); const handleMessage = useCallback( (event: WebViewMessageEvent) => { const response = JSON.parse(event.nativeEvent.data) as | { type: keyof VimeoPlayerEventMap; data: VimeoPlayerEventMap[keyof VimeoPlayerEventMap]; } | CommandResult | ReadyResult | null; if (!response) { return; } if (response.type === 'onReady') { setIsReady(true); return; } if (response.type === 'commandResult') { if (!playerRef.current) { console.warn('Player controller not available for command result'); return; } const pendingCommands = playerRef.current?.getPendingCommands(); const resolver = pendingCommands?.get(response.id); if (resolver) { resolver(response.data); pendingCommands?.delete(response.id); } return; } if (player.hasListeners(response.type)) { player.emit(response.type, response.data); } }, [player], ); const createPlayerHTML = useCallback(() => { const sourceUri = player.getSource(); if (sourceUri === null) { return '
Invalid Vimeo URL
'; } const embedOptions = player.getOptions(); const options = { url: sourceUri, ...embedOptions, }; return /* html */ `
`; }, [player]); useEffect(() => { if (isReady && webViewRef.current) { const controller = WebviewVimeoPlayerController.createInstance(webViewRef); playerRef.current = controller; player[INTERNAL_SET_CONTROLLER_INSTANCE](controller); } }, [isReady, player]); useEffect(() => { return () => { if (playerRef.current) { playerRef.current = null; } }; }, []); return ( ); } const styles = StyleSheet.create({ webView: { backgroundColor: 'transparent', }, }); export default VimeoView;