Created
April 5, 2017 10:24
-
-
Save liezl200/4fe136d010edbad993d11eedf0a28453 to your computer and use it in GitHub Desktop.
notification list with separate child_added and child_removed (rendering hangs though..)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component, PropTypes } from 'react'; | |
import { | |
ListView, | |
View, | |
} from 'react-native'; | |
// Import custom components | |
const NotificationItem = require('./NotificationItem'); | |
const NotificationModal = require('./NotificationModal'); | |
const styles = require('../styles.js'); | |
const firebaseApp = require('../modules/Firebase').firebaseApp; | |
const propTypes = { | |
firebaseUserKey: PropTypes.string.isRequired, | |
}; | |
class NotificationList extends Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
selectedNotif: {}, | |
dataSource: new ListView.DataSource({ | |
rowHasChanged: () => true, | |
}), | |
}; | |
this.notifsRef = firebaseApp.database().ref().child('notifs'); | |
this.allNotifsRef = firebaseApp.database().ref().child('allNotifs'); | |
this.userNotifsRef = firebaseApp.database().ref() | |
.child('users') | |
.child(this.props.firebaseUserKey) | |
.child('notifsInfo'); | |
// this.notifsRef.keepSynced(true); // TODO(liezl): actually enable persistence natively | |
// TODO(liezl): might have to find out how to explicitly force a sync when user requests reload | |
this.renderNotif = this.renderNotif.bind(this); | |
this.notifications = []; | |
} | |
componentDidMount() { | |
this.getUserNotifs(); | |
} | |
getUserNotifs() { | |
this.userNotifsRef.once('value', (snap) => { | |
snap.forEach((notifInfo) => { | |
// notifInfo.val().key is each key of the notification in the user's notifInfo list | |
this.getNotificationFromFB(notifInfo); | |
}); | |
this.listenForNotificationUpdates(); | |
}); | |
} | |
getNotificationFromFB(notifInfo) { | |
const notifKey = notifInfo.val().notifKey; | |
this.notifsRef.child(notifKey) | |
.once('value', (ungroupedNotifsSnap) => { | |
this.notifications.push({ | |
title: ungroupedNotifsSnap.val().title, | |
text: ungroupedNotifsSnap.val().text, | |
groups: ungroupedNotifsSnap.val().groups, | |
timeSent: ungroupedNotifsSnap.val().timeSent, | |
read: notifInfo.val().read, | |
archived: notifInfo.val().archived, | |
starred: notifInfo.val().starred, | |
key: notifInfo.key, | |
}); | |
this.notifications = this.notifications | |
.filter(notification => !notification.archived) | |
.sort((a, b) => (b.timeSent - a.timeSent)); | |
this.updateNotificationsDataSource(); | |
}); | |
} | |
listenForNotificationUpdates() { | |
// Case 1: Notification added | |
this.userNotifsRef.on('child_added', (snap) => { | |
console.log(snap); | |
this.getNotificationFromFB(snap); | |
this.updateNotificationsDataSource(); | |
}); | |
// Case 2: Notification modified | |
this.userNotifsRef.on('child_changed', (snap) => { | |
const notification = this.notifications.find(notif => (notif.key === snap.key)); | |
Object.assign(notification, snap.val()); | |
this.updateNotificationsDataSource(); | |
}); | |
} | |
updateNotificationsDataSource() { | |
this.setState({ | |
dataSource: this.state.dataSource.cloneWithRows(this.notifications), | |
}); | |
} | |
renderNotif(notif) { | |
const onPress = () => { | |
// Pop open notification modal. | |
this.userNotifsRef.child(notif.key).child('read').set(true); | |
this.modal.setModalVisible(true, notif); | |
this.setState({ | |
selectedNotif: notif, | |
}); | |
}; | |
const onArchivePress = () => { | |
// Archives this notification. | |
this.userNotifsRef.child(notif.key).child('archived').set(true); | |
}; | |
return ( | |
<NotificationItem notif={notif} onPress={onPress} onArchivePress={onArchivePress} /> | |
); | |
} | |
render() { | |
return ( | |
<View style={styles.container}> | |
<NotificationModal | |
ref={(c) => { this.modal = c; }} // store reference to child modal | |
firebaseUserKey={this.props.firebaseUserKey} | |
/> | |
<ListView | |
dataSource={this.state.dataSource} | |
renderRow={this.renderNotif} | |
enableEmptySections | |
/> | |
</View> | |
); | |
} | |
} | |
NotificationList.propTypes = propTypes; | |
module.exports = NotificationList; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment