瀏覽代碼

feat(unsupported-browser): show dial-in for mobile

- Move the existing components for the static dial in page into
  a separate folder for easier reuse.
- Reuse those components for displaying dial-on numbers on the
  mobile page for unsupported browsers.
- Modify those components to support having tel protocol
  links on the dial-in numbers.
- Have DialInSummary, formerly DialInInfoPage, respect a
  passed in className prop for easier styling differences.
j8
Leonard Kim 7 年之前
父節點
當前提交
1f82ce3d19

+ 23
- 1
css/unsupported-browser/_unsupported-mobile-browser.scss 查看文件

1
 .unsupported-mobile-browser {
1
 .unsupported-mobile-browser {
2
     background-color: #fff;
2
     background-color: #fff;
3
     height: 100vh;
3
     height: 100vh;
4
+    overflow: auto;
4
     padding: 35px 0;
5
     padding: 35px 0;
6
+    position: relative;
5
     width: 100vw;
7
     width: 100vw;
6
 
8
 
7
     a {
9
     a {
12
         color: $unsupportedBrowserTextColor;
14
         color: $unsupportedBrowserTextColor;
13
         margin: auto;
15
         margin: auto;
14
         max-width: 40em;
16
         max-width: 40em;
17
+        padding-bottom: 40px;
15
         text-align: center;
18
         text-align: center;
16
         width: 75%;
19
         width: 75%;
17
 
20
 
20
         }
23
         }
21
     }
24
     }
22
 
25
 
23
-    &__text {
26
+    &__text,
27
+    .unsupported-dial-in  {
24
         font-size: 1.2em;
28
         font-size: 1.2em;
25
         line-height: em(29px, 21px);
29
         line-height: em(29px, 21px);
26
         margin-bottom: 0.65em;
30
         margin-bottom: 0.65em;
65
             }
69
             }
66
         }
70
         }
67
     }
71
     }
72
+
73
+    .unsupported-dial-in {
74
+        display: none;
75
+
76
+        &.has-numbers {
77
+            align-items: center;
78
+            display: flex;
79
+            flex-direction: column;
80
+        }
81
+
82
+        .dial-in-numbers-list {
83
+            color: $unsupportedBrowserTextColor;
84
+        }
85
+
86
+        .dial-in-numbers-body {
87
+            vertical-align: top;
88
+        }
89
+    }
68
 }
90
 }

+ 4
- 2
react/features/invite/components/dial-in-info-page/DialInInfoApp.web.js 查看文件

5
 import parseURLParams from '../../../base/config/parseURLParams';
5
 import parseURLParams from '../../../base/config/parseURLParams';
6
 import { i18next } from '../../../base/i18n';
6
 import { i18next } from '../../../base/i18n';
7
 
7
 
8
-import DialInInfoPage from './DialInInfoPage';
8
+import { DialInSummary } from '../dial-in-summary';
9
 
9
 
