From 4b17c6f015c850fc70a4ab19cee9847e4e2c35d0 Mon Sep 17 00:00:00 2001 From: zbettenbuk Date: Wed, 14 Feb 2018 10:50:48 -0600 Subject: [PATCH] Add pull-to-refresh functionality --- .../components/native/NavigateSectionList.js | 26 ++++++++++ .../base/react/components/native/styles.js | 4 +- react/features/calendar-sync/actionTypes.js | 6 +++ react/features/calendar-sync/actions.js | 51 ++++++++++++------- .../components/MeetingList.native.js | 18 +++++++ react/features/calendar-sync/middleware.js | 4 ++ 6 files changed, 90 insertions(+), 19 deletions(-) diff --git a/react/features/base/react/components/native/NavigateSectionList.js b/react/features/base/react/components/native/NavigateSectionList.js index 01f1badd9..c3040a7fd 100644 --- a/react/features/base/react/components/native/NavigateSectionList.js +++ b/react/features/base/react/components/native/NavigateSectionList.js @@ -22,6 +22,11 @@ type Props = { */ onPress: Function, + /** + * Function to be invoked when pull-to-refresh is performed. + */ + onRefresh: Function, + /** * Sections to be rendered in the following format: * @@ -60,6 +65,7 @@ export default class NavigateSectionList extends Component { this._getAvatarColor = this._getAvatarColor.bind(this); this._getItemKey = this._getItemKey.bind(this); this._onPress = this._onPress.bind(this); + this._onRefresh = this._onRefresh.bind(this); this._renderItem = this._renderItem.bind(this); this._renderItemLine = this._renderItemLine.bind(this); this._renderItemLines = this._renderItemLines.bind(this); @@ -68,6 +74,8 @@ export default class NavigateSectionList extends Component { /** * Implements React's Component.render function. + * Note: we don't use the refreshing value yet, because refreshing of these + * lists is super quick, no need to complicate the code - yet. * * @inheritdoc */ @@ -79,6 +87,8 @@ export default class NavigateSectionList extends Component { style = { styles.container } > { }; } + _onRefresh: () => void + + /** + * Invokes the onRefresh callback if present. + * + * @private + * @returns {void} + */ + _onRefresh() { + const { onRefresh } = this.props; + + if (typeof onRefresh === 'function') { + onRefresh(); + } + } + _renderItem: Object => Object; /** diff --git a/react/features/base/react/components/native/styles.js b/react/features/base/react/components/native/styles.js index 43f6402ab..6fa8ca9e4 100644 --- a/react/features/base/react/components/native/styles.js +++ b/react/features/base/react/components/native/styles.js @@ -71,7 +71,7 @@ const HEADER_STYLES = { } }; -const SECTIONLIST_STYLES = { +const SECTION_LIST_STYLES = { /** * The style of the actual avatar. */ @@ -229,6 +229,6 @@ const SIDEBAR_STYLES = { */ export default createStyleSheet({ ...HEADER_STYLES, - ...SECTIONLIST_STYLES, + ...SECTION_LIST_STYLES, ...SIDEBAR_STYLES }); diff --git a/react/features/calendar-sync/actionTypes.js b/react/features/calendar-sync/actionTypes.js index 5ba7708cd..3366ac424 100644 --- a/react/features/calendar-sync/actionTypes.js +++ b/react/features/calendar-sync/actionTypes.js @@ -9,3 +9,9 @@ export const NEW_CALENDAR_ENTRY_LIST = Symbol('NEW_CALENDAR_ENTRY_LIST'); * Action to add a new known domain to the list. */ export const NEW_KNOWN_DOMAIN = Symbol('NEW_KNOWN_DOMAIN'); + +/** + * Action to refresh (re-fetch) the entry list. + */ +export const REFRESH_CALENDAR_ENTRY_LIST + = Symbol('REFRESH_CALENDAR_ENTRY_LIST'); diff --git a/react/features/calendar-sync/actions.js b/react/features/calendar-sync/actions.js index bff0b19ed..6d26df3ab 100644 --- a/react/features/calendar-sync/actions.js +++ b/react/features/calendar-sync/actions.js @@ -1,21 +1,9 @@ // @flow -import { NEW_CALENDAR_ENTRY_LIST, NEW_KNOWN_DOMAIN } from './actionTypes'; - -/** - * Sends an action to update the current calendar list in redux. - * - * @param {Array} events - The new list. - * @returns {{ - * type: NEW_CALENDAR_ENTRY_LIST, - * events: Array - * }} - */ -export function updateCalendarEntryList(events: Array) { - return { - type: NEW_CALENDAR_ENTRY_LIST, - events - }; -} +import { + NEW_CALENDAR_ENTRY_LIST, + NEW_KNOWN_DOMAIN, + REFRESH_CALENDAR_ENTRY_LIST +} from './actionTypes'; /** * Sends an action to add a new known domain if not present yet. @@ -32,3 +20,32 @@ export function maybeAddNewKnownDomain(domainName: string) { domainName }; } + +/** + * Sends an action to refresh the entry list (fetches new data). + * + * @returns {{ + * type: REFRESH_CALENDAR_ENTRY_LIST + * }} + */ +export function refreshCalendarEntryList() { + return { + type: REFRESH_CALENDAR_ENTRY_LIST + }; +} + +/** + * Sends an action to update the current calendar list in redux. + * + * @param {Array} events - The new list. + * @returns {{ + * type: NEW_CALENDAR_ENTRY_LIST, + * events: Array + * }} + */ +export function updateCalendarEntryList(events: Array) { + return { + type: NEW_CALENDAR_ENTRY_LIST, + events + }; +} diff --git a/react/features/calendar-sync/components/MeetingList.native.js b/react/features/calendar-sync/components/MeetingList.native.js index c00b401ab..79f7c580b 100644 --- a/react/features/calendar-sync/components/MeetingList.native.js +++ b/react/features/calendar-sync/components/MeetingList.native.js @@ -2,6 +2,8 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; +import { refreshCalendarEntryList } from '../actions'; + import { appNavigate } from '../../app'; import { translate } from '../../base/i18n'; import { NavigateSectionList } from '../../base/react'; @@ -51,6 +53,7 @@ class MeetingList extends Component { super(props); this._onPress = this._onPress.bind(this); + this._onRefresh = this._onRefresh.bind(this); this._toDisplayableItem = this._toDisplayableItem.bind(this); this._toDisplayableList = this._toDisplayableList.bind(this); this._toDateString = this._toDateString.bind(this); @@ -68,6 +71,7 @@ class MeetingList extends Component { ); } @@ -87,6 +91,20 @@ class MeetingList extends Component { dispatch(appNavigate(url)); } + _onRefresh: () => void + + /** + * Callback to execute when the list is doing a pull-to-refresh. + * + * @private + * @returns {void} + */ + _onRefresh() { + const { dispatch } = this.props; + + dispatch(refreshCalendarEntryList()); + } + _toDisplayableItem: Object => Object /** diff --git a/react/features/calendar-sync/middleware.js b/react/features/calendar-sync/middleware.js index c132a27cb..5528c236c 100644 --- a/react/features/calendar-sync/middleware.js +++ b/react/features/calendar-sync/middleware.js @@ -9,6 +9,7 @@ import { parseURIString } from '../base/util'; import { APP_WILL_MOUNT } from '../app'; import { maybeAddNewKnownDomain, updateCalendarEntryList } from './actions'; +import { REFRESH_CALENDAR_ENTRY_LIST } from './actionTypes'; const FETCH_END_DAYS = 10; const FETCH_START_DAYS = -1; @@ -23,6 +24,9 @@ MiddlewareRegistry.register(store => next => action => { _ensureDefaultServer(store); _fetchCalendarEntries(store); break; + case REFRESH_CALENDAR_ENTRY_LIST: + _fetchCalendarEntries(store); + break; case SET_ROOM: _parseAndAddDomain(store); }