about summary refs log tree commit diff
path: root/app/javascript/themes/glitch/reducers
diff options
context:
space:
mode:
authorkibigo! <marrus-sh@users.noreply.github.com>2017-12-03 23:26:40 -0800
committerkibigo! <marrus-sh@users.noreply.github.com>2017-12-03 23:26:40 -0800
commitbc4fa6b198557a7f3989eb0865e2c77ac7451d29 (patch)
treea18543e1e0555e88b97cad60adc6d2abe0bffb00 /app/javascript/themes/glitch/reducers
parentd216547382cf1f3419de31e1ee06272e816ea339 (diff)
Rename themes -> flavours ? ?
Diffstat (limited to 'app/javascript/themes/glitch/reducers')
-rw-r--r--app/javascript/themes/glitch/reducers/accounts.js135
-rw-r--r--app/javascript/themes/glitch/reducers/accounts_counters.js138
-rw-r--r--app/javascript/themes/glitch/reducers/alerts.js25
-rw-r--r--app/javascript/themes/glitch/reducers/cards.js14
-rw-r--r--app/javascript/themes/glitch/reducers/compose.js307
-rw-r--r--app/javascript/themes/glitch/reducers/contexts.js61
-rw-r--r--app/javascript/themes/glitch/reducers/custom_emojis.js16
-rw-r--r--app/javascript/themes/glitch/reducers/height_cache.js23
-rw-r--r--app/javascript/themes/glitch/reducers/index.js54
-rw-r--r--app/javascript/themes/glitch/reducers/local_settings.js45
-rw-r--r--app/javascript/themes/glitch/reducers/media_attachments.js15
-rw-r--r--app/javascript/themes/glitch/reducers/meta.js16
-rw-r--r--app/javascript/themes/glitch/reducers/modal.js17
-rw-r--r--app/javascript/themes/glitch/reducers/mutes.js29
-rw-r--r--app/javascript/themes/glitch/reducers/notifications.js191
-rw-r--r--app/javascript/themes/glitch/reducers/push_notifications.js51
-rw-r--r--app/javascript/themes/glitch/reducers/relationships.js46
-rw-r--r--app/javascript/themes/glitch/reducers/reports.js60
-rw-r--r--app/javascript/themes/glitch/reducers/search.js42
-rw-r--r--app/javascript/themes/glitch/reducers/settings.js119
-rw-r--r--app/javascript/themes/glitch/reducers/status_lists.js75
-rw-r--r--app/javascript/themes/glitch/reducers/statuses.js148
-rw-r--r--app/javascript/themes/glitch/reducers/timelines.js149
-rw-r--r--app/javascript/themes/glitch/reducers/user_lists.js80
24 files changed, 0 insertions, 1856 deletions
diff --git a/app/javascript/themes/glitch/reducers/accounts.js b/app/javascript/themes/glitch/reducers/accounts.js
deleted file mode 100644
index 0a65d3723..000000000
--- a/app/javascript/themes/glitch/reducers/accounts.js
+++ /dev/null
@@ -1,135 +0,0 @@
-import {
-  ACCOUNT_FETCH_SUCCESS,
-  FOLLOWERS_FETCH_SUCCESS,
-  FOLLOWERS_EXPAND_SUCCESS,
-  FOLLOWING_FETCH_SUCCESS,
-  FOLLOWING_EXPAND_SUCCESS,
-  FOLLOW_REQUESTS_FETCH_SUCCESS,
-  FOLLOW_REQUESTS_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/accounts';
-import {
-  BLOCKS_FETCH_SUCCESS,
-  BLOCKS_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/blocks';
-import {
-  MUTES_FETCH_SUCCESS,
-  MUTES_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/mutes';
-import { COMPOSE_SUGGESTIONS_READY } from 'themes/glitch/actions/compose';
-import {
-  REBLOG_SUCCESS,
-  UNREBLOG_SUCCESS,
-  FAVOURITE_SUCCESS,
-  UNFAVOURITE_SUCCESS,
-  REBLOGS_FETCH_SUCCESS,
-  FAVOURITES_FETCH_SUCCESS,
-} from 'themes/glitch/actions/interactions';
-import {
-  TIMELINE_REFRESH_SUCCESS,
-  TIMELINE_UPDATE,
-  TIMELINE_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/timelines';
-import {
-  STATUS_FETCH_SUCCESS,
-  CONTEXT_FETCH_SUCCESS,
-} from 'themes/glitch/actions/statuses';
-import { SEARCH_FETCH_SUCCESS } from 'themes/glitch/actions/search';
-import {
-  NOTIFICATIONS_UPDATE,
-  NOTIFICATIONS_REFRESH_SUCCESS,
-  NOTIFICATIONS_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/notifications';
-import {
-  FAVOURITED_STATUSES_FETCH_SUCCESS,
-  FAVOURITED_STATUSES_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/favourites';
-import { STORE_HYDRATE } from 'themes/glitch/actions/store';
-import emojify from 'themes/glitch/util/emoji';
-import { Map as ImmutableMap, fromJS } from 'immutable';
-import escapeTextContentForBrowser from 'escape-html';
-
-const normalizeAccount = (state, account) => {
-  account = { ...account };
-
-  delete account.followers_count;
-  delete account.following_count;
-  delete account.statuses_count;
-
-  const displayName = account.display_name.length === 0 ? account.username : account.display_name;
-  account.display_name_html = emojify(escapeTextContentForBrowser(displayName));
-  account.note_emojified = emojify(account.note);
-
-  return state.set(account.id, fromJS(account));
-};
-
-const normalizeAccounts = (state, accounts) => {
-  accounts.forEach(account => {
-    state = normalizeAccount(state, account);
-  });
-
-  return state;
-};
-
-const normalizeAccountFromStatus = (state, status) => {
-  state = normalizeAccount(state, status.account);
-
-  if (status.reblog && status.reblog.account) {
-    state = normalizeAccount(state, status.reblog.account);
-  }
-
-  return state;
-};
-
-const normalizeAccountsFromStatuses = (state, statuses) => {
-  statuses.forEach(status => {
-    state = normalizeAccountFromStatus(state, status);
-  });
-
-  return state;
-};
-
-const initialState = ImmutableMap();
-
-export default function accounts(state = initialState, action) {
-  switch(action.type) {
-  case STORE_HYDRATE:
-    return state.merge(action.state.get('accounts'));
-  case ACCOUNT_FETCH_SUCCESS:
-  case NOTIFICATIONS_UPDATE:
-    return normalizeAccount(state, action.account);
-  case FOLLOWERS_FETCH_SUCCESS:
-  case FOLLOWERS_EXPAND_SUCCESS:
-  case FOLLOWING_FETCH_SUCCESS:
-  case FOLLOWING_EXPAND_SUCCESS:
-  case REBLOGS_FETCH_SUCCESS:
-  case FAVOURITES_FETCH_SUCCESS:
-  case COMPOSE_SUGGESTIONS_READY:
-  case FOLLOW_REQUESTS_FETCH_SUCCESS:
-  case FOLLOW_REQUESTS_EXPAND_SUCCESS:
-  case BLOCKS_FETCH_SUCCESS:
-  case BLOCKS_EXPAND_SUCCESS:
-  case MUTES_FETCH_SUCCESS:
-  case MUTES_EXPAND_SUCCESS:
-    return action.accounts ? normalizeAccounts(state, action.accounts) : state;
-  case NOTIFICATIONS_REFRESH_SUCCESS:
-  case NOTIFICATIONS_EXPAND_SUCCESS:
-  case SEARCH_FETCH_SUCCESS:
-    return normalizeAccountsFromStatuses(normalizeAccounts(state, action.accounts), action.statuses);
-  case TIMELINE_REFRESH_SUCCESS:
-  case TIMELINE_EXPAND_SUCCESS:
-  case CONTEXT_FETCH_SUCCESS:
-  case FAVOURITED_STATUSES_FETCH_SUCCESS:
-  case FAVOURITED_STATUSES_EXPAND_SUCCESS:
-    return normalizeAccountsFromStatuses(state, action.statuses);
-  case REBLOG_SUCCESS:
-  case FAVOURITE_SUCCESS:
-  case UNREBLOG_SUCCESS:
-  case UNFAVOURITE_SUCCESS:
-    return normalizeAccountFromStatus(state, action.response);
-  case TIMELINE_UPDATE:
-  case STATUS_FETCH_SUCCESS:
-    return normalizeAccountFromStatus(state, action.status);
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/accounts_counters.js b/app/javascript/themes/glitch/reducers/accounts_counters.js
deleted file mode 100644
index e3728ecd7..000000000
--- a/app/javascript/themes/glitch/reducers/accounts_counters.js
+++ /dev/null
@@ -1,138 +0,0 @@
-import {
-  ACCOUNT_FETCH_SUCCESS,
-  FOLLOWERS_FETCH_SUCCESS,
-  FOLLOWERS_EXPAND_SUCCESS,
-  FOLLOWING_FETCH_SUCCESS,
-  FOLLOWING_EXPAND_SUCCESS,
-  FOLLOW_REQUESTS_FETCH_SUCCESS,
-  FOLLOW_REQUESTS_EXPAND_SUCCESS,
-  ACCOUNT_FOLLOW_SUCCESS,
-  ACCOUNT_UNFOLLOW_SUCCESS,
-} from 'themes/glitch/actions/accounts';
-import {
-  BLOCKS_FETCH_SUCCESS,
-  BLOCKS_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/blocks';
-import {
-  MUTES_FETCH_SUCCESS,
-  MUTES_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/mutes';
-import { COMPOSE_SUGGESTIONS_READY } from 'themes/glitch/actions/compose';
-import {
-  REBLOG_SUCCESS,
-  UNREBLOG_SUCCESS,
-  FAVOURITE_SUCCESS,
-  UNFAVOURITE_SUCCESS,
-  REBLOGS_FETCH_SUCCESS,
-  FAVOURITES_FETCH_SUCCESS,
-} from 'themes/glitch/actions/interactions';
-import {
-  TIMELINE_REFRESH_SUCCESS,
-  TIMELINE_UPDATE,
-  TIMELINE_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/timelines';
-import {
-  STATUS_FETCH_SUCCESS,
-  CONTEXT_FETCH_SUCCESS,
-} from 'themes/glitch/actions/statuses';
-import { SEARCH_FETCH_SUCCESS } from 'themes/glitch/actions/search';
-import {
-  NOTIFICATIONS_UPDATE,
-  NOTIFICATIONS_REFRESH_SUCCESS,
-  NOTIFICATIONS_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/notifications';
-import {
-  FAVOURITED_STATUSES_FETCH_SUCCESS,
-  FAVOURITED_STATUSES_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/favourites';
-import { STORE_HYDRATE } from 'themes/glitch/actions/store';
-import { Map as ImmutableMap, fromJS } from 'immutable';
-
-const normalizeAccount = (state, account) => state.set(account.id, fromJS({
-  followers_count: account.followers_count,
-  following_count: account.following_count,
-  statuses_count: account.statuses_count,
-}));
-
-const normalizeAccounts = (state, accounts) => {
-  accounts.forEach(account => {
-    state = normalizeAccount(state, account);
-  });
-
-  return state;
-};
-
-const normalizeAccountFromStatus = (state, status) => {
-  state = normalizeAccount(state, status.account);
-
-  if (status.reblog && status.reblog.account) {
-    state = normalizeAccount(state, status.reblog.account);
-  }
-
-  return state;
-};
-
-const normalizeAccountsFromStatuses = (state, statuses) => {
-  statuses.forEach(status => {
-    state = normalizeAccountFromStatus(state, status);
-  });
-
-  return state;
-};
-
-const initialState = ImmutableMap();
-
-export default function accountsCounters(state = initialState, action) {
-  switch(action.type) {
-  case STORE_HYDRATE:
-    return state.merge(action.state.get('accounts').map(item => fromJS({
-      followers_count: item.get('followers_count'),
-      following_count: item.get('following_count'),
-      statuses_count: item.get('statuses_count'),
-    })));
-  case ACCOUNT_FETCH_SUCCESS:
-  case NOTIFICATIONS_UPDATE:
-    return normalizeAccount(state, action.account);
-  case FOLLOWERS_FETCH_SUCCESS:
-  case FOLLOWERS_EXPAND_SUCCESS:
-  case FOLLOWING_FETCH_SUCCESS:
-  case FOLLOWING_EXPAND_SUCCESS:
-  case REBLOGS_FETCH_SUCCESS:
-  case FAVOURITES_FETCH_SUCCESS:
-  case COMPOSE_SUGGESTIONS_READY:
-  case FOLLOW_REQUESTS_FETCH_SUCCESS:
-  case FOLLOW_REQUESTS_EXPAND_SUCCESS:
-  case BLOCKS_FETCH_SUCCESS:
-  case BLOCKS_EXPAND_SUCCESS:
-  case MUTES_FETCH_SUCCESS:
-  case MUTES_EXPAND_SUCCESS:
-    return action.accounts ? normalizeAccounts(state, action.accounts) : state;
-  case NOTIFICATIONS_REFRESH_SUCCESS:
-  case NOTIFICATIONS_EXPAND_SUCCESS:
-  case SEARCH_FETCH_SUCCESS:
-    return normalizeAccountsFromStatuses(normalizeAccounts(state, action.accounts), action.statuses);
-  case TIMELINE_REFRESH_SUCCESS:
-  case TIMELINE_EXPAND_SUCCESS:
-  case CONTEXT_FETCH_SUCCESS:
-  case FAVOURITED_STATUSES_FETCH_SUCCESS:
-  case FAVOURITED_STATUSES_EXPAND_SUCCESS:
-    return normalizeAccountsFromStatuses(state, action.statuses);
-  case REBLOG_SUCCESS:
-  case FAVOURITE_SUCCESS:
-  case UNREBLOG_SUCCESS:
-  case UNFAVOURITE_SUCCESS:
-    return normalizeAccountFromStatus(state, action.response);
-  case TIMELINE_UPDATE:
-  case STATUS_FETCH_SUCCESS:
-    return normalizeAccountFromStatus(state, action.status);
-  case ACCOUNT_FOLLOW_SUCCESS:
-    if (action.alreadyFollowing) {
-      return state;
-    }
-    return state.updateIn([action.relationship.id, 'followers_count'], num => num + 1);
-  case ACCOUNT_UNFOLLOW_SUCCESS:
-    return state.updateIn([action.relationship.id, 'followers_count'], num => Math.max(0, num - 1));
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/alerts.js b/app/javascript/themes/glitch/reducers/alerts.js
deleted file mode 100644
index ad66b63f6..000000000
--- a/app/javascript/themes/glitch/reducers/alerts.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import {
-  ALERT_SHOW,
-  ALERT_DISMISS,
-  ALERT_CLEAR,
-} from 'themes/glitch/actions/alerts';
-import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
-
-const initialState = ImmutableList([]);
-
-export default function alerts(state = initialState, action) {
-  switch(action.type) {
-  case ALERT_SHOW:
-    return state.push(ImmutableMap({
-      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/javascript/themes/glitch/reducers/cards.js b/app/javascript/themes/glitch/reducers/cards.js
deleted file mode 100644
index 35be30444..000000000
--- a/app/javascript/themes/glitch/reducers/cards.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import { STATUS_CARD_FETCH_SUCCESS } from 'themes/glitch/actions/cards';
-
-import { Map as ImmutableMap, fromJS } from 'immutable';
-
-const initialState = ImmutableMap();
-
-export default function cards(state = initialState, action) {
-  switch(action.type) {
-  case STATUS_CARD_FETCH_SUCCESS:
-    return state.set(action.id, fromJS(action.card));
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/compose.js b/app/javascript/themes/glitch/reducers/compose.js
deleted file mode 100644
index be359fcb4..000000000
--- a/app/javascript/themes/glitch/reducers/compose.js
+++ /dev/null
@@ -1,307 +0,0 @@
-import {
-  COMPOSE_MOUNT,
-  COMPOSE_UNMOUNT,
-  COMPOSE_CHANGE,
-  COMPOSE_REPLY,
-  COMPOSE_REPLY_CANCEL,
-  COMPOSE_MENTION,
-  COMPOSE_SUBMIT_REQUEST,
-  COMPOSE_SUBMIT_SUCCESS,
-  COMPOSE_SUBMIT_FAIL,
-  COMPOSE_UPLOAD_REQUEST,
-  COMPOSE_UPLOAD_SUCCESS,
-  COMPOSE_UPLOAD_FAIL,
-  COMPOSE_UPLOAD_UNDO,
-  COMPOSE_UPLOAD_PROGRESS,
-  COMPOSE_SUGGESTIONS_CLEAR,
-  COMPOSE_SUGGESTIONS_READY,
-  COMPOSE_SUGGESTION_SELECT,
-  COMPOSE_ADVANCED_OPTIONS_CHANGE,
-  COMPOSE_SENSITIVITY_CHANGE,
-  COMPOSE_SPOILERNESS_CHANGE,
-  COMPOSE_SPOILER_TEXT_CHANGE,
-  COMPOSE_VISIBILITY_CHANGE,
-  COMPOSE_COMPOSING_CHANGE,
-  COMPOSE_EMOJI_INSERT,
-  COMPOSE_UPLOAD_CHANGE_REQUEST,
-  COMPOSE_UPLOAD_CHANGE_SUCCESS,
-  COMPOSE_UPLOAD_CHANGE_FAIL,
-  COMPOSE_DOODLE_SET,
-  COMPOSE_RESET,
-} from 'themes/glitch/actions/compose';
-import { TIMELINE_DELETE } from 'themes/glitch/actions/timelines';
-import { STORE_HYDRATE } from 'themes/glitch/actions/store';
-import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
-import uuid from 'themes/glitch/util/uuid';
-import { me } from 'themes/glitch/util/initial_state';
-
-const initialState = ImmutableMap({
-  mounted: false,
-  advanced_options: ImmutableMap({
-    do_not_federate: false,
-  }),
-  sensitive: false,
-  spoiler: false,
-  spoiler_text: '',
-  privacy: null,
-  text: '',
-  focusDate: null,
-  preselectDate: null,
-  in_reply_to: null,
-  is_composing: false,
-  is_submitting: false,
-  is_uploading: false,
-  progress: 0,
-  media_attachments: ImmutableList(),
-  suggestion_token: null,
-  suggestions: ImmutableList(),
-  default_advanced_options: ImmutableMap({
-    do_not_federate: false,
-  }),
-  default_privacy: 'public',
-  default_sensitive: false,
-  resetFileKey: Math.floor((Math.random() * 0x10000)),
-  idempotencyKey: null,
-  doodle: ImmutableMap({
-    fg: 'rgb(  0,    0,    0)',
-    bg: 'rgb(255,  255,  255)',
-    swapped: false,
-    mode: 'draw',
-    size: 'normal',
-    weight: 2,
-    opacity: 1,
-    adaptiveStroke: true,
-    smoothing: false,
-  }),
-});
-
-function statusToTextMentions(state, status) {
-  let set = ImmutableOrderedSet([]);
-
-  if (status.getIn(['account', 'id']) !== me) {
-    set = set.add(`@${status.getIn(['account', 'acct'])} `);
-  }
-
-  return set.union(status.get('mentions').filterNot(mention => mention.get('id') === me).map(mention => `@${mention.get('acct')} `)).join('');
-};
-
-function clearAll(state) {
-  return state.withMutations(map => {
-    map.set('text', '');
-    map.set('spoiler', false);
-    map.set('spoiler_text', '');
-    map.set('is_submitting', false);
-    map.set('in_reply_to', null);
-    map.set('advanced_options', state.get('default_advanced_options'));
-    map.set('privacy', state.get('default_privacy'));
-    map.set('sensitive', false);
-    map.update('media_attachments', list => list.clear());
-    map.set('idempotencyKey', uuid());
-  });
-};
-
-function appendMedia(state, media) {
-  const prevSize = state.get('media_attachments').size;
-
-  return state.withMutations(map => {
-    map.update('media_attachments', list => list.push(media));
-    map.set('is_uploading', false);
-    map.set('resetFileKey', Math.floor((Math.random() * 0x10000)));
-    map.update('text', oldText => `${oldText.trim()} ${media.get('text_url')}`);
-    map.set('focusDate', new Date());
-    map.set('idempotencyKey', uuid());
-
-    if (prevSize === 0 && (state.get('default_sensitive') || state.get('spoiler'))) {
-      map.set('sensitive', true);
-    }
-  });
-};
-
-function removeMedia(state, mediaId) {
-  const media    = state.get('media_attachments').find(item => item.get('id') === mediaId);
-  const prevSize = state.get('media_attachments').size;
-
-  return state.withMutations(map => {
-    map.update('media_attachments', list => list.filterNot(item => item.get('id') === mediaId));
-    map.update('text', text => text.replace(media.get('text_url'), '').trim());
-    map.set('idempotencyKey', uuid());
-
-    if (prevSize === 1) {
-      map.set('sensitive', false);
-    }
-  });
-};
-
-const insertSuggestion = (state, position, token, completion) => {
-  return state.withMutations(map => {
-    map.update('text', oldText => `${oldText.slice(0, position)}${completion}\u200B${oldText.slice(position + token.length)}`);
-    map.set('suggestion_token', null);
-    map.update('suggestions', ImmutableList(), list => list.clear());
-    map.set('focusDate', new Date());
-    map.set('idempotencyKey', uuid());
-  });
-};
-
-const insertEmoji = (state, position, emojiData) => {
-  const emoji = emojiData.native;
-
-  return state.withMutations(map => {
-    map.update('text', oldText => `${oldText.slice(0, position)}${emoji}\u200B${oldText.slice(position)}`);
-    map.set('focusDate', new Date());
-    map.set('idempotencyKey', uuid());
-  });
-};
-
-const privacyPreference = (a, b) => {
-  if (a === 'direct' || b === 'direct') {
-    return 'direct';
-  } else if (a === 'private' || b === 'private') {
-    return 'private';
-  } else if (a === 'unlisted' || b === 'unlisted') {
-    return 'unlisted';
-  } else {
-    return 'public';
-  }
-};
-
-const hydrate = (state, hydratedState) => {
-  state = clearAll(state.merge(hydratedState));
-
-  if (hydratedState.has('text')) {
-    state = state.set('text', hydratedState.get('text'));
-  }
-
-  return state;
-};
-
-export default function compose(state = initialState, action) {
-  switch(action.type) {
-  case STORE_HYDRATE:
-    return hydrate(state, action.state.get('compose'));
-  case COMPOSE_MOUNT:
-    return state.set('mounted', true);
-  case COMPOSE_UNMOUNT:
-    return state
-      .set('mounted', false)
-      .set('is_composing', false);
-  case COMPOSE_ADVANCED_OPTIONS_CHANGE:
-    return state
-      .set('advanced_options',
-        state.get('advanced_options').set(action.option, !state.getIn(['advanced_options', action.option])))
-      .set('idempotencyKey', uuid());
-  case COMPOSE_SENSITIVITY_CHANGE:
-    return state.withMutations(map => {
-      if (!state.get('spoiler')) {
-        map.set('sensitive', !state.get('sensitive'));
-      }
-
-      map.set('idempotencyKey', uuid());
-    });
-  case COMPOSE_SPOILERNESS_CHANGE:
-    return state.withMutations(map => {
-      map.set('spoiler_text', '');
-      map.set('spoiler', !state.get('spoiler'));
-      map.set('idempotencyKey', uuid());
-
-      if (!state.get('sensitive') && state.get('media_attachments').size >= 1) {
-        map.set('sensitive', true);
-      }
-    });
-  case COMPOSE_SPOILER_TEXT_CHANGE:
-    return state
-      .set('spoiler_text', action.text)
-      .set('idempotencyKey', uuid());
-  case COMPOSE_VISIBILITY_CHANGE:
-    return state
-      .set('privacy', action.value)
-      .set('idempotencyKey', uuid());
-  case COMPOSE_CHANGE:
-    return state
-      .set('text', action.text)
-      .set('idempotencyKey', uuid());
-  case COMPOSE_COMPOSING_CHANGE:
-    return state.set('is_composing', action.value);
-  case COMPOSE_REPLY:
-    return state.withMutations(map => {
-      map.set('in_reply_to', action.status.get('id'));
-      map.set('text', statusToTextMentions(state, action.status));
-      map.set('privacy', privacyPreference(action.status.get('visibility'), state.get('default_privacy')));
-      map.set('advanced_options', new ImmutableMap({
-        do_not_federate: /👁\ufe0f?<\/p>$/.test(action.status.get('content')),
-      }));
-      map.set('focusDate', new Date());
-      map.set('preselectDate', new Date());
-      map.set('idempotencyKey', uuid());
-
-      if (action.status.get('spoiler_text').length > 0) {
-        map.set('spoiler', true);
-        map.set('spoiler_text', action.status.get('spoiler_text'));
-      } else {
-        map.set('spoiler', false);
-        map.set('spoiler_text', '');
-      }
-    });
-  case COMPOSE_REPLY_CANCEL:
-  case COMPOSE_RESET:
-    return state.withMutations(map => {
-      map.set('in_reply_to', null);
-      map.set('text', '');
-      map.set('spoiler', false);
-      map.set('spoiler_text', '');
-      map.set('privacy', state.get('default_privacy'));
-      map.set('advanced_options', state.get('default_advanced_options'));
-      map.set('idempotencyKey', uuid());
-    });
-  case COMPOSE_SUBMIT_REQUEST:
-  case COMPOSE_UPLOAD_CHANGE_REQUEST:
-    return state.set('is_submitting', true);
-  case COMPOSE_SUBMIT_SUCCESS:
-    return clearAll(state);
-  case COMPOSE_SUBMIT_FAIL:
-  case COMPOSE_UPLOAD_CHANGE_FAIL:
-    return state.set('is_submitting', false);
-  case COMPOSE_UPLOAD_REQUEST:
-    return state.set('is_uploading', true);
-  case COMPOSE_UPLOAD_SUCCESS:
-    return appendMedia(state, fromJS(action.media));
-  case COMPOSE_UPLOAD_FAIL:
-    return state.set('is_uploading', false);
-  case COMPOSE_UPLOAD_UNDO:
-    return removeMedia(state, action.media_id);
-  case COMPOSE_UPLOAD_PROGRESS:
-    return state.set('progress', Math.round((action.loaded / action.total) * 100));
-  case COMPOSE_MENTION:
-    return state
-      .update('text', text => `${text}@${action.account.get('acct')} `)
-      .set('focusDate', new Date())
-      .set('idempotencyKey', uuid());
-  case COMPOSE_SUGGESTIONS_CLEAR:
-    return state.update('suggestions', ImmutableList(), list => list.clear()).set('suggestion_token', null);
-  case COMPOSE_SUGGESTIONS_READY:
-    return state.set('suggestions', ImmutableList(action.accounts ? action.accounts.map(item => item.id) : action.emojis)).set('suggestion_token', action.token);
-  case COMPOSE_SUGGESTION_SELECT:
-    return insertSuggestion(state, action.position, action.token, action.completion);
-  case TIMELINE_DELETE:
-    if (action.id === state.get('in_reply_to')) {
-      return state.set('in_reply_to', null);
-    } else {
-      return state;
-    }
-  case COMPOSE_EMOJI_INSERT:
-    return insertEmoji(state, action.position, action.emoji);
-  case COMPOSE_UPLOAD_CHANGE_SUCCESS:
-    return state
-      .set('is_submitting', false)
-      .update('media_attachments', list => list.map(item => {
-        if (item.get('id') === action.media.id) {
-          return item.set('description', action.media.description);
-        }
-
-        return item;
-      }));
-  case COMPOSE_DOODLE_SET:
-    return state.mergeIn(['doodle'], action.options);
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/contexts.js b/app/javascript/themes/glitch/reducers/contexts.js
deleted file mode 100644
index 56c930bd5..000000000
--- a/app/javascript/themes/glitch/reducers/contexts.js
+++ /dev/null
@@ -1,61 +0,0 @@
-import { CONTEXT_FETCH_SUCCESS } from 'themes/glitch/actions/statuses';
-import { TIMELINE_DELETE, TIMELINE_CONTEXT_UPDATE } from 'themes/glitch/actions/timelines';
-import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
-
-const initialState = ImmutableMap({
-  ancestors: ImmutableMap(),
-  descendants: ImmutableMap(),
-});
-
-const normalizeContext = (state, id, ancestors, descendants) => {
-  const ancestorsIds   = ImmutableList(ancestors.map(ancestor => ancestor.id));
-  const descendantsIds = ImmutableList(descendants.map(descendant => descendant.id));
-
-  return state.withMutations(map => {
-    map.setIn(['ancestors', id], ancestorsIds);
-    map.setIn(['descendants', id], descendantsIds);
-  });
-};
-
-const deleteFromContexts = (state, id) => {
-  state.getIn(['descendants', id], ImmutableList()).forEach(descendantId => {
-    state = state.updateIn(['ancestors', descendantId], ImmutableList(), list => list.filterNot(itemId => itemId === id));
-  });
-
-  state.getIn(['ancestors', id], ImmutableList()).forEach(ancestorId => {
-    state = state.updateIn(['descendants', ancestorId], ImmutableList(), list => list.filterNot(itemId => itemId === id));
-  });
-
-  state = state.deleteIn(['descendants', id]).deleteIn(['ancestors', id]);
-
-  return state;
-};
-
-const updateContext = (state, status, references) => {
-  return state.update('descendants', map => {
-    references.forEach(parentId => {
-      map = map.update(parentId, ImmutableList(), list => {
-        if (list.includes(status.id)) {
-          return list;
-        }
-
-        return list.push(status.id);
-      });
-    });
-
-    return map;
-  });
-};
-
-export default function contexts(state = initialState, action) {
-  switch(action.type) {
-  case CONTEXT_FETCH_SUCCESS:
-    return normalizeContext(state, action.id, action.ancestors, action.descendants);
-  case TIMELINE_DELETE:
-    return deleteFromContexts(state, action.id);
-  case TIMELINE_CONTEXT_UPDATE:
-    return updateContext(state, action.status, action.references);
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/custom_emojis.js b/app/javascript/themes/glitch/reducers/custom_emojis.js
deleted file mode 100644
index e3f1e0018..000000000
--- a/app/javascript/themes/glitch/reducers/custom_emojis.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { List as ImmutableList } from 'immutable';
-import { STORE_HYDRATE } from 'themes/glitch/actions/store';
-import { search as emojiSearch } from 'themes/glitch/util/emoji/emoji_mart_search_light';
-import { buildCustomEmojis } from 'themes/glitch/util/emoji';
-
-const initialState = ImmutableList();
-
-export default function custom_emojis(state = initialState, action) {
-  switch(action.type) {
-  case STORE_HYDRATE:
-    emojiSearch('', { custom: buildCustomEmojis(action.state.get('custom_emojis', [])) });
-    return action.state.get('custom_emojis');
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/height_cache.js b/app/javascript/themes/glitch/reducers/height_cache.js
deleted file mode 100644
index 93c31b42c..000000000
--- a/app/javascript/themes/glitch/reducers/height_cache.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import { Map as ImmutableMap } from 'immutable';
-import { HEIGHT_CACHE_SET, HEIGHT_CACHE_CLEAR } from 'themes/glitch/actions/height_cache';
-
-const initialState = ImmutableMap();
-
-const setHeight = (state, key, id, height) => {
-  return state.update(key, ImmutableMap(), map => map.set(id, height));
-};
-
-const clearHeights = () => {
-  return ImmutableMap();
-};
-
-export default function statuses(state = initialState, action) {
-  switch(action.type) {
-  case HEIGHT_CACHE_SET:
-    return setHeight(state, action.key, action.id, action.height);
-  case HEIGHT_CACHE_CLEAR:
-    return clearHeights();
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/index.js b/app/javascript/themes/glitch/reducers/index.js
deleted file mode 100644
index aa748421a..000000000
--- a/app/javascript/themes/glitch/reducers/index.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import { combineReducers } from 'redux-immutable';
-import timelines from './timelines';
-import meta from './meta';
-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 accounts_counters from './accounts_counters';
-import statuses from './statuses';
-import relationships from './relationships';
-import settings from './settings';
-import local_settings from './local_settings';
-import push_notifications from './push_notifications';
-import status_lists from './status_lists';
-import cards from './cards';
-import mutes from './mutes';
-import reports from './reports';
-import contexts from './contexts';
-import compose from './compose';
-import search from './search';
-import media_attachments from './media_attachments';
-import notifications from './notifications';
-import height_cache from './height_cache';
-import custom_emojis from './custom_emojis';
-
-const reducers = {
-  timelines,
-  meta,
-  alerts,
-  loadingBar: loadingBarReducer,
-  modal,
-  user_lists,
-  status_lists,
-  accounts,
-  accounts_counters,
-  statuses,
-  relationships,
-  settings,
-  local_settings,
-  push_notifications,
-  cards,
-  mutes,
-  reports,
-  contexts,
-  compose,
-  search,
-  media_attachments,
-  notifications,
-  height_cache,
-  custom_emojis,
-};
-
-export default combineReducers(reducers);
diff --git a/app/javascript/themes/glitch/reducers/local_settings.js b/app/javascript/themes/glitch/reducers/local_settings.js
deleted file mode 100644
index b1ffa047e..000000000
--- a/app/javascript/themes/glitch/reducers/local_settings.js
+++ /dev/null
@@ -1,45 +0,0 @@
-//  Package imports.
-import { Map as ImmutableMap } from 'immutable';
-
-//  Our imports.
-import { STORE_HYDRATE } from 'themes/glitch/actions/store';
-import { LOCAL_SETTING_CHANGE } from 'themes/glitch/actions/local_settings';
-
-const initialState = ImmutableMap({
-  layout    : 'auto',
-  stretch   : true,
-  navbar_under : false,
-  side_arm  : 'none',
-  collapsed : ImmutableMap({
-    enabled     : true,
-    auto        : ImmutableMap({
-      all              : false,
-      notifications    : true,
-      lengthy          : true,
-      reblogs          : false,
-      replies          : false,
-      media            : false,
-    }),
-    backgrounds : ImmutableMap({
-      user_backgrounds : false,
-      preview_images   : false,
-    }),
-  }),
-  media     : ImmutableMap({
-    letterbox   : true,
-    fullwidth   : true,
-  }),
-});
-
-const hydrate = (state, localSettings) => state.mergeDeep(localSettings);
-
-export default function localSettings(state = initialState, action) {
-  switch(action.type) {
-  case STORE_HYDRATE:
-    return hydrate(state, action.state.get('local_settings'));
-  case LOCAL_SETTING_CHANGE:
-    return state.setIn(action.key, action.value);
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/media_attachments.js b/app/javascript/themes/glitch/reducers/media_attachments.js
deleted file mode 100644
index 69a44639c..000000000
--- a/app/javascript/themes/glitch/reducers/media_attachments.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { STORE_HYDRATE } from 'themes/glitch/actions/store';
-import { Map as ImmutableMap } from 'immutable';
-
-const initialState = ImmutableMap({
-  accept_content_types: [],
-});
-
-export default function meta(state = initialState, action) {
-  switch(action.type) {
-  case STORE_HYDRATE:
-    return state.merge(action.state.get('media_attachments'));
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/meta.js b/app/javascript/themes/glitch/reducers/meta.js
deleted file mode 100644
index 2249f1d78..000000000
--- a/app/javascript/themes/glitch/reducers/meta.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { STORE_HYDRATE } from 'themes/glitch/actions/store';
-import { Map as ImmutableMap } from 'immutable';
-
-const initialState = ImmutableMap({
-  streaming_api_base_url: null,
-  access_token: null,
-});
-
-export default function meta(state = initialState, action) {
-  switch(action.type) {
-  case STORE_HYDRATE:
-    return state.merge(action.state.get('meta'));
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/modal.js b/app/javascript/themes/glitch/reducers/modal.js
deleted file mode 100644
index 97fb31203..000000000
--- a/app/javascript/themes/glitch/reducers/modal.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { MODAL_OPEN, MODAL_CLOSE } from 'themes/glitch/actions/modal';
-
-const initialState = {
-  modalType: null,
-  modalProps: {},
-};
-
-export default function modal(state = initialState, action) {
-  switch(action.type) {
-  case MODAL_OPEN:
-    return { modalType: action.modalType, modalProps: action.modalProps };
-  case MODAL_CLOSE:
-    return initialState;
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/mutes.js b/app/javascript/themes/glitch/reducers/mutes.js
deleted file mode 100644
index 8fe4ae0c3..000000000
--- a/app/javascript/themes/glitch/reducers/mutes.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import Immutable from 'immutable';
-
-import {
-  MUTES_INIT_MODAL,
-  MUTES_TOGGLE_HIDE_NOTIFICATIONS,
-} from 'themes/glitch/actions/mutes';
-
-const initialState = Immutable.Map({
-  new: Immutable.Map({
-    isSubmitting: false,
-    account: null,
-    notifications: true,
-  }),
-});
-
-export default function mutes(state = initialState, action) {
-  switch (action.type) {
-  case MUTES_INIT_MODAL:
-    return state.withMutations((state) => {
-      state.setIn(['new', 'isSubmitting'], false);
-      state.setIn(['new', 'account'], action.account);
-      state.setIn(['new', 'notifications'], true);
-    });
-  case MUTES_TOGGLE_HIDE_NOTIFICATIONS:
-    return state.updateIn(['new', 'notifications'], (old) => !old);
-  default:
-    return state;
-  }
-}
diff --git a/app/javascript/themes/glitch/reducers/notifications.js b/app/javascript/themes/glitch/reducers/notifications.js
deleted file mode 100644
index c4f505053..000000000
--- a/app/javascript/themes/glitch/reducers/notifications.js
+++ /dev/null
@@ -1,191 +0,0 @@
-import {
-  NOTIFICATIONS_UPDATE,
-  NOTIFICATIONS_REFRESH_SUCCESS,
-  NOTIFICATIONS_EXPAND_SUCCESS,
-  NOTIFICATIONS_REFRESH_REQUEST,
-  NOTIFICATIONS_EXPAND_REQUEST,
-  NOTIFICATIONS_REFRESH_FAIL,
-  NOTIFICATIONS_EXPAND_FAIL,
-  NOTIFICATIONS_CLEAR,
-  NOTIFICATIONS_SCROLL_TOP,
-  NOTIFICATIONS_DELETE_MARKED_REQUEST,
-  NOTIFICATIONS_DELETE_MARKED_SUCCESS,
-  NOTIFICATION_MARK_FOR_DELETE,
-  NOTIFICATIONS_DELETE_MARKED_FAIL,
-  NOTIFICATIONS_ENTER_CLEARING_MODE,
-  NOTIFICATIONS_MARK_ALL_FOR_DELETE,
-} from 'themes/glitch/actions/notifications';
-import {
-  ACCOUNT_BLOCK_SUCCESS,
-  ACCOUNT_MUTE_SUCCESS,
-} from 'themes/glitch/actions/accounts';
-import { TIMELINE_DELETE } from 'themes/glitch/actions/timelines';
-import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
-
-const initialState = ImmutableMap({
-  items: ImmutableList(),
-  next: null,
-  top: true,
-  unread: 0,
-  loaded: false,
-  isLoading: true,
-  cleaningMode: false,
-  // notification removal mark of new notifs loaded whilst cleaningMode is true.
-  markNewForDelete: false,
-});
-
-const notificationToMap = (state, notification) => ImmutableMap({
-  id: notification.id,
-  type: notification.type,
-  account: notification.account.id,
-  markedForDelete: state.get('markNewForDelete'),
-  status: notification.status ? notification.status.id : null,
-});
-
-const normalizeNotification = (state, notification) => {
-  const top = state.get('top');
-
-  if (!top) {
-    state = state.update('unread', unread => unread + 1);
-  }
-
-  return state.update('items', list => {
-    if (top && list.size > 40) {
-      list = list.take(20);
-    }
-
-    return list.unshift(notificationToMap(state, notification));
-  });
-};
-
-const normalizeNotifications = (state, notifications, next) => {
-  let items    = ImmutableList();
-  const loaded = state.get('loaded');
-
-  notifications.forEach((n, i) => {
-    items = items.set(i, notificationToMap(state, n));
-  });
-
-  if (state.get('next') === null) {
-    state = state.set('next', next);
-  }
-
-  return state
-    .update('items', list => loaded ? items.concat(list) : list.concat(items))
-    .set('loaded', true)
-    .set('isLoading', false);
-};
-
-const appendNormalizedNotifications = (state, notifications, next) => {
-  let items = ImmutableList();
-
-  notifications.forEach((n, i) => {
-    items = items.set(i, notificationToMap(state, n));
-  });
-
-  return state
-    .update('items', list => list.concat(items))
-    .set('next', next)
-    .set('isLoading', false);
-};
-
-const filterNotifications = (state, relationship) => {
-  return state.update('items', list => list.filterNot(item => item.get('account') === relationship.id));
-};
-
-const updateTop = (state, top) => {
-  if (top) {
-    state = state.set('unread', 0);
-  }
-
-  return state.set('top', top);
-};
-
-const deleteByStatus = (state, statusId) => {
-  return state.update('items', list => list.filterNot(item => item.get('status') === statusId));
-};
-
-const markForDelete = (state, notificationId, yes) => {
-  return state.update('items', list => list.map(item => {
-    if(item.get('id') === notificationId) {
-      return item.set('markedForDelete', yes);
-    } else {
-      return item;
-    }
-  }));
-};
-
-const markAllForDelete = (state, yes) => {
-  return state.update('items', list => list.map(item => {
-    if(yes !== null) {
-      return item.set('markedForDelete', yes);
-    } else {
-      return item.set('markedForDelete', !item.get('markedForDelete'));
-    }
-  }));
-};
-
-const unmarkAllForDelete = (state) => {
-  return state.update('items', list => list.map(item => item.set('markedForDelete', false)));
-};
-
-const deleteMarkedNotifs = (state) => {
-  return state.update('items', list => list.filterNot(item => item.get('markedForDelete')));
-};
-
-export default function notifications(state = initialState, action) {
-  let st;
-
-  switch(action.type) {
-  case NOTIFICATIONS_REFRESH_REQUEST:
-  case NOTIFICATIONS_EXPAND_REQUEST:
-  case NOTIFICATIONS_DELETE_MARKED_REQUEST:
-    return state.set('isLoading', true);
-  case NOTIFICATIONS_DELETE_MARKED_FAIL:
-  case NOTIFICATIONS_REFRESH_FAIL:
-  case NOTIFICATIONS_EXPAND_FAIL:
-    return state.set('isLoading', false);
-  case NOTIFICATIONS_SCROLL_TOP:
-    return updateTop(state, action.top);
-  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);
-  case ACCOUNT_BLOCK_SUCCESS:
-  case ACCOUNT_MUTE_SUCCESS:
-    return filterNotifications(state, action.relationship);
-  case NOTIFICATIONS_CLEAR:
-    return state.set('items', ImmutableList()).set('next', null);
-  case TIMELINE_DELETE:
-    return deleteByStatus(state, action.id);
-
-  case NOTIFICATION_MARK_FOR_DELETE:
-    return markForDelete(state, action.id, action.yes);
-
-  case NOTIFICATIONS_DELETE_MARKED_SUCCESS:
-    return deleteMarkedNotifs(state).set('isLoading', false);
-
-  case NOTIFICATIONS_ENTER_CLEARING_MODE:
-    st = state.set('cleaningMode', action.yes);
-    if (!action.yes) {
-      return unmarkAllForDelete(st).set('markNewForDelete', false);
-    } else {
-      return st;
-    }
-
-  case NOTIFICATIONS_MARK_ALL_FOR_DELETE:
-    st = state;
-    if (action.yes === null) {
-      // Toggle - this is a bit confusing, as it toggles the all-none mode
-      //st = st.set('markNewForDelete', !st.get('markNewForDelete'));
-    } else {
-      st = st.set('markNewForDelete', action.yes);
-    }
-    return markAllForDelete(st, action.yes);
-
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/push_notifications.js b/app/javascript/themes/glitch/reducers/push_notifications.js
deleted file mode 100644
index 744e4a0eb..000000000
--- a/app/javascript/themes/glitch/reducers/push_notifications.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import { STORE_HYDRATE } from 'themes/glitch/actions/store';
-import { SET_BROWSER_SUPPORT, SET_SUBSCRIPTION, CLEAR_SUBSCRIPTION, ALERTS_CHANGE } from 'themes/glitch/actions/push_notifications';
-import Immutable from 'immutable';
-
-const initialState = Immutable.Map({
-  subscription: null,
-  alerts: new Immutable.Map({
-    follow: false,
-    favourite: false,
-    reblog: false,
-    mention: false,
-  }),
-  isSubscribed: false,
-  browserSupport: false,
-});
-
-export default function push_subscriptions(state = initialState, action) {
-  switch(action.type) {
-  case STORE_HYDRATE: {
-    const push_subscription = action.state.get('push_subscription');
-
-    if (push_subscription) {
-      return state
-        .set('subscription', new Immutable.Map({
-          id: push_subscription.get('id'),
-          endpoint: push_subscription.get('endpoint'),
-        }))
-        .set('alerts', push_subscription.get('alerts') || initialState.get('alerts'))
-        .set('isSubscribed', true);
-    }
-
-    return state;
-  }
-  case SET_SUBSCRIPTION:
-    return state
-      .set('subscription', new Immutable.Map({
-        id: action.subscription.id,
-        endpoint: action.subscription.endpoint,
-      }))
-      .set('alerts', new Immutable.Map(action.subscription.alerts))
-      .set('isSubscribed', true);
-  case SET_BROWSER_SUPPORT:
-    return state.set('browserSupport', action.value);
-  case CLEAR_SUBSCRIPTION:
-    return initialState;
-  case ALERTS_CHANGE:
-    return state.setIn(action.key, action.value);
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/relationships.js b/app/javascript/themes/glitch/reducers/relationships.js
deleted file mode 100644
index d9135d6da..000000000
--- a/app/javascript/themes/glitch/reducers/relationships.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import {
-  ACCOUNT_FOLLOW_SUCCESS,
-  ACCOUNT_UNFOLLOW_SUCCESS,
-  ACCOUNT_BLOCK_SUCCESS,
-  ACCOUNT_UNBLOCK_SUCCESS,
-  ACCOUNT_MUTE_SUCCESS,
-  ACCOUNT_UNMUTE_SUCCESS,
-  RELATIONSHIPS_FETCH_SUCCESS,
-} from 'themes/glitch/actions/accounts';
-import {
-  DOMAIN_BLOCK_SUCCESS,
-  DOMAIN_UNBLOCK_SUCCESS,
-} from 'themes/glitch/actions/domain_blocks';
-import { Map as ImmutableMap, fromJS } from 'immutable';
-
-const normalizeRelationship = (state, relationship) => state.set(relationship.id, fromJS(relationship));
-
-const normalizeRelationships = (state, relationships) => {
-  relationships.forEach(relationship => {
-    state = normalizeRelationship(state, relationship);
-  });
-
-  return state;
-};
-
-const initialState = ImmutableMap();
-
-export default function relationships(state = initialState, action) {
-  switch(action.type) {
-  case ACCOUNT_FOLLOW_SUCCESS:
-  case ACCOUNT_UNFOLLOW_SUCCESS:
-  case ACCOUNT_BLOCK_SUCCESS:
-  case ACCOUNT_UNBLOCK_SUCCESS:
-  case ACCOUNT_MUTE_SUCCESS:
-  case ACCOUNT_UNMUTE_SUCCESS:
-    return normalizeRelationship(state, action.relationship);
-  case RELATIONSHIPS_FETCH_SUCCESS:
-    return normalizeRelationships(state, action.relationships);
-  case DOMAIN_BLOCK_SUCCESS:
-    return state.setIn([action.accountId, 'domain_blocking'], true);
-  case DOMAIN_UNBLOCK_SUCCESS:
-    return state.setIn([action.accountId, 'domain_blocking'], false);
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/reports.js b/app/javascript/themes/glitch/reducers/reports.js
deleted file mode 100644
index b714374ea..000000000
--- a/app/javascript/themes/glitch/reducers/reports.js
+++ /dev/null
@@ -1,60 +0,0 @@
-import {
-  REPORT_INIT,
-  REPORT_SUBMIT_REQUEST,
-  REPORT_SUBMIT_SUCCESS,
-  REPORT_SUBMIT_FAIL,
-  REPORT_CANCEL,
-  REPORT_STATUS_TOGGLE,
-  REPORT_COMMENT_CHANGE,
-} from 'themes/glitch/actions/reports';
-import { Map as ImmutableMap, Set as ImmutableSet } from 'immutable';
-
-const initialState = ImmutableMap({
-  new: ImmutableMap({
-    isSubmitting: false,
-    account_id: null,
-    status_ids: ImmutableSet(),
-    comment: '',
-  }),
-});
-
-export default function reports(state = initialState, action) {
-  switch(action.type) {
-  case REPORT_INIT:
-    return state.withMutations(map => {
-      map.setIn(['new', 'isSubmitting'], false);
-      map.setIn(['new', 'account_id'], action.account.get('id'));
-
-      if (state.getIn(['new', 'account_id']) !== action.account.get('id')) {
-        map.setIn(['new', 'status_ids'], action.status ? ImmutableSet([action.status.getIn(['reblog', 'id'], action.status.get('id'))]) : ImmutableSet());
-        map.setIn(['new', 'comment'], '');
-      } else if (action.status) {
-        map.updateIn(['new', 'status_ids'], ImmutableSet(), set => set.add(action.status.getIn(['reblog', 'id'], action.status.get('id'))));
-      }
-    });
-  case REPORT_STATUS_TOGGLE:
-    return state.updateIn(['new', 'status_ids'], ImmutableSet(), set => {
-      if (action.checked) {
-        return set.add(action.statusId);
-      }
-
-      return set.remove(action.statusId);
-    });
-  case REPORT_COMMENT_CHANGE:
-    return state.setIn(['new', 'comment'], action.comment);
-  case REPORT_SUBMIT_REQUEST:
-    return state.setIn(['new', 'isSubmitting'], true);
-  case REPORT_SUBMIT_FAIL:
-    return state.setIn(['new', 'isSubmitting'], false);
-  case REPORT_CANCEL:
-  case REPORT_SUBMIT_SUCCESS:
-    return state.withMutations(map => {
-      map.setIn(['new', 'account_id'], null);
-      map.setIn(['new', 'status_ids'], ImmutableSet());
-      map.setIn(['new', 'comment'], '');
-      map.setIn(['new', 'isSubmitting'], false);
-    });
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/search.js b/app/javascript/themes/glitch/reducers/search.js
deleted file mode 100644
index aec9e2efb..000000000
--- a/app/javascript/themes/glitch/reducers/search.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import {
-  SEARCH_CHANGE,
-  SEARCH_CLEAR,
-  SEARCH_FETCH_SUCCESS,
-  SEARCH_SHOW,
-} from 'themes/glitch/actions/search';
-import { COMPOSE_MENTION, COMPOSE_REPLY } from 'themes/glitch/actions/compose';
-import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
-
-const initialState = ImmutableMap({
-  value: '',
-  submitted: false,
-  hidden: false,
-  results: ImmutableMap(),
-});
-
-export default function search(state = initialState, action) {
-  switch(action.type) {
-  case SEARCH_CHANGE:
-    return state.set('value', action.value);
-  case SEARCH_CLEAR:
-    return state.withMutations(map => {
-      map.set('value', '');
-      map.set('results', ImmutableMap());
-      map.set('submitted', false);
-      map.set('hidden', false);
-    });
-  case SEARCH_SHOW:
-    return state.set('hidden', false);
-  case COMPOSE_REPLY:
-  case COMPOSE_MENTION:
-    return state.set('hidden', true);
-  case SEARCH_FETCH_SUCCESS:
-    return state.set('results', ImmutableMap({
-      accounts: ImmutableList(action.results.accounts.map(item => item.id)),
-      statuses: ImmutableList(action.results.statuses.map(item => item.id)),
-      hashtags: ImmutableList(action.results.hashtags),
-    })).set('submitted', true);
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/settings.js b/app/javascript/themes/glitch/reducers/settings.js
deleted file mode 100644
index c22bbbd8d..000000000
--- a/app/javascript/themes/glitch/reducers/settings.js
+++ /dev/null
@@ -1,119 +0,0 @@
-import { SETTING_CHANGE, SETTING_SAVE } from 'themes/glitch/actions/settings';
-import { COLUMN_ADD, COLUMN_REMOVE, COLUMN_MOVE } from 'themes/glitch/actions/columns';
-import { STORE_HYDRATE } from 'themes/glitch/actions/store';
-import { EMOJI_USE } from 'themes/glitch/actions/emojis';
-import { Map as ImmutableMap, fromJS } from 'immutable';
-import uuid from 'themes/glitch/util/uuid';
-
-const initialState = ImmutableMap({
-  saved: true,
-
-  onboarded: false,
-  layout: 'auto',
-
-  skinTone: 1,
-
-  home: ImmutableMap({
-    shows: ImmutableMap({
-      reblog: true,
-      reply: true,
-    }),
-
-    regex: ImmutableMap({
-      body: '',
-    }),
-  }),
-
-  notifications: ImmutableMap({
-    alerts: ImmutableMap({
-      follow: true,
-      favourite: true,
-      reblog: true,
-      mention: true,
-    }),
-
-    shows: ImmutableMap({
-      follow: true,
-      favourite: true,
-      reblog: true,
-      mention: true,
-    }),
-
-    sounds: ImmutableMap({
-      follow: true,
-      favourite: true,
-      reblog: true,
-      mention: true,
-    }),
-  }),
-
-  community: ImmutableMap({
-    regex: ImmutableMap({
-      body: '',
-    }),
-  }),
-
-  public: ImmutableMap({
-    regex: ImmutableMap({
-      body: '',
-    }),
-  }),
-
-  direct: ImmutableMap({
-    regex: ImmutableMap({
-      body: '',
-    }),
-  }),
-});
-
-const defaultColumns = fromJS([
-  { id: 'COMPOSE', uuid: uuid(), params: {} },
-  { id: 'HOME', uuid: uuid(), params: {} },
-  { id: 'NOTIFICATIONS', uuid: uuid(), params: {} },
-]);
-
-const hydrate = (state, settings) => state.mergeDeep(settings).update('columns', (val = defaultColumns) => val);
-
-const moveColumn = (state, uuid, direction) => {
-  const columns  = state.get('columns');
-  const index    = columns.findIndex(item => item.get('uuid') === uuid);
-  const newIndex = index + direction;
-
-  let newColumns;
-
-  newColumns = columns.splice(index, 1);
-  newColumns = newColumns.splice(newIndex, 0, columns.get(index));
-
-  return state
-    .set('columns', newColumns)
-    .set('saved', false);
-};
-
-const updateFrequentEmojis = (state, emoji) => state.update('frequentlyUsedEmojis', ImmutableMap(), map => map.update(emoji.id, 0, count => count + 1)).set('saved', false);
-
-export default function settings(state = initialState, action) {
-  switch(action.type) {
-  case STORE_HYDRATE:
-    return hydrate(state, action.state.get('settings'));
-  case SETTING_CHANGE:
-    return state
-      .setIn(action.key, action.value)
-      .set('saved', false);
-  case COLUMN_ADD:
-    return state
-      .update('columns', list => list.push(fromJS({ id: action.id, uuid: uuid(), params: action.params })))
-      .set('saved', false);
-  case COLUMN_REMOVE:
-    return state
-      .update('columns', list => list.filterNot(item => item.get('uuid') === action.uuid))
-      .set('saved', false);
-  case COLUMN_MOVE:
-    return moveColumn(state, action.uuid, action.direction);
-  case EMOJI_USE:
-    return updateFrequentEmojis(state, action.emoji);
-  case SETTING_SAVE:
-    return state.set('saved', true);
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/status_lists.js b/app/javascript/themes/glitch/reducers/status_lists.js
deleted file mode 100644
index 8dc7d374e..000000000
--- a/app/javascript/themes/glitch/reducers/status_lists.js
+++ /dev/null
@@ -1,75 +0,0 @@
-import {
-  FAVOURITED_STATUSES_FETCH_SUCCESS,
-  FAVOURITED_STATUSES_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/favourites';
-import {
-  PINNED_STATUSES_FETCH_SUCCESS,
-} from 'themes/glitch/actions/pin_statuses';
-import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
-import {
-  FAVOURITE_SUCCESS,
-  UNFAVOURITE_SUCCESS,
-  PIN_SUCCESS,
-  UNPIN_SUCCESS,
-} from 'themes/glitch/actions/interactions';
-
-const initialState = ImmutableMap({
-  favourites: ImmutableMap({
-    next: null,
-    loaded: false,
-    items: ImmutableList(),
-  }),
-  pins: ImmutableMap({
-    next: null,
-    loaded: false,
-    items: ImmutableList(),
-  }),
-});
-
-const normalizeList = (state, listType, statuses, next) => {
-  return state.update(listType, listMap => listMap.withMutations(map => {
-    map.set('next', next);
-    map.set('loaded', true);
-    map.set('items', ImmutableList(statuses.map(item => item.id)));
-  }));
-};
-
-const appendToList = (state, listType, statuses, next) => {
-  return state.update(listType, listMap => listMap.withMutations(map => {
-    map.set('next', next);
-    map.set('items', map.get('items').concat(statuses.map(item => item.id)));
-  }));
-};
-
-const prependOneToList = (state, listType, status) => {
-  return state.update(listType, listMap => listMap.withMutations(map => {
-    map.set('items', map.get('items').unshift(status.get('id')));
-  }));
-};
-
-const removeOneFromList = (state, listType, status) => {
-  return state.update(listType, listMap => listMap.withMutations(map => {
-    map.set('items', map.get('items').filter(item => item !== status.get('id')));
-  }));
-};
-
-export default function statusLists(state = initialState, action) {
-  switch(action.type) {
-  case FAVOURITED_STATUSES_FETCH_SUCCESS:
-    return normalizeList(state, 'favourites', action.statuses, action.next);
-  case FAVOURITED_STATUSES_EXPAND_SUCCESS:
-    return appendToList(state, 'favourites', action.statuses, action.next);
-  case FAVOURITE_SUCCESS:
-    return prependOneToList(state, 'favourites', action.status);
-  case UNFAVOURITE_SUCCESS:
-    return removeOneFromList(state, 'favourites', action.status);
-  case PINNED_STATUSES_FETCH_SUCCESS:
-    return normalizeList(state, 'pins', action.statuses, action.next);
-  case PIN_SUCCESS:
-    return prependOneToList(state, 'pins', action.status);
-  case UNPIN_SUCCESS:
-    return removeOneFromList(state, 'pins', action.status);
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/statuses.js b/app/javascript/themes/glitch/reducers/statuses.js
deleted file mode 100644
index ef8086865..000000000
--- a/app/javascript/themes/glitch/reducers/statuses.js
+++ /dev/null
@@ -1,148 +0,0 @@
-import {
-  REBLOG_REQUEST,
-  REBLOG_SUCCESS,
-  REBLOG_FAIL,
-  UNREBLOG_SUCCESS,
-  FAVOURITE_REQUEST,
-  FAVOURITE_SUCCESS,
-  FAVOURITE_FAIL,
-  UNFAVOURITE_SUCCESS,
-  PIN_SUCCESS,
-  UNPIN_SUCCESS,
-} from 'themes/glitch/actions/interactions';
-import {
-  STATUS_FETCH_SUCCESS,
-  CONTEXT_FETCH_SUCCESS,
-  STATUS_MUTE_SUCCESS,
-  STATUS_UNMUTE_SUCCESS,
-} from 'themes/glitch/actions/statuses';
-import {
-  TIMELINE_REFRESH_SUCCESS,
-  TIMELINE_UPDATE,
-  TIMELINE_DELETE,
-  TIMELINE_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/timelines';
-import {
-  ACCOUNT_BLOCK_SUCCESS,
-  ACCOUNT_MUTE_SUCCESS,
-} from 'themes/glitch/actions/accounts';
-import {
-  NOTIFICATIONS_UPDATE,
-  NOTIFICATIONS_REFRESH_SUCCESS,
-  NOTIFICATIONS_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/notifications';
-import {
-  FAVOURITED_STATUSES_FETCH_SUCCESS,
-  FAVOURITED_STATUSES_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/favourites';
-import {
-  PINNED_STATUSES_FETCH_SUCCESS,
-} from 'themes/glitch/actions/pin_statuses';
-import { SEARCH_FETCH_SUCCESS } from 'themes/glitch/actions/search';
-import emojify from 'themes/glitch/util/emoji';
-import { Map as ImmutableMap, fromJS } from 'immutable';
-import escapeTextContentForBrowser from 'escape-html';
-
-const domParser = new DOMParser();
-
-const normalizeStatus = (state, status) => {
-  if (!status) {
-    return state;
-  }
-
-  const normalStatus   = { ...status };
-  normalStatus.account = status.account.id;
-
-  if (status.reblog && status.reblog.id) {
-    state               = normalizeStatus(state, status.reblog);
-    normalStatus.reblog = status.reblog.id;
-  }
-
-  const searchContent = [status.spoiler_text, status.content].join('\n\n').replace(/<br \/>/g, '\n').replace(/<\/p><p>/g, '\n\n');
-
-  const emojiMap = normalStatus.emojis.reduce((obj, emoji) => {
-    obj[`:${emoji.shortcode}:`] = emoji;
-    return obj;
-  }, {});
-
-  normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent;
-  normalStatus.contentHtml = emojify(normalStatus.content, emojiMap);
-  normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(normalStatus.spoiler_text || ''), emojiMap);
-
-  return state.update(status.id, ImmutableMap(), map => map.mergeDeep(fromJS(normalStatus)));
-};
-
-const normalizeStatuses = (state, statuses) => {
-  statuses.forEach(status => {
-    state = normalizeStatus(state, status);
-  });
-
-  return state;
-};
-
-const deleteStatus = (state, id, references) => {
-  references.forEach(ref => {
-    state = deleteStatus(state, ref[0], []);
-  });
-
-  return state.delete(id);
-};
-
-const filterStatuses = (state, relationship) => {
-  state.forEach(status => {
-    if (status.get('account') !== relationship.id) {
-      return;
-    }
-
-    state = deleteStatus(state, status.get('id'), state.filter(item => item.get('reblog') === status.get('id')));
-  });
-
-  return state;
-};
-
-const initialState = ImmutableMap();
-
-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:
-  case FAVOURITE_SUCCESS:
-  case UNFAVOURITE_SUCCESS:
-  case PIN_SUCCESS:
-  case UNPIN_SUCCESS:
-    return normalizeStatus(state, action.response);
-  case FAVOURITE_REQUEST:
-    return state.setIn([action.status.get('id'), 'favourited'], true);
-  case FAVOURITE_FAIL:
-    return state.setIn([action.status.get('id'), 'favourited'], false);
-  case REBLOG_REQUEST:
-    return state.setIn([action.status.get('id'), 'reblogged'], true);
-  case REBLOG_FAIL:
-    return state.setIn([action.status.get('id'), 'reblogged'], false);
-  case STATUS_MUTE_SUCCESS:
-    return state.setIn([action.id, 'muted'], true);
-  case STATUS_UNMUTE_SUCCESS:
-    return state.setIn([action.id, 'muted'], false);
-  case TIMELINE_REFRESH_SUCCESS:
-  case TIMELINE_EXPAND_SUCCESS:
-  case CONTEXT_FETCH_SUCCESS:
-  case NOTIFICATIONS_REFRESH_SUCCESS:
-  case NOTIFICATIONS_EXPAND_SUCCESS:
-  case FAVOURITED_STATUSES_FETCH_SUCCESS:
-  case FAVOURITED_STATUSES_EXPAND_SUCCESS:
-  case PINNED_STATUSES_FETCH_SUCCESS:
-  case SEARCH_FETCH_SUCCESS:
-    return normalizeStatuses(state, action.statuses);
-  case TIMELINE_DELETE:
-    return deleteStatus(state, action.id, action.references);
-  case ACCOUNT_BLOCK_SUCCESS:
-  case ACCOUNT_MUTE_SUCCESS:
-    return filterStatuses(state, action.relationship);
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/timelines.js b/app/javascript/themes/glitch/reducers/timelines.js
deleted file mode 100644
index 7f19a1897..000000000
--- a/app/javascript/themes/glitch/reducers/timelines.js
+++ /dev/null
@@ -1,149 +0,0 @@
-import {
-  TIMELINE_REFRESH_REQUEST,
-  TIMELINE_REFRESH_SUCCESS,
-  TIMELINE_REFRESH_FAIL,
-  TIMELINE_UPDATE,
-  TIMELINE_DELETE,
-  TIMELINE_EXPAND_SUCCESS,
-  TIMELINE_EXPAND_REQUEST,
-  TIMELINE_EXPAND_FAIL,
-  TIMELINE_SCROLL_TOP,
-  TIMELINE_CONNECT,
-  TIMELINE_DISCONNECT,
-} from 'themes/glitch/actions/timelines';
-import {
-  ACCOUNT_BLOCK_SUCCESS,
-  ACCOUNT_MUTE_SUCCESS,
-  ACCOUNT_UNFOLLOW_SUCCESS,
-} from 'themes/glitch/actions/accounts';
-import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
-
-const initialState = ImmutableMap();
-
-const initialTimeline = ImmutableMap({
-  unread: 0,
-  online: false,
-  top: true,
-  loaded: false,
-  isLoading: false,
-  next: false,
-  items: ImmutableList(),
-});
-
-const normalizeTimeline = (state, timeline, statuses, next) => {
-  const oldIds    = state.getIn([timeline, 'items'], ImmutableList());
-  const ids       = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
-  const wasLoaded = state.getIn([timeline, 'loaded']);
-  const hadNext   = state.getIn([timeline, 'next']);
-
-  return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
-    mMap.set('loaded', true);
-    mMap.set('isLoading', false);
-    if (!hadNext) mMap.set('next', next);
-    mMap.set('items', wasLoaded ? ids.concat(oldIds) : ids);
-  }));
-};
-
-const appendNormalizedTimeline = (state, timeline, statuses, next) => {
-  const oldIds = state.getIn([timeline, 'items'], ImmutableList());
-  const ids    = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
-
-  return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
-    mMap.set('isLoading', false);
-    mMap.set('next', next);
-    mMap.set('items', oldIds.concat(ids));
-  }));
-};
-
-const updateTimeline = (state, timeline, status, references) => {
-  const top        = state.getIn([timeline, 'top']);
-  const ids        = state.getIn([timeline, 'items'], ImmutableList());
-  const includesId = ids.includes(status.get('id'));
-  const unread     = state.getIn([timeline, 'unread'], 0);
-
-  if (includesId) {
-    return state;
-  }
-
-  let newIds = ids;
-
-  return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
-    if (!top) mMap.set('unread', unread + 1);
-    if (top && ids.size > 40) newIds = newIds.take(20);
-    if (status.getIn(['reblog', 'id'], null) !== null) newIds = newIds.filterNot(item => references.includes(item));
-    mMap.set('items', newIds.unshift(status.get('id')));
-  }));
-};
-
-const deleteStatus = (state, id, accountId, references) => {
-  state.keySeq().forEach(timeline => {
-    state = state.updateIn([timeline, 'items'], list => list.filterNot(item => item === id));
-  });
-
-  // Remove reblogs of deleted status
-  references.forEach(ref => {
-    state = deleteStatus(state, ref[0], ref[1], []);
-  });
-
-  return state;
-};
-
-const filterTimelines = (state, relationship, statuses) => {
-  let references;
-
-  statuses.forEach(status => {
-    if (status.get('account') !== relationship.id) {
-      return;
-    }
-
-    references = statuses.filter(item => item.get('reblog') === status.get('id')).map(item => [item.get('id'), item.get('account')]);
-    state      = deleteStatus(state, status.get('id'), status.get('account'), references);
-  });
-
-  return state;
-};
-
-const filterTimeline = (timeline, state, relationship, statuses) =>
-  state.updateIn([timeline, 'items'], ImmutableList(), list =>
-    list.filterNot(statusId =>
-      statuses.getIn([statusId, 'account']) === relationship.id
-    ));
-
-const updateTop = (state, timeline, top) => {
-  return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
-    if (top) mMap.set('unread', 0);
-    mMap.set('top', top);
-  }));
-};
-
-export default function timelines(state = initialState, action) {
-  switch(action.type) {
-  case TIMELINE_REFRESH_REQUEST:
-  case TIMELINE_EXPAND_REQUEST:
-    return state.update(action.timeline, initialTimeline, map => map.set('isLoading', true));
-  case TIMELINE_REFRESH_FAIL:
-  case TIMELINE_EXPAND_FAIL:
-    return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
-  case TIMELINE_REFRESH_SUCCESS:
-    return normalizeTimeline(state, action.timeline, fromJS(action.statuses), action.next);
-  case TIMELINE_EXPAND_SUCCESS:
-    return appendNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next);
-  case TIMELINE_UPDATE:
-    return updateTimeline(state, action.timeline, fromJS(action.status), action.references);
-  case TIMELINE_DELETE:
-    return deleteStatus(state, action.id, action.accountId, action.references, action.reblogOf);
-  case ACCOUNT_BLOCK_SUCCESS:
-  case ACCOUNT_MUTE_SUCCESS:
-    return filterTimelines(state, action.relationship, action.statuses);
-  case ACCOUNT_UNFOLLOW_SUCCESS:
-    return filterTimeline('home', state, action.relationship, action.statuses);
-  case TIMELINE_SCROLL_TOP:
-    return updateTop(state, action.timeline, action.top);
-  case TIMELINE_CONNECT:
-    return state.update(action.timeline, initialTimeline, map => map.set('online', true));
-  case TIMELINE_DISCONNECT:
-    return state.update(action.timeline, initialTimeline, map => map.set('online', false));
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/themes/glitch/reducers/user_lists.js b/app/javascript/themes/glitch/reducers/user_lists.js
deleted file mode 100644
index 8c3a7d748..000000000
--- a/app/javascript/themes/glitch/reducers/user_lists.js
+++ /dev/null
@@ -1,80 +0,0 @@
-import {
-  FOLLOWERS_FETCH_SUCCESS,
-  FOLLOWERS_EXPAND_SUCCESS,
-  FOLLOWING_FETCH_SUCCESS,
-  FOLLOWING_EXPAND_SUCCESS,
-  FOLLOW_REQUESTS_FETCH_SUCCESS,
-  FOLLOW_REQUESTS_EXPAND_SUCCESS,
-  FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
-  FOLLOW_REQUEST_REJECT_SUCCESS,
-} from 'themes/glitch/actions/accounts';
-import {
-  REBLOGS_FETCH_SUCCESS,
-  FAVOURITES_FETCH_SUCCESS,
-} from 'themes/glitch/actions/interactions';
-import {
-  BLOCKS_FETCH_SUCCESS,
-  BLOCKS_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/blocks';
-import {
-  MUTES_FETCH_SUCCESS,
-  MUTES_EXPAND_SUCCESS,
-} from 'themes/glitch/actions/mutes';
-import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
-
-const initialState = ImmutableMap({
-  followers: ImmutableMap(),
-  following: ImmutableMap(),
-  reblogged_by: ImmutableMap(),
-  favourited_by: ImmutableMap(),
-  follow_requests: ImmutableMap(),
-  blocks: ImmutableMap(),
-  mutes: ImmutableMap(),
-});
-
-const normalizeList = (state, type, id, accounts, next) => {
-  return state.setIn([type, id], ImmutableMap({
-    next,
-    items: ImmutableList(accounts.map(item => item.id)),
-  }));
-};
-
-const appendToList = (state, type, id, accounts, next) => {
-  return state.updateIn([type, id], map => {
-    return map.set('next', next).update('items', list => list.concat(accounts.map(item => item.id)));
-  });
-};
-
-export default function userLists(state = initialState, action) {
-  switch(action.type) {
-  case FOLLOWERS_FETCH_SUCCESS:
-    return normalizeList(state, 'followers', action.id, action.accounts, action.next);
-  case FOLLOWERS_EXPAND_SUCCESS:
-    return appendToList(state, 'followers', action.id, action.accounts, action.next);
-  case FOLLOWING_FETCH_SUCCESS:
-    return normalizeList(state, 'following', action.id, action.accounts, action.next);
-  case FOLLOWING_EXPAND_SUCCESS:
-    return appendToList(state, 'following', action.id, action.accounts, action.next);
-  case REBLOGS_FETCH_SUCCESS:
-    return state.setIn(['reblogged_by', action.id], ImmutableList(action.accounts.map(item => item.id)));
-  case FAVOURITES_FETCH_SUCCESS:
-    return state.setIn(['favourited_by', action.id], ImmutableList(action.accounts.map(item => item.id)));
-  case FOLLOW_REQUESTS_FETCH_SUCCESS:
-    return state.setIn(['follow_requests', 'items'], ImmutableList(action.accounts.map(item => item.id))).setIn(['follow_requests', 'next'], action.next);
-  case FOLLOW_REQUESTS_EXPAND_SUCCESS:
-    return state.updateIn(['follow_requests', 'items'], list => list.concat(action.accounts.map(item => item.id))).setIn(['follow_requests', 'next'], action.next);
-  case FOLLOW_REQUEST_AUTHORIZE_SUCCESS:
-  case FOLLOW_REQUEST_REJECT_SUCCESS:
-    return state.updateIn(['follow_requests', 'items'], list => list.filterNot(item => item === action.id));
-  case BLOCKS_FETCH_SUCCESS:
-    return state.setIn(['blocks', 'items'], ImmutableList(action.accounts.map(item => item.id))).setIn(['blocks', 'next'], action.next);
-  case BLOCKS_EXPAND_SUCCESS:
-    return state.updateIn(['blocks', 'items'], list => list.concat(action.accounts.map(item => item.id))).setIn(['blocks', 'next'], action.next);
-  case MUTES_FETCH_SUCCESS:
-    return state.setIn(['mutes', 'items'], ImmutableList(action.accounts.map(item => item.id))).setIn(['mutes', 'next'], action.next);
-  case MUTES_EXPAND_SUCCESS:
-    return state.updateIn(['mutes', 'items'], list => list.concat(action.accounts.map(item => item.id))).setIn(['mutes', 'next'], action.next);
-  default:
-    return state;
-  }
-};