about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThibaut Girka <thib@sitedethib.com>2018-09-06 15:47:13 +0200
committerThibG <thib@sitedethib.com>2018-09-07 20:37:17 +0200
commitc8875b4d8aa00abd0ef432c025d479a8990202f1 (patch)
tree7a234c9035cce653d79904f0a4b89830c24fa687
parent711826cb37604df98d8e27c3415855ad298d49d9 (diff)
Keep track of unread notifications when the notification column isn't mounted
-rw-r--r--app/javascript/flavours/glitch/actions/notifications.js15
-rw-r--r--app/javascript/flavours/glitch/features/notifications/index.js24
-rw-r--r--app/javascript/flavours/glitch/reducers/notifications.js26
3 files changed, 58 insertions, 7 deletions
diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js
index e88eda78f..ee148e4ef 100644
--- a/app/javascript/flavours/glitch/actions/notifications.js
+++ b/app/javascript/flavours/glitch/actions/notifications.js
@@ -25,6 +25,9 @@ export const NOTIFICATIONS_EXPAND_FAIL    = 'NOTIFICATIONS_EXPAND_FAIL';
 export const NOTIFICATIONS_CLEAR      = 'NOTIFICATIONS_CLEAR';
 export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
 
+export const NOTIFICATIONS_MOUNT   = 'NOTIFICATIONS_MOUNT';
+export const NOTIFICATIONS_UNMOUNT = 'NOTIFICATIONS_UNMOUNT';
+
 defineMessages({
   mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
 });
@@ -216,3 +219,15 @@ export function deleteMarkedNotificationsSuccess() {
     type: NOTIFICATIONS_DELETE_MARKED_SUCCESS,
   };
 };
+
+export function mountNotifications() {
+  return {
+    type: NOTIFICATIONS_MOUNT,
+  };
+};
+
+export function unmountNotifications() {
+  return {
+    type: NOTIFICATIONS_UNMOUNT,
+  };
+};
diff --git a/app/javascript/flavours/glitch/features/notifications/index.js b/app/javascript/flavours/glitch/features/notifications/index.js
index 266d6807d..ee711bd8a 100644
--- a/app/javascript/flavours/glitch/features/notifications/index.js
+++ b/app/javascript/flavours/glitch/features/notifications/index.js
@@ -8,6 +8,8 @@ import {
   enterNotificationClearingMode,
   expandNotifications,
   scrollTopNotifications,
+  mountNotifications,
+  unmountNotifications,
 } from 'flavours/glitch/actions/notifications';
 import { addColumn, removeColumn, moveColumn } from 'flavours/glitch/actions/columns';
 import NotificationContainer from './containers/notification_container';
@@ -42,6 +44,12 @@ const mapDispatchToProps = dispatch => ({
   onEnterCleaningMode(yes) {
     dispatch(enterNotificationClearingMode(yes));
   },
+  onMount() {
+    dispatch(mountNotifications());
+  },
+  onUnmount() {
+    dispatch(unmountNotifications());
+  },
   dispatch,
 });
 
@@ -62,6 +70,8 @@ export default class Notifications extends React.PureComponent {
     localSettings: ImmutablePropTypes.map,
     notifCleaningActive: PropTypes.bool,
     onEnterCleaningMode: PropTypes.func,
+    onMount: PropTypes.func,
+    onUnmount: PropTypes.func,
   };
 
   static defaultProps = {
@@ -126,6 +136,20 @@ export default class Notifications extends React.PureComponent {
     }
   }
 
+  componentDidMount () {
+    const { onMount } = this.props;
+    if (onMount) {
+      onMount();
+    }
+  }
+
+  componentWillUnmount () {
+    const { onUnmount } = this.props;
+    if (onUnmount) {
+      onUnmount();
+    }
+  }
+
   render () {
     const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore } = this.props;
     const pinned = !!columnId;
diff --git a/app/javascript/flavours/glitch/reducers/notifications.js b/app/javascript/flavours/glitch/reducers/notifications.js
index b712aaa67..9087e226c 100644
--- a/app/javascript/flavours/glitch/reducers/notifications.js
+++ b/app/javascript/flavours/glitch/reducers/notifications.js
@@ -1,4 +1,6 @@
 import {
+  NOTIFICATIONS_MOUNT,
+  NOTIFICATIONS_UNMOUNT,
   NOTIFICATIONS_UPDATE,
   NOTIFICATIONS_EXPAND_SUCCESS,
   NOTIFICATIONS_EXPAND_REQUEST,
@@ -24,6 +26,7 @@ const initialState = ImmutableMap({
   items: ImmutableList(),
   hasMore: true,
   top: true,
+  mounted: 0,
   unread: 0,
   lastReadId: '0',
   isLoading: false,
@@ -41,7 +44,7 @@ const notificationToMap = (state, notification) => ImmutableMap({
 });
 
 const normalizeNotification = (state, notification) => {
-  const top = state.get('top');
+  const top = state.get('top') && state.get('mounted') > 0;
 
   if (top) {
     state = state.set('lastReadId', notification.id);
@@ -59,7 +62,7 @@ const normalizeNotification = (state, notification) => {
 };
 
 const expandNormalizedNotifications = (state, notifications, next) => {
-  const top = state.get('top');
+  const top = state.get('top') && state.get('mounted') > 0;
   const lastReadId = state.get('lastReadId');
   let items = ImmutableList();
 
@@ -102,18 +105,23 @@ const filterNotifications = (state, relationship) => {
   return state.update('items', list => list.filterNot(item => item !== null && item.get('account') === relationship.id));
 };
 
+const clearUnread = (state) => {
+  state = state.set('unread', 0);
+  const lastNotification = state.get('items').find(item => item !== null);
+  return state.set('lastReadId', lastNotification ? lastNotification.get('id') : '0');
+}
+
 const updateTop = (state, top) => {
-  if (top) {
-    state = state.set('unread', 0);
-    const lastNotification = state.get('items').find(item => item !== null);
-    state = state.set('lastReadId', lastNotification ? lastNotification.get('id') : '0');
+  if (top && state.get('mounted') > 0) {
+    state = clearUnread(state);
   }
 
   return state.set('top', top);
 };
 
 const deleteByStatus = (state, statusId) => {
-  if (!state.get('top')) {
+  const top = state.get('top') && state.get('mounted') > 0;
+  if (!top) {
     const lastReadId = state.get('lastReadId');
     const deletedUnread = state.get('items').filter(item => item !== null && item.get('status') === statusId && compareId(item.get('id'), lastReadId) > 0);
     state = state.update('unread', unread => unread - deletedUnread.size);
@@ -153,6 +161,10 @@ export default function notifications(state = initialState, action) {
   let st;
 
   switch(action.type) {
+  case NOTIFICATIONS_MOUNT:
+    return (state.get('top') ? clearUnread(state) : state).update('mounted', count => count + 1);
+  case NOTIFICATIONS_UNMOUNT:
+    return state.update('mounted', count => count - 1);
   case NOTIFICATIONS_EXPAND_REQUEST:
   case NOTIFICATIONS_DELETE_MARKED_REQUEST:
     return state.set('isLoading', true);