소스 검색

ref(RecentList): Improvements after review.

factor2
hristoterezov 6 년 전
부모
커밋
fb75180632
25개의 변경된 파일198개의 추가작업 그리고 145개의 파일을 삭제
  1. 15
    19
      conference.js
  2. 1
    1
      css/main.scss
  3. 5
    0
      package-lock.json
  4. 46
    0
      react/features/base/conference/middleware.js
  5. 9
    0
      react/features/base/lib-jitsi-meet/native/polyfills-browser.js
  6. 4
    6
      react/features/base/react/Types.js
  7. 7
    13
      react/features/base/react/components/NavigateSectionList.js
  8. 3
    1
      react/features/base/react/components/native/Container.js
  9. 3
    6
      react/features/base/react/components/native/NavigateSectionListEmptyComponent.js
  10. 25
    29
      react/features/base/react/components/native/NavigateSectionListItem.js
  11. 2
    1
      react/features/base/react/components/native/NavigateSectionListSectionHeader.js
  12. 2
    1
      react/features/base/react/components/web/NavigateSectionListItem.js
  13. 1
    1
      react/features/base/react/components/web/NavigateSectionListSectionHeader.js
  14. 1
    1
      react/features/base/react/components/web/SectionList.js
  15. 1
    0
      react/features/base/react/index.js
  16. 9
    5
      react/features/base/storage/middleware.js
  17. 5
    2
      react/features/recent-list/components/RecentList.js
  18. 0
    7
      react/features/recent-list/featureFlag.native.js
  19. 0
    10
      react/features/recent-list/featureFlag.web.js
  20. 15
    20
      react/features/recent-list/functions.any.js
  21. 11
    2
      react/features/recent-list/functions.native.js
  22. 18
    5
      react/features/recent-list/functions.web.js
  23. 9
    9
      react/features/recent-list/middleware.js
  24. 4
    4
      react/features/recent-list/reducer.js
  25. 2
    2
      react/features/welcome/components/WelcomePage.web.js

+ 15
- 19
conference.js 파일 보기

38
     conferenceWillLeave,
38
     conferenceWillLeave,
39
     dataChannelOpened,
39
     dataChannelOpened,
40
     EMAIL_COMMAND,
40
     EMAIL_COMMAND,
41
-    getCurrentConference,
42
     lockStateChanged,
41
     lockStateChanged,
43
     onStartMutedPolicyChanged,
42
     onStartMutedPolicyChanged,
44
     p2pStatusChanged,
43
     p2pStatusChanged,
