[NEW] Pull to refresh RoomsList (#1701)
This commit is contained in:
parent
ebe36cdc00
commit
42a53b4c9d
|
@ -22,6 +22,7 @@ export const SHARE = createRequestTypes('SHARE', [
|
||||||
export const USER = createRequestTypes('USER', ['SET']);
|
export const USER = createRequestTypes('USER', ['SET']);
|
||||||
export const ROOMS = createRequestTypes('ROOMS', [
|
export const ROOMS = createRequestTypes('ROOMS', [
|
||||||
...defaultTypes,
|
...defaultTypes,
|
||||||
|
'REFRESH',
|
||||||
'SET_SEARCH',
|
'SET_SEARCH',
|
||||||
'CLOSE_SERVER_DROPDOWN',
|
'CLOSE_SERVER_DROPDOWN',
|
||||||
'TOGGLE_SERVER_DROPDOWN',
|
'TOGGLE_SERVER_DROPDOWN',
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import * as types from './actionsTypes';
|
import * as types from './actionsTypes';
|
||||||
|
|
||||||
|
|
||||||
export function roomsRequest() {
|
export function roomsRequest(params = { allData: false }) {
|
||||||
return {
|
return {
|
||||||
type: types.ROOMS.REQUEST
|
type: types.ROOMS.REQUEST,
|
||||||
|
params
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +21,12 @@ export function roomsFailure(err) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function roomsRefresh() {
|
||||||
|
return {
|
||||||
|
type: types.ROOMS.REFRESH
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function setSearch(searchText) {
|
export function setSearch(searchText) {
|
||||||
return {
|
return {
|
||||||
type: types.ROOMS.SET_SEARCH,
|
type: types.ROOMS.SET_SEARCH,
|
||||||
|
|
|
@ -2,6 +2,7 @@ import * as types from '../actions/actionsTypes';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
isFetching: false,
|
isFetching: false,
|
||||||
|
refreshing: false,
|
||||||
failure: false,
|
failure: false,
|
||||||
errorMessage: {},
|
errorMessage: {},
|
||||||
searchText: '',
|
searchText: '',
|
||||||
|
@ -23,15 +24,23 @@ export default function login(state = initialState, action) {
|
||||||
case types.ROOMS.SUCCESS:
|
case types.ROOMS.SUCCESS:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
isFetching: false
|
isFetching: false,
|
||||||
|
refreshing: false
|
||||||
};
|
};
|
||||||
case types.ROOMS.FAILURE:
|
case types.ROOMS.FAILURE:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
isFetching: false,
|
isFetching: false,
|
||||||
|
refreshing: false,
|
||||||
failure: true,
|
failure: true,
|
||||||
errorMessage: action.err
|
errorMessage: action.err
|
||||||
};
|
};
|
||||||
|
case types.ROOMS.REFRESH:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isFetching: true,
|
||||||
|
refreshing: true
|
||||||
|
};
|
||||||
case types.ROOMS.SET_SEARCH:
|
case types.ROOMS.SET_SEARCH:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { Q } from '@nozbe/watermelondb';
|
||||||
|
|
||||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||||
import * as types from '../actions/actionsTypes';
|
import * as types from '../actions/actionsTypes';
|
||||||
import { roomsSuccess, roomsFailure } from '../actions/rooms';
|
import { roomsSuccess, roomsFailure, roomsRefresh } from '../actions/rooms';
|
||||||
import database from '../lib/database';
|
import database from '../lib/database';
|
||||||
import log from '../utils/log';
|
import log from '../utils/log';
|
||||||
import mergeSubscriptionsRooms from '../lib/methods/helpers/mergeSubscriptionsRooms';
|
import mergeSubscriptionsRooms from '../lib/methods/helpers/mergeSubscriptionsRooms';
|
||||||
|
@ -26,15 +26,20 @@ const updateRooms = function* updateRooms({ server, newRoomsUpdatedAt }) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRoomsRequest = function* handleRoomsRequest() {
|
const handleRoomsRequest = function* handleRoomsRequest({ params }) {
|
||||||
try {
|
try {
|
||||||
const serversDB = database.servers;
|
const serversDB = database.servers;
|
||||||
yield RocketChat.subscribeRooms();
|
RocketChat.subscribeRooms();
|
||||||
const newRoomsUpdatedAt = new Date();
|
const newRoomsUpdatedAt = new Date();
|
||||||
|
let roomsUpdatedAt;
|
||||||
const server = yield select(state => state.server.server);
|
const server = yield select(state => state.server.server);
|
||||||
const serversCollection = serversDB.collections.get('servers');
|
if (params.allData) {
|
||||||
const serverRecord = yield serversCollection.find(server);
|
yield put(roomsRefresh());
|
||||||
const { roomsUpdatedAt } = serverRecord;
|
} else {
|
||||||
|
const serversCollection = serversDB.collections.get('servers');
|
||||||
|
const serverRecord = yield serversCollection.find(server);
|
||||||
|
({ roomsUpdatedAt } = serverRecord);
|
||||||
|
}
|
||||||
const [subscriptionsResult, roomsResult] = yield RocketChat.getRooms(roomsUpdatedAt);
|
const [subscriptionsResult, roomsResult] = yield RocketChat.getRooms(roomsUpdatedAt);
|
||||||
const { subscriptions } = mergeSubscriptionsRooms(subscriptionsResult, roomsResult);
|
const { subscriptions } = mergeSubscriptionsRooms(subscriptionsResult, roomsResult);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FlatList, InteractionManager } from 'react-native';
|
import { FlatList, InteractionManager, RefreshControl } from 'react-native';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import orderBy from 'lodash/orderBy';
|
import orderBy from 'lodash/orderBy';
|
||||||
import { Q } from '@nozbe/watermelondb';
|
import { Q } from '@nozbe/watermelondb';
|
||||||
|
@ -15,6 +15,7 @@ import { isIOS } from '../../utils/deviceInfo';
|
||||||
import { animateNextTransition } from '../../utils/layoutAnimation';
|
import { animateNextTransition } from '../../utils/layoutAnimation';
|
||||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import debounce from '../../utils/debounce';
|
import debounce from '../../utils/debounce';
|
||||||
|
import { themes } from '../../constants/colors';
|
||||||
|
|
||||||
class List extends React.Component {
|
class List extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -237,8 +238,13 @@ class List extends React.Component {
|
||||||
maxToRenderPerBatch={5}
|
maxToRenderPerBatch={5}
|
||||||
windowSize={10}
|
windowSize={10}
|
||||||
ListFooterComponent={this.renderFooter}
|
ListFooterComponent={this.renderFooter}
|
||||||
onRefresh={this.onRefresh}
|
refreshControl={(
|
||||||
refreshing={refreshing}
|
<RefreshControl
|
||||||
|
refreshing={refreshing}
|
||||||
|
onRefresh={this.onRefresh}
|
||||||
|
tintColor={themes[theme].auxiliaryText}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{...scrollPersistTaps}
|
{...scrollPersistTaps}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -6,7 +6,8 @@ import {
|
||||||
BackHandler,
|
BackHandler,
|
||||||
Text,
|
Text,
|
||||||
Keyboard,
|
Keyboard,
|
||||||
Dimensions
|
Dimensions,
|
||||||
|
RefreshControl
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { isEqual, orderBy } from 'lodash';
|
import { isEqual, orderBy } from 'lodash';
|
||||||
|
@ -87,7 +88,8 @@ const shouldUpdateProps = [
|
||||||
'StoreLastMessage',
|
'StoreLastMessage',
|
||||||
'appState',
|
'appState',
|
||||||
'theme',
|
'theme',
|
||||||
'split'
|
'split',
|
||||||
|
'refreshing'
|
||||||
];
|
];
|
||||||
const getItemLayout = (data, index) => ({
|
const getItemLayout = (data, index) => ({
|
||||||
length: ROW_HEIGHT,
|
length: ROW_HEIGHT,
|
||||||
|
@ -163,6 +165,7 @@ class RoomsListView extends React.Component {
|
||||||
groupByType: PropTypes.bool,
|
groupByType: PropTypes.bool,
|
||||||
showFavorites: PropTypes.bool,
|
showFavorites: PropTypes.bool,
|
||||||
showUnread: PropTypes.bool,
|
showUnread: PropTypes.bool,
|
||||||
|
refreshing: PropTypes.bool,
|
||||||
StoreLastMessage: PropTypes.bool,
|
StoreLastMessage: PropTypes.bool,
|
||||||
appState: PropTypes.string,
|
appState: PropTypes.string,
|
||||||
theme: PropTypes.string,
|
theme: PropTypes.string,
|
||||||
|
@ -672,6 +675,11 @@ class RoomsListView extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onRefresh = () => {
|
||||||
|
const { roomsRequest } = this.props;
|
||||||
|
roomsRequest({ allData: true });
|
||||||
|
}
|
||||||
|
|
||||||
getScrollRef = ref => (this.scroll = ref);
|
getScrollRef = ref => (this.scroll = ref);
|
||||||
|
|
||||||
renderListHeader = () => {
|
renderListHeader = () => {
|
||||||
|
@ -757,8 +765,10 @@ class RoomsListView extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderScroll = () => {
|
renderScroll = () => {
|
||||||
const { loading, chats, search } = this.state;
|
const {
|
||||||
const { theme } = this.props;
|
loading, chats, search
|
||||||
|
} = this.state;
|
||||||
|
const { theme, refreshing } = this.props;
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return <ActivityIndicator theme={theme} />;
|
return <ActivityIndicator theme={theme} />;
|
||||||
|
@ -778,6 +788,13 @@ class RoomsListView extends React.Component {
|
||||||
removeClippedSubviews={isIOS}
|
removeClippedSubviews={isIOS}
|
||||||
keyboardShouldPersistTaps='always'
|
keyboardShouldPersistTaps='always'
|
||||||
initialNumToRender={INITIAL_NUM_TO_RENDER}
|
initialNumToRender={INITIAL_NUM_TO_RENDER}
|
||||||
|
refreshControl={(
|
||||||
|
<RefreshControl
|
||||||
|
refreshing={refreshing}
|
||||||
|
onRefresh={this.onRefresh}
|
||||||
|
tintColor={themes[theme].auxiliaryText}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
windowSize={9}
|
windowSize={9}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -825,6 +842,7 @@ const mapStateToProps = state => ({
|
||||||
loadingServer: state.server.loading,
|
loadingServer: state.server.loading,
|
||||||
showServerDropdown: state.rooms.showServerDropdown,
|
showServerDropdown: state.rooms.showServerDropdown,
|
||||||
showSortDropdown: state.rooms.showSortDropdown,
|
showSortDropdown: state.rooms.showSortDropdown,
|
||||||
|
refreshing: state.rooms.refreshing,
|
||||||
sortBy: state.sortPreferences.sortBy,
|
sortBy: state.sortPreferences.sortBy,
|
||||||
groupByType: state.sortPreferences.groupByType,
|
groupByType: state.sortPreferences.groupByType,
|
||||||
showFavorites: state.sortPreferences.showFavorites,
|
showFavorites: state.sortPreferences.showFavorites,
|
||||||
|
@ -839,7 +857,7 @@ const mapDispatchToProps = dispatch => ({
|
||||||
openSearchHeader: () => dispatch(openSearchHeaderAction()),
|
openSearchHeader: () => dispatch(openSearchHeaderAction()),
|
||||||
closeSearchHeader: () => dispatch(closeSearchHeaderAction()),
|
closeSearchHeader: () => dispatch(closeSearchHeaderAction()),
|
||||||
appStart: () => dispatch(appStartAction()),
|
appStart: () => dispatch(appStartAction()),
|
||||||
roomsRequest: () => dispatch(roomsRequestAction()),
|
roomsRequest: params => dispatch(roomsRequestAction(params)),
|
||||||
selectServerRequest: server => dispatch(selectServerRequestAction(server)),
|
selectServerRequest: server => dispatch(selectServerRequestAction(server)),
|
||||||
closeServerDropdown: () => dispatch(closeServerDropdownAction())
|
closeServerDropdown: () => dispatch(closeServerDropdownAction())
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue