@shoutem/ui 9.2.0 → 9.2.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,12 @@
1
1
  import React, { PureComponent } from 'react';
2
2
  import { View } from 'react-native';
3
+ import { Vimeo } from 'react-native-vimeo-iframe';
3
4
  import { WebView } from 'react-native-webview';
5
+ import YoutubePlayer from 'react-native-youtube-iframe';
4
6
  import PropTypes from 'prop-types';
5
7
  import { connectAnimation } from '@shoutem/animation';
6
8
  import { connectStyle } from '@shoutem/theme';
9
+ import { isAndroid } from '../../services';
7
10
  import VideoSourceReader from './VideoSourceReader';
8
11
 
9
12
  function getSource(sourceReader, poster, headers) {
@@ -29,14 +32,28 @@ function getSource(sourceReader, poster, headers) {
29
32
  return source;
30
33
  }
31
34
 
35
+ // YouTube/Vimeo iframe players require a numeric height (they can't take
36
+ // '100%'), so resolve one from the height prop, then the themed container
37
+ // height, then a default.
38
+ function resolveEmbedHeight(height, style) {
39
+ if (typeof height === 'number') {
40
+ return height;
41
+ }
42
+
43
+ const containerHeight = style?.container?.height;
44
+
45
+ if (typeof containerHeight === 'number') {
46
+ return containerHeight;
47
+ }
48
+
49
+ return 240;
50
+ }
51
+
32
52
  /**
33
- * Renders a Video based on the source type
34
- * if source is an url to a web player the
35
- * it is displayed in a WebView, if not
36
- * a Video HTML element is displayed in the
37
- * WebView.
38
- *
39
- * @returns {*}
53
+ * Renders a video based on its source type. YouTube and Vimeo go through their
54
+ * dedicated iframe players so the embed loads with a valid origin - a bare
55
+ * YouTube embed in a plain WebView has no Referer and fails with "Error 153".
56
+ * Any other source is rendered as an HTML5 video inside a WebView.
40
57
  */
41
58
  class Video extends PureComponent {
42
59
  constructor(props) {
@@ -47,7 +64,43 @@ class Video extends PureComponent {
47
64
  }
48
65
 
49
66
  render() {
50
- const { width, height = '100%', style, poster, headers } = this.props;
67
+ const {
68
+ width,
69
+ height = '100%',
70
+ style,
71
+ poster,
72
+ headers,
73
+ playerParams,
74
+ } = this.props;
75
+
76
+ if (this.sourceReader.isYouTube) {
77
+ return (
78
+ <View style={style.container}>
79
+ <YoutubePlayer
80
+ videoId={this.sourceReader.getYouTubeId()}
81
+ height={resolveEmbedHeight(height, style)}
82
+ initialPlayerParams={playerParams}
83
+ webViewProps={{ renderToHardwareTextureAndroid: true }}
84
+ />
85
+ </View>
86
+ );
87
+ }
88
+
89
+ if (this.sourceReader.isVimeo) {
90
+ return (
91
+ <View style={style.container}>
92
+ <Vimeo
93
+ videoId={this.sourceReader.getVimeoId()}
94
+ style={{ height: resolveEmbedHeight(height, style) }}
95
+ {...(isAndroid && {
96
+ overScrollMode: 'never',
97
+ androidLayerType: 'software',
98
+ })}
99
+ />
100
+ </View>
101
+ );
102
+ }
103
+
51
104
  const webViewSource = getSource(this.sourceReader, poster, headers);
52
105
 
53
106
  return (
@@ -2,7 +2,7 @@ import { stringify } from 'qs';
2
2
 
3
3
  function getYouTubeVideoId(url) {
4
4
  // eslint-disable-next-line no-useless-escape
5
- const regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\??v?=?))([^#&\?]*).*/;
5
+ const regExp = /^.*(?:(youtu.be\/)|(shorts\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\??v?=?))([^#&\?]*).*/;
6
6
  const match = url.match(regExp);
7
7
 
8
8
  if (match && match[7].length === 11) {
@@ -65,4 +65,12 @@ export default class VideoSourceReader {
65
65
 
66
66
  return this.source;
67
67
  }
68
+
69
+ getYouTubeId() {
70
+ return getYouTubeVideoId(this.source);
71
+ }
72
+
73
+ getVimeoId() {
74
+ return getVimeoVideoId(this.source);
75
+ }
68
76
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shoutem/ui",
3
- "version": "9.2.0",
3
+ "version": "9.2.1-rc.1",
4
4
  "description": "Styleable set of components for React Native applications",
5
5
  "scripts": {
6
6
  "lint": "eslint .",