浏览代码

feature-flags: add flag for enabling calendar integration

master
Saúl Ibarra Corretgé 6 年前
父节点
当前提交
97e0303065

+ 3
- 2
react/features/base/flags/constants.js 查看文件

1
 // @flow
1
 // @flow
2
 
2
 
3
 /**
3
 /**
4
- * Flag indicating if calendar integration should be disabled.
4
+ * Flag indicating if calendar integration should be enabled.
5
+ * Default: enabled (true) on Android, auto-detected on iOS.
5
  */
6
  */
6
-export const CALENDAR_DISABLED = 'calendar.disabled';
7
+export const CALENDAR_ENABLED = 'calendar.enabled';
7
 
8
 
8
 /**
9
 /**
9
  * Flag indicating if chat should be enabled.
10
  * Flag indicating if chat should be enabled.

+ 8
- 6
react/features/calendar-sync/actions.web.js 查看文件

30
  */
30
  */
31
 export function bootstrapCalendarIntegration(): Function {
31
 export function bootstrapCalendarIntegration(): Function {
32
     return (dispatch, getState) => {
32
     return (dispatch, getState) => {
33
+        const state = getState();
34
+
35
+        if (!isCalendarEnabled(state)) {
36
+            return Promise.reject();
37
+        }
38
+
33
         const {
39
         const {
34
             googleApiApplicationClientID
40
             googleApiApplicationClientID
35
-        } = getState()['features/base/config'];
41
+        } = state['features/base/config'];
36
         const {
42
         const {
37
             integrationReady,
43
             integrationReady,
38
             integrationType
44
             integrationType
39
-        } = getState()['features/calendar-sync'];
40
-
41
-        if (!isCalendarEnabled()) {
42
-            return Promise.reject();
43
-        }
45
+        } = state['features/calendar-sync'];
44
 
46
 
45
         return Promise.resolve()
47
         return Promise.resolve()
46
             .then(() => {
48
             .then(() => {

+ 1
- 4
react/features/calendar-sync/components/CalendarList.native.js 查看文件

9
 import { connect } from '../../base/redux';
9
 import { connect } from '../../base/redux';
10
 
10
 
11
 import { refreshCalendar } from '../actions';
11
 import { refreshCalendar } from '../actions';
12
-import { isCalendarEnabled } from '../functions';
13
 import styles from './styles';
12
 import styles from './styles';
14
 
13
 
15
 import CalendarListContent from './CalendarListContent';
14
 import CalendarListContent from './CalendarListContent';
138
     };
137
     };
139
 }
138
 }
140
 
139
 
141
-export default isCalendarEnabled()
142
-    ? translate(connect(_mapStateToProps)(CalendarList))
143
-    : undefined;
140
+export default translate(connect(_mapStateToProps)(CalendarList));

+ 1
- 4
react/features/calendar-sync/components/CalendarList.web.js 查看文件

14
 
14
 
15
 import { refreshCalendar } from '../actions';
15
 import { refreshCalendar } from '../actions';
16
 import { ERRORS } from '../constants';
16
 import { ERRORS } from '../constants';
17
-import { isCalendarEnabled } from '../functions';
18
 
17
 
19
 import CalendarListContent from './CalendarListContent';
18
 import CalendarListContent from './CalendarListContent';
20
 
19
 
257
     };
256
     };
258
 }
257
 }
259
 
258
 
260
-export default isCalendarEnabled()
261
-    ? translate(connect(_mapStateToProps)(CalendarList))
262
-    : undefined;
259
+export default translate(connect(_mapStateToProps)(CalendarList));

+ 1
- 4
react/features/calendar-sync/components/CalendarListContent.native.js 查看文件

13
 import { connect } from '../../base/redux';
13
 import { connect } from '../../base/redux';
14
 
14
 
15
 import { refreshCalendar, openUpdateCalendarEventDialog } from '../actions';
15
 import { refreshCalendar, openUpdateCalendarEventDialog } from '../actions';
16
-import { isCalendarEnabled } from '../functions';
17
 
16
 
18
 
17
 
19
 /**
18
 /**
271
     };
270
     };
272
 }
271
 }
273
 
272
 
274
-export default isCalendarEnabled()
275
-    ? translate(connect(_mapStateToProps)(CalendarListContent))
276
-    : undefined;
273
+export default translate(connect(_mapStateToProps)(CalendarListContent));

+ 1
- 5
react/features/calendar-sync/components/CalendarListContent.web.js 查看文件

11
 import { MeetingsList } from '../../base/react';
11
 import { MeetingsList } from '../../base/react';
12
 import { connect } from '../../base/redux';
12
 import { connect } from '../../base/redux';
13
 
13
 
14
-import { isCalendarEnabled } from '../functions';
15
-
16
 import AddMeetingUrlButton from './AddMeetingUrlButton';
14
 import AddMeetingUrlButton from './AddMeetingUrlButton';
17
 import JoinButton from './JoinButton';
15
 import JoinButton from './JoinButton';
18
 
16
 
172
     };
170
     };
173
 }
171
 }
174
 
172
 
175
-export default isCalendarEnabled()
176
-    ? connect(_mapStateToProps)(CalendarListContent)
177
-    : undefined;
173
+export default connect(_mapStateToProps)(CalendarListContent);

+ 1
- 4
react/features/calendar-sync/components/ConferenceNotification.native.js 查看文件

10
 import { connect } from '../../base/redux';
10
 import { connect } from '../../base/redux';
11
 import { ASPECT_RATIO_NARROW } from '../../base/responsive-ui';
11
 import { ASPECT_RATIO_NARROW } from '../../base/responsive-ui';
12
 
12
 
13
-import { isCalendarEnabled } from '../functions';
14
 import styles from './styles';
13
 import styles from './styles';
15
 
14
 
16
 const ALERT_MILLISECONDS = 5 * 60 * 1000;
15
 const ALERT_MILLISECONDS = 5 * 60 * 1000;
294
     };
293
     };
295
 }
294
 }
296
 
295
 
297
-export default isCalendarEnabled()
298
-    ? translate(connect(_mapStateToProps)(ConferenceNotification))
299
-    : undefined;
296
+export default translate(connect(_mapStateToProps)(ConferenceNotification));

+ 11
- 2
react/features/calendar-sync/functions.native.js 查看文件

4
 import RNCalendarEvents from 'react-native-calendar-events';
4
 import RNCalendarEvents from 'react-native-calendar-events';
5
 import type { Store } from 'redux';
5
 import type { Store } from 'redux';
6
 
6
 
7
+import { CALENDAR_ENABLED, getFeatureFlag } from '../base/flags';
7
 import { getShareInfoText } from '../invite';
8
 import { getShareInfoText } from '../invite';
8
 
9
 
9
 import { setCalendarAuthorization } from './actions';
10
 import { setCalendarAuthorization } from './actions';
54
  * Determines whether the calendar feature is enabled by the app. For
55
  * Determines whether the calendar feature is enabled by the app. For
55
  * example, Apple through its App Store requires
56
  * example, Apple through its App Store requires
56
  * {@code NSCalendarsUsageDescription} in the app's Info.plist or App Store
57
  * {@code NSCalendarsUsageDescription} in the app's Info.plist or App Store
57
- * rejects the app.
58
+ * rejects the app. It could also be disabled with a feature flag.
58
  *
59
  *
60
+ * @param {Function|Object} stateful - The redux store or {@code getState}
61
+ * function.
59
  * @returns {boolean} If the app has enabled the calendar feature, {@code true};
62
  * @returns {boolean} If the app has enabled the calendar feature, {@code true};
60
  * otherwise, {@code false}.
63
  * otherwise, {@code false}.
61
  */
64
  */
