Properly gate calendar feature on-off

This commit is contained in:
zbettenbuk 2018-04-16 18:39:26 +02:00 committed by Lyubo Marinov
parent 09482f053b
commit 374e3ccf2c
11 changed files with 216 additions and 170 deletions

View File

@ -267,7 +267,7 @@ class ConferenceNotification extends Component<Props, State> {
* _eventList: Array
* }}
*/
export function _mapStateToProps(state: Object) {
function _mapStateToProps(state: Object) {
const { locationURL } = state['features/base/connection'];
return {

View File

@ -10,6 +10,7 @@ import { NavigateSectionList } from '../../base/react';
import { openSettings } from '../../mobile/permissions';
import { refreshCalendar } from '../actions';
import { CALENDAR_ENABLED } from '../constants';
import styles from './styles';
type Props = {
@ -59,6 +60,23 @@ class MeetingList extends Component<Props> {
_eventList: []
};
/**
* Public API method for {@code Component}s rendered in
* {@link AbstractPagedList}. When invoked, refreshes the calendar entries
* in the app.
*
* Note: It is a static method as the {@code Component} may not be
* initialized yet when the UI invokes refresh (e.g. {@link TabBarIOS} tab
* change).
*
* @param {Function} dispatch - The Redux dispatch function.
* @public
* @returns {void}
*/
static refresh(dispatch) {
dispatch(refreshCalendar());
}
/**
* Constructor of the MeetingList component.
*
@ -82,21 +100,6 @@ class MeetingList extends Component<Props> {
this._toDateString = this._toDateString.bind(this);
}
/**
* Implements React Component's componentWillReceiveProps.
*
* @inheritdoc
*/
componentWillReceiveProps(newProps) {
const { displayed } = this.props;
if (newProps.displayed && !displayed) {
const { dispatch } = this.props;
dispatch(refreshCalendar());
}
}
/**
* Implements the React Components's render.
*
@ -266,7 +269,7 @@ class MeetingList extends Component<Props> {
* _eventList: Array
* }}
*/
export function _mapStateToProps(state: Object) {
function _mapStateToProps(state: Object) {
const calendarSyncState = state['features/calendar-sync'];
return {
@ -275,4 +278,6 @@ export function _mapStateToProps(state: Object) {
};
}
export default translate(connect(_mapStateToProps)(MeetingList));
export default CALENDAR_ENABLED
? translate(connect(_mapStateToProps)(MeetingList))
: undefined;

View File

@ -0,0 +1,26 @@
// @flow
import { NativeModules } from 'react-native';
/**
* The indicator which determines whether the calendar feature is enabled by the
* app.
*
* @type {boolean}
*/
export const CALENDAR_ENABLED = _isCalendarEnabled();
/**
* Determines whether the calendar feature is enabled by the app. For
* example, Apple through its App Store requires
* {@code NSCalendarsUsageDescription} in the app's Info.plist or App Store
* rejects the app.
*
* @returns {boolean} If the app has enabled the calendar feature, {@code true};
* otherwise, {@code false}.
*/
function _isCalendarEnabled() {
const { calendarEnabled } = NativeModules.AppInfo;
return typeof calendarEnabled === 'undefined' ? true : calendarEnabled;
}

View File

@ -1,4 +1,3 @@
export * from './actions';
export * from './components';
import './middleware';

View File

@ -1,6 +1,5 @@
// @flow
import { NativeModules } from 'react-native';
import RNCalendarEvents from 'react-native-calendar-events';
import { APP_WILL_MOUNT } from '../app';
@ -15,6 +14,7 @@ import {
setCalendarEvents
} from './actions';
import { REFRESH_CALENDAR } from './actionTypes';
import { CALENDAR_ENABLED } from './constants';
const logger = require('jitsi-meet-logger').getLogger(__filename);
@ -22,7 +22,8 @@ const FETCH_END_DAYS = 10;
const FETCH_START_DAYS = -1;
const MAX_LIST_LENGTH = 10;
MiddlewareRegistry.register(store => next => action => {
CALENDAR_ENABLED
&& MiddlewareRegistry.register(store => next => action => {
const result = next(action);
switch (action.type) {
@ -123,11 +124,6 @@ function _fetchCalendarEntries(
{ dispatch, getState },
maybePromptForPermission,
forcePermission) {
if (!_isCalendarEnabled()) {
// The calendar feature is not enabled.
return;
}
const state = getState()['features/calendar-sync'];
const promptForPermission
= (maybePromptForPermission && !state.authorization)
@ -203,20 +199,6 @@ function _getURLFromEvent(event, knownDomains) {
return null;
}
/**
* Determines whether the calendar feature is enabled by the app. For
* example, Apple through its App Store requires NSCalendarsUsageDescription in
* the app's Info.plist or App Store rejects the app.
*
* @returns {boolean} If the app has enabled the calendar feature, {@code true};
* otherwise, {@code false}.
*/
export function _isCalendarEnabled() {
const { calendarEnabled } = NativeModules.AppInfo;
return typeof calendarEnabled === 'undefined' ? true : calendarEnabled;
}
/**
* Retrieves the domain name of a room upon join and stores it in the known
* domain list, if not present yet.

View File

@ -8,6 +8,7 @@ import {
SET_CALENDAR_AUTHORIZATION,
SET_CALENDAR_EVENTS
} from './actionTypes';
import { CALENDAR_ENABLED } from './constants';
const DEFAULT_STATE = {
/**
@ -24,11 +25,13 @@ const MAX_DOMAIN_LIST_SIZE = 10;
const STORE_NAME = 'features/calendar-sync';
PersistenceRegistry.register(STORE_NAME, {
CALENDAR_ENABLED
&& PersistenceRegistry.register(STORE_NAME, {
knownDomains: true
});
ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => {
CALENDAR_ENABLED
&& ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => {
switch (action.type) {
case ADD_KNOWN_DOMAIN:
return _addKnownDomain(state, action);

View File

@ -1,53 +0,0 @@
// @flow
import { Component } from 'react';
/**
* The page to be displayed on render.
*/
export const DEFAULT_PAGE = 0;
type Props = {
/**
* Indicates if the list is disabled or not.
*/
disabled: boolean,
/**
* The Redux dispatch function.
*/
dispatch: Function,
/**
* The i18n translate function
*/
t: Function
}
type State = {
/**
* The currently selected page.
*/
pageIndex: number
}
/**
* Abstract class for the platform specific paged lists.
*/
export default class AbstractPagedList extends Component<Props, State> {
/**
* Constructor of the component.
*
* @inheritdoc
*/
constructor(props: Props) {
super(props);
this.state = {
pageIndex: DEFAULT_PAGE
};
}
}

View File

@ -0,0 +1,91 @@
// @flow
import React, { Component } from 'react';
import { View } from 'react-native';
import { isCalendarEnabled } from '../../calendar-sync';
import { RecentList } from '../../recent-list';
import styles from './styles';
/**
* The page to be displayed on render.
*/
export const DEFAULT_PAGE = 0;
type Props = {
/**
* Indicates if the list is disabled or not.
*/
disabled: boolean,
/**
* The Redux dispatch function.
*/
dispatch: Function,
/**
* The i18n translate function
*/
t: Function
}
type State = {
/**
* The currently selected page.
*/
pageIndex: number
}
/**
* Abstract class for the platform specific paged lists.
*/
export default class AbstractPagedList extends Component<Props, State> {
/**
* True if the calendar feature is enabled on the platform, false otherwise.
*/
_calendarEnabled: boolean
/**
* Constructor of the component.
*
* @inheritdoc
*/
constructor(props: Props) {
super(props);
this._calendarEnabled = isCalendarEnabled();
this.state = {
pageIndex: DEFAULT_PAGE
};
}
/**
* Renders the component.
*
* @inheritdoc
*/
render() {
const { disabled } = this.props;
return (
<View
style = { [
styles.pagedListContainer,
disabled ? styles.pagedListContainerDisabled : null
] }>
{
(this._calendarEnabled && this._renderPagedList(disabled))
|| <RecentList
disabled = { disabled }
style = { styles.pagedList } />
}
</View>
);
}
_renderPagedList: boolean => Object
}

View File

@ -35,20 +35,17 @@ export default class PagedList extends AbstractPagedList {
}
/**
* Renders the paged list.
* Renders the entire paged list if calendar is enabled.
*
* @inheritdoc
* @param {boolean} disabled - True if the rendered lists should be
* disabled.
* @returns {ReactElement}
*/
render() {
const { disabled } = this.props;
_renderPagedList(disabled) {
const { pageIndex } = this.state;
return (
<View
style = { [
styles.pagedListContainer,
disabled ? styles.pagedListContainerDisabled : null
] }>
<View style = { styles.pagedListContainer }>
<ViewPagerAndroid
initialPage = { DEFAULT_PAGE }
onPageSelected = { this._onPageSelected }

View File

@ -1,7 +1,7 @@
// @flow
import React from 'react';
import { View, TabBarIOS } from 'react-native';
import { TabBarIOS } from 'react-native';
import { connect } from 'react-redux';
import { translate } from '../../base/i18n';
@ -31,20 +31,17 @@ class PagedList extends AbstractPagedList {
}
/**
* Renders the paged list.
* Renders the entire paged list if calendar is enabled.
*
* @inheritdoc
* @param {boolean} disabled - True if the rendered lists should be
* disabled.
* @returns {ReactElement}
*/
render() {
_renderPagedList(disabled) {
const { pageIndex } = this.state;
const { disabled, t } = this.props;
const { t } = this.props;
return (
<View
style = { [
styles.pagedListContainer,
disabled ? styles.pagedListContainerDisabled : null
] }>
<TabBarIOS
itemPositioning = 'fill'
style = { styles.pagedList }>
@ -63,7 +60,6 @@ class PagedList extends AbstractPagedList {
disabled = { disabled } />
</TabBarIOS.Item>
</TabBarIOS>
</View>
);
}