1- import React from 'react'
2- import { TouchableWithoutFeedback } from 'react-native'
1+ import React , { useCallback , useEffect , useRef , useState } from 'react'
32import { WebView } from 'react-native-webview'
43
54import webplayer from './template'
6- import { LayoutProps } from './types'
5+ import { LayoutProps , PlayerActions , PlayerEvents } from './types'
76
87export const Vimeo : React . FC < LayoutProps > = ( {
98 videoId,
@@ -18,70 +17,132 @@ export const Vimeo: React.FC<LayoutProps> = ({
1817 autoPlay,
1918 speed = false ,
2019 style,
20+ onVolumeChange,
21+ onError,
22+ containerStyle,
23+ getVimeoPlayer,
2124} ) => {
22- const [ isReady , setReady ] = React . useState < boolean > ( )
25+ const [ isPlaying , setPlaying ] = useState < boolean > ( false )
26+ const ref = useRef < WebView > ( )
2327
24- const [ autoPlayValue , setAutoPlay ] = React . useState < boolean > ( autoPlay )
25- const toggleAutoPlay = React . useCallback ( ( ) => setAutoPlay ( ! autoPlayValue ) , [
28+ const [ autoPlayValue , setAutoPlay ] = useState < boolean > ( autoPlay )
29+ const toggleAutoPlay = useCallback ( ( ) => setAutoPlay ( ! autoPlayValue ) , [
2630 autoPlayValue ,
2731 ] )
2832
2933 const handlers : any = { }
30- const registerHandlers = ( ) => {
31- registerBridgeEventHandler ( 'ready' , onReady ?? onReadyDefault )
34+
35+ const player = useCallback (
36+ ( action : PlayerActions ) => {
37+ const handler = ref ?. current ?. injectJavaScript
38+
39+ if ( handler ) {
40+ switch ( action . type ) {
41+ case PlayerEvents . PLAY :
42+ if ( isPlaying ) return
43+ handler ( 'play();' )
44+ setPlaying ( true )
45+ break
46+ case PlayerEvents . PAUSE :
47+ if ( ! isPlaying ) return
48+ handler ( 'await pause();' )
49+ setPlaying ( false )
50+ break
51+ case PlayerEvents . SET_TIME :
52+ handler ( `setTime(${ action . time } );` )
53+ break
54+ case PlayerEvents . GET_DURATION :
55+ handler ( `
56+ const videoDuration = getDuration();
57+ const callback = ${ action . callback } ;
58+ callback(videoDuration);
59+ ` )
60+ break
61+ default :
62+ break
63+ }
64+ }
65+ } ,
66+ [ ref , isPlaying ]
67+ )
68+
69+ const onReadyDefault = useCallback ( ( ) => {
70+ onReady && setTimeout ( onReady )
71+ } , [ onReady ] )
72+
73+ const registerHandlers = useCallback ( ( ) => {
74+ registerBridgeEventHandler ( 'ready' , onReadyDefault )
3275 registerBridgeEventHandler ( 'play' , onPlay )
3376 registerBridgeEventHandler ( 'playProgress' , onPlayProgress )
3477 registerBridgeEventHandler ( 'pause' , onPause )
3578 registerBridgeEventHandler ( 'finish' , onFinish )
36- }
79+ registerBridgeEventHandler ( 'volumeChange' , onVolumeChange )
80+ registerBridgeEventHandler ( 'error' , onError )
81+ } , [
82+ onReadyDefault ,
83+ onPlay ,
84+ onPlayProgress ,
85+ onError ,
86+ onVolumeChange ,
87+ onPause ,
88+ onFinish ,
89+ ] )
3790
3891 const registerBridgeEventHandler = ( eventName : string , handler : any ) => {
3992 handlers [ eventName ] = handler
4093 }
4194
42- React . useEffect ( ( ) => {
95+ useEffect ( ( ) => {
4396 registerHandlers ( )
4497 } , [ videoId , scalesPageToFit ] )
4598
46- const onBridgeMessage = ( event : any ) => {
47- const message = event . nativeEvent . data
48- let payload
49- try {
50- payload = JSON . parse ( message )
51- if ( payload ?. name === 'finish' ) {
52- toggleAutoPlay ( )
99+ const onBridgeMessage = useCallback (
100+ ( event : any ) => {
101+ const message = event . nativeEvent . data
102+ let payload
103+ try {
104+ payload = JSON . parse ( message )
105+ if ( payload ?. name === 'finish' ) {
106+ toggleAutoPlay ( )
107+ }
108+ } catch ( err ) {
109+ return
53110 }
54- } catch ( err ) {
55- return
56- }
57- let handler = handlers [ payload . name ]
58- if ( handler ) handler ( payload . data )
59- }
60111
61- const onReadyDefault = ( ) => {
62- setReady ( true )
63- if ( onReady ) setTimeout ( onReady )
64- }
112+ let bridgeMessageHandler = handlers [ payload ?. name ]
113+ if ( bridgeMessageHandler ) bridgeMessageHandler ( payload ?. data )
114+ } ,
115+ [ toggleAutoPlay , handlers ]
116+ )
117+
118+ useEffect ( ( ) => {
119+ getVimeoPlayer && getVimeoPlayer ( player )
120+ } , [ getVimeoPlayer , player ] )
65121
66122 return (
67- < TouchableWithoutFeedback onPress = { toggleAutoPlay } >
68- < WebView
69- source = { {
70- html : webplayer ( videoId , loop , autoPlayValue , controls , speed ) ,
71- } }
72- javaScriptEnabled = { true }
73- bounces = { false }
74- onMessage = { onBridgeMessage }
75- scalesPageToFit = { scalesPageToFit }
76- onError = { ( error ) => console . error ( error ) }
77- style = { [
78- {
79- marginTop : - 8 ,
80- marginLeft : - 10 ,
81- } ,
82- style ,
83- ] }
84- />
85- </ TouchableWithoutFeedback >
123+ < WebView
124+ source = { {
125+ html : webplayer ( videoId , loop , autoPlayValue , controls , speed ) ,
126+ } }
127+ javaScriptEnabled = { true }
128+ ref = { ref as any }
129+ onMessage = { onBridgeMessage }
130+ bounces = { false }
131+ scrollEnabled = { false }
132+ scalesPageToFit = { scalesPageToFit }
133+ onError = { ( error ) => console . error ( error ) }
134+ style = { [
135+ {
136+ marginTop : - 8 ,
137+ marginLeft : - 10 ,
138+ } ,
139+ style ,
140+ ] }
141+ containerStyle = { containerStyle }
142+ setBuiltInZoomControls = { false }
143+ setDisplayZoomControls = { false }
144+ automaticallyAdjustContentInsets
145+ onNavigationStateChange = { ( a ) => console . log ( a ?. url ) }
146+ />
86147 )
87148}
0 commit comments