Sfoglia il codice sorgente

[React] Cross-platform Components

Introduce certain React Components which may be used to write
cross-platform source code such as Audio like Web's audio, Container
like Web's div, Text like Web's p, etc.
master
Lyubo Marinov 8 anni fa
parent
commit
409255f056
28 ha cambiato i file con 314 aggiunte e 97 eliminazioni
  1. 111
    0
      react/features/base/media/components/AbstractAudio.js
  2. 3
    2
      react/features/base/media/components/AbstractVideoTrack.js
  3. 1
    0
      react/features/base/media/components/_.web.js
  4. 9
    9
      react/features/base/media/components/native/Audio.js
  5. 7
    5
      react/features/base/media/components/native/Video.js
  6. 1
    1
      react/features/base/media/components/native/VideoTrack.js
  7. 2
    2
      react/features/base/media/components/native/index.js
  8. 26
    0
      react/features/base/media/components/web/Audio.js
  9. 1
    0
      react/features/base/media/components/web/index.js
  10. 17
    5
      react/features/base/participants/components/Avatar.native.js
  11. 13
    3
      react/features/base/participants/components/Avatar.web.js
  12. 5
    0
      react/features/base/react/components/AbstractContainer.js
  13. 0
    58
      react/features/base/react/components/Container.native.js
  14. 0
    0
      react/features/base/react/components/Container.web.js
  15. 0
    0
      react/features/base/react/components/Link.web.js
  16. 0
    0
      react/features/base/react/components/Watermarks.native.js
  17. 1
    0
      react/features/base/react/components/_.native.js
  18. 1
    0
      react/features/base/react/components/_.web.js
  19. 1
    3
      react/features/base/react/components/index.js
  20. 55
    0
      react/features/base/react/components/native/Container.js
  21. 6
    6
      react/features/base/react/components/native/Link.js
  22. 1
    0
      react/features/base/react/components/native/Text.js
  23. 3
    0
      react/features/base/react/components/native/index.js
  24. 25
    0
      react/features/base/react/components/web/Container.js
  25. 19
    0
      react/features/base/react/components/web/Text.js
  26. 1
    1
      react/features/base/react/components/web/Watermarks.js
  27. 3
    0
      react/features/base/react/components/web/index.js
  28. 2
    2
      react/features/welcome/components/WelcomePage.native.js

+ 111
- 0
react/features/base/media/components/AbstractAudio.js Vedi File