307
     _onConferenceFailed(err, ...params) {
306
     _onConferenceFailed(err, ...params) {
308
         APP.store.dispatch(conferenceFailed(room, err, ...params));
307
         APP.store.dispatch(conferenceFailed(room, err, ...params));
309
         logger.error('CONFERENCE FAILED:', err, ...params);
308
         logger.error('CONFERENCE FAILED:', err, ...params);
310
-        const state = APP.store.getState();
311
-
312
-        // The conference we have already joined or are joining.
313
-        const conference = getCurrentConference(state);
314
 
309
 
315
         switch (err) {
310
         switch (err) {
316
         case JitsiConferenceErrors.CONNECTION_ERROR: {
311
         case JitsiConferenceErrors.CONNECTION_ERROR: {
378
 
373
 
379
         case JitsiConferenceErrors.FOCUS_LEFT:
374
         case JitsiConferenceErrors.FOCUS_LEFT:
380
         case JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE:
375
         case JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE:
376
+            APP.store.dispatch(conferenceWillLeave(room));
377
+
381
             // FIXME the conference should be stopped by the library and not by
378
             // FIXME the conference should be stopped by the library and not by
382
             // the app. Both the errors above are unrecoverable from the library
379
             // the app. Both the errors above are unrecoverable from the library
383
             // perspective.
380
             // perspective.
384
-            APP.store.dispatch(conferenceWillLeave(conference));
385
             room.leave().then(() => connection.disconnect());
381
             room.leave().then(() => connection.disconnect());
386
             break;
382
             break;
387
 
383
 
475
             JitsiConnectionEvents.CONNECTION_FAILED,
471
             JitsiConnectionEvents.CONNECTION_FAILED,
476
             _connectionFailedHandler);
472
             _connectionFailedHandler);
477
         if (room) {
473
         if (room) {
478
-            const state = APP.store.getState();
479
-
480
-            // The conference we have already joined or are joining.
481
-            const conference = getCurrentConference(state);
482
-
483
-            APP.store.dispatch(conferenceWillLeave(conference));
474
+            APP.store.dispatch(conferenceWillLeave(room));
484
             room.leave();
475
             room.leave();
485
         }
476
         }
486
     }
477
     }
2478
      * requested
2469
      * requested
2479
      */
2470
      */
2480
     hangup(requestFeedback = false) {
2471
     hangup(requestFeedback = false) {
2481
-        const state = APP.store.getState();
2482
-
2483
-        // The conference we have already joined or are joining.
2484
-        const conference = getCurrentConference(state);
2485
-
2486
-        APP.store.dispatch(conferenceWillLeave(conference));
2487
         eventEmitter.emit(JitsiMeetConferenceEvents.BEFORE_HANGUP);
2472
         eventEmitter.emit(JitsiMeetConferenceEvents.BEFORE_HANGUP);
2488
         APP.UI.removeLocalMedia();
2473
         APP.UI.removeLocalMedia();
2489
 
2474
 
2512
         // before all operations are done.
2497
         // before all operations are done.
2513
         Promise.all([
2498
         Promise.all([
2514
             requestFeedbackPromise,
2499
             requestFeedbackPromise,
2515
-            room.leave().then(disconnect, disconnect)
2500
+            this.leaveRoomAndDisconnect()
2516
         ]).then(values => {
2501
         ]).then(values => {
2517
             APP.API.notifyReadyToClose();
2502
             APP.API.notifyReadyToClose();
2518
             maybeRedirectToWelcomePage(values[0]);
2503
             maybeRedirectToWelcomePage(values[0]);
2519
         });
2504
         });
2520
     },
2505
     },
2521
 
2506
 
2507
+    /**
2508
+     * Leaves the room and calls JitsiConnection.disconnect.
2509
+     *
2510
+     * @returns {Promise}
2511
+     */
2512
+    leaveRoomAndDisconnect() {
2513
+        APP.store.dispatch(conferenceWillLeave(room));
2514
+
2515
+        return room.leave().then(disconnect, disconnect);
2516
+    },
2517
+
2522
     /**
2518
     /**
2523
      * Changes the email for the local user
2519
      * Changes the email for the local user
2524
      * @param email {string} the new email
2520
      * @param email {string} the new email

+ 1
- 1
css/main.scss 파일 보기

79
 @import 'deep-linking/main';
79
 @import 'deep-linking/main';
80
 @import 'transcription-subtitles';
80
 @import 'transcription-subtitles';
81
 @import 'navigate_section_list';
81
 @import 'navigate_section_list';
82
-@import 'transcription-subtitles';
82
+/* Modules END */

+ 5
- 0
package-lock.json 파일 보기

10502
       "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.4.tgz",
10502
       "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.4.tgz",
10503
       "integrity": "sha512-1xFTAknSLfc47DIxHDUbnJWC+UwgWxATmymaxIPQpmMh7LBm7ZbwVEsuushqwL2GYZU0jie4xO+TK44hJPjNSQ=="
10503
       "integrity": "sha512-1xFTAknSLfc47DIxHDUbnJWC+UwgWxATmymaxIPQpmMh7LBm7ZbwVEsuushqwL2GYZU0jie4xO+TK44hJPjNSQ=="
10504
     },
10504
     },
