Count unread notifications when window loses focus
This commit is contained in:
		@@ -28,6 +28,8 @@ export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
 | 
			
		||||
export const NOTIFICATIONS_MOUNT   = 'NOTIFICATIONS_MOUNT';
 | 
			
		||||
export const NOTIFICATIONS_UNMOUNT = 'NOTIFICATIONS_UNMOUNT';
 | 
			
		||||
 | 
			
		||||
export const NOTIFICATIONS_SET_VISIBILITY = 'NOTIFICATIONS_SET_VISIBILITY';
 | 
			
		||||
 | 
			
		||||
defineMessages({
 | 
			
		||||
  mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
 | 
			
		||||
});
 | 
			
		||||
@@ -231,3 +233,10 @@ export function unmountNotifications() {
 | 
			
		||||
    type: NOTIFICATIONS_UNMOUNT,
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function notificationsSetVisibility(visibility) {
 | 
			
		||||
  return {
 | 
			
		||||
    type: NOTIFICATIONS_SET_VISIBILITY,
 | 
			
		||||
    visibility: visibility,
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ import { isMobile } from 'flavours/glitch/util/is_mobile';
 | 
			
		||||
import { debounce } from 'lodash';
 | 
			
		||||
import { uploadCompose, resetCompose } from 'flavours/glitch/actions/compose';
 | 
			
		||||
import { expandHomeTimeline } from 'flavours/glitch/actions/timelines';
 | 
			
		||||
import { expandNotifications } from 'flavours/glitch/actions/notifications';
 | 
			
		||||
import { expandNotifications, notificationsSetVisibility } from 'flavours/glitch/actions/notifications';
 | 
			
		||||
import { fetchFilters } from 'flavours/glitch/actions/filters';
 | 
			
		||||
import { clearHeight } from 'flavours/glitch/actions/height_cache';
 | 
			
		||||
import { WrappedSwitch, WrappedRoute } from 'flavours/glitch/util/react_router_helpers';
 | 
			
		||||
@@ -206,7 +206,27 @@ export default class UI extends React.Component {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleVisibilityChange = () => {
 | 
			
		||||
    const visibility = !document[this.visibilityHiddenProp];
 | 
			
		||||
    this.props.dispatch(notificationsSetVisibility(visibility));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  componentWillMount () {
 | 
			
		||||
    if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support
 | 
			
		||||
      this.visibilityHiddenProp = 'hidden';
 | 
			
		||||
      this.visibilityChange = 'visibilitychange';
 | 
			
		||||
    } else if (typeof document.msHidden !== 'undefined') {
 | 
			
		||||
      this.visibilityHiddenProp = 'msHidden';
 | 
			
		||||
      this.visibilityChange = 'msvisibilitychange';
 | 
			
		||||
    } else if (typeof document.webkitHidden !== 'undefined') {
 | 
			
		||||
      this.visibilityHiddenProp = 'webkitHidden';
 | 
			
		||||
      this.visibilityChange = 'webkitvisibilitychange';
 | 
			
		||||
    }
 | 
			
		||||
    if (this.visibilityChange !== undefined) {
 | 
			
		||||
      document.addEventListener(this.visibilityChange, this.handleVisibilityChange, false);
 | 
			
		||||
      this.handleVisibilityChange();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    window.addEventListener('beforeunload', this.handleBeforeUnload, false);
 | 
			
		||||
    window.addEventListener('resize', this.handleResize, { passive: true });
 | 
			
		||||
    document.addEventListener('dragenter', this.handleDragEnter, false);
 | 
			
		||||
@@ -250,6 +270,10 @@ export default class UI extends React.Component {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  componentWillUnmount () {
 | 
			
		||||
    if (this.visibilityChange !== undefined) {
 | 
			
		||||
      document.removeEventListener(this.visibilityChange, this.handleVisibilityChange);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    window.removeEventListener('beforeunload', this.handleBeforeUnload);
 | 
			
		||||
    window.removeEventListener('resize', this.handleResize);
 | 
			
		||||
    document.removeEventListener('dragenter', this.handleDragEnter);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
import {
 | 
			
		||||
  NOTIFICATIONS_MOUNT,
 | 
			
		||||
  NOTIFICATIONS_UNMOUNT,
 | 
			
		||||
  NOTIFICATIONS_SET_VISIBILITY,
 | 
			
		||||
  NOTIFICATIONS_UPDATE,
 | 
			
		||||
  NOTIFICATIONS_EXPAND_SUCCESS,
 | 
			
		||||
  NOTIFICATIONS_EXPAND_REQUEST,
 | 
			
		||||
@@ -31,6 +32,7 @@ const initialState = ImmutableMap({
 | 
			
		||||
  lastReadId: '0',
 | 
			
		||||
  isLoading: false,
 | 
			
		||||
  cleaningMode: false,
 | 
			
		||||
  isTabVisible: true,
 | 
			
		||||
  // notification removal mark of new notifs loaded whilst cleaningMode is true.
 | 
			
		||||
  markNewForDelete: false,
 | 
			
		||||
});
 | 
			
		||||
@@ -44,7 +46,7 @@ const notificationToMap = (state, notification) => ImmutableMap({
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const normalizeNotification = (state, notification) => {
 | 
			
		||||
  const top = state.get('top') && state.get('mounted') > 0;
 | 
			
		||||
  const top = !shouldCountUnreadNotifications(state);
 | 
			
		||||
 | 
			
		||||
  if (top) {
 | 
			
		||||
    state = state.set('lastReadId', notification.id);
 | 
			
		||||
@@ -62,7 +64,7 @@ const normalizeNotification = (state, notification) => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const expandNormalizedNotifications = (state, notifications, next) => {
 | 
			
		||||
  const top = state.get('top') && state.get('mounted') > 0;
 | 
			
		||||
  const top = !(shouldCountUnreadNotifications(state));
 | 
			
		||||
  const lastReadId = state.get('lastReadId');
 | 
			
		||||
  let items = ImmutableList();
 | 
			
		||||
 | 
			
		||||
@@ -112,7 +114,9 @@ const clearUnread = (state) => {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const updateTop = (state, top) => {
 | 
			
		||||
  if (top && state.get('mounted') > 0) {
 | 
			
		||||
  state = state.set('top', top);
 | 
			
		||||
 | 
			
		||||
  if (!shouldCountUnreadNotifications(state)) {
 | 
			
		||||
    state = clearUnread(state);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -120,7 +124,7 @@ const updateTop = (state, top) => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const deleteByStatus = (state, statusId) => {
 | 
			
		||||
  const top = state.get('top') && state.get('mounted') > 0;
 | 
			
		||||
  const top = !(shouldCountUnreadNotifications(state));
 | 
			
		||||
  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);
 | 
			
		||||
@@ -157,14 +161,36 @@ const deleteMarkedNotifs = (state) => {
 | 
			
		||||
  return state.update('items', list => list.filterNot(item => item.get('markedForDelete')));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const updateMounted = (state) => {
 | 
			
		||||
  state = state.update('mounted', count => count + 1);
 | 
			
		||||
  if (!shouldCountUnreadNotifications(state)) {
 | 
			
		||||
    state = clearUnread(state);
 | 
			
		||||
  }
 | 
			
		||||
  return state;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const updateVisibility = (state, visibility) => {
 | 
			
		||||
  state = state.set('isTabVisible', visibility);
 | 
			
		||||
  if (!shouldCountUnreadNotifications(state)) {
 | 
			
		||||
    state = clearUnread(state);
 | 
			
		||||
  }
 | 
			
		||||
  return state;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const shouldCountUnreadNotifications = (state) => {
 | 
			
		||||
  return !(state.get('isTabVisible') && state.get('top') && state.get('mounted') > 0);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
    return updateMounted(state);
 | 
			
		||||
  case NOTIFICATIONS_UNMOUNT:
 | 
			
		||||
    return state.update('mounted', count => count - 1);
 | 
			
		||||
  case NOTIFICATIONS_SET_VISIBILITY:
 | 
			
		||||
    return updateVisibility(state, action.visibility);
 | 
			
		||||
  case NOTIFICATIONS_EXPAND_REQUEST:
 | 
			
		||||
  case NOTIFICATIONS_DELETE_MARKED_REQUEST:
 | 
			
		||||
    return state.set('isLoading', true);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user