1
+import React, { Component } from 'react';
2
+
3
+/**
4
+ * The React {@link Component} which is similar to Web's
5
+ * {@code HTMLAudioElement}.
6
+ */
7
+export default class AbstractAudio extends Component {
8
+    /**
9
+     * The (reference to the) {@link ReactElement} which actually implements
10
+     * this {@code AbstractAudio}.
11
+     */
12
+    _ref: ?Object
13
+
14
+    /**
15
+     * {@code AbstractAudio} component's property types.
16
+     *
17
+     * @static
18
+     */
19
+    static propTypes = {
20
+        /**
21
+         * The URL of a media resource to use in the element.
22
+         *
23
+         * @type {string}
24
+         */
25
+        src: React.PropTypes.string,
26
+        stream: React.PropTypes.object
27
+    };
28
+
29
+    /**
30
+     * Initializes a new {@code AbstractAudio} instance.
31
+     *
32
+     * @param {Object} props - The read-only properties with which the new
33
+     * instance is to be initialized.
34
+     */
35
+    constructor(props) {
36
+        super(props);
37
+
38
+        // Bind event handlers so they are only bound once for every instance.
39
+        this._setRef = this._setRef.bind(this);
40
+    }
41
+
42
+    /**
43
+     * Attempts to pause the playback of the media.
44
+     *
45
+     * @public
46
+     * @returns {void}
47
+     */
48
+    pause() {
49
+        this._ref && typeof this._ref.pause === 'function' && this._ref.pause();
50
+    }
51
+
52
+    /**
53
+     * Attempts to being the playback of the media.
54
+     *
55
+     * @public
56
+     * @returns {void}
57
+     */
58
+    play() {
59
+        this._ref && typeof this._ref.play === 'function' && this._ref.play();
60
+    }
61
+
62
+    /**
63
+     * Renders this {@code AbstractAudio} as a React {@link Component} of a
64
+     * specific type.
65
+     *
66
+     * @param {string|ReactClass} type - The type of the React {@code Component}
67
+     * which is to be rendered.
68
+     * @param {Object|undefined} props - The read-only React {@code Component}
69
+     * properties, if any, to render. If {@code undefined}, the props of this
70
+     * instance will be rendered.
71
+     * @protected
72
+     * @returns {ReactElement}
73
+     */
74
+    _render(type, props) {
75
+        const {
76
+            children,
77
+
78
+            /* eslint-disable no-unused-vars */
79
+
80
+            // The following properties are consumed by React itself so they are
81
+            // to not be propagated.
82
+            ref,
83
+
84
+            /* eslint-enable no-unused-vars */
85
+
86
+            ...filteredProps
87
+        } = props || this.props;
88
+
89
+        return (
90
+            React.createElement(
91
+                type,
92
+                {
93
+                    ...filteredProps,
94
+                    ref: this._setRef
95
+                },
96
+                children));
97
+    }
98
+
99
+    /**
100
+     * Set the (reference to the) {@link ReactElement} which actually implements
101
+     * this {@code AbstractAudio}.
102
+     *
103
+     * @param {Object} ref - The (reference to the) {@code ReactElement} which
104
+     * actually implements this {@code AbstractAudio}.
105
+     * @private
106
+     * @returns {void}
107
+     */
108
+    _setRef(ref) {
109
+        this._ref = ref;
110
+    }
111
+}

+ 3
- 2
react/features/base/media/components/AbstractVideoTrack.js Vedi File

6
 import { Video } from './_';
6
 import { Video } from './_';
7
 
7
 
8
 /**
8
 /**
9
- * Component that renders video element for a specified video track.
9
+ * Implements a React {@link Component} that renders video element for a
10
+ * specific video track.
10
  *
11
  *
11
  * @abstract
12
  * @abstract
12
  */
13
  */
13
-export class AbstractVideoTrack extends Component {
14
+export default class AbstractVideoTrack extends Component {
14
     /**
15
     /**
15
      * AbstractVideoTrack component's property types.
16
      * AbstractVideoTrack component's property types.
16
      *
17
      *

+ 1
- 0
react/features/base/media/components/_.web.js Vedi File

1
+export * from './web';

+ 9
- 9
react/features/base/media/components/native/Audio.js Vedi File

1
-import React, { Component } from 'react';
1
+/* @flow */
2
+
3
+import AbstractAudio from '../AbstractAudio';
2
 
4
 
3
 /**
5
 /**
4
- * The React Native component which is similar to Web's audio element and wraps
5
- * around react-native-webrtc's RTCView.
6
+ * The React Native/mobile {@link Component} which is similar to Web's
7
+ * {@code HTMLAudioElement} and wraps around react-native-webrtc's
8
+ * {@link RTCView}.
6
  */
9
  */
7
-export class Audio extends Component {
10
+export default class Audio extends AbstractAudio {
8
     /**
11
     /**
9
-     * Audio component's property types.
12
+     * {@code Audio} component's property types.
10
      *
13
      *
11
      * @static
14
      * @static
12
      */
15
      */
13
-    static propTypes = {
14
-        muted: React.PropTypes.bool,
15
-        stream: React.PropTypes.object
16
-    };
16
+    static propTypes = AbstractAudio.propTypes;
17
 
17
 
18
     /**
18
     /**
19
      * Implements React's {@link Component#render()}.
19
      * Implements React's {@link Component#render()}.

+ 7
- 5
react/features/base/media/components/native/Video.js Vedi File

1
+/* @flow */
2
+
1
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
2
 import { RTCView } from 'react-native-webrtc';
4
 import { RTCView } from 'react-native-webrtc';
3
 
5
 
4
 import { styles } from './styles';
6
 import { styles } from './styles';
5
 
7
 
6
 /**
8
 /**
7
- * The React Native component which is similar to Web's video element and wraps
8
- * around react-native-webrtc's RTCView.
9
+ * The React Native {@link Component} which is similar to Web's
10
+ * {@code HTMLVideoElement} and wraps around react-native-webrtc's
11
+ * {@link RTCView}.
9
  */
12
  */
10
-export class Video extends Component {
13
+export default class Video extends Component {
11
     /**
14
     /**
12
-     * Video component's property types.
15
+     * {@code Video} component's property types.
13
      *
16
      *
14
      * @static
17
      * @static
15
      */
18
      */
16
     static propTypes = {
19
     static propTypes = {
17
         mirror: React.PropTypes.bool,
20
         mirror: React.PropTypes.bool,
18
-        muted: React.PropTypes.bool,
19
         onPlaying: React.PropTypes.func,
21
         onPlaying: React.PropTypes.func,
20
         stream: React.PropTypes.object,
22
         stream: React.PropTypes.object,
21
 
23
 

+ 1
- 1
react/features/base/media/components/native/VideoTrack.js Vedi File

2
 import { Animated } from 'react-native';
2
 import { Animated } from 'react-native';
3
 import { connect } from 'react-redux';
3
 import { connect } from 'react-redux';
4
 
4
 
5
-import { AbstractVideoTrack } from '../AbstractVideoTrack';
5
+import AbstractVideoTrack from '../AbstractVideoTrack';
6
 import { styles } from './styles';
6
 import { styles } from './styles';
7
 
7
 
8
 /**
8
 /**

+ 2
- 2
react/features/base/media/components/native/index.js Vedi File

1
-export * from './Audio';
2
-export * from './Video';
1
+export { default as Audio } from './Audio';
2
+export { default as Video } from './Video';
3
 export { default as VideoTrack } from './VideoTrack';
3
 export { default as VideoTrack } from './VideoTrack';

+ 26
- 0
react/features/base/media/components/web/Audio.js Vedi File

1
+/* @flow */
2
+
3
+import AbstractAudio from '../AbstractAudio';
4
+
5
+/**
6
+ * The React/Web {@link Component} which is similar to and wraps around
7
+ * {@code HTMLAudioElement} in order to facilitate cross-platform source code.
8
+ */
9
+export default class Audio extends AbstractAudio {
10
+    /**
11
+     * {@code Audio} component's property types.
12
+     *
13
+     * @static
14
+     */
15
+    static propTypes = AbstractAudio.propTypes;
16
+
17
+    /**
18
+     * Implements React's {@link Component#render()}.
19
+     *
20
+     * @inheritdoc
21
+     * @returns {ReactElement}
22
+     */
23
+    render() {
24
+        return super._render('audio');
25
+    }
26
+}

+ 1
- 0
react/features/base/media/components/web/index.js Vedi File

1
+export { default as Audio } from './Audio';

+ 17
- 5
react/features/base/participants/components/Avatar.native.js Vedi File

2
 import { Image } from 'react-native';
2
 import { Image } from 'react-native';
3
 
3
 
4
 /**
4
 /**
5
- * Display a participant avatar.
5
+ * Implements an avatar as a React Native/mobile {@link Component}.
6
  */
6
  */
7
 export default class Avatar extends Component {
7
 export default class Avatar extends Component {
8
     /**
8
     /**
12
      */
12
      */
13
     static propTypes = {
13
     static propTypes = {
14
         /**
14
         /**
15
-         * The optional style to add to an Avatar in order to customize its base
16
-         * look (and feel).
15
+         * The optional style to add to the {@link Avatar} in order to customize
16
+         * its base look (and feel).
17
          */
17
          */
18
         style: React.PropTypes.object,
18
         style: React.PropTypes.object,
19
+
20
+        /**
21
+         * The URI of the {@link Avatar}.
22
+         *
23
+         * @type {string}
24
+         */
19
         uri: React.PropTypes.string
25
         uri: React.PropTypes.string
20
     };
26
     };
21
 
27
 
87
      * @inheritdoc
93
      * @inheritdoc
88
      */
94
      */
89
     render() {
95
     render() {
96
+        // Propagate all props of this Avatar but the ones consumed by this
97
+        // Avatar to the Image it renders.
98
+
99
+        // eslint-disable-next-line no-unused-vars
100
+        const { uri, ...props } = this.props;
101
+
90
         return (
102
         return (
91
             <Image
103
             <Image
104
+                { ...props }
92
 
105
 
93
                 // XXX Avatar is expected to display the whole image.
106
                 // XXX Avatar is expected to display the whole image.
94
                 resizeMode = 'contain'
107
                 resizeMode = 'contain'
95
-                source = { this.state.source }
96
-                style = { this.props.style } />
108
+                source = { this.state.source } />
97
         );
109
         );
98
     }
110
     }
99
 }
111
 }

+ 13
- 3
react/features/base/participants/components/Avatar.web.js Vedi File

1
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
2
 
2
 
3
 /**
3
 /**
4
- * Display a participant avatar.
4
+ * Implements an avatar as a React/Web {@link Component}.
5
  */
5
  */
6
 export default class Avatar extends Component {
6
 export default class Avatar extends Component {
7
     /**
7
     /**
11
      */
11
      */
12
     static propTypes = {
12
     static propTypes = {
13
         /**
13
         /**
14
-         * The URL for the avatar.
14
+         * The URI of the {@link Avatar}.
15
          *
15
          *
16
          * @type {string}
16
          * @type {string}
17
          */
17
          */
24
      * @inheritdoc
24
      * @inheritdoc
25
      */
25
      */
26
     render() {
26
     render() {
27
-        return <img src = { this.props.uri } />;
27
+        // Propagate all props of this Avatar but the ones consumed by this
28
+        // Avatar to the img it renders.
29
+
30
+        // eslint-disable-next-line no-unused-vars
31
+        const { uri, ...props } = this.props;
32
+
33
+        return (
34
+            <img
35
+                { ...props }
36
+                src = { uri } />
37
+        );
28
     }
38
     }
29
 }
39
 }

+ 5
- 0
react/features/base/react/components/AbstractContainer.js Vedi File

69
             ...filteredProps
69
             ...filteredProps
70
         } = props || this.props;
70
         } = props || this.props;
71
 
71
 
72
+        // visible
73
+        if (typeof visible !== 'undefined' && !visible) {
74
+            return null;
75
+        }
76
+
72
         return React.createElement(type, filteredProps, children);
77
         return React.createElement(type, filteredProps, children);
73
     }
78
     }
74
 }
79
 }

+ 0
- 58
react/features/base/react/components/Container.native.js Vedi File

1
-import React from 'react';
2
-import {
3
-    TouchableHighlight,
4
-    TouchableWithoutFeedback,
5
-    View
6
-} from 'react-native';
7
-
8
-import AbstractContainer from './AbstractContainer';
9
-
10
-/**
11
- * Represents a container of React Native Component children with a style.
12
- *
13
- * @extends AbstractContainer
14
- */
15
-export class Container extends AbstractContainer {
16
-    /**
17
-     * Container component's property types.
18
-     *
19
-     * @static
20
-     */
21
-    static propTypes = AbstractContainer.propTypes
22
-
23
-    /**
24
-     * Implements React's {@link Component#render()}.
25
-     *
26
-     * @inheritdoc
27
-     * @returns {ReactElement}
28
-     */
29
-    render() {
30
-        // eslint-disable-next-line prefer-const
31
-        let { onClick, style, touchFeedback, visible, ...props } = this.props;
32
-
33
-        // visible
34
-        if (typeof visible !== 'undefined' && !visible) {
35
-            return null;
36
-        }
37
-
38
-        // onClick & touchFeedback
39
-        (typeof touchFeedback === 'undefined') && (touchFeedback = onClick);
40
-
41
-        const renderParent = touchFeedback || onClick;
42
-
43
-        // eslint-disable-next-line object-property-newline
44
-        let component = this._render(View, { ...props, style });
45
-
46
-        if (renderParent) {
47
-            const parentType
48
-                = touchFeedback ? TouchableHighlight : TouchableWithoutFeedback;
49
-            const parentProps = {};
50
-
51
-            onClick && (parentProps.onPress = onClick);
52
-
53
-            component = React.createElement(parentType, parentProps, component);
54
-        }
55
-
56
-        return component;
57
-    }
58
-}

+ 0
- 0
react/features/base/react/components/Container.web.js Vedi File


+ 0
- 0
react/features/base/react/components/Link.web.js Vedi File


+ 0
- 0
react/features/base/react/components/Watermarks.native.js Vedi File


+ 1
- 0
react/features/base/react/components/_.native.js Vedi File

1
+export * from './native';

+ 1
- 0
react/features/base/react/components/_.web.js Vedi File

1
+export * from './web';

+ 1
- 3
react/features/base/react/components/index.js Vedi File

1
-export * from './Container';
2
-export * from './Link';
3
-export { default as Watermarks } from './Watermarks';
1
+export * from './_';

+ 55
- 0
react/features/base/react/components/native/Container.js Vedi File

1
+import React from 'react';
2
+import {
3
+    TouchableHighlight,
4
+    TouchableWithoutFeedback,
5
+    View
6
+} from 'react-native';
7
+
8
+import AbstractContainer from '../AbstractContainer';
9
+
10
+/**
11
+ * Represents a container of React Native/mobile {@link Component} children.
12
+ *
13
+ * @extends AbstractContainer
14
+ */
15
+export default class Container extends AbstractContainer {
16
+    /**
17
+     * {@code Container} component's property types.
18
+     *
19
+     * @static
20
+     */
21
+    static propTypes = AbstractContainer.propTypes;
22
+
23
+    /**
24
+     * Implements React's {@link Component#render()}.
25
+     *
26
+     * @inheritdoc
27
+     * @returns {ReactElement}
28
+     */
29
+    render() {
30
+        // eslint-disable-next-line prefer-const
31
+        let { onClick, style, touchFeedback, ...props } = this.props;
32
+
33
+        // eslint-disable-next-line object-property-newline
34
+        let component = this._render(View, { ...props, style });
35
+
36
+        if (component) {
37
+            // onClick & touchFeedback
38
+            (typeof touchFeedback === 'undefined') && (touchFeedback = onClick);
39
+            if (touchFeedback || onClick) {
40
+                const parentType
41
+                    = touchFeedback
42
+                        ? TouchableHighlight
43
+                        : TouchableWithoutFeedback;
44
+                const parentProps = {};
45
+
46
+                onClick && (parentProps.onPress = onClick);
47
+
48
+                component
49
+                    = React.createElement(parentType, parentProps, component);
50
+            }
51
+        }
52
+
53
+        return component;
54
+    }
55
+}

react/features/base/react/components/Link.native.js → react/features/base/react/components/native/Link.js Vedi File

1
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
2
-import { Linking, Text } from 'react-native';
2
+import { Linking } from 'react-native';
3
+
4
+import Text from './Text';
3
 
5
 
4
 /**
6
 /**
5
  * Implements a (hyper)link to a URL in the fashion of the HTML anchor element
7
  * Implements a (hyper)link to a URL in the fashion of the HTML anchor element
6
  * and its href attribute.
8
  * and its href attribute.
7
  */
9
  */
8
-export class Link extends Component {
10
+export default class Link extends Component {
9
     /**
11
     /**
10
-     * Link component's property types.
12
+     * {@code Link} component's property types.
11
      *
13
      *
12
      * @static
14
      * @static
13
      */
15
      */
56
             <Text
58
             <Text
57
                 onPress = { this._onPress }
59
                 onPress = { this._onPress }
58
                 style = { this.props.style }>
60
                 style = { this.props.style }>
59
-                {
60
-                    this.props.children
61
-                }
61
+                { this.props.children }
62
             </Text>
62
             </Text>
63
         );
63
         );
64
     }
64
     }

+ 1
- 0
react/features/base/react/components/native/Text.js Vedi File

1
+export { Text as default } from 'react-native';

+ 3
- 0
react/features/base/react/components/native/index.js Vedi File

1
+export { default as Container } from './Container';
2
+export { default as Link } from './Link';
3
+export { default as Text } from './Text';

+ 25
- 0
react/features/base/react/components/web/Container.js Vedi File

1
+import AbstractContainer from '../AbstractContainer';
2
+
3
+/**
4
+ * Represents a container of React/Web {@link Component} children with a style.
5
+ *
6
+ * @extends AbstractContainer
7
+ */
8
+export default class Container extends AbstractContainer {
9
+    /**
10
+     * {@code Container} component's property types.
11
+     *
12
+     * @static
13
+     */
14
+    static propTypes = AbstractContainer.propTypes;
15
+
16
+    /**
17
+     * Implements React's {@link Component#render()}.
18
+     *
19
+     * @inheritdoc
20
+     * @returns {ReactElement}
21
+     */
22
+    render() {
23
+        return this._render('div');
24
+    }
25
+}

+ 19
- 0
react/features/base/react/components/web/Text.js Vedi File

1
+import React, { Component } from 'react';
2
+
3
+/**
4
+ * Implements a React/Web {@link Component} for displaying text similar to React
5
+ * Native's {@code Text} in order to faciliate cross-platform source code.
6
+ *
7
+ * @extends Component
8
+ */
9
+export default class Text extends Component {
10
+    /**
11
+     * Implements React's {@link Component#render()}.
12
+     *
13
+     * @inheritdoc
14
+     * @returns {ReactElement}
15
+     */
16
+    render() {
17
+        return React.createElement('p', this.props);
18
+    }
19
+}

react/features/base/react/components/Watermarks.web.js → react/features/base/react/components/web/Watermarks.js Vedi File

3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 import { connect } from 'react-redux';
4
 import { connect } from 'react-redux';
5
 
5
 
6
-import { translate } from '../../i18n';
6
+import { translate } from '../../../i18n';
7
 
7
 
8
 declare var interfaceConfig: Object;
8
 declare var interfaceConfig: Object;
9
 
9
 

+ 3
- 0
react/features/base/react/components/web/index.js Vedi File

1
+export { default as Container } from './Container';
2
+export { default as Text } from './Text';
3
+export { default as Watermarks } from './Watermarks';

+ 2
- 2
react/features/welcome/components/WelcomePage.native.js Vedi File

1
 import React from 'react';
1
 import React from 'react';
2
-import { Text, TextInput, TouchableHighlight, View } from 'react-native';
2
+import { TextInput, TouchableHighlight, View } from 'react-native';
3
 import { connect } from 'react-redux';
3
 import { connect } from 'react-redux';
4
 
4
 
5
 import { translate } from '../../base/i18n';
5
 import { translate } from '../../base/i18n';
6
-import { Link } from '../../base/react';
6
+import { Link, Text } from '../../base/react';
7
 import { ColorPalette } from '../../base/styles';
7
 import { ColorPalette } from '../../base/styles';
8
 
8
 
9
 import { AbstractWelcomePage, _mapStateToProps } from './AbstractWelcomePage';
9
 import { AbstractWelcomePage, _mapStateToProps } from './AbstractWelcomePage';

Loading…
Annulla
Salva