diff --git a/app/components/post_list/post/body/content/youtube/index.ts b/app/components/post_list/post/body/content/youtube/index.ts
deleted file mode 100644
index 22ad39fbc7..0000000000
--- a/app/components/post_list/post/body/content/youtube/index.ts
+++ /dev/null
@@ -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));
diff --git a/app/components/post_list/post/body/content/youtube/index.tsx b/app/components/post_list/post/body/content/youtube/index.tsx
new file mode 100644
index 0000000000..cb208ed1a8
--- /dev/null
+++ b/app/components/post_list/post/body/content/youtube/index.tsx
@@ -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 (
+
+
+
+
+
+
+
+ );
+};
+
+export default React.memo(YouTube);
diff --git a/app/components/post_list/post/body/content/youtube/youtube.tsx b/app/components/post_list/post/body/content/youtube/youtube.tsx
deleted file mode 100644
index 7c9b2095af..0000000000
--- a/app/components/post_list/post/body/content/youtube/youtube.tsx
+++ /dev/null
@@ -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 (
-
-
-
-
-
-
-
- );
-};
-
-export default React.memo(YouTube);
diff --git a/ios/Mattermost.xcodeproj/project.pbxproj b/ios/Mattermost.xcodeproj/project.pbxproj
index 8ad2779e91..3df5c9ebab 100644
--- a/ios/Mattermost.xcodeproj/project.pbxproj
+++ b/ios/Mattermost.xcodeproj/project.pbxproj
@@ -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;
diff --git a/ios/Podfile b/ios/Podfile
index 99b8c4b101..b4d42696b8 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -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)
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 7394ade679..8a53a3f218 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -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
diff --git a/ios/patches/XCDYouTubeVideoOperation.patch b/ios/patches/XCDYouTubeVideoOperation.patch
deleted file mode 100644
index 041d8cb55f..0000000000
--- a/ios/patches/XCDYouTubeVideoOperation.patch
+++ /dev/null
@@ -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];
diff --git a/package-lock.json b/package-lock.json
index 1edd7d4b63..ed3541965c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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",
diff --git a/package.json b/package.json
index af2289d6bb..c5a1128687 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/patches/react-native-youtube+2.0.2.patch b/patches/react-native-youtube+2.0.2.patch
deleted file mode 100644
index 8c0d8752ac..0000000000
--- a/patches/react-native-youtube+2.0.2.patch
+++ /dev/null
@@ -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 {
- }
-
- export declare const YouTubeStandaloneIOS: {
-- playVideo(videoId: string): Promise;
-+ playVideo(videoId: string, startTime: number): Promise;
- };
-
- export declare const YouTubeStandaloneAndroid: {