初步完成提醒页面

This commit is contained in:
mx1700 2019-07-06 19:54:09 +08:00
parent 07a2f4493d
commit 3f547d559a
3 changed files with 287 additions and 60 deletions

View file

@ -1,9 +1,11 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
import {StyleSheet, Text, View, FlatList, InteractionManager} from 'react-native'; import {StyleSheet, Text, View, FlatList, InteractionManager, ActivityIndicator, Platform} from 'react-native';
import {Navigation} from 'react-native-navigation'; import {Navigation} from 'react-native-navigation';
import Api from '../../util/api'; import Api from '../../util/api';
import Notification from './notification'; import Notification from './notification';
import Color from "../../style/color";
import {ListEmptyRefreshable} from "../listEmpty";
export default class NotificationList extends Component { export default class NotificationList extends Component {
@ -13,7 +15,8 @@ export default class NotificationList extends Component {
this.state = { this.state = {
notifications: [], notifications: [],
refreshing: false refreshing: false,
error: false
}; };
} }
@ -23,42 +26,79 @@ export default class NotificationList extends Component {
}); });
} }
refresh() { refresh(showRefreshing = true) {
this.setState({refreshing: true}); if(showRefreshing) {
Api.getMessagesHistory() this.setState({refreshing: true});
.then(notifications => { }
if(notifications) {
let reducedNoti = notifications.reduce((ret, v) => {
if(v.type == 1) {
let items = ret.filter(x => x.type === 1 && x.link_id === v.link_id);
if(items.length > 0) {
items[0].list.push(v);
} else { (async () => {
ret.push({ try {
type: 1, let notifications = await this.getMessages()
link_id: v.link_id, this.notificationsData = notifications;
created: v.created, this.setNotifications(notifications);
list: [v] } catch (e) {
}); this.setState({error: true});
} }
this.setState({refreshing: false});
})();
} else if (v.type == 2) { this.props.onRefresh && this.props.onRefresh();
ret.push(v); }
}
return ret;
}, []); setNotifications(notifications){
if(notifications) {
let reducedNoti = notifications.reduce((ret, v) => {
if(v.type == 1) {
let items = ret.filter(x => x.type === 1 && x.link_id === v.link_id);
if(items.length > 0) {
items[0].list.push(v);
this.setState({ } else {
notifications: reducedNoti ret.push({
}); type: 1,
link_id: v.link_id,
created: v.created,
list: [v]
});
}
} else if (v.type == 2) {
ret.push(v);
} }
}).done(() => { return ret;
this.setState({refreshing: false});
}, []);
this.setState({
notifications: reducedNoti
}); });
}
}
getMessages() {
if(this.props.isHistory) {
return Api.getMessagesHistory();
} else {
return Api.getMessages();
}
}
async _setRead(msg) {
let ids = null;
if (msg.type === 1) { //回复
ids = msg.list.map(it => it.id);
} else if (msg.type === 2) { //关注
ids = [msg.id];
}
try {
this.notificationsData = this.notificationsData.filter((msg) => ids.indexOf(msg.id) === -1);
this.setNotifications(this.notificationsData);
await Api.deleteMessage(ids);
} catch (err) {
console.log(err);
}
} }
_onCommentPress(msg) { _onCommentPress(msg) {
@ -79,6 +119,10 @@ export default class NotificationList extends Component {
} }
} }
}); });
if(this.props.isSetRead) {
this._setRead(msg);
}
} }
_onFollowPress(msg) { _onFollowPress(msg) {
@ -99,6 +143,10 @@ export default class NotificationList extends Component {
} }
} }
}); });
if(this.props.isSetRead) {
this._setRead(msg);
}
} }
render() { render() {
@ -124,13 +172,35 @@ export default class NotificationList extends Component {
onRefresh={this.refresh.bind(this)} onRefresh={this.refresh.bind(this)}
/> />
) : null; ) : this.renderEmpty();
}
renderEmpty() {
if (this.state.refreshing) {
return (
<View style={{alignItems:'center', justifyContent: 'center' , height: '100%'}}>
<ActivityIndicator animating={true} color={Color.primary} size={Platform.OS === 'android' ? 'large' : 'small'}/>
</View>
)
}
let text = this.state.error ? '出错了 :(':'没有提醒 :)';
return (
<ListEmptyRefreshable message={text} onPress={this.refresh.bind(this)}/>
);
} }
} }
const localStyle = StyleSheet.create({ // NotificationList.propTypes = {
// isHistory: PropTypes.boolean,
}); // onRefresh: PropTypes.func,
// isSetRead: PropTypes.boolean
// };
//
// NotificationList.defaultProps = {
// isHistory: true,
// isSetRead: false,
// };

