[RN] Make the calendar the default tab when there are calendar entries fetched.

This commit is contained in:
Bettenbuk Zoltan 2018-05-31 11:00:33 +02:00 committed by Saúl Ibarra Corretgé
parent a4cfe97b38
commit 6a1e9e256d
4 changed files with 92 additions and 14 deletions

View File

@ -55,16 +55,26 @@ export default class AbstractPagedList extends Component<Props, State> {
constructor(props: Props) { constructor(props: Props) {
super(props); super(props);
// props.defaultPage may point to a non existing page if some of the
// pages are disabled.
const maxPageIndex
= props.pages.filter(page => page.component).length - 1;
this.state = { this.state = {
pageIndex: Math.max(0, Math.min(maxPageIndex, props.defaultPage)) pageIndex: this._validatePageIndex(props.defaultPage)
}; };
} }
/**
* Implements React {@code Component}'s componentWillReceiveProps.
*
* @inheritdoc
*/
componentWillReceiveProps(newProps: Props) {
const { defaultPage } = newProps;
if (defaultPage !== this.props.defaultPage) {
// Default page changed due to a redux update. This is likely to
// happen after APP_WILL_MOUNT. So we update the active tab.
this._platformSpecificPageSelect(defaultPage);
}
}
/** /**
* Renders the component. * Renders the component.
* *
@ -95,6 +105,20 @@ export default class AbstractPagedList extends Component<Props, State> {
); );
} }
_platformSpecificPageSelect: number => void
/**
* Method to be overriden by the components implementing this abstract class
* to handle platform specific actions on page select.
*
* @protected
* @param {number} pageIndex - The selected page index.
* @returns {void}
*/
_platformSpecificPageSelect(pageIndex) {
this._selectPage(pageIndex);
}
_renderPagedList: boolean => React$Node; _renderPagedList: boolean => React$Node;
_selectPage: number => void; _selectPage: number => void;
@ -107,13 +131,15 @@ export default class AbstractPagedList extends Component<Props, State> {
* @returns {void} * @returns {void}
*/ */
_selectPage(pageIndex: number) { _selectPage(pageIndex: number) {
const validatedPageIndex = this._validatePageIndex(pageIndex);
this.setState({ this.setState({
pageIndex pageIndex: validatedPageIndex
}); });
// The page's Component may have a refresh(dispatch) function which we // The page's Component may have a refresh(dispatch) function which we
// invoke when the page is selected. // invoke when the page is selected.
const selectedPage = this.props.pages[pageIndex]; const selectedPage = this.props.pages[validatedPageIndex];
if (selectedPage && selectedPage.component) { if (selectedPage && selectedPage.component) {
const { refresh } = selectedPage.component; const { refresh } = selectedPage.component;
@ -121,4 +147,22 @@ export default class AbstractPagedList extends Component<Props, State> {
typeof refresh === 'function' && refresh(this.props.dispatch); typeof refresh === 'function' && refresh(this.props.dispatch);
} }
} }
_validatePageIndex: number => number
/**
* Validates the requested page index and returns a safe value.
*
* @private
* @param {number} pageIndex - The requested page index.
* @returns {number}
*/
_validatePageIndex(pageIndex) {
// pageIndex may point to a non existing page if some of the pages are
// disabled (their component property is undefined).
const maxPageIndex
= this.props.pages.filter(page => page.component).length - 1;
return Math.max(0, Math.min(maxPageIndex, pageIndex));
}
} }

View File

@ -86,6 +86,18 @@ class PagedList extends AbstractPagedList {
} }
} }
/**
* Platform specific actions to run on page select.
*
* @private
* @param {number} pageIndex - The selected page index.
* @returns {void}
*/
_platformSpecificPageSelect(pageIndex) {
this._viewPager.setPage(pageIndex);
this._selectPage(pageIndex);
}
/** /**
* Renders a single page of the page list. * Renders a single page of the page list.
* *

View File

@ -66,11 +66,9 @@ CALENDAR_ENABLED
&& store.dispatch(addKnownDomains(knownDomains)); && store.dispatch(addKnownDomains(knownDomains));
} }
const result = next(action);
_fetchCalendarEntries(store, false, false); _fetchCalendarEntries(store, false, false);
return result; return next(action);
} }
case REFRESH_CALENDAR: { case REFRESH_CALENDAR: {

View File

@ -2,6 +2,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Platform } from 'react-native'; import { Platform } from 'react-native';
import { connect } from 'react-redux';
import { translate } from '../../base/i18n'; import { translate } from '../../base/i18n';
import { PagedList } from '../../base/react'; import { PagedList } from '../../base/react';
@ -10,6 +11,11 @@ import { RecentList } from '../../recent-list';
type Props = { type Props = {
/**
* True if the calendar feature has fetched entries, false otherwise
*/
_hasCalendarEntries: boolean,
/** /**
* Renders the lists disabled. * Renders the lists disabled.
*/ */
@ -74,15 +80,33 @@ class WelcomePageLists extends Component<Props> {
* @inheritdoc * @inheritdoc
*/ */
render() { render() {
const { disabled } = this.props; const { disabled, _hasCalendarEntries } = this.props;
return ( return (
<PagedList <PagedList
defaultPage = { 0 } defaultPage = { _hasCalendarEntries ? 1 : 0 }
disabled = { disabled } disabled = { disabled }
pages = { this.pages } /> pages = { this.pages } />
); );
} }
} }
export default translate(WelcomePageLists); /**
* Maps (parts of) the redux state to the React {@code Component} props of
* {@code WelcomePageLists}.
*
* @param {Object} state - The redux state.
* @protected
* @returns {{
* _hasCalendarEntries: boolean
* }}
*/
function _mapStateToProps(state: Object) {
const { events } = state['features/calendar-sync'];
return {
_hasCalendarEntries: Boolean(events && events.length)
};
}
export default translate(connect(_mapStateToProps)(WelcomePageLists));