Skip to content

Instantly share code, notes, and snippets.

@liezl200
Created April 5, 2017 10:24
Show Gist options
  • Save liezl200/4fe136d010edbad993d11eedf0a28453 to your computer and use it in GitHub Desktop.
Save liezl200/4fe136d010edbad993d11eedf0a28453 to your computer and use it in GitHub Desktop.
notification list with separate child_added and child_removed (rendering hangs though..)
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