浏览代码

More generic way to refresh lists on the welcome screen

master
zbettenbuk 7 年前
父节点
当前提交
63c165ee8b

+ 0
- 14
react/features/calendar-sync/components/MeetingList.native.js 查看文件

35
      */
35
      */
36
     dispatch: Function,
36
     dispatch: Function,
37
 
37
 
38
-    /**
39
-     * Tells the component if it's being displayed at the moment, or not. Note:
40
-     * as an example, on Android it can happen that the component is rendered
41
-     * but not displayed, because components like ViewPagerAndroid render their
42
-     * children even if they are not visible at the moment.
43
-     */
44
-    displayed: boolean,
45
-
46
     /**
38
     /**
47
      * The translate function.
39
      * The translate function.
48
      */
40
      */
85
     constructor(props) {
77
     constructor(props) {
86
         super(props);
78
         super(props);
87
 
79
 
88
-        const { dispatch, displayed } = props;
89
-
90
-        if (displayed) {
91
-            dispatch(refreshCalendar());
92
-        }
93
-
94
         this._getRenderListEmptyComponent
80
         this._getRenderListEmptyComponent
95
             = this._getRenderListEmptyComponent.bind(this);
81
             = this._getRenderListEmptyComponent.bind(this);
96
         this._onPress = this._onPress.bind(this);
82
         this._onPress = this._onPress.bind(this);

+ 46
- 11
react/features/welcome/components/AbstractPagedList.native.js 查看文件

2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 import { View } from 'react-native';
4
 import { View } from 'react-native';
5
-import { isCalendarEnabled } from '../../calendar-sync';
5
+
6
+import { MeetingList } from '../../calendar-sync';
6
 import { RecentList } from '../../recent-list';
7
 import { RecentList } from '../../recent-list';
7
 
8
 
8
 import styles from './styles';
9
 import styles from './styles';
28
      * The i18n translate function
29
      * The i18n translate function
29
      */
30
      */
30
     t: Function
31
     t: Function
31
-}
32
+};
32
 
33
 
33
 type State = {
34
 type State = {
34
 
35
 
36
      * The currently selected page.
37
      * The currently selected page.
37
      */
38
      */
38
     pageIndex: number
39
     pageIndex: number
39
-}
40
+};
40
 
41
 
41
 /**
42
 /**
42
  * Abstract class for the platform specific paged lists.
43
  * Abstract class for the platform specific paged lists.
43
  */
44
  */
44
 export default class AbstractPagedList extends Component<Props, State> {
45
 export default class AbstractPagedList extends Component<Props, State> {
45
     /**
46
     /**
46
-     * True if the calendar feature is enabled on the platform, false otherwise.
47
+     * The list of pages displayed in the component, referenced by page index.
47
      */
48
      */
48
-    _calendarEnabled: boolean
49
+    _pages: Array<Object>;
49
 
50
 
50
     /**
51
     /**
51
      * Constructor of the component.
52
      * Constructor of the component.
55
     constructor(props: Props) {
56
     constructor(props: Props) {
56
         super(props);
57
         super(props);
57
 
58
 
58
-        this._calendarEnabled = isCalendarEnabled();
59
+        this._pages = [];
60
+        for (const component of [ RecentList, MeetingList ]) {
61
+            // XXX Certain pages may be contributed by optional features. For
62
+            // example, MeetingList is contributed by the calendar feature and
63
+            // apps i.e. SDK consumers may not enable the calendar feature.
64
+            component && this._pages.push(component);
65
+        }
59
 
66
 
60
         this.state = {
67
         this.state = {
61
             pageIndex: DEFAULT_PAGE
68
             pageIndex: DEFAULT_PAGE
77
                     disabled ? styles.pagedListContainerDisabled : null
84
                     disabled ? styles.pagedListContainerDisabled : null
78
                 ] }>
85
                 ] }>
79
                 {
86
                 {
80
-                    (this._calendarEnabled && this._renderPagedList(disabled))
81
-                    || <RecentList
82
-                        disabled = { disabled }
83
-                        style = { styles.pagedList } />
87
+                    this._pages.length > 1
88
+                        ? this._renderPagedList(disabled)
89
+                        : React.createElement(
90
+                            /* type */ this._pages[0],
91
+                            /* props */ {
92
+                                disabled,
93
+                                style: styles.pagedList
94
+                            })
84
                 }
95
                 }
85
             </View>
96
             </View>
86
         );
97
         );
87
     }
98
     }
88
 
99
 
89
-    _renderPagedList: boolean => Object
100
+    _renderPagedList: boolean => React$Node;
90
 
101
 
102
+    _selectPage: number => void;
103
+
104
+    /**
105
+     * Sets the selected page.
106
+     *
107
+     * @param {number} pageIndex - The index of the active page.
108
+     * @protected
109
+     * @returns {void}
110
+     */
111
+    _selectPage(pageIndex: number) {
112
+        this.setState({
113
+            pageIndex
114
+        });
115
+
116
+        // The page's Component may have a refresh(dispatch) function which we
117
+        // invoke when the page is selected.
118
+        const selectedPageComponent = this._pages[pageIndex];
119
+
120
+        if (selectedPageComponent) {
121
+            const { refresh } = selectedPageComponent;
122
+
123
+            typeof refresh === 'function' && refresh(this.props.dispatch);
124
+        }
125
+    }
91
 }
126
 }

+ 65
- 67
react/features/welcome/components/PagedList.android.js 查看文件

1
 // @flow
1
 // @flow
2
+
2
 import React from 'react';
3
 import React from 'react';
3
 import { Text, TouchableOpacity, View, ViewPagerAndroid } from 'react-native';
4
 import { Text, TouchableOpacity, View, ViewPagerAndroid } from 'react-native';
5
+import { connect } from 'react-redux';
4
 
6
 
5
 import { Icon } from '../../base/font-icons';
7
 import { Icon } from '../../base/font-icons';
6
 import { MeetingList } from '../../calendar-sync';
8
 import { MeetingList } from '../../calendar-sync';
14
  *
16
  *
15
  * @extends PagedList
17
  * @extends PagedList
16
  */
18
  */
