about summary refs log tree commit diff
path: root/app/assets/javascripts
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-01-26 04:30:40 +0100
committerEugen Rochko <eugen@zeonfederated.com>2017-01-26 04:30:40 +0100
commit905c82917959a5afe24cb85c62c0b0ba13f0da8b (patch)
treea22df9a8737250f97a6024943af3445a163917b3 /app/assets/javascripts
parent57f7cf834921d49f28f346571e0e6fb596ccd6f8 (diff)
Improve infinite scroll on notifications
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/components/actions/notifications.jsx8
-rw-r--r--app/assets/javascripts/components/features/notifications/index.jsx9
-rw-r--r--app/assets/javascripts/components/reducers/notifications.jsx23
3 files changed, 32 insertions, 8 deletions
diff --git a/app/assets/javascripts/components/actions/notifications.jsx b/app/assets/javascripts/components/actions/notifications.jsx
index 23bdcb5c7..1731c1857 100644
--- a/app/assets/javascripts/components/actions/notifications.jsx
+++ b/app/assets/javascripts/components/actions/notifications.jsx
@@ -96,13 +96,17 @@ export function expandNotifications() {
   return (dispatch, getState) => {
     const url = getState().getIn(['notifications', 'next'], null);
 
-    if (url === null) {
+    if (url === null || getState().getIn(['notifications', 'isLoading'])) {
       return;
     }
 
     dispatch(expandNotificationsRequest());
 
-    api(getState).get(url).then(response => {
+    api(getState).get(url, {
+      params: {
+        limit: 5
+      }
+    }).then(response => {
       const next = getLinks(response).refs.find(link => link.rel === 'next');
 
       dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null));
diff --git a/app/assets/javascripts/components/features/notifications/index.jsx b/app/assets/javascripts/components/features/notifications/index.jsx
index 366d8f5e9..b4593aaff 100644
--- a/app/assets/javascripts/components/features/notifications/index.jsx
+++ b/app/assets/javascripts/components/features/notifications/index.jsx
@@ -20,7 +20,8 @@ const getNotifications = createSelector([
 ], (excludedTypes, notifications) => notifications.filterNot(item => excludedTypes.includes(item.get('type'))));
 
 const mapStateToProps = state => ({
-  notifications: getNotifications(state)
+  notifications: getNotifications(state),
+  isLoading: state.getIn(['notifications', 'isLoading'], true)
 });
 
 const Notifications = React.createClass({
@@ -29,7 +30,8 @@ const Notifications = React.createClass({
     notifications: ImmutablePropTypes.list.isRequired,
     dispatch: React.PropTypes.func.isRequired,
     trackScroll: React.PropTypes.bool,
-    intl: React.PropTypes.object.isRequired
+    intl: React.PropTypes.object.isRequired,
+    isLoading: React.PropTypes.bool
   },
 
   getDefaultProps () {
@@ -42,8 +44,9 @@ const Notifications = React.createClass({
 
   handleScroll (e) {
     const { scrollTop, scrollHeight, clientHeight } = e.target;
+    const offset = scrollHeight - scrollTop - clientHeight;
 
-    if (scrollTop === scrollHeight - clientHeight) {
+    if (250 > offset && !this.props.isLoading) {
       this.props.dispatch(expandNotifications());
     }
   },
diff --git a/app/assets/javascripts/components/reducers/notifications.jsx b/app/assets/javascripts/components/reducers/notifications.jsx
index c85e7b460..482093c33 100644
--- a/app/assets/javascripts/components/reducers/notifications.jsx
+++ b/app/assets/javascripts/components/reducers/notifications.jsx
@@ -2,6 +2,10 @@ import {
   NOTIFICATIONS_UPDATE,
   NOTIFICATIONS_REFRESH_SUCCESS,
   NOTIFICATIONS_EXPAND_SUCCESS,
+  NOTIFICATIONS_REFRESH_REQUEST,
+  NOTIFICATIONS_EXPAND_REQUEST,
+  NOTIFICATIONS_REFRESH_FAIL,
+  NOTIFICATIONS_EXPAND_FAIL
 } from '../actions/notifications';
 import { ACCOUNT_BLOCK_SUCCESS } from '../actions/accounts';
 import Immutable from 'immutable';
@@ -9,7 +13,8 @@ import Immutable from 'immutable';
 const initialState = Immutable.Map({
   items: Immutable.List(),
   next: null,
-  loaded: false
+  loaded: false,
+  isLoading: true
 });
 
 const notificationToMap = notification => Immutable.Map({
@@ -31,7 +36,11 @@ const normalizeNotifications = (state, notifications, next) => {
     items = items.set(i, notificationToMap(n));
   });
 
-  return state.update('items', list => loaded ? list.unshift(...items) : list.push(...items)).set('next', next).set('loaded', true);
+  return state
+    .update('items', list => loaded ? list.unshift(...items) : list.push(...items))
+    .set('next', next)
+    .set('loaded', true)
+    .set('isLoading', false);
 };
 
 const appendNormalizedNotifications = (state, notifications, next) => {
@@ -41,7 +50,10 @@ const appendNormalizedNotifications = (state, notifications, next) => {
     items = items.set(i, notificationToMap(n));
   });
 
-  return state.update('items', list => list.push(...items)).set('next', next);
+  return state
+    .update('items', list => list.push(...items))
+    .set('next', next)
+    .set('isLoading', false);
 };
 
 const filterNotifications = (state, relationship) => {
@@ -50,6 +62,11 @@ const filterNotifications = (state, relationship) => {
 
 export default function notifications(state = initialState, action) {
   switch(action.type) {
+  case NOTIFICATIONS_REFRESH_REQUEST:
+  case NOTIFICATIONS_EXPAND_REQUEST:
+  case NOTIFICATIONS_REFRESH_FAIL:
+  case NOTIFICATIONS_EXPAND_FAIL:
+    return state.set('isLoading', true);
   case NOTIFICATIONS_UPDATE:
     return normalizeNotification(state, action.notification);
   case NOTIFICATIONS_REFRESH_SUCCESS: