diff --git a/ios/Ecency.xcodeproj/project.pbxproj b/ios/Ecency.xcodeproj/project.pbxproj index 15c48edc5..217a0f1f5 100644 --- a/ios/Ecency.xcodeproj/project.pbxproj +++ b/ios/Ecency.xcodeproj/project.pbxproj @@ -742,6 +742,7 @@ "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf", "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf", "${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle", + "${PODS_ROOT}/YoutubePlayer-in-WKWebView/WKYTPlayerView/WKYTPlayerView.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -763,6 +764,7 @@ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/WKYTPlayerView.bundle", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index eed63661e..3f976b0d1 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -151,6 +151,9 @@ PODS: - Folly (= 2018.10.22.00) - RCTRequired (= 0.61.5) - React-Core (= 0.61.5) + - RCTYouTube (2.0.1): + - React + - YoutubePlayer-in-WKWebView (~> 0.3.1) - React (0.61.5): - React-Core (= 0.61.5) - React-Core/DevSupport (= 0.61.5) @@ -427,6 +430,7 @@ PODS: - toolbar-android (0.1.0-rc.2): - React - Yoga (1.14.0) + - YoutubePlayer-in-WKWebView (0.3.5) DEPENDENCIES: - appcenter-analytics (from `../node_modules/appcenter-analytics/ios`) @@ -443,6 +447,7 @@ DEPENDENCIES: - lottie-react-native (from `../node_modules/lottie-react-native`) - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) + - RCTYouTube (from `../node_modules/react-native-youtube`) - React (from `../node_modules/react-native/`) - React-Core (from `../node_modules/react-native/`) - React-Core/DevSupport (from `../node_modules/react-native/`) @@ -517,6 +522,7 @@ SPEC REPOS: - SDWebImage - SDWebImageWebPCoder - TOCropViewController + - YoutubePlayer-in-WKWebView EXTERNAL SOURCES: appcenter-analytics: @@ -547,6 +553,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/Libraries/RCTRequired" RCTTypeSafety: :path: "../node_modules/react-native/Libraries/TypeSafety" + RCTYouTube: + :path: "../node_modules/react-native-youtube" React: :path: "../node_modules/react-native/" React-Core: @@ -674,6 +682,7 @@ SPEC CHECKSUMS: Protobuf: 0cde852566359049847168e51bd1c690e0f70056 RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1 RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320 + RCTYouTube: 4509d59a7de050dd0c7c6cb1f427d37678d63b5c React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78 React-Core: 688b451f7d616cc1134ac95295b593d1b5158a04 React-CoreModules: d04f8494c1a328b69ec11db9d1137d667f916dcb @@ -723,6 +732,7 @@ SPEC CHECKSUMS: TOCropViewController: 3105367e808b7d3d886a74ff59bf4804e7d3ab38 toolbar-android: 85f3ef4d691469f2d304e7dee4bca013aa1ba1ff Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b + YoutubePlayer-in-WKWebView: cfbf46da51d7370662a695a8f351e5fa1d3e1008 PODFILE CHECKSUM: fe3729fa5bd9034637b0c0653446c2895b1c839d diff --git a/package.json b/package.json index ef6f34cf1..bc5138721 100644 --- a/package.json +++ b/package.json @@ -104,6 +104,7 @@ "react-native-version": "^4.0.0", "react-native-version-number": "^0.3.5", "react-native-webview": "^11.2.1", + "react-native-youtube": "^2.0.1", "react-navigation": "^4.0.10", "react-navigation-drawer": "^2.3.3", "react-navigation-redux-helpers": "^4.0.1", diff --git a/src/components/postElements/body/view/config.js b/src/components/postElements/body/view/config.js index 47348adc3..d423010ab 100644 --- a/src/components/postElements/body/view/config.js +++ b/src/components/postElements/body/view/config.js @@ -97,6 +97,21 @@ document.addEventListener('click', function(event) { window.ReactNativeWebView.postMessage(JSON.stringify(result)); return false; } + + if (el.classList.contains('markdown-video-link-youtube')) { + var embedUrl = el.getAttribute('data-embed-src'); + + if (embedUrl) { + + var result = { + type: 'markdown-video-link-youtube', + tag: embedUrl + }; + window.ReactNativeWebView.postMessage(JSON.stringify(result)); + return false; + } + } + if (el.classList.contains('markdown-video-link')) { var embedSrc = ''; if (embedSrc) { @@ -113,6 +128,8 @@ document.addEventListener('click', function(event) { return false; } } + + var author = el.getAttribute('data-author').toString(); window.ReactNativeWebView.postMessage(JSON.stringify(author)); }); @@ -236,6 +253,23 @@ document.addEventListener('click', function(event) { window.ReactNativeWebView.postMessage(JSON.stringify(result)); return false; } + + if (el.classList.contains('markdown-video-link-youtube')) { + var embedUrl = el.getAttribute('data-embed-src'); + + if (embedUrl) { + + + var result = { + type: 'markdown-video-link-youtube', + tag: embedUrl + }; + window.ReactNativeWebView.postMessage(JSON.stringify(result)); + return false; + } + } + + if (el.classList.contains('markdown-video-link')) { var embedSrc = ''; if (embedSrc) { @@ -252,6 +286,7 @@ document.addEventListener('click', function(event) { return false; } } + }); true; `; diff --git a/src/components/postElements/body/view/postBodyView.js b/src/components/postElements/body/view/postBodyView.js index 5de5884e3..a154f2a6b 100644 --- a/src/components/postElements/body/view/postBodyView.js +++ b/src/components/postElements/body/view/postBodyView.js @@ -11,6 +11,8 @@ import RNFetchBlob from 'rn-fetch-blob'; import ActionSheet from 'react-native-actionsheet'; import { connect } from 'react-redux'; +import { YouTubeStandaloneAndroid } from 'react-native-youtube'; +import Config from 'react-native-config'; import { customBodyScript } from './config'; import { PostPlaceHolder, CommentPlaceHolder } from '../../../basicUIElements'; @@ -20,6 +22,7 @@ import { toastNotification } from '../../../../redux/actions/uiAction'; // Constants import { default as ROUTES } from '../../../../constants/routeNames'; +import getYoutubeId from '../../../../utils/getYoutubeId'; const WIDTH = Dimensions.get('window').width; @@ -115,6 +118,9 @@ const PostBody = ({ break; case 'markdown-proposal-link': break; + case 'markdown-video-link-youtube': + _handleYoutubePress(tag); + break; case 'markdown-video-link': break; case 'image': @@ -128,6 +134,27 @@ const PostBody = ({ } catch (error) {} }; + const _handleYoutubePress = (embedUrl) => { + const videoId = getYoutubeId(embedUrl); + + if (Platform.OS === 'ios') { + //standalone play for ios goes against youtube policies, + //that is why using it as component in separate screen + navigation.navigate(ROUTES.SCREENS.YOUTUBE, { + videoId, + }); + } else { + YouTubeStandaloneAndroid.playVideo({ + apiKey: Config.YOUTUBE_API_KEY, + videoId: videoId, // The YouTube video ID, + lightboxMode: true, + autoplay: true, + }) + .then(() => console.log('Standalone Player Exited')) + .catch((errorMessage) => console.error(errorMessage)); + } + }; + const handleImagePress = (ind) => { if (ind === 1) { //open gallery mode @@ -454,6 +481,7 @@ const PostBody = ({ handleLinkPress(index); }} /> + {/* {isLoading && (isComment ? : )} */} { diff --git a/src/screens/youtube/youtubePlayer.tsx b/src/screens/youtube/youtubePlayer.tsx new file mode 100644 index 000000000..591b1180d --- /dev/null +++ b/src/screens/youtube/youtubePlayer.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { View } from 'react-native'; +import YouTube from 'react-native-youtube'; + +const YoutubePlayer = ({navigation}) => { + + const videoId = navigation.getParam('videoId'); + + if(!videoId){ + throw new Error("Please pass videoId"); + } + + return ( + + { + + }} + onChangeFullscreen={(e)=>{ + if(!e.isFullscreen){ + navigation.goBack(); + } + }} + onError={e => { + navigation.goBack(); + }} + style={{ alignSelf: 'stretch', height: '90%', backgroundColor:'black' }} + origin="http://www.youtube.com" + /> + + ) +}; + + +export default YoutubePlayer + + diff --git a/src/utils/getYoutubeId.ts b/src/utils/getYoutubeId.ts new file mode 100644 index 000000000..36eac03f8 --- /dev/null +++ b/src/utils/getYoutubeId.ts @@ -0,0 +1,10 @@ + + +export default (url) => { + var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/; + var match = url.match(regExp); + var videoId = (match&&match[7].length==11)? match[7] : false; + + console.log("Extracting id ", videoId, url); + return videoId; +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 95261723e..dea21d3de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7245,7 +7245,7 @@ prop-types@15.6.2: loose-envify "^1.3.1" object-assign "^4.1.1" -prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -7692,6 +7692,13 @@ react-native-webview@^11.2.1: escape-string-regexp "2.0.0" invariant "2.2.4" +react-native-youtube@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/react-native-youtube/-/react-native-youtube-2.0.1.tgz#1b6275ca2c1db8e13539a59ccfda8ae8479b1590" + integrity sha512-CVzJyynKoEEMXHv/Nx+s8HdovnfVIZs0DIUjWUQsgEd+kbBubXJZTguCKj4WigI8SI1LJ0thF8SEGbdqW8oJkw== + dependencies: + prop-types "^15.5.0" + react-native@0.61.5: version "0.61.5" resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.61.5.tgz#6e21acb56cbd75a3baeb1f70201a66f42600bba8"