Skip to content

Commit

Permalink
Bugfix/several bugs (#7)
Browse files Browse the repository at this point in the history
* change main file package.json

* several improvements

* suggestions and fixes

* other fixes

* types safety

* fixes on handlers
  • Loading branch information
Marcoo09 authored Sep 6, 2021
1 parent 1e0d48a commit 0eb1e4a
Show file tree
Hide file tree
Showing 10 changed files with 2,370 additions and 97 deletions.
11 changes: 11 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,15 @@ module.exports = {
'simple-import-sort/imports': 'error',
'sort-imports': 'off',
},
settings: {
'import/extensions': ['.js', '.ts', '.tsx'],
'import/parsers': {
'@typescript-eslint/parser': ['.ts', '.tsx'],
},
'import/resolver': {
node: {
extensions: ['.js', '.ts', '.tsx'],
},
},
},
}
1 change: 1 addition & 0 deletions babel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./lib/module/babel/index.js')
57 changes: 48 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,37 @@
{
"name": "react-native-vimeo-iframe",
"version": "1.0.1",
"description": "",
"version": "1.0.2",
"description": "React Native Vimeo Iframe is a library to render Vimeo videos in a React Native app. This component allows you to embed a Vimeo video in your app and have full access to the Vimeo player JS API (more information https://developer.vimeo.com/player/js-api).",
"homepage": "https://github.com/MetaLabs-inc/react-native-vimeo-iframe#readme",
"main": "src/index.tsx",
"types": "lib/index.d.ts",
"main": "lib/commonjs/index.js",
"types": "lib/typescript/index.d.ts",
"module": "lib/module/index.js",
"react-native": "src/index.tsx",
"source": "src/index.tsx",
"author": "Marco Fiorito <marcofiorito1@gmail.com>",
"license": "MIT",
"files": [
"lib"
"src",
"lib",
"babel.js"
],
"repository": {
"type": "git",
"url": "https://github.com/MetaLabs-inc/react-native-vimeo-iframe"
},
"keywords": [
"android",
"ios",
"react native",
"component library",
"vimeo",
"videos"
],
"scripts": {
"typescript": "tsc --noEmit",
"prepare": "bob build && node ./scripts/generate-mappings.js",
"compile": "rm -rf lib && tsc -p .",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
"prepare": "yarn compile",
"test": "jest"
},
"devDependencies": {
Expand All @@ -28,14 +46,18 @@
"eslint-plugin-simple-import-sort": "^7.0.0",
"jest": "^26.6.3",
"metro-react-native-babel-preset": "^0.65.0",
"babel-cli": "^6.26.0",
"react": "^17.0.1",
"react-native": "^0.63.4",
"react-test-renderer": "^17.0.1",
"typescript": "^4.1.3"
"react-native-webview": "11.2.3",
"typescript": "^4.1.3",
"react-native-builder-bob": "^0.17.1"
},
"peerDependencies": {
"react-native": "^0.63.4",
"react-native-webview": "11.2.3"
"react": "*",
"react-native": "*",
"react-native-webview": "*"
},
"jest": {
"preset": "react-native",
Expand All @@ -47,5 +69,22 @@
"json",
"node"
]
},
"react-native-builder-bob": {
"source": "src",
"output": "lib",
"targets": [
"commonjs",
"module",
[
"typescript",
{
"project": "tsconfig.build.json"
}
]
],
"files": [
"src/"
]
}
}
66 changes: 66 additions & 0 deletions scripts/generate-mappings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* @flow */

const path = require('path')
const fs = require('fs')
const types = require('babel-types')
const parser = require('@babel/parser')

const packageJson = require('../package.json')
const root = path.resolve(__dirname, '..')
const output = path.join(root, 'lib/mappings.json')
const source = fs.readFileSync(path.resolve(root, 'src', 'index.tsx'), 'utf8')
const ast = parser.parse(source, {
sourceType: 'module',
plugins: [
'jsx',
'typescript',
'objectRestSpread',
'classProperties',
'asyncGenerators',
],
})

const index = packageJson.module
const relative = (value /* : string */) =>
path.relative(root, path.resolve(path.dirname(index), value))

const mappings = ast.program.body.reduce((acc, declaration, index, self) => {
if (types.isExportNamedDeclaration(declaration)) {
if (declaration.source) {
declaration.specifiers.forEach((specifier) => {
acc[specifier.exported.name] = {
path: relative(declaration.source.value),
name: specifier.local.name,
}
})
} else {
declaration.specifiers.forEach((specifier) => {
const name = specifier.exported.name

self.forEach((it) => {
if (
types.isImportDeclaration(it) &&
it.specifiers.some(
(s) =>
types.isImportNamespaceSpecifier(s) &&
s.local.name === specifier.local.name
)
) {
acc[name] = {
path: relative(it.source.value),
name: '*',
}
}
})
})
}
}

return acc
}, {})

fs.existsSync(path.dirname(output)) || fs.mkdirSync(path.dirname(output))
fs.writeFileSync(
output,
JSON.stringify({ name: packageJson.name, index, mappings }, null, 2)
)
153 changes: 107 additions & 46 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React from 'react'
import { TouchableWithoutFeedback } from 'react-native'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { WebView } from 'react-native-webview'

import webplayer from './template'
import { LayoutProps } from './types'
import { LayoutProps, PlayerActions, PlayerEvents } from './types'

export const Vimeo: React.FC<LayoutProps> = ({
videoId,
Expand All @@ -18,70 +17,132 @@ export const Vimeo: React.FC<LayoutProps> = ({
autoPlay,
speed = false,
style,
onVolumeChange,
onError,
containerStyle,
getVimeoPlayer,
}) => {
const [isReady, setReady] = React.useState<boolean>()
const [isPlaying, setPlaying] = useState<boolean>(false)
const ref = useRef<WebView>()

const [autoPlayValue, setAutoPlay] = React.useState<boolean>(autoPlay)
const toggleAutoPlay = React.useCallback(() => setAutoPlay(!autoPlayValue), [
const [autoPlayValue, setAutoPlay] = useState<boolean>(autoPlay)
const toggleAutoPlay = useCallback(() => setAutoPlay(!autoPlayValue), [
autoPlayValue,
])

const handlers: any = {}
const registerHandlers = () => {
registerBridgeEventHandler('ready', onReady ?? onReadyDefault)

const player = useCallback(
(action: PlayerActions) => {
const handler = ref?.current?.injectJavaScript

if (handler) {
switch (action.type) {
case PlayerEvents.PLAY:
if (isPlaying) return
handler('play();')
setPlaying(true)
break
case PlayerEvents.PAUSE:
if (!isPlaying) return
handler('await pause();')
setPlaying(false)
break
case PlayerEvents.SET_TIME:
handler(`setTime(${action.time});`)
break
case PlayerEvents.GET_DURATION:
handler(`
const videoDuration = getDuration();
const callback = ${action.callback};
callback(videoDuration);
`)
break
default:
break
}
}
},
[ref, isPlaying]
)

const onReadyDefault = useCallback(() => {
onReady && setTimeout(onReady)
}, [onReady])

const registerHandlers = useCallback(() => {
registerBridgeEventHandler('ready', onReadyDefault)
registerBridgeEventHandler('play', onPlay)
registerBridgeEventHandler('playProgress', onPlayProgress)
registerBridgeEventHandler('pause', onPause)
registerBridgeEventHandler('finish', onFinish)
}
registerBridgeEventHandler('volumeChange', onVolumeChange)
registerBridgeEventHandler('error', onError)
}, [
onReadyDefault,
onPlay,
onPlayProgress,
onError,
onVolumeChange,
onPause,
onFinish,
])

const registerBridgeEventHandler = (eventName: string, handler: any) => {
handlers[eventName] = handler
}

React.useEffect(() => {
useEffect(() => {
registerHandlers()
}, [videoId, scalesPageToFit])

const onBridgeMessage = (event: any) => {
const message = event.nativeEvent.data
let payload
try {
payload = JSON.parse(message)
if (payload?.name === 'finish') {
toggleAutoPlay()
const onBridgeMessage = useCallback(
(event: any) => {
const message = event.nativeEvent.data
let payload
try {
payload = JSON.parse(message)
if (payload?.name === 'finish') {
toggleAutoPlay()
}
} catch (err) {
return
}
} catch (err) {
return
}
let handler = handlers[payload.name]
if (handler) handler(payload.data)
}

const onReadyDefault = () => {
setReady(true)
if (onReady) setTimeout(onReady)
}
let bridgeMessageHandler = handlers[payload?.name]
if (bridgeMessageHandler) bridgeMessageHandler(payload?.data)
},
[toggleAutoPlay, handlers]
)

useEffect(() => {
getVimeoPlayer && getVimeoPlayer(player)
}, [getVimeoPlayer, player])

return (
<TouchableWithoutFeedback onPress={toggleAutoPlay}>
<WebView
source={{
html: webplayer(videoId, loop, autoPlayValue, controls, speed),
}}
javaScriptEnabled={true}
bounces={false}
onMessage={onBridgeMessage}
scalesPageToFit={scalesPageToFit}
onError={(error) => console.error(error)}
style={[
{
marginTop: -8,
marginLeft: -10,
},
style,
]}
/>
</TouchableWithoutFeedback>
<WebView
source={{
html: webplayer(videoId, loop, autoPlayValue, controls, speed),
}}
javaScriptEnabled={true}
ref={ref as any}
onMessage={onBridgeMessage}
bounces={false}
scrollEnabled={false}
scalesPageToFit={scalesPageToFit}
onError={(error) => console.error(error)}
style={[
{
marginTop: -8,
marginLeft: -10,
},
style,
]}
containerStyle={containerStyle}
setBuiltInZoomControls={false}
setDisplayZoomControls={false}
automaticallyAdjustContentInsets
onNavigationStateChange={(a) => console.log(a?.url)}
/>
)
}
4 changes: 2 additions & 2 deletions src/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export default (
loop: boolean,
autoPlay: boolean,
controls: boolean,
speed: boolean,
speed: boolean
) => `
<html><head>
<title></title>
Expand Down Expand Up @@ -74,4 +74,4 @@ const sendEvent = (evt, data) => {
webViewBridge();
</script>
</body></html>
`;
`
Loading

0 comments on commit 0eb1e4a

Please sign in to comment.