View file

@ -1,5 +1,5 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native'; import {Platform, StyleSheet, Text, View, InteractionManager, DeviceEventEmitter, ListView, ActivityIndicator, RefreshControl} from 'react-native';
import {Button} from 'react-native-elements' import {Button} from 'react-native-elements'
import {Navigation} from 'react-native-navigation'; import {Navigation} from 'react-native-navigation';
@ -7,31 +7,47 @@ import Color from '../style/color'
import {Icon} from '../style/icon' import {Icon} from '../style/icon'
import {ListEmptyRefreshable} from '../component/listEmpty' import {ListEmptyRefreshable} from '../component/listEmpty'
import Push from "../util/push";
import Api from "../util/api";
import Event from "../util/event";
import Notification from "../component/notification/notification";
import NotificationList from "../component/notification/notificationList";
const LOOP_TIME_SHORT = 30 * 1000;
const LOOP_TIME_LONG = 60 * 1000;
export default class NotificationPage extends Component { export default class NotificationPage extends Component {
constructor(props) {
super(props);
Navigation.events().bindComponent(this);
}
static options(passProps) { static options(passProps) {
return { return {
topBar: { topBar: {
title: { title: {
text: '提醒' text: '提醒'
}, },
rightButtons: [{ rightButtons: [{
id: 'history', id: 'history',
icon: Icon.navButtonTime, icon: Icon.navButtonTime,
color: Color.primary // android color: Color.primary // android
}] }]
} }
}; };
} }
constructor(props) {
super(props);
Navigation.events().bindComponent(this);
// const ds = new ListView.DataSource({
// rowHasChanged: (r1, r2) => r1 !== r2
// });
// this.state = ({
// messages: [],
// messagesDataSource: ds,
// refreshing: true,
// });
}
navigationButtonPressed({buttonId}) { navigationButtonPressed({buttonId}) {
Navigation.push(this.props.componentId, { Navigation.push(this.props.componentId, {
component: { component: {
@ -40,21 +56,147 @@ export default class NotificationPage extends Component {
}); });
} }
loopTime = LOOP_TIME_LONG;
tipTimer = null;
componentDidMount() {
InteractionManager.runAfterInteractions(() => {
if (Platform.OS === 'android') {
this.initAndroid().done()
} else {
this.initIOS().done()
}
this.restartTipTimer().done();
});
this.loginListener = DeviceEventEmitter.addListener(Event.login, () => {
this.registerUser().done();
this.restartTipTimer().done();
});
this.updatePushInfo().done();
}
componentWillUnmount() {
this.loginListener.remove();
//todo:删除 push 事件注册,删除定时器
}
async updatePushInfo() {
let info;
try {
info = await Api.updatePushInfo()
} catch (err) {
console.error(err)
}
// console.log('updatePushInfo', info)
}
/**
* 更新刷新定时器
* @returns {Promise<void>}
*/
async restartTipTimer() {
if (this.tipTimer) {
clearTimeout(this.tipTimer);
}
this.tipTimer = setTimeout(() => {
this.refresh();
}, this.loopTime)
}
async initAndroid() {
Push.init((msg) => {
console.log("push init: " + msg);
this.registerUser();
Push.addReceiveNotificationListener((msg) => {
this.restartTipTimer().done();
});
})
}
async initIOS() {
Push.init((msg) => {
console.log("push init: " + msg);
this.registerUser();
Push.addReceiveNotificationListener((msg) => {
this.restartTipTimer().done();
});
})
}
async registerUser() {
const user = await Api.getSelfInfoByStore();
if (!user || !user.id) return;
//const settings = await Api.getSettings();
//const push = settings['pushMessage'];
const push = true;
const alias = push ? user.id.toString() : user.id.toString() + '_close';
Push.setAccount(alias, success => {
console.log('JPushModule.setAlias ' + alias + ' ' + success);
});
// Crashlytics.setUserName(user.name);
// Crashlytics.setUserEmail(user.email);
// Crashlytics.setUserIdentifier(user.id.toString());
}
_onRefresh() {
this.restartTipTimer().done();
}
refresh() {
this.list.refresh(false);
}
_onDeletePress(msg) {
this._setRead(msg).done();
}
render() { render() {
return ( return (
<ListEmptyRefreshable message={'没有提醒:)'}></ListEmptyRefreshable> <View style={{flex: 1, backgroundColor: 'white'}}>
<NotificationList ref={(r) => {this.list = r}}
isHistory={false}
onRefresh={this._onRefresh.bind(this)}
isSetRead={true}
{...this.props}/>
</View>
)
}
renderEmpty() {
if (this.state.refreshing) {
return (
<View style={{alignItems:'center', justifyContent: 'center' , height: '100%'}}>
<ActivityIndicator animating={true} color={Color.primary} size={Platform.OS === 'android' ? 'large' : 'small'}/>
</View>
)
}
let text = this.state.error ? '出错了 :(':'没有提醒 :)';
return (
<ListEmptyRefreshable message={text}/>
); );
} }
} }
const localStyle = StyleSheet.create({ const styles = StyleSheet.create({
container: { message: {
alignItems:'center', padding: 20,
justifyContent: 'center', borderColor: Color.line,
height: '100%' borderBottomWidth: StyleSheet.hairlineWidth,
flexDirection: 'row'
}, },
text: { icon: {
paddingBottom: 15, marginRight: 10,
color: Color.text marginTop: 1,
lineHeight: 20,
},
delete: {
lineHeight: 20,
paddingHorizontal: 8,
} }
}); });

View file

@ -247,11 +247,18 @@ async function addFollow(user_id) {
return call('POST', '/relation/' + user_id); return call('POST', '/relation/' + user_id);
} }
async function getMessages() {
return call('GET', '/tip');
}
async function getMessagesHistory() { async function getMessagesHistory() {
return call('GET', '/tip/history'); return call('GET', '/tip/history');
} }
async function deleteMessage(ids) {
return call('POST', '/tip/read/' + ids.join(','))
}
async function getDiary(id) { async function getDiary(id) {
return call('GET', '/diaries/' + id); return call('GET', '/diaries/' + id);
} }
@ -343,6 +350,10 @@ async function getUpdateInfo() {
return callV2('GET', '/updateInfo'); return callV2('GET', '/updateInfo');
} }
export async function updatePushInfo() {
return callV2('POST', '/push');
}
async function upload(method, api, body) { async function upload(method, api, body) {
let token = await Token.getUserToken(); let token = await Token.getUserToken();
@ -525,7 +536,9 @@ export default {
deleteFollowBy, deleteFollowBy,
addFollow, addFollow,
getMessages,
getMessagesHistory, getMessagesHistory,
deleteMessage,
updateNotebookCover, updateNotebookCover,
createNotebook, createNotebook,
@ -534,5 +547,7 @@ export default {
report, report,
feedback, feedback,
getUpdateInfo getUpdateInfo,
updatePushInfo,
} }