commit: 37c832cdf7a307511b27e64174ed1a3e160ec66e
parent: f68fa930ea448f5e94057160cfdcc78fec4aba11
Author: Sorin Davidoi <sorin.davidoi@gmail.com>
Date: Sun, 9 Jul 2017 12:16:08 +0200
refactor: Make all reducers sync (#4125)
Diffstat:
8 files changed, 18 insertions(+), 90 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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'