62
-export function isCalendarEnabled() {
65
+export function isCalendarEnabled(stateful: Function | Object) {
66
+    const flag = getFeatureFlag(stateful, CALENDAR_ENABLED);
67
+
68
+    if (typeof flag !== 'undefined') {
69
+        return flag;
70
+    }
71
+
63
     const { calendarEnabled = true } = NativeModules.AppInfo;
72
     const { calendarEnabled = true } = NativeModules.AppInfo;
64
 
73
 
65
     return calendarEnabled;
74
     return calendarEnabled;

+ 11
- 7
react/features/calendar-sync/functions.web.js 查看文件

16
 import { _updateCalendarEntries } from './functions';
16
 import { _updateCalendarEntries } from './functions';
17
 import { googleCalendarApi } from './web/googleCalendar';
17
 import { googleCalendarApi } from './web/googleCalendar';
18
 import { microsoftCalendarApi } from './web/microsoftCalendar';
18
 import { microsoftCalendarApi } from './web/microsoftCalendar';
19
+import { toState } from '../base/redux';
19
 
20
 
20
 const logger = require('jitsi-meet-logger').getLogger(__filename);
21
 const logger = require('jitsi-meet-logger').getLogger(__filename);
21
 
22
 
22
-declare var config: Object;
23
-
24
 /**
23
 /**
25
  * Determines whether the calendar feature is enabled by the web.
24
  * Determines whether the calendar feature is enabled by the web.
26
  *
25
  *
26
+ * @param {Function|Object} stateful - The redux store or {@code getState}
27
+ * function.
27
  * @returns {boolean} If the app has enabled the calendar feature, {@code true};
28
  * @returns {boolean} If the app has enabled the calendar feature, {@code true};
28
  * otherwise, {@code false}.
29
  * otherwise, {@code false}.
29
  */
30
  */
30
-export function isCalendarEnabled() {
31
-    return Boolean(
32
-        config.enableCalendarIntegration
33
-            && (config.googleApiApplicationClientID
34
-                || config.microsoftApiApplicationClientID));
31
+export function isCalendarEnabled(stateful: Function | Object) {
32
+    const {
33
+        enableCalendarIntegration,
34
+        googleApiApplicationClientID,
35
+        microsoftApiApplicationClientID
36
+    } = toState(stateful)['features/base/config'] || {};
37
+
38
+    return Boolean(enableCalendarIntegration && (googleApiApplicationClientID || microsoftApiApplicationClientID));
35
 }
39
 }
36
 
40
 
37
 /* eslint-disable no-unused-vars */
41
 /* eslint-disable no-unused-vars */

+ 37
- 33
react/features/calendar-sync/middleware.js 查看文件

9
 import { REFRESH_CALENDAR } from './actionTypes';
9
 import { REFRESH_CALENDAR } from './actionTypes';
10
 import { _fetchCalendarEntries, isCalendarEnabled } from './functions';
10
 import { _fetchCalendarEntries, isCalendarEnabled } from './functions';
11
 
11
 
12
-isCalendarEnabled()
13
-    && MiddlewareRegistry.register(store => next => action => {
14
-        switch (action.type) {
15
-        case ADD_KNOWN_DOMAINS: {
16
-            // XXX Fetch new calendar entries only when an actual domain has
17
-            // become known.
18
-            const { getState } = store;
19
-            const oldValue = getState()['features/base/known-domains'];
20
-            const result = next(action);
21
-            const newValue = getState()['features/base/known-domains'];
12
+MiddlewareRegistry.register(store => next => action => {
13
+    const { getState } = store;
22
 
14
 
23
-            equals(oldValue, newValue)
24
-                || _fetchCalendarEntries(store, false, false);
15
+    if (!isCalendarEnabled(getState)) {
16
+        return next(action);
17
+    }
25
 
18
 
26
-            return result;
27
-        }
19
+    switch (action.type) {
20
+    case ADD_KNOWN_DOMAINS: {
21
+        // XXX Fetch new calendar entries only when an actual domain has
22
+        // become known.
23
+        const oldValue = getState()['features/base/known-domains'];
24
+        const result = next(action);
25
+        const newValue = getState()['features/base/known-domains'];
28
 
26
 
29
-        case APP_STATE_CHANGED: {
30
-            const result = next(action);
27
+        equals(oldValue, newValue)
28
+            || _fetchCalendarEntries(store, false, false);
31
 
29
 
32
-            _maybeClearAccessStatus(store, action);
30
+        return result;
31
+    }
33
 
32
 
34
-            return result;
35
-        }
33
+    case APP_STATE_CHANGED: {
34
+        const result = next(action);
36
 
35
 
37
-        case SET_CONFIG: {
38
-            const result = next(action);
36
+        _maybeClearAccessStatus(store, action);
39
 
37
 
40
-            _fetchCalendarEntries(store, false, false);
38
+        return result;
39
+    }
41
 
40
 
42
-            return result;
43
-        }
41
+    case SET_CONFIG: {
42
+        const result = next(action);
44
 
43
 
45
-        case REFRESH_CALENDAR: {
46
-            const result = next(action);
44
+        _fetchCalendarEntries(store, false, false);
47
 
45
 
48
-            _fetchCalendarEntries(
49
-                store, action.isInteractive, action.forcePermission);
46
+        return result;
47
+    }
50
 
48
 
51
-            return result;
52
-        }
53
-        }
49
+    case REFRESH_CALENDAR: {
50
+        const result = next(action);
54
 
51
 
55
-        return next(action);
56
-    });
52
+        _fetchCalendarEntries(
53
+            store, action.isInteractive, action.forcePermission);
54
+
55
+        return result;
56
+    }
57
+    }
58
+
59
+    return next(action);
60
+});
57
 
61
 
58
 /**
62
 /**
59
  * Clears the calendar access status when the app comes back from the
63
  * Clears the calendar access status when the app comes back from the

+ 43
- 41
react/features/calendar-sync/reducer.js 查看文件

44
  * runtime value to see if we need to re-request the calendar permission from
44
  * runtime value to see if we need to re-request the calendar permission from
45
  * the user.
45
  * the user.
46
  */
46
  */
47
-isCalendarEnabled()
48
-    && PersistenceRegistry.register(STORE_NAME, {
49
-        integrationType: true,
50
-        msAuthState: true
51
-    });
52
-
53
-isCalendarEnabled()
54
-    && ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => {
55
-        switch (action.type) {
56
-        case CLEAR_CALENDAR_INTEGRATION:
57
-            return DEFAULT_STATE;
58
-
59
-        case SET_CALENDAR_AUTH_STATE: {
60
-            if (!action.msAuthState) {
61
-                // received request to delete the state
62
-                return set(state, 'msAuthState', undefined);
63
-            }
64
-
65
-            return set(state, 'msAuthState', {
66
-                ...state.msAuthState,
67
-                ...action.msAuthState
68
-            });
47
+PersistenceRegistry.register(STORE_NAME, {
48
+    integrationType: true,
49
+    msAuthState: true
50
+});
51
+
52
+ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => {
53
+    if (!isCalendarEnabled(state)) {
54
+        return state;
55
+    }
56
+
57
+    switch (action.type) {
58
+    case CLEAR_CALENDAR_INTEGRATION:
59
+        return DEFAULT_STATE;
60
+
61
+    case SET_CALENDAR_AUTH_STATE: {
62
+        if (!action.msAuthState) {
63
+            // received request to delete the state
64
+            return set(state, 'msAuthState', undefined);
69
         }
65
         }
70
 
66
 
71
-        case SET_CALENDAR_AUTHORIZATION:
72
-            return set(state, 'authorization', action.authorization);
67
+        return set(state, 'msAuthState', {
68
+            ...state.msAuthState,
69
+            ...action.msAuthState
70
+        });
71
+    }
73
 
72
 
74
-        case SET_CALENDAR_ERROR:
75
-            return set(state, 'error', action.error);
73
+    case SET_CALENDAR_AUTHORIZATION:
74
+        return set(state, 'authorization', action.authorization);
76
 
75
 
77
-        case SET_CALENDAR_EVENTS:
78
-            return set(state, 'events', action.events);
76
+    case SET_CALENDAR_ERROR:
77
+        return set(state, 'error', action.error);
79
 
78
 
80
-        case SET_CALENDAR_INTEGRATION:
81
-            return {
82
-                ...state,
83
-                integrationReady: action.integrationReady,
84
-                integrationType: action.integrationType
85
-            };
79
+    case SET_CALENDAR_EVENTS:
80
+        return set(state, 'events', action.events);
86
 
81
 
87
-        case SET_CALENDAR_PROFILE_EMAIL:
88
-            return set(state, 'profileEmail', action.email);
82
+    case SET_CALENDAR_INTEGRATION:
83
+        return {
84
+            ...state,
85
+            integrationReady: action.integrationReady,
86
+            integrationType: action.integrationType
87
+        };
89
 
88
 
90
-        case SET_LOADING_CALENDAR_EVENTS:
91
-            return set(state, 'isLoadingEvents', action.isLoadingEvents);
92
-        }
89
+    case SET_CALENDAR_PROFILE_EMAIL:
90
+        return set(state, 'profileEmail', action.email);
93
 
91
 
94
-        return state;
95
-    });
92
+    case SET_LOADING_CALENDAR_EVENTS:
93
+        return set(state, 'isLoadingEvents', action.isLoadingEvents);
94
+    }
95
+
96
+    return state;
97
+});

