Avoid asking for calendar permission on app start

This commit is contained in:
zbettenbuk 2018-03-06 17:30:59 +01:00 committed by Lyubo Marinov
parent c86c7beb24
commit 7da26042b3
4 changed files with 46 additions and 8 deletions

View File

@ -20,6 +20,14 @@ type Props = {
*/
dispatch: Function,
/**
* Tells the component if it's being displayed at the moment, or not.
* Note: as an example, on Android it can happen that the component
* is rendered but not displayed, because components like ViewPagerAndroid
* render their children even if they are not visible at the moment.
*/
displayed: boolean,
/**
* The calendar event list.
*/
@ -35,6 +43,7 @@ type Props = {
* Component to display a list of events from the (mobile) user's calendar.
*/
class MeetingList extends Component<Props> {
_initialLoaded: boolean
/**
* Default values for the component's props.
@ -58,6 +67,26 @@ class MeetingList extends Component<Props> {
this._toDateString = this._toDateString.bind(this);
}
/**
* Implements React Component's componentWillReceiveProps function.
*
* @inheritdoc
*/
componentWillReceiveProps(newProps) {
// This is a conditional logic to refresh the calendar entries (thus
// to request access to calendar) on component first receives a
// displayed=true prop - to avoid requesting calendar access on
// app start.
if (!this._initialLoaded
&& newProps.displayed
&& !this.props.displayed) {
const { dispatch } = this.props;
this._initialLoaded = true;
dispatch(refreshCalendarEntryList());
}
}
/**
* Implements the React Components's render method.
*

View File

@ -22,10 +22,10 @@ MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case APP_WILL_MOUNT:
_ensureDefaultServer(store);
_fetchCalendarEntries(store);
_fetchCalendarEntries(store, false);
break;
case REFRESH_CALENDAR_ENTRY_LIST:
_fetchCalendarEntries(store);
_fetchCalendarEntries(store, true);
break;
case SET_ROOM:
_parseAndAddDomain(store);
@ -38,15 +38,17 @@ MiddlewareRegistry.register(store => next => action => {
* Ensures calendar access if possible and resolves the promise if it's granted.
*
* @private
* @param {boolean} promptForPermission - Flag to tell the app if it should
* prompt for a calendar permission if it wasn't granted yet.
* @returns {Promise}
*/
function _ensureCalendarAccess() {
function _ensureCalendarAccess(promptForPermission) {
return new Promise((resolve, reject) => {
RNCalendarEvents.authorizationStatus()
.then(status => {
if (status === 'authorized') {
resolve();
} else if (status === 'undetermined') {
} else if (promptForPermission) {
RNCalendarEvents.authorizeEventStore()
.then(result => {
if (result === 'authorized') {
@ -89,10 +91,12 @@ function _ensureDefaultServer(store) {
*
* @private
* @param {Object} store - The redux store.
* @param {boolean} promptForPermission - Flag to tell the app if it should
* prompt for a calendar permission if it wasn't granted yet.
* @returns {void}
*/
function _fetchCalendarEntries(store) {
_ensureCalendarAccess()
function _fetchCalendarEntries(store, promptForPermission) {
_ensureCalendarAccess(promptForPermission)
.then(() => {
const startDate = new Date();
const endDate = new Date();

View File

@ -41,6 +41,7 @@ export default class PagedList extends AbstractPagedList {
*/
render() {
const { disabled } = this.props;
const { pageIndex } = this.state;
return (
<View
@ -59,7 +60,9 @@ export default class PagedList extends AbstractPagedList {
<RecentList disabled = { disabled } />
</View>
<View key = { 1 }>
<MeetingList disabled = { disabled } />
<MeetingList
disabled = { disabled }
displayed = { pageIndex === 1 } />
</View>
</ViewPagerAndroid>
<View style = { styles.pageIndicatorContainer }>

View File

@ -58,7 +58,9 @@ class PagedList extends AbstractPagedList {
onPress = { this._onTabSelected(1) }
selected = { pageIndex === 1 }
title = { t('welcomepage.calendar') } >
<MeetingList disabled = { disabled } />
<MeetingList
disabled = { disabled }
displayed = { pageIndex === 1 } />
</TabBarIOS.Item>
</TabBarIOS>
</View>