about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/reducers
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/flavours/glitch/reducers')
-rw-r--r--app/javascript/flavours/glitch/reducers/conversations.js102
-rw-r--r--app/javascript/flavours/glitch/reducers/index.js2
-rw-r--r--app/javascript/flavours/glitch/reducers/settings.js1
3 files changed, 105 insertions, 0 deletions
diff --git a/app/javascript/flavours/glitch/reducers/conversations.js b/app/javascript/flavours/glitch/reducers/conversations.js
new file mode 100644
index 000000000..c01659da5
--- /dev/null
+++ b/app/javascript/flavours/glitch/reducers/conversations.js
@@ -0,0 +1,102 @@
+import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
+import {
+  CONVERSATIONS_MOUNT,
+  CONVERSATIONS_UNMOUNT,
+  CONVERSATIONS_FETCH_REQUEST,
+  CONVERSATIONS_FETCH_SUCCESS,
+  CONVERSATIONS_FETCH_FAIL,
+  CONVERSATIONS_UPDATE,
+  CONVERSATIONS_READ,
+} from '../actions/conversations';
+import compareId from 'flavours/glitch/util/compare_id';
+
+const initialState = ImmutableMap({
+  items: ImmutableList(),
+  isLoading: false,
+  hasMore: true,
+  mounted: 0,
+});
+
+const conversationToMap = item => ImmutableMap({
+  id: item.id,
+  unread: item.unread,
+  accounts: ImmutableList(item.accounts.map(a => a.id)),
+  last_status: item.last_status ? item.last_status.id : null,
+});
+
+const updateConversation = (state, item) => state.update('items', list => {
+  const index   = list.findIndex(x => x.get('id') === item.id);
+  const newItem = conversationToMap(item);
+
+  if (index === -1) {
+    return list.unshift(newItem);
+  } else {
+    return list.set(index, newItem);
+  }
+});
+
+const expandNormalizedConversations = (state, conversations, next, isLoadingRecent) => {
+  let items = ImmutableList(conversations.map(conversationToMap));
+
+  return state.withMutations(mutable => {
+    if (!items.isEmpty()) {
+      mutable.update('items', list => {
+        list = list.map(oldItem => {
+          const newItemIndex = items.findIndex(x => x.get('id') === oldItem.get('id'));
+
+          if (newItemIndex === -1) {
+            return oldItem;
+          }
+
+          const newItem = items.get(newItemIndex);
+          items = items.delete(newItemIndex);
+
+          return newItem;
+        });
+
+        list = list.concat(items);
+
+        return list.sortBy(x => x.get('last_status'), (a, b) => {
+          if(a === null || b === null) {
+            return -1;
+          }
+
+          return compareId(a, b) * -1;
+        });
+      });
+    }
+
+    if (!next && !isLoadingRecent) {
+      mutable.set('hasMore', false);
+    }
+
+    mutable.set('isLoading', false);
+  });
+};
+
+export default function conversations(state = initialState, action) {
+  switch (action.type) {
+  case CONVERSATIONS_FETCH_REQUEST:
+    return state.set('isLoading', true);
+  case CONVERSATIONS_FETCH_FAIL:
+    return state.set('isLoading', false);
+  case CONVERSATIONS_FETCH_SUCCESS:
+    return expandNormalizedConversations(state, action.conversations, action.next, action.isLoadingRecent);
+  case CONVERSATIONS_UPDATE:
+    return updateConversation(state, action.conversation);
+  case CONVERSATIONS_MOUNT:
+    return state.update('mounted', count => count + 1);
+  case CONVERSATIONS_UNMOUNT:
+    return state.update('mounted', count => count - 1);
+  case CONVERSATIONS_READ:
+    return state.update('items', list => list.map(item => {
+      if (item.get('id') === action.id) {
+        return item.set('unread', false);
+      }
+
+      return item;
+    }));
+  default:
+    return state;
+  }
+};
diff --git a/app/javascript/flavours/glitch/reducers/index.js b/app/javascript/flavours/glitch/reducers/index.js
index 45b93b92c..266d87dc1 100644
--- a/app/javascript/flavours/glitch/reducers/index.js
+++ b/app/javascript/flavours/glitch/reducers/index.js
@@ -28,6 +28,7 @@ import lists from './lists';
 import listEditor from './list_editor';
 import listAdder from './list_adder';
 import filters from './filters';
+import conversations from './conversations';
 import suggestions from './suggestions';
 import pinnedAccountsEditor from './pinned_accounts_editor';
 import polls from './polls';
@@ -64,6 +65,7 @@ const reducers = {
   listEditor,
   listAdder,
   filters,
+  conversations,
   suggestions,
   pinnedAccountsEditor,
   polls,
diff --git a/app/javascript/flavours/glitch/reducers/settings.js b/app/javascript/flavours/glitch/reducers/settings.js
index dfb1d6bd7..0ce51ef97 100644
--- a/app/javascript/flavours/glitch/reducers/settings.js
+++ b/app/javascript/flavours/glitch/reducers/settings.js
@@ -72,6 +72,7 @@ const initialState = ImmutableMap({
   }),
 
   direct: ImmutableMap({
+    conversations: true,
     regex: ImmutableMap({
       body: '',
     }),