forked from Ivasoft/mattermost-mobile
Remove react-native-youtube and allow the link to be handled natively (#6239)
This commit is contained in:
@@ -1,17 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
|
||||
import withObservables from '@nozbe/with-observables';
|
||||
|
||||
import {observeConfigValue} from '@queries/servers/system';
|
||||
|
||||
import YouTube from './youtube';
|
||||
|
||||
import type {WithDatabaseArgs} from '@typings/database/database';
|
||||
|
||||
const enhance = withObservables([], ({database}: WithDatabaseArgs) => ({
|
||||
googleDeveloperKey: observeConfigValue(database, 'GoogleDeveloperKey'),
|
||||
}));
|
||||
|
||||
export default withDatabase(enhance(YouTube));
|
||||
102
app/components/post_list/post/body/content/youtube/index.tsx
Normal file
102
app/components/post_list/post/body/content/youtube/index.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useCallback} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Alert, Image, StyleSheet, TouchableOpacity, View} from 'react-native';
|
||||
|
||||
import ProgressiveImage from '@components/progressive_image';
|
||||
import {useIsTablet} from '@hooks/device';
|
||||
import {emptyFunction} from '@utils/general';
|
||||
import {calculateDimensions, getViewPortWidth} from '@utils/images';
|
||||
import {getYouTubeVideoId, tryOpenURL} from '@utils/url';
|
||||
|
||||
type YouTubeProps = {
|
||||
isReplyPost: boolean;
|
||||
layoutWidth?: number;
|
||||
metadata: PostMetadata;
|
||||
}
|
||||
|
||||
const MAX_YOUTUBE_IMAGE_HEIGHT = 202;
|
||||
const MAX_YOUTUBE_IMAGE_WIDTH = 360;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
imageContainer: {
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'flex-start',
|
||||
marginBottom: 6,
|
||||
marginTop: 10,
|
||||
},
|
||||
image: {
|
||||
alignItems: 'center',
|
||||
borderRadius: 3,
|
||||
justifyContent: 'center',
|
||||
marginVertical: 1,
|
||||
},
|
||||
playButton: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
const YouTube = ({isReplyPost, layoutWidth, metadata}: YouTubeProps) => {
|
||||
const intl = useIntl();
|
||||
const isTablet = useIsTablet();
|
||||
const link = metadata.embeds![0].url;
|
||||
const videoId = getYouTubeVideoId(link);
|
||||
const dimensions = calculateDimensions(
|
||||
MAX_YOUTUBE_IMAGE_HEIGHT,
|
||||
MAX_YOUTUBE_IMAGE_WIDTH,
|
||||
layoutWidth || getViewPortWidth(isReplyPost, isTablet),
|
||||
);
|
||||
|
||||
const playYouTubeVideo = useCallback(() => {
|
||||
const onError = () => {
|
||||
Alert.alert(
|
||||
intl.formatMessage({
|
||||
id: 'mobile.link.error.title',
|
||||
defaultMessage: 'Error',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'mobile.link.error.text',
|
||||
defaultMessage: 'Unable to open the link.',
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
tryOpenURL(link, onError);
|
||||
}, [link, intl.locale]);
|
||||
|
||||
let imgUrl;
|
||||
if (metadata.images) {
|
||||
imgUrl = Object.keys(metadata.images)[0];
|
||||
}
|
||||
|
||||
if (!imgUrl) {
|
||||
// Fallback to default YouTube thumbnail if available
|
||||
imgUrl = `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`;
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[styles.imageContainer, {height: dimensions.height}]}
|
||||
onPress={playYouTubeVideo}
|
||||
>
|
||||
<ProgressiveImage
|
||||
id={imgUrl}
|
||||
isBackgroundImage={true}
|
||||
imageUri={imgUrl}
|
||||
style={[styles.image, dimensions]}
|
||||
resizeMode='cover'
|
||||
onError={emptyFunction}
|
||||
>
|
||||
<View style={styles.playButton}>
|
||||
<Image source={require('@assets/images/icons/youtube-play-icon.png')}/>
|
||||
</View>
|
||||
</ProgressiveImage>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(YouTube);
|
||||
@@ -1,172 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useCallback} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Alert, Image, Platform, StatusBar, StyleSheet, TouchableOpacity, View} from 'react-native';
|
||||
import {YouTubeStandaloneAndroid, YouTubeStandaloneIOS} from 'react-native-youtube';
|
||||
|
||||
import ProgressiveImage from '@components/progressive_image';
|
||||
import {useIsTablet} from '@hooks/device';
|
||||
import {emptyFunction} from '@utils/general';
|
||||
import {calculateDimensions, getViewPortWidth} from '@utils/images';
|
||||
import {getYouTubeVideoId, tryOpenURL} from '@utils/url';
|
||||
|
||||
type YouTubeProps = {
|
||||
googleDeveloperKey?: string;
|
||||
isReplyPost: boolean;
|
||||
layoutWidth?: number;
|
||||
metadata: PostMetadata;
|
||||
}
|
||||
|
||||
const MAX_YOUTUBE_IMAGE_HEIGHT = 202;
|
||||
const MAX_YOUTUBE_IMAGE_WIDTH = 360;
|
||||
const timeRegex = /[\\?&](t|start|time_continue)=([0-9]+h)?([0-9]+m)?([0-9]+s?)/;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
imageContainer: {
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'flex-start',
|
||||
marginBottom: 6,
|
||||
marginTop: 10,
|
||||
},
|
||||
image: {
|
||||
alignItems: 'center',
|
||||
borderRadius: 3,
|
||||
justifyContent: 'center',
|
||||
marginVertical: 1,
|
||||
},
|
||||
playButton: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
const YouTube = ({googleDeveloperKey, isReplyPost, layoutWidth, metadata}: YouTubeProps) => {
|
||||
const intl = useIntl();
|
||||
const isTablet = useIsTablet();
|
||||
const link = metadata.embeds![0].url;
|
||||
const videoId = getYouTubeVideoId(link);
|
||||
const dimensions = calculateDimensions(
|
||||
MAX_YOUTUBE_IMAGE_HEIGHT,
|
||||
MAX_YOUTUBE_IMAGE_WIDTH,
|
||||
layoutWidth || getViewPortWidth(isReplyPost, isTablet),
|
||||
);
|
||||
|
||||
const getYouTubeTime = () => {
|
||||
const time = link.match(timeRegex);
|
||||
if (!time || !time[0]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const hours = time[2] ? time[2].match(/([0-9]+)h/) : null;
|
||||
const minutes = time[3] ? time[3].match(/([0-9]+)m/) : null;
|
||||
const seconds = time[4] ? time[4].match(/([0-9]+)s?/) : null;
|
||||
|
||||
let ticks = 0;
|
||||
|
||||
if (hours && hours[1]) {
|
||||
ticks += parseInt(hours[1], 10) * 3600;
|
||||
}
|
||||
|
||||
if (minutes && minutes[1]) {
|
||||
ticks += parseInt(minutes[1], 10) * 60;
|
||||
}
|
||||
|
||||
if (seconds && seconds[1]) {
|
||||
ticks += parseInt(seconds[1], 10);
|
||||
}
|
||||
|
||||
return ticks;
|
||||
};
|
||||
|
||||
const playYouTubeVideo = useCallback(() => {
|
||||
const startTime = getYouTubeTime();
|
||||
|
||||
if (googleDeveloperKey) {
|
||||
if (Platform.OS === 'ios') {
|
||||
YouTubeStandaloneIOS.
|
||||
playVideo(videoId, startTime).
|
||||
then(playYouTubeVideoEnded).
|
||||
catch(playYouTubeVideoError);
|
||||
return;
|
||||
}
|
||||
|
||||
YouTubeStandaloneAndroid.playVideo({
|
||||
apiKey: googleDeveloperKey,
|
||||
videoId,
|
||||
autoplay: true,
|
||||
startTime,
|
||||
}).catch(playYouTubeVideoError);
|
||||
} else {
|
||||
const onError = () => {
|
||||
Alert.alert(
|
||||
intl.formatMessage({
|
||||
id: 'mobile.link.error.title',
|
||||
defaultMessage: 'Error',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'mobile.link.error.text',
|
||||
defaultMessage: 'Unable to open the link.',
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
tryOpenURL(link, onError);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const playYouTubeVideoEnded = () => {
|
||||
if (Platform.OS === 'ios') {
|
||||
StatusBar.setHidden(false);
|
||||
}
|
||||
};
|
||||
|
||||
const playYouTubeVideoError = (errorMessage: string) => {
|
||||
Alert.alert(
|
||||
intl.formatMessage({
|
||||
id: 'mobile.youtube_playback_error.title',
|
||||
defaultMessage: 'YouTube playback error',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'mobile.youtube_playback_error.description',
|
||||
defaultMessage: 'An error occurred while trying to play the YouTube video.\nDetails: {details}',
|
||||
}, {
|
||||
details: errorMessage,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
let imgUrl;
|
||||
if (metadata.images) {
|
||||
imgUrl = Object.keys(metadata.images)[0];
|
||||
}
|
||||
|
||||
if (!imgUrl) {
|
||||
// Fallback to default YouTube thumbnail if available
|
||||
imgUrl = `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`;
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[styles.imageContainer, {height: dimensions.height}]}
|
||||
onPress={playYouTubeVideo}
|
||||
>
|
||||
<ProgressiveImage
|
||||
id={imgUrl}
|
||||
isBackgroundImage={true}
|
||||
imageUri={imgUrl}
|
||||
style={[styles.image, dimensions]}
|
||||
resizeMode='cover'
|
||||
onError={emptyFunction}
|
||||
>
|
||||
<View style={styles.playButton}>
|
||||
<Image source={require('@assets/images/icons/youtube-play-icon.png')}/>
|
||||
</View>
|
||||
</ProgressiveImage>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(YouTube);
|
||||
@@ -620,7 +620,6 @@
|
||||
"${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}/React-Core/AccessibilityResources.bundle",
|
||||
"${PODS_ROOT}/YoutubePlayer-in-WKWebView/WKYTPlayerView/WKYTPlayerView.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/iosMath/mathFonts.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
@@ -642,7 +641,6 @@
|
||||
"${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}/AccessibilityResources.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/WKYTPlayerView.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/mathFonts.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
||||
@@ -27,7 +27,6 @@ target 'Mattermost' do
|
||||
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi', :modular_headers => true
|
||||
pod 'simdjson', path: '../node_modules/@nozbe/simdjson'
|
||||
|
||||
pod 'XCDYouTubeKit', '2.8.2'
|
||||
pod 'Swime', '3.0.6'
|
||||
|
||||
# TODO: Remove this once upstream PR https://github.com/daltoniam/Starscream/pull/871 is merged
|
||||
@@ -46,9 +45,6 @@ end
|
||||
react_native_post_install(installer)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
|
||||
puts 'Patching XCDYouTube so it can playback videos'
|
||||
%x(patch Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoOperation.m < patches/XCDYouTubeVideoOperation.patch)
|
||||
|
||||
puts 'Patching Alamofire to include X-Uncompressed-Content-Length to measure download progress'
|
||||
%x(patch Pods/Alamofire/Source/SessionDelegate.swift < patches/SessionDelegate.patch)
|
||||
|
||||
|
||||
@@ -123,9 +123,6 @@ PODS:
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.68.0)
|
||||
- React-Core (= 0.68.0)
|
||||
- RCTYouTube (2.0.2):
|
||||
- React
|
||||
- YoutubePlayer-in-WKWebView (~> 0.3.1)
|
||||
- React (0.68.0):
|
||||
- React-Core (= 0.68.0)
|
||||
- React-Core/DevSupport (= 0.68.0)
|
||||
@@ -536,11 +533,9 @@ PODS:
|
||||
- WatermelonDB (0.24.0):
|
||||
- React
|
||||
- React-jsi
|
||||
- XCDYouTubeKit (2.8.2)
|
||||
- Yoga (1.14.0)
|
||||
- YogaKit (1.18.1):
|
||||
- Yoga (~> 1.14)
|
||||
- YoutubePlayer-in-WKWebView (0.3.8)
|
||||
|
||||
DEPENDENCIES:
|
||||
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||
@@ -581,7 +576,6 @@ DEPENDENCIES:
|
||||
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- 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-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
|
||||
- React-Codegen (from `build/generated/ios`)
|
||||
@@ -649,7 +643,6 @@ DEPENDENCIES:
|
||||
- Starscream (from `https://github.com/mattermost/Starscream.git`, commit `cb83dd247339ff6c155f0e749d6fe2cc145f5283`)
|
||||
- Swime (= 3.0.6)
|
||||
- "WatermelonDB (from `../node_modules/@nozbe/watermelondb`)"
|
||||
- XCDYouTubeKit (= 2.8.2)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
SPEC REPOS:
|
||||
@@ -679,9 +672,7 @@ SPEC REPOS:
|
||||
- SocketRocket
|
||||
- SwiftyJSON
|
||||
- Swime
|
||||
- XCDYouTubeKit
|
||||
- YogaKit
|
||||
- YoutubePlayer-in-WKWebView
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
boost:
|
||||
@@ -712,8 +703,6 @@ 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-callinvoker:
|
||||
@@ -884,7 +873,6 @@ SPEC CHECKSUMS:
|
||||
RCT-Folly: 4d8508a426467c48885f1151029bc15fa5d7b3b8
|
||||
RCTRequired: bab4a7c3d7eb9553b13773ee190f279712efd1fc
|
||||
RCTTypeSafety: efbeb6e450ff6cef8e19c2cb5314c6d8bfeeef77
|
||||
RCTYouTube: a8bb45705622a6fc9decf64be04128d3658ed411
|
||||
React: 28e4d45839b7d0fd9512af899e0379a17a5172ec
|
||||
React-callinvoker: 5585d1ef6795786f288690b19e08bed253c33155
|
||||
React-Codegen: 80ce98fda08a8ddb6f47116375ae2c1670bf8cda
|
||||
@@ -956,11 +944,9 @@ SPEC CHECKSUMS:
|
||||
SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e
|
||||
Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b
|
||||
WatermelonDB: baec390a1039dcebeee959218900c978af3407c9
|
||||
XCDYouTubeKit: 79baadb0560673a67c771eba45f83e353fd12c1f
|
||||
Yoga: 6671cf077f614314c22fd09ddf87d7abeee64e96
|
||||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||
YoutubePlayer-in-WKWebView: 4fca3b4f6f09940077bfbae7bddb771f2b43aacd
|
||||
|
||||
PODFILE CHECKSUM: 9b7206e144619146e3d5456de646e7d0c34b25ec
|
||||
PODFILE CHECKSUM: bb161ae7bf12d0d04e6c9584b673aeeee5bf3639
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
--- Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoOperation.m 2021-05-28 20:53:40.000000000 -0400
|
||||
+++ XCDYouTubeVideoOperation.m 2021-05-28 20:55:18.000000000 -0400
|
||||
@@ -119,7 +119,7 @@
|
||||
NSString *eventLabel = [self.eventLabels objectAtIndex:0];
|
||||
[self.eventLabels removeObjectAtIndex:0];
|
||||
|
||||
- NSDictionary *query = @{ @"video_id": self.videoIdentifier, @"hl": self.languageIdentifier, @"el": eventLabel, @"ps": @"default" };
|
||||
+ NSDictionary *query = @{ @"video_id": self.videoIdentifier, @"hl": self.languageIdentifier, @"el": eventLabel, @"ps": @"default", @"html5": @"1"};
|
||||
NSString *queryString = XCDQueryStringWithDictionary(query);
|
||||
NSURL *videoInfoURL = [NSURL URLWithString:[@"https://www.youtube.com/get_video_info?" stringByAppendingString:queryString]];
|
||||
[self startRequestWithURL:videoInfoURL type:XCDYouTubeRequestTypeGetVideoInfo];
|
||||
20
package-lock.json
generated
20
package-lock.json
generated
@@ -85,7 +85,6 @@
|
||||
"react-native-vector-icons": "9.1.0",
|
||||
"react-native-video": "5.2.0",
|
||||
"react-native-webview": "11.18.1",
|
||||
"react-native-youtube": "2.0.2",
|
||||
"react-syntax-highlighter": "15.5.0",
|
||||
"reanimated-bottom-sheet": "1.0.0-alpha.22",
|
||||
"rn-placeholder": "3.0.3",
|
||||
@@ -19584,17 +19583,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-youtube": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-youtube/-/react-native-youtube-2.0.2.tgz",
|
||||
"integrity": "sha512-tyoGG8mqv0q2327BUYCXBmloUO8twFTOsGdwYvj0tiINAwtxNid8bS0KxnjViH3f/HmBqATDbPwhHpNXpOCsLA==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react-native": ">=0.60"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native/node_modules/@jest/types": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
|
||||
@@ -38611,14 +38599,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-native-youtube": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-youtube/-/react-native-youtube-2.0.2.tgz",
|
||||
"integrity": "sha512-tyoGG8mqv0q2327BUYCXBmloUO8twFTOsGdwYvj0tiINAwtxNid8bS0KxnjViH3f/HmBqATDbPwhHpNXpOCsLA==",
|
||||
"requires": {
|
||||
"prop-types": "^15.5.0"
|
||||
}
|
||||
},
|
||||
"react-refresh": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
|
||||
|
||||
@@ -83,7 +83,6 @@
|
||||
"react-native-vector-icons": "9.1.0",
|
||||
"react-native-video": "5.2.0",
|
||||
"react-native-webview": "11.18.1",
|
||||
"react-native-youtube": "2.0.2",
|
||||
"react-syntax-highlighter": "15.5.0",
|
||||
"reanimated-bottom-sheet": "1.0.0-alpha.22",
|
||||
"rn-placeholder": "3.0.3",
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
diff --git a/node_modules/react-native-youtube/RCTYouTubeStandalone.m b/node_modules/react-native-youtube/RCTYouTubeStandalone.m
|
||||
index fabd291..45b322b 100644
|
||||
--- a/node_modules/react-native-youtube/RCTYouTubeStandalone.m
|
||||
+++ b/node_modules/react-native-youtube/RCTYouTubeStandalone.m
|
||||
@@ -5,6 +5,15 @@
|
||||
#endif
|
||||
@import AVKit;
|
||||
|
||||
+@interface AVPlayerViewControllerRotation : AVPlayerViewController
|
||||
+@end
|
||||
+
|
||||
+@implementation AVPlayerViewControllerRotation
|
||||
+- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
||||
+ return UIInterfaceOrientationMaskAllButUpsideDown;
|
||||
+}
|
||||
+@end
|
||||
+
|
||||
@implementation RCTYouTubeStandalone {
|
||||
RCTPromiseResolveBlock resolver;
|
||||
RCTPromiseRejectBlock rejecter;
|
||||
@@ -14,6 +23,7 @@ RCT_EXPORT_MODULE();
|
||||
|
||||
RCT_REMAP_METHOD(playVideo,
|
||||
playVideoWithResolver:(NSString*)videoId
|
||||
+ startTime:(NSNumber* _Nonnull)startTime
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
@@ -22,10 +32,10 @@ RCT_REMAP_METHOD(playVideo,
|
||||
#else
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
UIViewController *root = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
||||
- AVPlayerViewController *playerViewController = [AVPlayerViewController new];
|
||||
+ AVPlayerViewControllerRotation *playerViewController = [AVPlayerViewControllerRotation new];
|
||||
[root presentViewController:playerViewController animated:YES completion:nil];
|
||||
|
||||
- __weak AVPlayerViewController *weakPlayerViewController = playerViewController;
|
||||
+ __weak AVPlayerViewControllerRotation *weakPlayerViewController = playerViewController;
|
||||
|
||||
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:videoId
|
||||
completionHandler:^(XCDYouTubeVideo * _Nullable video, NSError * _Nullable error) {
|
||||
@@ -38,10 +48,18 @@ RCT_REMAP_METHOD(playVideo,
|
||||
streamURLs[@(XCDYouTubeVideoQualitySmall240)
|
||||
];
|
||||
|
||||
- weakPlayerViewController.player = [AVPlayer playerWithURL:streamURL];
|
||||
- [weakPlayerViewController.player play];
|
||||
-
|
||||
- resolve(@"YouTubeStandaloneIOS player launched successfully");
|
||||
+ @try {
|
||||
+ CMTime initialPlaybackTime = CMTimeMakeWithSeconds([startTime doubleValue], 1);
|
||||
+ weakPlayerViewController.player = [AVPlayer playerWithURL:streamURL];
|
||||
+ [weakPlayerViewController.player seekToTime:initialPlaybackTime completionHandler: ^(BOOL finished) {
|
||||
+ [weakPlayerViewController.player play];
|
||||
+ resolve(@"YouTubeStandaloneIOS player launched successfully");
|
||||
+ }];
|
||||
+ }
|
||||
+ @catch (NSException *ex) {
|
||||
+ reject(@"error", ex.reason, nil);
|
||||
+ [root dismissViewControllerAnimated:YES completion:nil];
|
||||
+ }
|
||||
} else {
|
||||
reject(@"error", error.localizedDescription, nil);
|
||||
[root dismissViewControllerAnimated:YES completion:nil];
|
||||
diff --git a/node_modules/react-native-youtube/YouTubeStandalone.ios.js b/node_modules/react-native-youtube/YouTubeStandalone.ios.js
|
||||
index 0ee59c6..4a8294b 100644
|
||||
--- a/node_modules/react-native-youtube/YouTubeStandalone.ios.js
|
||||
+++ b/node_modules/react-native-youtube/YouTubeStandalone.ios.js
|
||||
@@ -4,4 +4,4 @@ const { YouTubeStandalone } = NativeModules;
|
||||
|
||||
export const YouTubeStandaloneIOS = !YouTubeStandalone
|
||||
? null
|
||||
- : { playVideo: (videoId) => YouTubeStandalone.playVideo(videoId) };
|
||||
+ : { playVideo: (videoId, startTime) => YouTubeStandalone.playVideo(videoId, startTime) };
|
||||
diff --git a/node_modules/react-native-youtube/android/build.gradle b/node_modules/react-native-youtube/android/build.gradle
|
||||
index 0417bc6..6249f65 100755
|
||||
--- a/node_modules/react-native-youtube/android/build.gradle
|
||||
+++ b/node_modules/react-native-youtube/android/build.gradle
|
||||
@@ -6,8 +6,9 @@ def safeExtGet(prop, fallback) {
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
+ mavenCentral()
|
||||
+ mavenLocal()
|
||||
google()
|
||||
- jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
diff --git a/node_modules/react-native-youtube/main.d.ts b/node_modules/react-native-youtube/main.d.ts
|
||||
index 80c7df5..849104b 100644
|
||||
--- a/node_modules/react-native-youtube/main.d.ts
|
||||
+++ b/node_modules/react-native-youtube/main.d.ts
|
||||
@@ -36,7 +36,7 @@ declare class YouTube extends React.Component<YouTubeProps> {
|
||||
}
|
||||
|
||||
export declare const YouTubeStandaloneIOS: {
|
||||
- playVideo(videoId: string): Promise<void>;
|
||||
+ playVideo(videoId: string, startTime: number): Promise<void>;
|
||||
};
|
||||
|
||||
export declare const YouTubeStandaloneAndroid: {
|
||||
Reference in New Issue
Block a user