about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSorin Davidoi <sorin.davidoi@gmail.com>2017-07-09 12:16:08 +0200
committerEugen Rochko <eugen@zeonfederated.com>2017-07-09 12:16:08 +0200
commit37c832cdf7a307511b27e64174ed1a3e160ec66e (patch)
treed06be7f23f6634286ffd7adf4fcddd3cbd6c3384
parentf68fa930ea448f5e94057160cfdcc78fec4aba11 (diff)
refactor: Make all reducers sync (#4125)
-rw-r--r--app/javascript/mastodon/actions/store.js7
-rw-r--r--app/javascript/mastodon/containers/mastodon.js3
-rw-r--r--app/javascript/mastodon/features/ui/util/async-components.js41
-rw-r--r--app/javascript/mastodon/reducers/compose.js4
-rw-r--r--app/javascript/mastodon/reducers/index.js15
-rw-r--r--app/javascript/mastodon/reducers/media_attachments.js4
-rw-r--r--app/javascript/mastodon/store/configureStore.js25
-rwxr-xr-xapp/views/layouts/application.html.haml9
8 files changed, 18 insertions, 90 deletions
diff --git a/app/javascript/mastodon/actions/store.js b/app/javascript/mastodon/actions/store.js
index 08c2810ca..efdb0771a 100644
--- a/app/javascript/mastodon/actions/store.js
+++ b/app/javascript/mastodon/actions/store.js
@@ -16,10 +16,3 @@ export function hydrateStore(rawState) {
     state,
   };
 };
-
-export function hydrateStoreLazy(name, state) {
-  return {
-    type: `${STORE_HYDRATE_LAZY}-${name}`,
-    state,
-  };
-};
diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.js
index 6e79f9e4f..87ab6023c 100644
--- a/app/javascript/mastodon/containers/mastodon.js
+++ b/app/javascript/mastodon/containers/mastodon.js
@@ -23,8 +23,7 @@ const { localeData, messages } = getLocale();
 addLocaleData(localeData);
 
 export const store = configureStore();
-const initialState = JSON.parse(document.getElementById('initial-state').textContent);
-export const hydrateAction = hydrateStore(initialState);
+const hydrateAction = hydrateStore(JSON.parse(document.getElementById('initial-state').textContent));
 store.dispatch(hydrateAction);
 
 export default class Mastodon extends React.PureComponent {
diff --git a/app/javascript/mastodon/features/ui/util/async-components.js b/app/javascript/mastodon/features/ui/util/async-components.js
index 56880dd1f..55de114b5 100644
--- a/app/javascript/mastodon/features/ui/util/async-components.js
+++ b/app/javascript/mastodon/features/ui/util/async-components.js
@@ -1,40 +1,13 @@
-import { store } from '../../../containers/mastodon';
-import { refreshNotifications } from '../../../actions/notifications';
-import { injectAsyncReducer } from '../../../store/configureStore';
-
-// NOTE: When lazy-loading reducers, make sure to add them
-// to application.html.haml (if the component is preloaded there)
-
 export function EmojiPicker () {
   return import(/* webpackChunkName: "emojione_picker" */'emojione-picker');
 }
 
 export function Compose () {
-  return Promise.all([
-    import(/* webpackChunkName: "features/compose" */'../../compose'),
-    import(/* webpackChunkName: "reducers/compose" */'../../../reducers/compose'),
-    import(/* webpackChunkName: "reducers/media_attachments" */'../../../reducers/media_attachments'),
-    import(/* webpackChunkName: "reducers/search" */'../../../reducers/search'),
-  ]).then(([component, composeReducer, mediaAttachmentsReducer, searchReducer]) => {
-    injectAsyncReducer(store, 'compose', composeReducer.default);
-    injectAsyncReducer(store, 'media_attachments', mediaAttachmentsReducer.default);
-    injectAsyncReducer(store, 'search', searchReducer.default);
-
-    return component;
-  });
+  return import(/* webpackChunkName: "features/compose" */'../../compose');
 }
 
 export function Notifications () {
-  return Promise.all([
-    import(/* webpackChunkName: "features/notifications" */'../../notifications'),
-    import(/* webpackChunkName: "reducers/notifications" */'../../../reducers/notifications'),
-  ]).then(([component, notificationsReducer]) => {
-    injectAsyncReducer(store, 'notifications', notificationsReducer.default);
-
-    store.dispatch(refreshNotifications());
-
-    return component;
-  });
+  return import(/* webpackChunkName: "features/notifications" */'../../notifications');
 }
 
 export function HomeTimeline () {
@@ -110,15 +83,7 @@ export function MediaModal () {
 }
 
 export function OnboardingModal () {
-  return Promise.all([
-    import(/* webpackChunkName: "modals/onboarding_modal" */'../components/onboarding_modal'),
-    import(/* webpackChunkName: "reducers/compose" */'../../../reducers/compose'),
-    import(/* webpackChunkName: "reducers/media_attachments" */'../../../reducers/media_attachments'),
-  ]).then(([component, composeReducer, mediaAttachmentsReducer]) => {
-    injectAsyncReducer(store, 'compose', composeReducer.default);
-    injectAsyncReducer(store, 'media_attachments', mediaAttachmentsReducer.default);
-    return component;
-  });
+  return import(/* webpackChunkName: "modals/onboarding_modal" */'../components/onboarding_modal');
 }
 
 export function VideoModal () {
diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js
index 09db95e2d..d0b47a85c 100644
--- a/app/javascript/mastodon/reducers/compose.js
+++ b/app/javascript/mastodon/reducers/compose.js
@@ -23,7 +23,7 @@ import {
   COMPOSE_EMOJI_INSERT,
 } from '../actions/compose';
 import { TIMELINE_DELETE } from '../actions/timelines';
-import { STORE_HYDRATE_LAZY } from '../actions/store';
+import { STORE_HYDRATE } from '../actions/store';
 import Immutable from 'immutable';
 import uuid from '../uuid';
 
@@ -134,7 +134,7 @@ const privacyPreference = (a, b) => {
 
 export default function compose(state = initialState, action) {
   switch(action.type) {
-  case `${STORE_HYDRATE_LAZY}-compose`:
+  case STORE_HYDRATE:
     return clearAll(state.merge(action.state.get('compose')));
   case COMPOSE_MOUNT:
     return state.set('mounted', true);
diff --git a/app/javascript/mastodon/reducers/index.js b/app/javascript/mastodon/reducers/index.js
index 79062f2f9..919345f16 100644
--- a/app/javascript/mastodon/reducers/index.js
+++ b/app/javascript/mastodon/reducers/index.js
@@ -14,6 +14,10 @@ import status_lists from './status_lists';
 import cards from './cards';
 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';
 
 const reducers = {
   timelines,
@@ -31,13 +35,10 @@ const reducers = {
   cards,
   reports,
   contexts,
+  compose,
+  search,
+  media_attachments,
+  notifications,
 };
 
-export function createReducer(asyncReducers) {
-  return combineReducers({
-    ...reducers,
-    ...asyncReducers,
-  });
-}
-
 export default combineReducers(reducers);
diff --git a/app/javascript/mastodon/reducers/media_attachments.js b/app/javascript/mastodon/reducers/media_attachments.js
index d17d465aa..85bea4f0b 100644
--- a/app/javascript/mastodon/reducers/media_attachments.js
+++ b/app/javascript/mastodon/reducers/media_attachments.js
@@ -1,4 +1,4 @@
-import { STORE_HYDRATE_LAZY } from '../actions/store';
+import { STORE_HYDRATE } from '../actions/store';
 import Immutable from 'immutable';
 
 const initialState = Immutable.Map({
@@ -7,7 +7,7 @@ const initialState = Immutable.Map({
 
 export default function meta(state = initialState, action) {
   switch(action.type) {
-  case `${STORE_HYDRATE_LAZY}-media_attachments`:
+  case STORE_HYDRATE:
     return state.merge(action.state.get('media_attachments'));
   default:
     return state;
diff --git a/app/javascript/mastodon/store/configureStore.js b/app/javascript/mastodon/store/configureStore.js
index 0fe29f031..1376d4cba 100644
--- a/app/javascript/mastodon/store/configureStore.js
+++ b/app/javascript/mastodon/store/configureStore.js
@@ -1,36 +1,15 @@
 import { createStore, applyMiddleware, compose } from 'redux';
 import thunk from 'redux-thunk';
-import appReducer, { createReducer } from '../reducers';
-import { hydrateStoreLazy } from '../actions/store';
-import { hydrateAction } from '../containers/mastodon';
+import appReducer from '../reducers';
 import loadingBarMiddleware from '../middleware/loading_bar';
 import errorsMiddleware from '../middleware/errors';
 import soundsMiddleware from '../middleware/sounds';
 
 export default function configureStore() {
-  const store = createStore(appReducer, compose(applyMiddleware(
+  return createStore(appReducer, compose(applyMiddleware(
     thunk,
     loadingBarMiddleware({ promiseTypeSuffixes: ['REQUEST', 'SUCCESS', 'FAIL'] }),
     errorsMiddleware(),
     soundsMiddleware()
   ), window.devToolsExtension ? window.devToolsExtension() : f => f));
-
-  store.asyncReducers = { };
-
-  return store;
 };
-
-export function injectAsyncReducer(store, name, asyncReducer) {
-  if (!store.asyncReducers[name]) {
-    // Keep track that we injected this reducer
-    store.asyncReducers[name] = asyncReducer;
-
-    // Add the current reducer to the store
-    store.replaceReducer(createReducer(store.asyncReducers));
-
-    // The state this reducer handles defaults to its initial state (stored inside the reducer)
-    // But that state may be out of date because of the server-side hydration, so we replay
-    // the hydration action but only for this reducer (all async reducers must listen for this dynamic action)
-    store.dispatch(hydrateStoreLazy(name, hydrateAction.state));
-  }
-}
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 68d346859..580d8fb4d 100755
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -22,19 +22,10 @@
     = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous'
 
     = javascript_pack_tag 'features/getting_started', integrity: true, crossorigin: 'anonymous', rel: 'preload', as: 'script'
-
     = javascript_pack_tag 'features/compose', integrity: true, crossorigin: 'anonymous', rel: 'preload', as: 'script'
-    = javascript_pack_tag 'reducers/compose', integrity: true, crossorigin: 'anonymous', rel: 'preload', as: 'script'
-    = javascript_pack_tag 'reducers/media_attachments', integrity: true, crossorigin: 'anonymous', rel: 'preload', as: 'script'
-    = javascript_pack_tag 'reducers/search', integrity: true, crossorigin: 'anonymous', rel: 'preload', as: 'script'
-
     = javascript_pack_tag 'features/home_timeline', integrity: true, crossorigin: 'anonymous', rel: 'preload', as: 'script'
-
     = javascript_pack_tag 'features/notifications', integrity: true, crossorigin: 'anonymous', rel: 'preload', as: 'script'
-    = javascript_pack_tag 'reducers/notifications', integrity: true, crossorigin: 'anonymous', rel: 'preload', as: 'script'
-
     = javascript_pack_tag 'features/community_timeline', integrity: true, crossorigin: 'anonymous', rel: 'preload', as: 'script'
-
     = javascript_pack_tag 'features/public_timeline', integrity: true, crossorigin: 'anonymous', rel: 'preload', as: 'script'
 
     = javascript_pack_tag "locale_#{I18n.locale}", integrity: true, crossorigin: 'anonymous'