mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-11-29 22:07:46 +03:00
Merge pull request #427 from esteemapp/bugfix/notification-loading
Bugfix/notification loading
This commit is contained in:
commit
e794585e27
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
View, Text, Image, StyleSheet,
|
||||
View, Image, StyleSheet,
|
||||
} from 'react-native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
@ -35,25 +35,25 @@ export default class PulseAnimation extends Component {
|
||||
},
|
||||
};
|
||||
|
||||
mounted = true;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
color: this.props.color,
|
||||
duration: this.props.duration,
|
||||
image: this.props.image,
|
||||
maxDiameter: this.props.diameter,
|
||||
numPulses: this.props.numPulses,
|
||||
color: props.color,
|
||||
duration: props.duration,
|
||||
image: props.image,
|
||||
maxDiameter: props.diameter,
|
||||
numPulses: props.numPulses,
|
||||
pulses: [],
|
||||
pulseStyle: this.props.pulseStyle,
|
||||
speed: this.props.speed,
|
||||
pulseStyle: props.pulseStyle,
|
||||
speed: props.speed,
|
||||
started: false,
|
||||
style: this.props.style,
|
||||
style: props.style,
|
||||
};
|
||||
}
|
||||
|
||||
mounted = true;
|
||||
|
||||
componentDidMount() {
|
||||
const { numPulses, duration, speed } = this.state;
|
||||
|
||||
@ -79,15 +79,16 @@ export default class PulseAnimation extends Component {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
|
||||
createPulse = (pKey) => {
|
||||
createPulse = () => {
|
||||
if (this.mounted) {
|
||||
const pulses = this.state.pulses;
|
||||
const { pulses, maxDiameter } = this.state;
|
||||
const { initialDiameter } = this.props;
|
||||
|
||||
const pulse = {
|
||||
pulseKey: pulses.length + 1,
|
||||
diameter: this.props.initialDiameter,
|
||||
diameter: initialDiameter,
|
||||
opacity: 0.5,
|
||||
centerOffset: (this.state.maxDiameter - this.props.initialDiameter) / 2,
|
||||
centerOffset: (maxDiameter - initialDiameter) / 2,
|
||||
};
|
||||
|
||||
pulses.push(pulse);
|
||||
@ -99,10 +100,10 @@ export default class PulseAnimation extends Component {
|
||||
updatePulse = () => {
|
||||
if (this.mounted) {
|
||||
const pulses = this.state.pulses.map((p, i) => {
|
||||
const maxDiameter = this.state.maxDiameter;
|
||||
const { maxDiameter } = this.state;
|
||||
const newDiameter = p.diameter > maxDiameter ? 0 : p.diameter + 2;
|
||||
const centerOffset = (maxDiameter - newDiameter) / 2;
|
||||
const opacity = Math.abs(newDiameter / this.state.maxDiameter - 1);
|
||||
const opacity = Math.abs(newDiameter / maxDiameter - 1);
|
||||
|
||||
const pulse = {
|
||||
pulseKey: i + 1,
|
||||
|
@ -22,7 +22,6 @@ const FilterBarView = ({
|
||||
iconSize,
|
||||
isHide,
|
||||
onDropdownSelect,
|
||||
pageType,
|
||||
onRightIconPress,
|
||||
options,
|
||||
rightIconName,
|
||||
|
@ -5,4 +5,17 @@ export default EStyleSheet.create({
|
||||
backgroundColor: '$primaryBackgroundColor',
|
||||
flex: 1,
|
||||
},
|
||||
flatlistFooter: {
|
||||
alignContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginTop: 10,
|
||||
marginBottom: 40,
|
||||
borderColor: '$borderColor',
|
||||
},
|
||||
loading: {
|
||||
alignContent: 'center',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
@ -1,5 +1,7 @@
|
||||
import React, { PureComponent, Fragment } from 'react';
|
||||
import { View, ScrollView, FlatList } from 'react-native';
|
||||
import {
|
||||
View, ScrollView, FlatList, ActivityIndicator, RefreshControl,
|
||||
} from 'react-native';
|
||||
import { injectIntl } from 'react-intl';
|
||||
|
||||
// Constants
|
||||
@ -34,6 +36,7 @@ class NotificationView extends PureComponent {
|
||||
{ key: 'follows', value: 'FOLLOWS' },
|
||||
{ key: 'reblogs', value: 'REBLOGS' },
|
||||
],
|
||||
selectedFilter: null,
|
||||
};
|
||||
}
|
||||
|
||||
@ -45,7 +48,8 @@ class NotificationView extends PureComponent {
|
||||
const { getActivities } = this.props;
|
||||
const { filters } = this.state;
|
||||
|
||||
getActivities(filters[index].key);
|
||||
this.setState({ selectedFilter: filters[index].key });
|
||||
getActivities(filters[index].key, false);
|
||||
};
|
||||
|
||||
_renderList = (data) => {
|
||||
@ -60,11 +64,25 @@ class NotificationView extends PureComponent {
|
||||
handleOnPressNotification={navigateToNotificationRoute}
|
||||
/>
|
||||
)}
|
||||
initialNumToRender={data.length}
|
||||
maxToRenderPerBatch={data.length}
|
||||
keyExtractor={item => item.id}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
_renderFooterLoading = () => {
|
||||
const { loading, notifications } = this.props;
|
||||
if (loading && notifications.length > 0) {
|
||||
return (
|
||||
<View style={styles.flatlistFooter}>
|
||||
<ActivityIndicator animating size="large" />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
_getNotificationsArrays = () => {
|
||||
const { notifications, intl } = this.props;
|
||||
|
||||
@ -113,31 +131,39 @@ class NotificationView extends PureComponent {
|
||||
};
|
||||
|
||||
_getTimeListIndex = (timestamp) => {
|
||||
if (isToday(timestamp)) {
|
||||
return 0;
|
||||
}
|
||||
if (isToday(timestamp)) return 0;
|
||||
|
||||
if (isYesterday(timestamp)) {
|
||||
return 1;
|
||||
}
|
||||
if (isYesterday(timestamp)) return 1;
|
||||
|
||||
if (isThisWeek(timestamp)) {
|
||||
return 2;
|
||||
}
|
||||
if (isThisWeek(timestamp)) return 2;
|
||||
|
||||
if (isThisMonth(timestamp)) {
|
||||
return 3;
|
||||
}
|
||||
if (isThisMonth(timestamp)) return 3;
|
||||
|
||||
return 4;
|
||||
};
|
||||
|
||||
_getActivityIndicator = () => (
|
||||
<View style={styles.loading}>
|
||||
<ActivityIndicator animating size="large" />
|
||||
</View>
|
||||
);
|
||||
|
||||
render() {
|
||||
const { readAllNotification } = this.props;
|
||||
const { filters } = this.state;
|
||||
const {
|
||||
readAllNotification,
|
||||
getActivities,
|
||||
loading,
|
||||
readAllNotificationLoading,
|
||||
isDarkTheme,
|
||||
} = this.props;
|
||||
const { filters, selectedFilter } = this.state;
|
||||
|
||||
const _notifications = this._getNotificationsArrays();
|
||||
|
||||
if (_notifications.length === 0) {
|
||||
return this._getActivityIndicator();
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<FilterBar
|
||||
@ -145,12 +171,36 @@ class NotificationView extends PureComponent {
|
||||
options={filters.map(item => item.value)}
|
||||
defaultText="ALL ACTIVITIES"
|
||||
onDropdownSelect={this._handleOnDropdownSelect}
|
||||
rightIconName="ios-checkmark"
|
||||
rightIconName="check"
|
||||
rightIconType="MaterialIcons"
|
||||
onRightIconPress={readAllNotification}
|
||||
/>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
<ScrollView
|
||||
style={styles.scrollView}
|
||||
onScroll={(e) => {
|
||||
let paddingToBottom = 1;
|
||||
paddingToBottom += e.nativeEvent.layoutMeasurement.height;
|
||||
if (
|
||||
e.nativeEvent.contentOffset.y >= e.nativeEvent.contentSize.height - paddingToBottom
|
||||
&& !loading
|
||||
) {
|
||||
getActivities(selectedFilter, true);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<FlatList
|
||||
data={_notifications}
|
||||
refreshing={readAllNotificationLoading}
|
||||
onRefresh={() => null}
|
||||
refreshControl={(
|
||||
<RefreshControl
|
||||
refreshing={readAllNotificationLoading}
|
||||
progressBackgroundColor="#357CE6"
|
||||
tintColor={!isDarkTheme ? '#357ce6' : '#96c0ff'}
|
||||
titleColor="#fff"
|
||||
colors={['#fff']}
|
||||
/>
|
||||
)}
|
||||
renderItem={({ item, index }) => (
|
||||
<Fragment>
|
||||
<ContainerHeader
|
||||
@ -163,6 +213,7 @@ class NotificationView extends PureComponent {
|
||||
</Fragment>
|
||||
)}
|
||||
keyExtractor={item => item.title}
|
||||
ListFooterComponent={this._renderFooterLoading}
|
||||
/>
|
||||
</ScrollView>
|
||||
</View>
|
||||
|
@ -26,10 +26,10 @@ class NotificationLineView extends PureComponent {
|
||||
|
||||
// Component Life Cycles
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { isRead } = this.props;
|
||||
const { notification } = this.props;
|
||||
|
||||
if (isRead !== nextProps.isRead) {
|
||||
this.setState({ isRead: nextProps.isRead });
|
||||
if (notification.read !== nextProps.notification.read) {
|
||||
this.setState({ isRead: nextProps.notification.read });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,20 @@ class NotificationContainer extends Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
notifications: [],
|
||||
lastNotificationId: null,
|
||||
notificationLoading: false,
|
||||
readAllNotificationLoading: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { username } = this.props;
|
||||
|
||||
if (username) {
|
||||
this._getAvtivities();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.activeBottomTab === ROUTES.TABBAR.NOTIFICATION) {
|
||||
if (nextProps.username) {
|
||||
@ -27,12 +38,24 @@ class NotificationContainer extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
_getAvtivities = (type = null) => {
|
||||
_getAvtivities = (type = null, loadMore = false) => {
|
||||
const { username } = this.props;
|
||||
const { lastNotificationId, notifications } = this.state;
|
||||
const since = loadMore ? lastNotificationId : null;
|
||||
|
||||
getActivities({ user: username, type }).then((res) => {
|
||||
this.setState({ notifications: res });
|
||||
});
|
||||
this.setState({ notificationLoading: true });
|
||||
|
||||
getActivities({ user: username, type, since })
|
||||
.then((res) => {
|
||||
const lastId = [...res].pop().id;
|
||||
|
||||
this.setState({
|
||||
notifications: loadMore ? [...notifications, ...res] : res,
|
||||
lastNotificationId: lastId,
|
||||
notificationLoading: false,
|
||||
});
|
||||
})
|
||||
.catch(() => this.setState({ notificationLoading: false }));
|
||||
};
|
||||
|
||||
_navigateToNotificationRoute = (data) => {
|
||||
@ -65,10 +88,13 @@ class NotificationContainer extends Component {
|
||||
_readAllNotification = () => {
|
||||
const { username, dispatch } = this.props;
|
||||
const { notifications } = this.state;
|
||||
|
||||
this.setState({ readAllNotificationLoading: true });
|
||||
|
||||
markActivityAsRead(username).then((result) => {
|
||||
dispatch(updateUnreadActivityCount(result.unread));
|
||||
const updatedNotifications = notifications.map(item => ({ ...item, read: 1 }));
|
||||
this.setState({ notifications: updatedNotifications });
|
||||
this.setState({ notifications: updatedNotifications, readAllNotificationLoading: false });
|
||||
});
|
||||
};
|
||||
|
||||
@ -79,24 +105,32 @@ class NotificationContainer extends Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { notifications } = this.state;
|
||||
const { isLoggedIn } = this.props;
|
||||
const {
|
||||
notifications, notificationLoading, readAllNotificationLoading, isDarkTheme,
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<NotificationScreen
|
||||
getActivities={this._getAvtivities}
|
||||
notifications={notifications}
|
||||
isDarkTheme={isDarkTheme}
|
||||
navigateToNotificationRoute={this._navigateToNotificationRoute}
|
||||
readAllNotification={this._readAllNotification}
|
||||
handleLoginPress={this._handleOnPressLogin}
|
||||
{...this.props}
|
||||
notificationLoading={notificationLoading}
|
||||
readAllNotificationLoading={readAllNotificationLoading}
|
||||
isLoggedIn={isLoggedIn}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
username: state.account.currentAccount.name,
|
||||
isLoggedIn: state.application.isLoggedIn,
|
||||
isDarkTheme: state.application.isDarkTheme,
|
||||
|
||||
username: state.account.currentAccount.name,
|
||||
activeBottomTab: state.ui.activeBottomTab,
|
||||
});
|
||||
|
||||
|
@ -29,7 +29,10 @@ class NotificationScreen extends PureComponent {
|
||||
readAllNotification,
|
||||
handleLoginPress,
|
||||
isLoggedIn,
|
||||
notificationLoading,
|
||||
readAllNotificationLoading,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Header />
|
||||
@ -51,6 +54,8 @@ class NotificationScreen extends PureComponent {
|
||||
notifications={notifications}
|
||||
navigateToNotificationRoute={navigateToNotificationRoute}
|
||||
readAllNotification={readAllNotification}
|
||||
readAllNotificationLoading={readAllNotificationLoading}
|
||||
loading={notificationLoading}
|
||||
/>
|
||||
) : (
|
||||
<NoPost
|
||||
|
Loading…
Reference in New Issue
Block a user