10
 document.addEventListener('DOMContentLoaded', () => {
10
 document.addEventListener('DOMContentLoaded', () => {
11
     const params = parseURLParams(window.location, true, 'search');
11
     const params = parseURLParams(window.location, true, 'search');
12
 
12
 
13
     ReactDOM.render(
13
     ReactDOM.render(
14
         <I18nextProvider i18n = { i18next }>
14
         <I18nextProvider i18n = { i18next }>
15
-            <DialInInfoPage
15
+            <DialInSummary
16
+                className = 'dial-in-page'
17
+                clickableNumbers = { false }
16
                 room = { params.room } />
18
                 room = { params.room } />
17
         </I18nextProvider>,
19
         </I18nextProvider>,
18
         document.getElementById('react')
20
         document.getElementById('react')

react/features/invite/components/dial-in-info-page/ConferenceID.native.js → react/features/invite/components/dial-in-summary/ConferenceID.native.js 查看文件


react/features/invite/components/dial-in-info-page/ConferenceID.web.js → react/features/invite/components/dial-in-summary/ConferenceID.web.js 查看文件


react/features/invite/components/dial-in-info-page/DialInInfoPage.native.js → react/features/invite/components/dial-in-summary/DialInSummary.native.js 查看文件


react/features/invite/components/dial-in-info-page/DialInInfoPage.web.js → react/features/invite/components/dial-in-summary/DialInSummary.web.js 查看文件

14
  *
14
  *
15
  * @extends Component
15
  * @extends Component
16
  */
16
  */
17
-class DialInInfoPage extends Component {
17
+class DialInSummary extends Component {
18
     /**
18
     /**
19
-     * {@code DialInInfoPage} component's property types.
19
+     * {@code DialInSummary} component's property types.
20
      *
20
      *
21
      * @static
21
      * @static
22
      */
22
      */
23
     static propTypes = {
23
     static propTypes = {
24
+        /**
25
+         * Additional CSS classnames to append to the root of the component.
26
+         */
27
+        className: PropTypes.string,
28
+
29
+        /**
30
+         * Whether or not numbers should include links with the telephone
31
+         * protocol.
32
+         */
33
+        clickableNumbers: PropTypes.bool,
34
+
24
         /**
35
         /**
25
          * The name of the conference to show a conferenceID for.
36
          * The name of the conference to show a conferenceID for.
26
          */
37
          */
33
     };
44
     };
34
 
45
 
35
     /**
46
     /**
36
-     * {@code DialInInfoPage} component's local state.
47
+     * {@code DialInSummary} component's local state.
37
      *
48
      *
38
      * @type {Object}
49
      * @type {Object}
39
      * @property {number} conferenceID - The numeric ID of the conference, used
50
      * @property {number} conferenceID - The numeric ID of the conference, used
53
     };
64
     };
54
 
65
 
55
     /**
66
     /**
56
-     * Initializes a new {@code DialInInfoPage} instance.
67
+     * Initializes a new {@code DialInSummary} instance.
57
      *
68
      *
58
      * @param {Object} props - The read-only properties with which the new
69
      * @param {Object} props - The read-only properties with which the new
59
      * instance is to be initialized.
70
      * instance is to be initialized.
60
      */
71
      */
61
     constructor(props) {
72
     constructor(props) {
73
+        console.warn(props);
62
         super(props);
74
         super(props);
63
 
75
 
64
         // Bind event handlers so they are only bound once for every instance.
76
         // Bind event handlers so they are only bound once for every instance.
97
      * @returns {ReactElement}
109
      * @returns {ReactElement}
98
      */
110
      */
99
     render() {
111
     render() {
112
+        let className = '';
100
         let contents;
113
         let contents;
101
 
114
 
102
         const { conferenceID, error, loading, numbersEnabled } = this.state;
115
         const { conferenceID, error, loading, numbersEnabled } = this.state;
108
         } else if (error) {
121
         } else if (error) {
109
             contents = error;
122
             contents = error;
110
         } else {
123
         } else {
124
+            className = 'has-numbers';
111
             contents = [
125
             contents = [
112
                 conferenceID
126
                 conferenceID
113
                     ? <ConferenceID
127
                     ? <ConferenceID
115
                         key = 'conferenceID' />
129
                         key = 'conferenceID' />
116
                     : null,
130
                     : null,
117
                 <NumbersList
131
                 <NumbersList
132
+                    clickableNumbers = { this.props.clickableNumbers }
118
                     key = 'numbers'
133
                     key = 'numbers'
119
                     numbers = { this.state.numbers } />
134
                     numbers = { this.state.numbers } />
120
             ];
135
             ];
121
         }
136
         }
122
 
137
 
123
         return (
138
         return (
124
-            <div className = 'dial-in-page'>
139
+            <div className = { `${this.props.className} ${className}` }>
125
                 { contents }
140
                 { contents }
126
             </div>
141
             </div>
127
         );
142
         );
217
     }
232
     }
218
 }
233
 }
219
 
234
 
220
-export default translate(DialInInfoPage);
235
+export default translate(DialInSummary);

react/features/invite/components/dial-in-info-page/NumbersList.native.js → react/features/invite/components/dial-in-summary/NumbersList.native.js 查看文件


react/features/invite/components/dial-in-info-page/NumbersList.web.js → react/features/invite/components/dial-in-summary/NumbersList.web.js 查看文件

15
      * @static
15
      * @static
16
      */
16
      */
17
     static propTypes = {
17
     static propTypes = {
18
+        /**
19
+         * Whether or not numbers should include links with the telephone
20
+         * protocol.
21
+         */
22
+        clickableNumbers: PropTypes.bool,
23
+
18
         /**
24
         /**
19
          * The phone numbers to display. Can be an array of numbers
25
          * The phone numbers to display. Can be an array of numbers
20
          * or an object with countries as keys and an array of numbers
26
          * or an object with countries as keys and an array of numbers
51
                         <th>{ t('info.numbers') }</th>
57
                         <th>{ t('info.numbers') }</th>
52
                     </tr>
58
                     </tr>
53
                 </thead>
59
                 </thead>
54
-                <tbody>
60
+                <tbody className = 'dial-in-numbers-body'>
55
                     { showWithoutCountries
61
                     { showWithoutCountries
56
                         ? numbers.map(this._renderNumberRow)
62
                         ? numbers.map(this._renderNumberRow)
57
                         : this._renderWithCountries() }
63
                         : this._renderWithCountries() }
69
         const rows = [];
75
         const rows = [];
70
 
76
 
71
         for (const [ country, numbers ] of Object.entries(this.props.numbers)) {
77
         for (const [ country, numbers ] of Object.entries(this.props.numbers)) {
72
-            const formattedNumbers = numbers.map(this._renderNumberDiv);
78
+            const formattedNumbers = numbers.map(
79
+                number => this._renderNumberDiv(number));
73
 
80
 
74
             rows.push(
81
             rows.push(
75
                 <tr key = { country }>
82
                 <tr key = { country }>
93
         return (
100
         return (
94
             <tr key = { number }>
101
             <tr key = { number }>
95
                 <td className = 'dial-in-number'>
102
                 <td className = 'dial-in-number'>
96
-                    { number }
103
+                    { this._renderNumberLink(number) }
97
                 </td>
104
                 </td>
98
             </tr>
105
             </tr>
99
         );
106
         );
111
             <div
118
             <div
112
                 className = 'dial-in-number'
119
                 className = 'dial-in-number'
113
                 key = { number }>
120
                 key = { number }>
114
-                { number }
121
+                { this._renderNumberLink(number) }
115
             </div>
122
             </div>
116
         );
123
         );
117
     }
124
     }
125
+
126
+    /**
127
+     * Renders a ReactElement for displaying a telephone number. If the
128
+     * component prop {@code clickableNumbers} is true, then the number will
129
+     * have a link with the telephone protocol.
130
+     *
131
+     * @param {string} number - The phone number to display.
132
+     * @private
133
+     * @returns {ReactElement}
134
+     */
135
+    _renderNumberLink(number) {
136
+        if (this.props.clickableNumbers) {
137
+            return (
138
+                <a
139
+                    href = { `tel:${number}` }
140
+                    key = { number } >
141
+                    { number }
142
+                </a>
143
+            );
144
+        }
145
+
146
+        return number;
147
+    }
148
+
118
 }
149
 }
119
 
150
 
120
 export default translate(NumbersList);
151
 export default translate(NumbersList);

+ 1
- 0
react/features/invite/components/dial-in-summary/index.js 查看文件

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

+ 1
- 0
react/features/invite/components/index.js 查看文件

1
 export { default as AddPeopleDialog } from './AddPeopleDialog';
1
 export { default as AddPeopleDialog } from './AddPeopleDialog';
2
 export { default as InfoDialogButton } from './InfoDialogButton';
2
 export { default as InfoDialogButton } from './InfoDialogButton';
3
 export { default as InviteButton } from './InviteButton';
3
 export { default as InviteButton } from './InviteButton';
4
+export { DialInSummary } from './dial-in-summary';

+ 28
- 3
react/features/unsupported-browser/components/UnsupportedMobileBrowser.js 查看文件

2
 
2
 
3
 import PropTypes from 'prop-types';
3
 import PropTypes from 'prop-types';
4
 import React, { Component } from 'react';
4
 import React, { Component } from 'react';
5
+import { connect } from 'react-redux';
5
 
6
 
6
 import { translate, translateToHTML } from '../../base/i18n';
7
 import { translate, translateToHTML } from '../../base/i18n';
7
 import { Platform } from '../../base/react';
8
 import { Platform } from '../../base/react';
8
-
9
+import { DialInSummary } from '../../invite';
9
 import HideNotificationBarStyle from './HideNotificationBarStyle';
10
 import HideNotificationBarStyle from './HideNotificationBarStyle';
10
 
11
 
11
 declare var interfaceConfig: Object;
12
 declare var interfaceConfig: Object;
54
      * @static
55
      * @static
55
      */
56
      */
56
     static propTypes = {
57
     static propTypes = {
58
+        /**
59
+         * The name of the conference attempting to being joined.
60
+         */
61
+        _room: PropTypes.string,
62
+
57
         /**
63
         /**
58
          * The function to translate human-readable text.
64
          * The function to translate human-readable text.
59
          *
65
          *
122
                             { t(`${_TNS}.downloadApp`) }
128
                             { t(`${_TNS}.downloadApp`) }
123
                         </button>
129
                         </button>
124
                     </a>
130
                     </a>
131
+                    <DialInSummary
132
+                        className = 'unsupported-dial-in'
133
+                        clickableNumbers = { true }
134
+                        room = { this.props._room } />
125
                 </div>
135
                 </div>
126
-
127
                 <HideNotificationBarStyle />
136
                 <HideNotificationBarStyle />
128
             </div>
137
             </div>
129
         );
138
         );
130
     }
139
     }
131
 }
140
 }
132
 
141
 
133
-export default translate(UnsupportedMobileBrowser);
142
+/**
143
+ * Maps (parts of) the Redux state to the associated props for the
144
+ * {@code UnsupportedMobileBrowser} component.
145
+ *
146
+ * @param {Object} state - The Redux state.
147
+ * @private
148
+ * @returns {{
149
+ *     _room: string
150
+ * }}
151
+ */
152
+function _mapStateToProps(state) {
153
+    return {
154
+        _room: state['features/base/conference'].room
155
+    };
156
+}
157
+
158
+export default translate(connect(_mapStateToProps)(UnsupportedMobileBrowser));

Loading…
取消
儲存