about summary refs log tree commit diff
path: root/app/assets/javascripts/components/reducers
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/components/reducers')
-rw-r--r--app/assets/javascripts/components/reducers/accounts.jsx8
-rw-r--r--app/assets/javascripts/components/reducers/alerts.jsx25
-rw-r--r--app/assets/javascripts/components/reducers/index.jsx28
-rw-r--r--app/assets/javascripts/components/reducers/notifications.jsx60
-rw-r--r--app/assets/javascripts/components/reducers/statuses.jsx12
5 files changed, 106 insertions, 27 deletions
diff --git a/app/assets/javascripts/components/reducers/accounts.jsx b/app/assets/javascripts/components/reducers/accounts.jsx
index c0ea961b7..68247a98c 100644
--- a/app/assets/javascripts/components/reducers/accounts.jsx
+++ b/app/assets/javascripts/components/reducers/accounts.jsx
@@ -28,6 +28,11 @@ import {
   CONTEXT_FETCH_SUCCESS
 } from '../actions/statuses';
 import { SEARCH_SUGGESTIONS_READY } from '../actions/search';
+import {
+  NOTIFICATIONS_UPDATE,
+  NOTIFICATIONS_REFRESH_SUCCESS,
+  NOTIFICATIONS_EXPAND_SUCCESS
+} from '../actions/notifications';
 import Immutable from 'immutable';
 
 const normalizeAccount = (state, account) => state.set(account.id, Immutable.fromJS(account));