17
-export default class PagedList extends AbstractPagedList {
19
+class PagedList extends AbstractPagedList {
18
     /**
20
     /**
19
      * A reference to the viewpager.
21
      * A reference to the viewpager.
20
      */
22
      */
21
     _viewPager: Object;
23
     _viewPager: Object;
22
 
24
 
23
     /**
25
     /**
24
-     * Constructor of the PagedList Component.
26
+     * Initializes a new {@code PagedList} instance.
25
      *
27
      *
26
      * @inheritdoc
28
      * @inheritdoc
27
      */
29
      */
28
     constructor(props) {
30
     constructor(props) {
29
         super(props);
31
         super(props);
30
 
32
 
33
+        // Bind event handlers so they are only bound once per instance.
31
         this._getIndicatorStyle = this._getIndicatorStyle.bind(this);
34
         this._getIndicatorStyle = this._getIndicatorStyle.bind(this);
32
         this._onPageSelected = this._onPageSelected.bind(this);
35
         this._onPageSelected = this._onPageSelected.bind(this);
33
         this._onSelectPage = this._onSelectPage.bind(this);
36
         this._onSelectPage = this._onSelectPage.bind(this);
34
-        this._setPagerReference = this._setPagerReference.bind(this);
37
+        this._setViewPager = this._setViewPager.bind(this);
38
+    }
39
+
40
+    _getIndicatorStyle: number => Object;
41
+
42
+    /**
43
+     * Constructs the style of an indicator.
44
+     *
45
+     * @param {number} indicatorIndex - The index of the indicator.
46
+     * @private
47
+     * @returns {Object}
48
+     */
49
+    _getIndicatorStyle(indicatorIndex) {
50
+        if (this.state.pageIndex === indicatorIndex) {
51
+            return styles.pageIndicatorTextActive;
52
+        }
53
+
54
+        return null;
55
+    }
56
+
57
+    _onPageSelected: Object => void;
58
+
59
+    /**
60
+     * Updates the index of the currently selected page.
61
+     *
62
+     * @param {Object} event - The native event of the callback.
63
+     * @private
64
+     * @returns {void}
65
+     */
66
+    _onPageSelected({ nativeEvent: { position } }) {
67
+        if (this.state.pageIndex !== position) {
68
+            this._selectPage(position);
69
+        }
70
+    }
71
+
72
+    _onSelectPage: number => Function;
73
+
74
+    /**
75
+     * Constructs a function to be used as a callback for the tab bar.
76
+     *
77
+     * @param {number} pageIndex - The index of the page to activate via the
78
+     * callback.
79
+     * @private
80
+     * @returns {Function}
81
+     */
82
+    _onSelectPage(pageIndex) {
83
+        return () => {
84
+            this._viewPager.setPage(pageIndex);
85
+            this._selectPage(pageIndex);
86
+        };
35
     }
87
     }
36
 
88
 
37
     /**
89
     /**
42
      * @returns {ReactElement}
94
      * @returns {ReactElement}
43
      */
95
      */
44
     _renderPagedList(disabled) {
96
     _renderPagedList(disabled) {
45
-        const { pageIndex } = this.state;
46
-
47
         return (
97
         return (
48
             <View style = { styles.pagedListContainer }>
98
             <View style = { styles.pagedListContainer }>
49
                 <ViewPagerAndroid
99
                 <ViewPagerAndroid
50
                     initialPage = { DEFAULT_PAGE }
100
                     initialPage = { DEFAULT_PAGE }
51
                     onPageSelected = { this._onPageSelected }
101
                     onPageSelected = { this._onPageSelected }
52
                     peekEnabled = { true }
102
                     peekEnabled = { true }
53
-                    ref = { this._setPagerReference }
103
+                    ref = { this._setViewPager }
54
                     style = { styles.pagedList }>
104
                     style = { styles.pagedList }>
55
                     <View key = { 0 }>
105
                     <View key = { 0 }>
56
                         <RecentList disabled = { disabled } />
106
                         <RecentList disabled = { disabled } />
57
                     </View>
107
                     </View>
58
                     <View key = { 1 }>
108
                     <View key = { 1 }>
59
-                        <MeetingList
60
-                            disabled = { disabled }
61
-                            displayed = { pageIndex === 1 } />
109
+                        <MeetingList disabled = { disabled } />
62
                     </View>
110
                     </View>
63
                 </ViewPagerAndroid>
111
                 </ViewPagerAndroid>
64
                 <View style = { styles.pageIndicatorContainer }>
112
                 <View style = { styles.pageIndicatorContainer }>
107
         );
155
         );
108
     }
156
     }
109
 
157
 
110
-    _getIndicatorStyle: number => Object;
111
-
112
-    /**
113
-     * Constructs the style of an indicator.
114
-     *
115
-     * @private
116
-     * @param {number} indicatorIndex - The index of the indicator.
117
-     * @returns {Object}
118
-     */
119
-    _getIndicatorStyle(indicatorIndex) {
120
-        if (this.state.pageIndex === indicatorIndex) {
121
-            return styles.pageIndicatorTextActive;
122
-        }
123
-
124
-        return null;
125
-    }
126
-
127
-    _onPageSelected: Object => void;
158
+    _setViewPager: Object => void;
128
 
159
 
129
     /**
160
     /**
130
-     * Updates the index of the currently selected page.
161
+     * Sets the {@link ViewPagerAndroid} instance.
131
      *
162
      *
163
+     * @param {ViewPagerAndroid} viewPager - The {@code ViewPagerAndroid}
164
+     * instance.
132
      * @private
165
      * @private
133
-     * @param {Object} event - The native event of the callback.
134
      * @returns {void}
166
      * @returns {void}
135
      */
167
      */
136
-    _onPageSelected({ nativeEvent: { position } }) {
137
-        if (this.state.pageIndex !== position) {
138
-            this.setState({
139
-                pageIndex: position
140
-            });
141
-        }
142
-    }
143
-
144
-    _onSelectPage: number => Function
145
-
146
-    /**
147
-     * Constructs a function to be used as a callback for the tab bar.
148
-     *
149
-     * @private
150
-     * @param {number} pageIndex - The index of the page to activate via the
151
-     * callback.
152
-     * @returns {Function}
153
-     */
154
-    _onSelectPage(pageIndex) {
155
-        return () => {
156
-            this._viewPager.setPage(pageIndex);
157
-            this.setState({
158
-                pageIndex
159
-            });
160
-        };
161
-    }
162
-
163
-    _setPagerReference: Object => void
164
-
165
-    /**
166
-     * Sets the pager's reference for direct modification.
167
-     *
168
-     * @private
169
-     * @param {React@Node} component - The pager component.
170
-     * @returns {void}
171
-     */
172
-    _setPagerReference(component) {
173
-        this._viewPager = component;
168
+    _setViewPager(viewPager) {
169
+        this._viewPager = viewPager;
174
     }
170
     }
175
 }
171
 }
172
+
173
+export default connect()(PagedList);

+ 20
- 32
react/features/welcome/components/PagedList.ios.js 查看文件

5
 import { connect } from 'react-redux';
5
 import { connect } from 'react-redux';
6
 
6
 
7
 import { translate } from '../../base/i18n';
7
 import { translate } from '../../base/i18n';
8
-import { MeetingList, refreshCalendar } from '../../calendar-sync';
8
+import { MeetingList } from '../../calendar-sync';
9
 import { RecentList } from '../../recent-list';
9
 import { RecentList } from '../../recent-list';
10
 
10
 
11
 import AbstractPagedList from './AbstractPagedList';
11
 import AbstractPagedList from './AbstractPagedList';
21
 class PagedList extends AbstractPagedList {
21
 class PagedList extends AbstractPagedList {
22
 
22
 
23
     /**
23
     /**
24
-     * Constructor of the PagedList Component.
24
+     * Initializes a new {@code PagedList} instance.
25
      *
25
      *
26
      * @inheritdoc
26
      * @inheritdoc
27
      */
27
      */
28
     constructor(props) {
28
     constructor(props) {
29
         super(props);
29
         super(props);
30
+
31
+        // Bind event handlers so they are only bound once per instance.
30
         this._onTabSelected = this._onTabSelected.bind(this);
32
         this._onTabSelected = this._onTabSelected.bind(this);
31
     }
33
     }
32
 
34
 
35
+    _onTabSelected: number => Function;
36
+
37
+    /**
38
+     * Constructs a callback to update the selected tab.
39
+     *
40
+     * @param {number} tabIndex - The selected tab.
41
+     * @private
42
+     * @returns {Function}
43
+     */
44
+    _onTabSelected(tabIndex) {
45
+        return () => super._selectPage(tabIndex);
46
+    }
47
+
33
     /**
48
     /**
34
      * Renders the entire paged list if calendar is enabled.
49
      * Renders the entire paged list if calendar is enabled.
35
      *
50
      *
48
                 <TabBarIOS.Item
63
                 <TabBarIOS.Item
49
                     onPress = { this._onTabSelected(0) }
64
                     onPress = { this._onTabSelected(0) }
50
                     selected = { pageIndex === 0 }
65
                     selected = { pageIndex === 0 }
51
-                    systemIcon = 'history' >
66
+                    systemIcon = 'history'>
52
                     <RecentList disabled = { disabled } />
67
                     <RecentList disabled = { disabled } />
53
                 </TabBarIOS.Item>
68
                 </TabBarIOS.Item>
54
                 <TabBarIOS.Item
69
                 <TabBarIOS.Item
55
                     icon = { CALENDAR_ICON }
70
                     icon = { CALENDAR_ICON }
56
                     onPress = { this._onTabSelected(1) }
71
                     onPress = { this._onTabSelected(1) }
57
                     selected = { pageIndex === 1 }
72
                     selected = { pageIndex === 1 }
58
-                    title = { t('welcomepage.calendar') } >
59
-                    <MeetingList
60
-                        disabled = { disabled } />
73
+                    title = { t('welcomepage.calendar') }>
74
+                    <MeetingList disabled = { disabled } />
61
                 </TabBarIOS.Item>
75
                 </TabBarIOS.Item>
62
             </TabBarIOS>
76
             </TabBarIOS>
63
         );
77
         );
64
     }
78
     }
65
-
66
-    _onTabSelected: number => Function;
67
-
68
-    /**
69
-     * Constructs a callback to update the selected tab.
70
-     *
71
-     * @private
72
-     * @param {number} tabIndex - The selected tab.
73
-     * @returns {Function}
74
-     */
75
-    _onTabSelected(tabIndex) {
76
-        return () => {
77
-            this.setState({
78
-                pageIndex: tabIndex
79
-            });
80
-
81
-            if (tabIndex === 1) {
82
-                /**
83
-                 * This is a workaround as TabBarIOS doesn't invoke
84
-                 * componentWillReciveProps on prop change of the MeetingList
85
-                 * component.
86
-                 */
87
-                this.props.dispatch(refreshCalendar());
88
-            }
89
-        };
90
-    }
91
 }
79
 }
92
 
80
 
93
 export default translate(connect()(PagedList));
81
 export default translate(connect()(PagedList));

正在加载...
取消
保存