10505
+    "moment-duration-format": {
10506
+      "version": "2.2.2",
10507
+      "resolved": "https://registry.npmjs.org/moment-duration-format/-/moment-duration-format-2.2.2.tgz",
10508
+      "integrity": "sha1-uVdhLeJgFsmtnrYIfAVFc+USd3k="
10509
+    },
10505
     "morgan": {
10510
     "morgan": {
10506
       "version": "1.9.0",
10511
       "version": "1.9.0",
10507
       "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
10512
       "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",

+ 46
- 0
react/features/base/conference/middleware.js 파일 보기

24
 import {
24
 import {
25
     conferenceFailed,
25
     conferenceFailed,
26
     conferenceLeft,
26
     conferenceLeft,
27
+    conferenceWillLeave,
27
     createConference,
28
     createConference,
28
     setLastN
29
     setLastN
29
 } from './actions';
30
 } from './actions';
30
 import {
31
 import {
31
     CONFERENCE_FAILED,
32
     CONFERENCE_FAILED,
32
     CONFERENCE_JOINED,
33
     CONFERENCE_JOINED,
34
+    CONFERENCE_WILL_LEAVE,
33
     DATA_CHANNEL_OPENED,
35
     DATA_CHANNEL_OPENED,
34
     SET_AUDIO_ONLY,
36
     SET_AUDIO_ONLY,
35
     SET_LASTN,
37
     SET_LASTN,
46
 
48
 
47
 declare var APP: Object;
49
 declare var APP: Object;
48
 
50
 
51
+/**
52
+ * Handler for before unload event.
53
+ */
54
+let beforeUnloadHandler;
55
+
49
 /**
56
 /**
50
  * Implements the middleware of the feature base/conference.
57
  * Implements the middleware of the feature base/conference.
51
  *
58
  *
66
     case CONNECTION_FAILED:
73
     case CONNECTION_FAILED:
67
         return _connectionFailed(store, next, action);
74
         return _connectionFailed(store, next, action);
68
 
75
 
76
+    case CONFERENCE_WILL_LEAVE:
77
+        _conferenceWillLeave();
78
+        break;
79
+
69
     case DATA_CHANNEL_OPENED:
80
     case DATA_CHANNEL_OPENED:
70
         return _syncReceiveVideoQuality(store, next, action);
81
         return _syncReceiveVideoQuality(store, next, action);
71
 
82
 
135
     // conference is handled by /conference.js and appropriate failure handlers
146
     // conference is handled by /conference.js and appropriate failure handlers
136
     // are set there.
147
     // are set there.
137
     if (typeof APP !== 'undefined') {
148
     if (typeof APP !== 'undefined') {
149
+        if (typeof beforeUnloadHandler !== 'undefined') {
150
+            window.removeEventListener('beforeunload', beforeUnloadHandler);
151
+            beforeUnloadHandler = undefined;
152
+        }
153
+
138
         return result;
154
         return result;
139
     }
155
     }
140
 
156
 
175
     // and the LastN value needs to be synchronized here.
191
     // and the LastN value needs to be synchronized here.
176
     audioOnly && conference.getLastN() !== 0 && dispatch(setLastN(0));
192
     audioOnly && conference.getLastN() !== 0 && dispatch(setLastN(0));
177
 
193
 
194
+    // FIXME: Very dirty solution. This will work on web only.
195
+    // When the user closes the window or quits the browser, lib-jitsi-meet
196
+    // handles the process of leaving the conference. This is temporary solution
197
+    // that should cover the described use case as part of the effort to
198
+    // implement the conferenceWillLeave action for web.
199
+    beforeUnloadHandler = () => {
200
+        dispatch(conferenceWillLeave(conference));
201
+    };
202
+    window.addEventListener('beforeunload', beforeUnloadHandler);
203
+
178
     return result;
204
     return result;
179
 }
205
 }
180
 
206
 
227
 
253
 
228
     const result = next(action);
254
     const result = next(action);
229
 
255
 
256
+    if (typeof beforeUnloadHandler !== 'undefined') {
257
+        window.removeEventListener('beforeunload', beforeUnloadHandler);
258
+        beforeUnloadHandler = undefined;
259
+    }
260
+
230
     // FIXME: Workaround for the web version. Currently, the creation of the
261
     // FIXME: Workaround for the web version. Currently, the creation of the
231
     // conference is handled by /conference.js and appropriate failure handlers
262
     // conference is handled by /conference.js and appropriate failure handlers
232
     // are set there.
263
     // are set there.
266
     return result;
297
     return result;
267
 }
298
 }
268
 
299
 
300
+/**
301
+ * Notifies the feature base/conference that the action
302
+ * {@code CONFERENCE_WILL_LEAVE} is being dispatched within a specific redux
303
+ * store.
304
+ *
305
+ * @private
306
+ * @returns {void}
307
+ */
308
+function _conferenceWillLeave() {
309
+    if (typeof beforeUnloadHandler !== 'undefined') {
310
+        window.removeEventListener('beforeunload', beforeUnloadHandler);
311
+        beforeUnloadHandler = undefined;
312
+    }
313
+}
314
+
269
 /**
315
 /**
270
  * Returns whether or not a CONNECTION_FAILED action is for a possible split
316
  * Returns whether or not a CONNECTION_FAILED action is for a possible split
271
  * brain error. A split brain error occurs when at least two users join a
317
  * brain error. A split brain error occurs when at least two users join a

+ 9
- 0
react/features/base/lib-jitsi-meet/native/polyfills-browser.js 파일 보기

114
         global.addEventListener = () => {};
114
         global.addEventListener = () => {};
115
     }
115
     }
116
 
116
 
117
+    // removeEventListener
118
+    //
119
+    // Required by:
120
+    // - features/base/conference/middleware
121
+    if (typeof global.removeEventListener === 'undefined') {
122
+        // eslint-disable-next-line no-empty-function
123
+        global.removeEventListener = () => {};
124
+    }
125
+
117
     // Array.prototype[@@iterator]
126
     // Array.prototype[@@iterator]
118
     //
127
     //
119
     // Required by:
128
     // Required by:

+ 4
- 6
react/features/base/react/Types.js 파일 보기

1
 // @flow
1
 // @flow
2
+
3
+import type { ComponentType, Element } from 'react';
4
+
2
 /**
5
 /**
3
- * item data for NavigateSectionList
6
+ * Item data for <tt>NavigateSectionList</tt>.
4
  */
7
  */
5
-import type {
6
-    ComponentType,
7
-    Element
8
-} from 'react';
9
-
10
 export type Item = {
8
 export type Item = {
11
 
9
 
12
     /**
10
     /**

+ 7
- 13
react/features/base/react/components/NavigateSectionList.js 파일 보기

2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 
4
 
5
-import { translate } from '../../i18n';
6
-
5
+// TODO: Maybe try to make all NavigateSectionList components to work for both
6
+// mobile and web, and move them to NavigateSectionList component.
7
 import {
7
 import {
8
     NavigateSectionListEmptyComponent,
8
     NavigateSectionListEmptyComponent,
9
     NavigateSectionListItem,
9
     NavigateSectionListItem,
19
      */
19
      */
20
     disabled: boolean,
20
     disabled: boolean,
21
 
21
 
22
-    /**
23
-     * The translate function.
24
-     */
25
-    t: Function,
26
-
27
     /**
22
     /**
28
      * Function to be invoked when an item is pressed. The item's URL is passed.
23
      * Function to be invoked when an item is pressed. The item's URL is passed.
29
      */
24
      */
59
      * @private
54
      * @private
60
      * @returns {Object}
55
      * @returns {Object}
61
      */
56
      */
62
-    static createSection(title, key) {
57
+    static createSection(title: string, key: string) {
63
         return {
58
         return {
64
             data: [],
59
             data: [],
65
             key,
60
             key,
166
      * @private
161
      * @private
167
      * @returns {Component}
162
      * @returns {Component}
168
      */
163
      */
169
-    _renderItem(listItem, key = '') {
164
+    _renderItem(listItem, key: string = '') {
170
         const { item } = listItem;
165
         const { item } = listItem;
171
         const { url } = item;
166
         const { url } = item;
172
 
167
 
197
      * @returns {React$Node}
192
      * @returns {React$Node}
198
      */
193
      */
199
     _renderListEmptyComponent() {
194
     _renderListEmptyComponent() {
200
-        const { t, onRefresh } = this.props;
195
+        const { onRefresh } = this.props;
201
 
196
 
202
         if (typeof onRefresh === 'function') {
197
         if (typeof onRefresh === 'function') {
203
             return (
198
             return (
204
-                <NavigateSectionListEmptyComponent
205
-                    t = { t } />
199
+                <NavigateSectionListEmptyComponent />
206
             );
200
             );
207
         }
201
         }
208
 
202
 
226
     }
220
     }
227
 }
221
 }
228
 
222
 
229
-export default translate(NavigateSectionList);
223
+export default NavigateSectionList;

+ 3
- 1
react/features/base/react/components/native/Container.js 파일 보기

34
             accessible,
34
             accessible,
35
             onClick,
35
             onClick,
36
             touchFeedback = onClick,
36
             touchFeedback = onClick,
37
+            underlayColor,
37
             visible = true,
38
             visible = true,
38
             ...props
39
             ...props
39
         } = this.props;
40
         } = this.props;
62
                     {
63
                     {
63
                         accessibilityLabel,
64
                         accessibilityLabel,
64
                         accessible,
65
                         accessible,
65
-                        onPress: onClick
66
+                        onPress: onClick,
67
+                        underlayColor
66
                     },
68
                     },
67
                     element);
69
                     element);
68
         }
70
         }

+ 3
- 6
react/features/base/react/components/native/NavigateSectionListEmptyComponent.js 파일 보기

1
 // @flow
1
 // @flow
2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
-import {
5
-    Text,
6
-    View
7
-} from 'react-native';
4
+import { Text, View } from 'react-native';
8
 
5
 
9
-import { Icon } from '../../../font-icons/index';
10
-import { translate } from '../../../i18n/index';
6
+import { Icon } from '../../../font-icons';
7
+import { translate } from '../../../i18n';
11
 
8
 
12
 import styles from './styles';
9
 import styles from './styles';
13
 
10
 

+ 25
- 29
react/features/base/react/components/native/NavigateSectionListItem.js 파일 보기

1
 // @flow
1
 // @flow
2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
-import { TouchableHighlight } from 'react-native';
5
 
4
 
6
-import {
7
-    Text,
8
-    Container
9
-} from './index';
5
+import Container from './Container';
6
+import Text from './Text';
10
 import styles, { UNDERLAY_COLOR } from './styles';
7
 import styles, { UNDERLAY_COLOR } from './styles';
11
 import type { Item } from '../../Types';
8
 import type { Item } from '../../Types';
12
 
9
 
110
      */
107
      */
111
     render() {
108
     render() {
112
         const { colorBase, lines, title } = this.props.item;
109
         const { colorBase, lines, title } = this.props.item;
110
+        const avatarStyles = {
111
+            ...styles.avatar,
112
+            ...this._getAvatarColor(colorBase)
113
+        };
113
 
114
 
114
         return (
115
         return (
115
-            <TouchableHighlight
116
-                onPress = { this.props.onPress }
116
+            <Container
117
+                onClick = { this.props.onPress }
118
+                style = { styles.listItem }
117
                 underlayColor = { UNDERLAY_COLOR }>
119
                 underlayColor = { UNDERLAY_COLOR }>
118
-                <Container style = { styles.listItem }>
119
-                    <Container style = { styles.avatarContainer }>
120
-                        <Container
121
-                            style = { [
122
-                                styles.avatar,
123
-                                this._getAvatarColor(colorBase)
124
-                            ] }>
125
-                            <Text style = { styles.avatarContent }>
126
-                                {title.substr(0, 1).toUpperCase()}
127
-                            </Text>
128
-                        </Container>
129
-                    </Container>
130
-                    <Container style = { styles.listItemDetails }>
131
-                        <Text
132
-                            numberOfLines = { 1 }
133
-                            style = { [
134
-                                styles.listItemText,
135
-                                styles.listItemTitle
136
-                            ] }>
137
-                            {title}
120
+                <Container style = { styles.avatarContainer }>
121
+                    <Container style = { avatarStyles }>
122
+                        <Text style = { styles.avatarContent }>
123
+                            {title.substr(0, 1).toUpperCase()}
138
                         </Text>
124
                         </Text>
139
-                        {this._renderItemLines(lines)}
140
                     </Container>
125
                     </Container>
141
                 </Container>
126
                 </Container>
142
-            </TouchableHighlight>
127
+                <Container style = { styles.listItemDetails }>
128
+                    <Text
129
+                        numberOfLines = { 1 }
130
+                        style = {{
131
+                            ...styles.listItemText,
132
+                            ...styles.listItemTitle
133
+                        }}>
134
+                        {title}
135
+                    </Text>
136
+                    {this._renderItemLines(lines)}
137
+                </Container>
138
+            </Container>
143
         );
139
         );
144
     }
140
     }
145
 }
141
 }

+ 2
- 1
react/features/base/react/components/native/NavigateSectionListSectionHeader.js 파일 보기

2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 
4
 
5
-import { Text, Container } from './index';
5
+import Container from './Container';
6
 import styles from './styles';
6
 import styles from './styles';
7
+import Text from './Text';
7
 import type { SetionListSection } from '../../Types';
8
 import type { SetionListSection } from '../../Types';
8
 
9
 
9
 type Props = {
10
 type Props = {

+ 2
- 1
react/features/base/react/components/web/NavigateSectionListItem.js 파일 보기

2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 
4
 
5
-import { Text, Container } from './index';
5
+import Container from './Container';
6
+import Text from './Text';
6
 import type { Item } from '../../Types';
7
 import type { Item } from '../../Types';
7
 
8
 
8
 type Props = {
9
 type Props = {

+ 1
- 1
react/features/base/react/components/web/NavigateSectionListSectionHeader.js 파일 보기

2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 
4
 
5
-import { Text } from './index';
5
+import Text from './Text';
6
 import type { Section } from '../../Types';
6
 import type { Section } from '../../Types';
7
 
7
 
8
 type Props = {
8
 type Props = {

+ 1
- 1
react/features/base/react/components/web/SectionList.js 파일 보기

2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 
4
 
5
-import { Container } from './index';
5
+import Container from './Container';
6
 import type { Section } from '../../Types';
6
 import type { Section } from '../../Types';
7
 
7
 
8
 type Props = {
8
 type Props = {

+ 1
- 0
react/features/base/react/index.js 파일 보기

1
 export * from './components';
1
 export * from './components';
2
 export { default as Platform } from './Platform';
2
 export { default as Platform } from './Platform';
3
+export * from './Types';

+ 9
- 5
react/features/base/storage/middleware.js 파일 보기

20
         state => PersistenceRegistry.persistState(state),
20
         state => PersistenceRegistry.persistState(state),
21
         PERSIST_STATE_DELAY);
21
         PERSIST_STATE_DELAY);
22
 
22
 
23
+// Web only code.
24
+// We need the <tt>if</tt> beacuse it appears that on mobile the polyfill is not
25
+// executed yet.
26
+if (typeof window.addEventListener === 'function') {
27
+    window.addEventListener('unload', () => {
28
+        throttledPersistState.flush();
29
+    });
30
+}
31
+
23
 /**
32
 /**
24
  * A master MiddleWare to selectively persist state. Please use the
33
  * A master MiddleWare to selectively persist state. Please use the
25
  * {@link persisterconfig.json} to set which subtrees of the redux state should
34
  * {@link persisterconfig.json} to set which subtrees of the redux state should
37
 
46
 
38
     return result;
47
     return result;
39
 });
48
 });
40
-
41
-window.addEventListener('beforeunload', () => {
42
-    // Stop the LogCollector
43
-    throttledPersistState.flush();
44
-});

+ 5
- 2
react/features/recent-list/components/RecentList.js 파일 보기

4
 
4
 
5
 import { appNavigate, getDefaultURL } from '../../app';
5
 import { appNavigate, getDefaultURL } from '../../app';
6
 import { translate } from '../../base/i18n';
6
 import { translate } from '../../base/i18n';
7
-import type { Section } from '../../base/react/Types';
8
 import { NavigateSectionList } from '../../base/react';
7
 import { NavigateSectionList } from '../../base/react';
8
+import type { Section } from '../../base/react';
9
 
9
 
10
-import { toDisplayableList } from '../functions';
10
+import { isRecentListEnabled, toDisplayableList } from '../functions';
11
 
11
 
12
 /**
12
 /**
13
  * The type of the React {@code Component} props of {@link RecentList}
13
  * The type of the React {@code Component} props of {@link RecentList}
62
      * @inheritdoc
62
      * @inheritdoc
63
      */
63
      */
64
     render() {
64
     render() {
65
+        if (!isRecentListEnabled()) {
66
+            return null;
67
+        }
65
         const { disabled, t, _defaultServerURL, _recentList } = this.props;
68
         const { disabled, t, _defaultServerURL, _recentList } = this.props;
66
         const recentList = toDisplayableList(_recentList, t, _defaultServerURL);
69
         const recentList = toDisplayableList(_recentList, t, _defaultServerURL);
67
 
70
 

+ 0
- 7
react/features/recent-list/featureFlag.native.js 파일 보기

1
-/**
2
- * Everything about recent list on web should be behind a feature flag and in
3
- * order to share code, this alias for the feature flag on mobile is always true
4
- * because we dont need a feature flag for recent list on mobile
5
- * @type {boolean}
6
- */
7
-export const RECENT_LIST_ENABLED = true;

+ 0
- 10
react/features/recent-list/featureFlag.web.js 파일 보기

1
-// @flow
2
-declare var interfaceConfig: Object;
3
-
4
-/**
5
- * Everything about recent list on web should be behind a feature flag and in
6
- * order to share code, this alias for the feature flag on mobile is set to the
7
- * value defined in interface_config
8
- * @type {boolean}
9
- */
10
-export const { RECENT_LIST_ENABLED } = interfaceConfig;

react/features/recent-list/functions.all.js → react/features/recent-list/functions.any.js 파일 보기

1
-import { getLocalizedDateFormatter, getLocalizedDurationFormatter }
2
-    from '../base/i18n/index';
3
-import { parseURIString } from '../base/util/index';
1
+import {
2
+    getLocalizedDateFormatter,
3
+    getLocalizedDurationFormatter
4
+} from '../base/i18n';
5
+import { parseURIString } from '../base/util';
4
 
6
 
5
 /**
7
 /**
6
  * Creates a displayable list item of a recent list entry.
8
  * Creates a displayable list item of a recent list entry.
12
  * @returns {Object}
14
  * @returns {Object}
13
  */
15
  */
14
 export function toDisplayableItem(item, defaultServerURL, t) {
16
 export function toDisplayableItem(item, defaultServerURL, t) {
15
-    // const { _defaultServerURL } = this.props;
16
     const location = parseURIString(item.conference);
17
     const location = parseURIString(item.conference);
17
     const baseURL = `${location.protocol}//${location.host}`;
18
     const baseURL = `${location.protocol}//${location.host}`;
18
     const serverName = baseURL === defaultServerURL ? null : location.host;
19
     const serverName = baseURL === defaultServerURL ? null : location.host;
54
  * @returns {string}
55
  * @returns {string}
55
  */
56
  */
56
 export function _toDateString(itemDate, t) {
57
 export function _toDateString(itemDate, t) {
57
-    const date = new Date(itemDate);
58
-    const dateString = date.toDateString();
59
     const m = getLocalizedDateFormatter(itemDate);
58
     const m = getLocalizedDateFormatter(itemDate);
60
-    const yesterday = new Date();
61
-
62
-    yesterday.setDate(yesterday.getDate() - 1);
63
-    const yesterdayString = yesterday.toDateString();
64
-    const today = new Date();
65
-    const todayString = today.toDateString();
66
-    const currentYear = today.getFullYear();
67
-    const year = date.getFullYear();
59
+    const date = new Date(itemDate);
60
+    const dateInMs = date.getTime();
61
+    const now = new Date();
62
+    const todayInMs = (new Date()).setHours(0, 0, 0, 0);
63
+    const yesterdayInMs = todayInMs - 86400000; // 1 day = 86400000ms
68
 
64
 
69
-    if (dateString === todayString) {
70
-        // The date is today, we use fromNow format.
65
+    if (dateInMs >= todayInMs) {
71
         return m.fromNow();
66
         return m.fromNow();
72
-    } else if (dateString === yesterdayString) {
67
+    } else if (dateInMs >= yesterdayInMs) {
73
         return t('dateUtils.yesterday');
68
         return t('dateUtils.yesterday');
74
-    } else if (year !== currentYear) {
75
-        // we only want to include the year in the date if its not the current
76
-        // year
69
+    } else if (date.getFullYear() !== now.getFullYear()) {
70
+        // We only want to include the year in the date if its not the current
71
+        // year.
77
         return m.format('ddd, MMMM DD h:mm A, gggg');
72
         return m.format('ddd, MMMM DD h:mm A, gggg');
78
     }
73
     }
79
 
74
 

+ 11
- 2
react/features/recent-list/functions.native.js 파일 보기

1
-import { NavigateSectionList } from '../base/react/index';
1
+import { NavigateSectionList } from '../base/react';
2
 
2
 
3
-import { toDisplayableItem } from './functions.all';
3
+import { toDisplayableItem } from './functions.any';
4
 
4
 
5
 /**
5
 /**
6
  * Transforms the history list to a displayable list
6
  * Transforms the history list to a displayable list
60
     return displayableList;
60
     return displayableList;
61
 }
61
 }
62
 
62
 
63
+/**
64
+ * Returns <tt>true</tt> if recent list is enabled and <tt>false</tt> otherwise.
65
+ *
66
+ * @returns {boolean} <tt>true</tt> if recent list is enabled and <tt>false</tt>
67
+ * otherwise.
68
+ */
69
+export function isRecentListEnabled() {
70
+    return true;
71
+}

+ 18
- 5
react/features/recent-list/functions.web.js 파일 보기

1
-import { NavigateSectionList } from '../base/react/index';
1
+/* global interfaceConfig */
2
+
3
+import { NavigateSectionList } from '../base/react';
4
+
5
+import { toDisplayableItem } from './functions.any';
2
 
6
 
3
-import { toDisplayableItem } from './functions.all';
4
 
7
 
5
 /**
8
 /**
6
  * Transforms the history list to a displayable list
9
  * Transforms the history list to a displayable list
14
  */
17
  */
15
 export function toDisplayableList(recentList, t, defaultServerURL) {
18
 export function toDisplayableList(recentList, t, defaultServerURL) {
16
     const { createSection } = NavigateSectionList;
19
     const { createSection } = NavigateSectionList;
17
-    const section = createSection(t('recentList.joinPastMeeting'), 'all');
20
+    const section
21
+        = createSection(t('recentList.joinPastMeeting'), 'joinPastMeeting');
18
 
22
 
19
-    // we only want the last three conferences we were in for web
20
-    for (const item of recentList.slice(1).slice(-3)) {
23
+    // We only want the last three conferences we were in for web.
24
+    for (const item of recentList.slice(-3)) {
21
         const displayableItem = toDisplayableItem(item, defaultServerURL, t);
25
         const displayableItem = toDisplayableItem(item, defaultServerURL, t);
22
 
26
 
23
         section.data.push(displayableItem);
27
         section.data.push(displayableItem);
32
     return displayableList;
36
     return displayableList;
33
 }
37
 }
34
 
38
 
39
+/**
40
+ * Returns <tt>true</tt> if recent list is enabled and <tt>false</tt> otherwise.
41
+ *
42
+ * @returns {boolean} <tt>true</tt> if recent list is enabled and <tt>false</tt>
43
+ * otherwise.
44
+ */
45
+export function isRecentListEnabled() {
46
+    return interfaceConfig.RECENT_LIST_ENABLED;
47
+}

+ 9
- 9
react/features/recent-list/middleware.js 파일 보기

1
 // @flow
1
 // @flow
2
 
2
 
3
 import { APP_WILL_MOUNT } from '../base/app';
3
 import { APP_WILL_MOUNT } from '../base/app';
4
-import { CONFERENCE_WILL_LEAVE, SET_ROOM } from '../base/conference';
5
-import { JITSI_CONFERENCE_URL_KEY } from '../base/conference/constants';
4
+import {
5
+    CONFERENCE_WILL_LEAVE,
6
+    SET_ROOM,
7
+    JITSI_CONFERENCE_URL_KEY
8
+} from '../base/conference';
6
 import { addKnownDomains } from '../base/known-domains';
9
 import { addKnownDomains } from '../base/known-domains';
7
 import { MiddlewareRegistry } from '../base/redux';
10
 import { MiddlewareRegistry } from '../base/redux';
8
 import { parseURIString } from '../base/util';
11
 import { parseURIString } from '../base/util';
9
-import { RECENT_LIST_ENABLED } from './featureFlag';
10
 
12
 
11
 import { _storeCurrentConference, _updateConferenceDuration } from './actions';
13
 import { _storeCurrentConference, _updateConferenceDuration } from './actions';
14
+import { isRecentListEnabled } from './functions';
12
 
15
 
13
-/**
14
- * used in order to get the device because there is a different way to get the
15
- * location URL on web and on native
16
- */
17
 declare var APP: Object;
16
 declare var APP: Object;
18
 
17
 
19
 /**
18
 /**
24
  * @returns {Function}
23
  * @returns {Function}
25
  */
24
  */
26
 MiddlewareRegistry.register(store => next => action => {
25
 MiddlewareRegistry.register(store => next => action => {
27
-    if (RECENT_LIST_ENABLED) {
26
+    if (isRecentListEnabled()) {
28
         switch (action.type) {
27
         switch (action.type) {
29
         case APP_WILL_MOUNT:
28
         case APP_WILL_MOUNT:
30
             return _appWillMount(store, next, action);
29
             return _appWillMount(store, next, action);
89
 function _conferenceWillLeave({ dispatch, getState }, next, action) {
88
 function _conferenceWillLeave({ dispatch, getState }, next, action) {
90
     let locationURL;
89
     let locationURL;
91
 
90
 
92
-    /** FIXME
91
+    /**
92
+     * FIXME:
93
      * It is better to use action.conference[JITSI_CONFERENCE_URL_KEY]
93
      * It is better to use action.conference[JITSI_CONFERENCE_URL_KEY]
94
      * in order to make sure we get the url the conference is leaving
94
      * in order to make sure we get the url the conference is leaving
95
      * from (i.e. the room we are leaving from) because if the order of events
95
      * from (i.e. the room we are leaving from) because if the order of events

+ 4
- 4
react/features/recent-list/reducer.js 파일 보기

8
     _STORE_CURRENT_CONFERENCE,
8
     _STORE_CURRENT_CONFERENCE,
9
     _UPDATE_CONFERENCE_DURATION
9
     _UPDATE_CONFERENCE_DURATION
10
 } from './actionTypes';
10
 } from './actionTypes';
11
-import { RECENT_LIST_ENABLED } from './featureFlag';
11
+import { isRecentListEnabled } from './functions';
12
 
12
 
13
 const logger = require('jitsi-meet-logger').getLogger(__filename);
13
 const logger = require('jitsi-meet-logger').getLogger(__filename);
14
 
14
 
50
 ReducerRegistry.register(
50
 ReducerRegistry.register(
51
     STORE_NAME,
51
     STORE_NAME,
52
     (state = _getLegacyRecentRoomList(), action) => {
52
     (state = _getLegacyRecentRoomList(), action) => {
53
-        if (RECENT_LIST_ENABLED) {
53
+        if (isRecentListEnabled()) {
54
             switch (action.type) {
54
             switch (action.type) {
55
             case APP_WILL_MOUNT:
55
             case APP_WILL_MOUNT:
56
                 return _appWillMount(state);
56
                 return _appWillMount(state);
62
             default:
62
             default:
63
                 return state;
63
                 return state;
64
             }
64
             }
65
-        } else {
66
-            return state;
67
         }
65
         }
66
+
67
+        return state;
68
     });
68
     });
69
 
69
 
70
 /**
70
 /**

+ 2
- 2
react/features/welcome/components/WelcomePage.web.js 파일 보기

100
      */
100
      */
101
     render() {
101
     render() {
102
         const { t } = this.props;
102
         const { t } = this.props;
103
-        const { APP_NAME, RECENT_LIST_ENABLED } = interfaceConfig;
103
+        const { APP_NAME } = interfaceConfig;
104
         const showAdditionalContent = this._shouldShowAdditionalContent();
104
         const showAdditionalContent = this._shouldShowAdditionalContent();
105
 
105
 
106
         return (
106
         return (
147
                                 { t('welcomepage.go') }
147
                                 { t('welcomepage.go') }
148
                             </Button>
148
                             </Button>
149
                         </div>
149
                         </div>
150
-                        { RECENT_LIST_ENABLED ? <RecentList /> : null }
150
+                        <RecentList />
151
                     </div>
151
                     </div>
152
                     { showAdditionalContent
152
                     { showAdditionalContent
153
                         ? <div
153
                         ? <div

Loading…
취소
저장