+ 19
- 4
react/features/conference/components/native/Conference.js 查看文件

13
     makeAspectRatioAware
13
     makeAspectRatioAware
14
 } from '../../../base/responsive-ui';
14
 } from '../../../base/responsive-ui';
15
 import { TestConnectionInfo } from '../../../base/testing';
15
 import { TestConnectionInfo } from '../../../base/testing';
16
-import { ConferenceNotification } from '../../../calendar-sync';
16
+import { ConferenceNotification, isCalendarEnabled } from '../../../calendar-sync';
17
 import { Chat } from '../../../chat';
17
 import { Chat } from '../../../chat';
18
 import { DisplayNameLabel } from '../../../display-name';
18
 import { DisplayNameLabel } from '../../../display-name';
19
 import {
19
 import {
42
  */
42
  */
43
 type Props = AbstractProps & {
43
 type Props = AbstractProps & {
44
 
44
 
45
+    /**
46
+     * Wherther the calendar feature is enabled or not.
47
+     *
48
+     * @private
49
+     */
50
+    _calendarEnabled: boolean,
51
+
45
     /**
52
     /**
46
      * The indicator which determines that we are still connecting to the
53
      * The indicator which determines that we are still connecting to the
47
      * conference which includes establishing the XMPP connection and then
54
      * conference which includes establishing the XMPP connection and then
331
      * @returns {React$Node}
338
      * @returns {React$Node}
332
      */
339
      */
333
     _renderConferenceNotification() {
340
     _renderConferenceNotification() {
334
-        // XXX If the calendar feature is disabled on a platform, then we don't
335
-        // have its components exported so an undefined check is necessary.
341
+        const { _calendarEnabled, _reducedUI } = this.props;
342
+
336
         return (
343
         return (
337
-            !this.props._reducedUI && ConferenceNotification
344
+            _calendarEnabled && !_reducedUI
338
                 ? <ConferenceNotification />
345
                 ? <ConferenceNotification />
339
                 : undefined);
346
                 : undefined);
340
     }
347
     }
417
     return {
424
     return {
418
         ...abstractMapStateToProps(state),
425
         ...abstractMapStateToProps(state),
419
 
426
 
427
+        /**
428
+         * Wherther the calendar feature is enabled or not.
429
+         *
430
+         * @private
431
+         * @type {boolean}
432
+         */
433
+        _calendarEnabled: isCalendarEnabled(state),
434
+
420
         /**
435
         /**
421
          * The indicator which determines that we are still connecting to the
436
          * The indicator which determines that we are still connecting to the
422
          * conference which includes establishing the XMPP connection and then
437
          * conference which includes establishing the XMPP connection and then

+ 1
- 1
react/features/settings/components/web/CalendarTab.js 查看文件

285
         googleApiApplicationClientID,
285
         googleApiApplicationClientID,
286
         microsoftApiApplicationClientID
286
         microsoftApiApplicationClientID
287
     } = state['features/base/config'];
287
     } = state['features/base/config'];
288
-    const calendarEnabled = isCalendarEnabled();
288
+    const calendarEnabled = isCalendarEnabled(state);
289
 
289
 
290
     return {
290
     return {
291
         _appName: interfaceConfig.APP_NAME,
291
         _appName: interfaceConfig.APP_NAME,

+ 1
- 1
react/features/settings/components/web/SettingsDialog.js 查看文件

135
     const showProfileSettings
135
     const showProfileSettings
136
         = configuredTabs.includes('profile') && jwt.isGuest;
136
         = configuredTabs.includes('profile') && jwt.isGuest;
137
     const showCalendarSettings
137
     const showCalendarSettings
138
-        = configuredTabs.includes('calendar') && isCalendarEnabled();
138
+        = configuredTabs.includes('calendar') && isCalendarEnabled(state);
139
     const tabs = [];
139
     const tabs = [];
140
 
140
 
141
     if (showDeviceSettings) {
141
     if (showDeviceSettings) {

+ 8
- 0
react/features/welcome/components/AbstractWelcomePage.js 查看文件

6
 
6
 
7
 import { createWelcomePageEvent, sendAnalytics } from '../../analytics';
7
 import { createWelcomePageEvent, sendAnalytics } from '../../analytics';
8
 import { appNavigate } from '../../app';
8
 import { appNavigate } from '../../app';
9
+import { isCalendarEnabled } from '../../calendar-sync';
9
 import { isRoomValid } from '../../base/conference';
10
 import { isRoomValid } from '../../base/conference';
10
 
11
 
11
 /**
12
 /**
13
  */
14
  */
14
 type Props = {
15
 type Props = {
15
 
16
 
17
+    /**
18
+     * Whether the calendar functionality is enabled or not.
19
+     */
20
+    _calendarEnabled: boolean,
21
+
16
     /**
22
     /**
17
      * Room name to join to.
23
      * Room name to join to.
18
      */
24
      */
237
  * @param {Object} state - The redux state.
243
  * @param {Object} state - The redux state.
238
  * @protected
244
  * @protected
239
  * @returns {{
245
  * @returns {{
246
+ *     _calendarEnabled: boolean,
240
  *     _room: string,
247
  *     _room: string,
241
  *     _settings: Object
248
  *     _settings: Object
242
  * }}
249
  * }}
243
  */
250
  */
244
 export function _mapStateToProps(state: Object) {
251
 export function _mapStateToProps(state: Object) {
245
     return {
252
     return {
253
+        _calendarEnabled: isCalendarEnabled(state),
246
         _room: state['features/base/conference'].room,
254
         _room: state['features/base/conference'].room,
247
         _settings: state['features/base/settings']
255
         _settings: state['features/base/settings']
248
     };
256
     };

+ 2
- 2
react/features/welcome/components/WelcomePage.web.js 查看文件

225
             return null;
225
             return null;
226
         }
226
         }
227
 
227
 
228
-        const { t } = this.props;
228
+        const { _calendarEnabled, t } = this.props;
229
 
229
 
230
         const tabs = [];
230
         const tabs = [];
231
 
231
 
232
-        if (CalendarList) {
232
+        if (_calendarEnabled) {
233
             tabs.push({
233
             tabs.push({
234
                 label: t('welcomepage.calendar'),
234
                 label: t('welcomepage.calendar'),
235
                 content: <CalendarList />
235
                 content: <CalendarList />

+ 28
- 31
react/features/welcome/components/WelcomePageLists.js 查看文件

5
 import { translate } from '../../base/i18n';
5
 import { translate } from '../../base/i18n';
6
 import { PagedList } from '../../base/react';
6
 import { PagedList } from '../../base/react';
7
 import { connect } from '../../base/redux';
7
 import { connect } from '../../base/redux';
8
-import { CalendarList } from '../../calendar-sync';
8
+import { CalendarList, isCalendarEnabled } from '../../calendar-sync';
9
 import { RecentList } from '../../recent-list';
9
 import { RecentList } from '../../recent-list';
10
 
10
 
11
 import { setWelcomePageListsDefaultPage } from '../actions';
11
 import { setWelcomePageListsDefaultPage } from '../actions';
15
  */
15
  */
16
 type Props = {
16
 type Props = {
17
 
17
 
18
+    /**
19
+     * Whether the calendar functionality is enabled or not.
20
+     */
21
+    _calendarEnabled: boolean,
22
+
18
     /**
23
     /**
19
      * The stored default page index.
24
      * The stored default page index.
20
      */
25
      */
40
  * Implements the lists displayed on the mobile welcome screen.
45
  * Implements the lists displayed on the mobile welcome screen.
41
  */
46
  */
42
 class WelcomePageLists extends Component<Props> {
47
 class WelcomePageLists extends Component<Props> {
43
-    /**
44
-     * The pages to be rendered.
45
-     *
46
-     * Note: An element's  {@code component} may be {@code undefined} if a
47
-     * feature (such as Calendar) is disabled, and that means that the page must
48
-     * not be rendered.
49
-     */
50
-    pages: Array<{
51
-        component: ?Object,
52
-        icon: string | number,
53
-        title: string
54
-    }>;
55
-
56
     /**
48
     /**
57
      * Initializes a new {@code WelcomePageLists} instance.
49
      * Initializes a new {@code WelcomePageLists} instance.
58
      *
50
      *
61
     constructor(props) {
53
     constructor(props) {
62
         super(props);
54
         super(props);
63
 
55
 
64
-        const { t } = props;
65
-
66
-        this.pages = [
67
-            {
68
-                component: RecentList,
69
-                icon: 'restore',
70
-                title: t('welcomepage.recentList')
71
-            },
72
-            {
73
-                component: CalendarList,
74
-                icon: 'event_note',
75
-                title: t('welcomepage.calendar')
76
-            }
77
-        ];
78
-
79
         // Bind event handlers so they are only bound once per instance.
56
         // Bind event handlers so they are only bound once per instance.
80
         this._onSelectPage = this._onSelectPage.bind(this);
57
         this._onSelectPage = this._onSelectPage.bind(this);
81
     }
58
     }
86
      * @inheritdoc
63
      * @inheritdoc
87
      */
64
      */
88
     render() {
65
     render() {
89
-        const { _defaultPage } = this.props;
66
+        const { _calendarEnabled, _defaultPage, t } = this.props;
90
 
67
 
91
         if (typeof _defaultPage === 'undefined') {
68
         if (typeof _defaultPage === 'undefined') {
92
             return null;
69
             return null;
93
         }
70
         }
94
 
71
 
72
+        const pages = [
73
+            {
74
+                component: RecentList,
75
+                icon: 'restore',
76
+                title: t('welcomepage.recentList')
77
+            }
78
+        ];
79
+
80
+        if (_calendarEnabled) {
81
+            pages.push(
82
+                {
83
+                    component: CalendarList,
84
+                    icon: 'event_note',
85
+                    title: t('welcomepage.calendar')
86
+                }
87
+            );
88
+        }
89
+
95
         return (
90
         return (
96
             <PagedList
91
             <PagedList
97
                 defaultPage = { _defaultPage }
92
                 defaultPage = { _defaultPage }
98
                 disabled = { this.props.disabled }
93
                 disabled = { this.props.disabled }
99
                 onSelectPage = { this._onSelectPage }
94
                 onSelectPage = { this._onSelectPage }
100
-                pages = { this.pages } />
95
+                pages = { pages } />
101
         );
96
         );
102
     }
97
     }
103
 
98
 
122
  * @param {Object} state - The redux state.
117
  * @param {Object} state - The redux state.
123
  * @protected
118
  * @protected
124
  * @returns {{
119
  * @returns {{
120
+ *     _calendarEnabled: boolean,
125
  *     _defaultPage: number
121
  *     _defaultPage: number
126
  * }}
122
  * }}
127
  */
123
  */
135
     }
131
     }
136
 
132
 
137
     return {
133
     return {
134
+        _calendarEnabled: isCalendarEnabled(state),
138
         _defaultPage: defaultPage
135
         _defaultPage: defaultPage
139
     };
136
     };
140
 }
137
 }

正在加载...
取消
保存