@@ -64,6 +69,7 @@ export default function accounts(state = initialState, action) {
   switch(action.type) {
     case ACCOUNT_SET_SELF:
     case ACCOUNT_FETCH_SUCCESS:
+    case NOTIFICATIONS_UPDATE:
       return normalizeAccount(state, action.account);
     case SUGGESTIONS_FETCH_SUCCESS:
     case FOLLOWERS_FETCH_SUCCESS:
@@ -74,6 +80,8 @@ export default function accounts(state = initialState, action) {
     case FAVOURITES_FETCH_SUCCESS:
     case COMPOSE_SUGGESTIONS_READY:
     case SEARCH_SUGGESTIONS_READY:
+    case NOTIFICATIONS_REFRESH_SUCCESS:
+    case NOTIFICATIONS_EXPAND_SUCCESS:
       return normalizeAccounts(state, action.accounts);
     case TIMELINE_REFRESH_SUCCESS:
     case TIMELINE_EXPAND_SUCCESS:
diff --git a/app/assets/javascripts/components/reducers/alerts.jsx b/app/assets/javascripts/components/reducers/alerts.jsx
new file mode 100644
index 000000000..42987f649
--- /dev/null
+++ b/app/assets/javascripts/components/reducers/alerts.jsx
@@ -0,0 +1,25 @@
+import {
+  ALERT_SHOW,
+  ALERT_DISMISS,
+  ALERT_CLEAR
+} from '../actions/alerts';
+import Immutable from 'immutable';
+
+const initialState = Immutable.List([]);
+
+export default function alerts(state = initialState, action) {
+  switch(action.type) {
+    case ALERT_SHOW:
+      return state.push(Immutable.Map({
+        key: state.size > 0 ? state.last().get('key') + 1 : 0,
+        title: action.title,
+        message: action.message
+      }));
+    case ALERT_DISMISS:
+      return state.filterNot(item => item.get('key') === action.alert.key);
+    case ALERT_CLEAR:
+      return state.clear();
+    default:
+      return state;
+  }
+};
diff --git a/app/assets/javascripts/components/reducers/index.jsx b/app/assets/javascripts/components/reducers/index.jsx
index 1e015cf74..aea9239f8 100644
--- a/app/assets/javascripts/components/reducers/index.jsx
+++ b/app/assets/javascripts/components/reducers/index.jsx
@@ -1,26 +1,28 @@
-import { combineReducers }   from 'redux-immutable';
-import timelines             from './timelines';
-import meta                  from './meta';
-import compose               from './compose';
-import notifications         from './notifications';
+import { combineReducers } from 'redux-immutable';
+import timelines from './timelines';
+import meta from './meta';
+import compose from './compose';
+import alerts from './alerts';
 import { loadingBarReducer } from 'react-redux-loading-bar';
-import modal                 from './modal';
-import user_lists            from './user_lists';
-import accounts              from './accounts';
-import statuses              from './statuses';
-import relationships         from './relationships';
-import search                from './search';
+import modal from './modal';
+import user_lists from './user_lists';
+import accounts from './accounts';
+import statuses from './statuses';
+import relationships from './relationships';
+import search from './search';
+import notifications from './notifications';
 
 export default combineReducers({
   timelines,
   meta,
   compose,
-  notifications,
+  alerts,
   loadingBar: loadingBarReducer,
   modal,
   user_lists,
   accounts,
   statuses,
   relationships,
-  search
+  search,
+  notifications
 });
diff --git a/app/assets/javascripts/components/reducers/notifications.jsx b/app/assets/javascripts/components/reducers/notifications.jsx
index efe8d9739..0e67e732a 100644
--- a/app/assets/javascripts/components/reducers/notifications.jsx
+++ b/app/assets/javascripts/components/reducers/notifications.jsx
@@ -1,24 +1,56 @@
 import {
-  NOTIFICATION_SHOW,
-  NOTIFICATION_DISMISS,
-  NOTIFICATION_CLEAR
+  NOTIFICATIONS_UPDATE,
+  NOTIFICATIONS_REFRESH_SUCCESS,
+  NOTIFICATIONS_EXPAND_SUCCESS
 } from '../actions/notifications';
 import Immutable from 'immutable';
 
-const initialState = Immutable.List([]);
+const initialState = Immutable.Map({
+  items: Immutable.List(),
+  next: null,
+  loaded: false
+});
+
+const notificationToMap = notification => Immutable.Map({
+  id: notification.id,
+  type: notification.type,
+  account: notification.account.id,
+  status: notification.status ? notification.status.id : null
+});
+
+const normalizeNotification = (state, notification) => {
+  return state.update('items', list => list.unshift(notificationToMap(notification)));
+};
+
+const normalizeNotifications = (state, notifications, next) => {
+  let items    = Immutable.List();
+  const loaded = state.get('loaded');
+
+  notifications.forEach((n, i) => {
+    items = items.set(i, notificationToMap(n));
+  });
+
+  return state.update('items', list => loaded ? list.unshift(...items) : list.push(...items)).set('next', next).set('loaded', true);
+};
+
+const appendNormalizedNotifications = (state, notifications, next) => {
+  let items = Immutable.List();
+
+  notifications.forEach((n, i) => {
+    items = items.set(i, notificationToMap(n));
+  });
+
+  return state.update('items', list => list.push(...items)).set('next', next);
+};
 
 export default function notifications(state = initialState, action) {
   switch(action.type) {
-    case NOTIFICATION_SHOW:
-      return state.push(Immutable.Map({
-        key: state.size > 0 ? state.last().get('key') + 1 : 0,
-        title: action.title,
-        message: action.message
-      }));
-    case NOTIFICATION_DISMISS:
-      return state.filterNot(item => item.get('key') === action.notification.key);
-    case NOTIFICATION_CLEAR:
-      return state.clear();
+    case NOTIFICATIONS_UPDATE:
+      return normalizeNotification(state, action.notification);
+    case NOTIFICATIONS_REFRESH_SUCCESS:
+      return normalizeNotifications(state, action.notifications, action.next);
+    case NOTIFICATIONS_EXPAND_SUCCESS:
+      return appendNormalizedNotifications(state, action.notifications, action.next);
     default:
       return state;
   }
diff --git a/app/assets/javascripts/components/reducers/statuses.jsx b/app/assets/javascripts/components/reducers/statuses.jsx
index 69c0e6193..2a24a75e4 100644
--- a/app/assets/javascripts/components/reducers/statuses.jsx
+++ b/app/assets/javascripts/components/reducers/statuses.jsx
@@ -18,9 +18,18 @@ import {
   ACCOUNT_TIMELINE_FETCH_SUCCESS,
   ACCOUNT_TIMELINE_EXPAND_SUCCESS
 } from '../actions/accounts';
+import {
+  NOTIFICATIONS_UPDATE,
+  NOTIFICATIONS_REFRESH_SUCCESS,
+  NOTIFICATIONS_EXPAND_SUCCESS
+} from '../actions/notifications';
 import Immutable from 'immutable';
 
 const normalizeStatus = (state, status) => {
+  if (!status) {
+    return state;
+  }
+
   status.account = status.account.id;
 
   if (status.reblog && status.reblog.id) {
@@ -53,6 +62,7 @@ export default function statuses(state = initialState, action) {
   switch(action.type) {
     case TIMELINE_UPDATE:
     case STATUS_FETCH_SUCCESS:
+    case NOTIFICATIONS_UPDATE:
       return normalizeStatus(state, action.status);
     case REBLOG_SUCCESS:
     case UNREBLOG_SUCCESS:
@@ -64,6 +74,8 @@ export default function statuses(state = initialState, action) {
     case ACCOUNT_TIMELINE_FETCH_SUCCESS:
     case ACCOUNT_TIMELINE_EXPAND_SUCCESS:
     case CONTEXT_FETCH_SUCCESS:
+    case NOTIFICATIONS_REFRESH_SUCCESS:
+    case NOTIFICATIONS_EXPAND_SUCCESS:
       return normalizeStatuses(state, action.statuses);
     case TIMELINE_DELETE:
       return deleteStatus(state, action.id, action.references);