diff --git a/app/soapbox/actions/compose.js b/app/soapbox/actions/compose.js index 8c947655a..f4a644e87 100644 --- a/app/soapbox/actions/compose.js +++ b/app/soapbox/actions/compose.js @@ -440,17 +440,6 @@ export function updateTagHistory(tags) { }; } -export function hydrateCompose() { - return (dispatch, getState) => { - const me = getState().get('me'); - const history = tagHistory.get(me); - - if (history !== null) { - dispatch(updateTagHistory(history)); - } - }; -} - function insertIntoTagHistory(recognizedTags, text) { return (dispatch, getState) => { const state = getState(); diff --git a/app/soapbox/actions/settings.js b/app/soapbox/actions/settings.js index 097265814..205250c3b 100644 --- a/app/soapbox/actions/settings.js +++ b/app/soapbox/actions/settings.js @@ -2,6 +2,7 @@ import { debounce } from 'lodash'; import { showAlertForError } from './alerts'; import { patchMe } from 'soapbox/actions/me'; import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; +import uuid from '../uuid'; export const SETTING_CHANGE = 'SETTING_CHANGE'; export const SETTING_SAVE = 'SETTING_SAVE'; @@ -114,6 +115,12 @@ const defaultSettings = ImmutableMap({ trends: ImmutableMap({ show: true, }), + + columns: ImmutableList([ + ImmutableMap({ id: 'COMPOSE', uuid: uuid(), params: {} }), + ImmutableMap({ id: 'HOME', uuid: uuid(), params: {} }), + ImmutableMap({ id: 'NOTIFICATIONS', uuid: uuid(), params: {} }), + ]), }); export function getSettings(state) { diff --git a/app/soapbox/actions/store.js b/app/soapbox/actions/store.js deleted file mode 100644 index 87e495b99..000000000 --- a/app/soapbox/actions/store.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Iterable, fromJS } from 'immutable'; -import { hydrateCompose } from './compose'; - -export const STORE_HYDRATE = 'STORE_HYDRATE'; -export const STORE_HYDRATE_LAZY = 'STORE_HYDRATE_LAZY'; - -const convertState = rawState => - fromJS(rawState, (k, v) => - Iterable.isIndexed(v) ? v.toList() : v.toMap()); - -export function hydrateStore(rawState) { - return dispatch => { - const state = convertState(rawState); - - dispatch({ - type: STORE_HYDRATE, - state, - }); - - dispatch(hydrateCompose()); - // dispatch(importFetchedAccounts(Object.values(rawState.accounts))); - }; -}; diff --git a/app/soapbox/containers/soapbox.js b/app/soapbox/containers/soapbox.js index ed4549d27..138d12701 100644 --- a/app/soapbox/containers/soapbox.js +++ b/app/soapbox/containers/soapbox.js @@ -14,8 +14,6 @@ import { ScrollContext } from 'react-router-scroll-4'; import UI from '../features/ui'; // import Introduction from '../features/introduction'; import { fetchCustomEmojis } from '../actions/custom_emojis'; -import { hydrateStore } from '../actions/store'; -import initialState from '../initial_state'; import { preload } from '../actions/preload'; import { IntlProvider } from 'react-intl'; import ErrorBoundary from '../components/error_boundary'; @@ -32,9 +30,6 @@ const validLocale = locale => Object.keys(messages).includes(locale); export const store = configureStore(); -const hydrateAction = hydrateStore(initialState); - -store.dispatch(hydrateAction); store.dispatch(preload()); store.dispatch(fetchMe()); store.dispatch(fetchInstance()); diff --git a/app/soapbox/initial_state.js b/app/soapbox/initial_state.js deleted file mode 100644 index dd47e4e8b..000000000 --- a/app/soapbox/initial_state.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; - -const element = document.getElementById('initial-state'); -const initialState = element ? JSON.parse(element.textContent) : {}; - -export default initialState; diff --git a/app/soapbox/reducers/__tests__/compose-test.js b/app/soapbox/reducers/__tests__/compose-test.js index 230036fe8..d8122bab2 100644 --- a/app/soapbox/reducers/__tests__/compose-test.js +++ b/app/soapbox/reducers/__tests__/compose-test.js @@ -3,18 +3,18 @@ import { Map as ImmutableMap } from 'immutable'; import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS } from 'soapbox/actions/me'; import { SETTING_CHANGE } from 'soapbox/actions/settings'; import * as actions from 'soapbox/actions/compose'; -//import { STORE_HYDRATE } from 'soapbox/actions/store'; //import { REDRAFT } from 'soapbox/actions/statuses'; import { TIMELINE_DELETE } from 'soapbox/actions/timelines'; describe('compose reducer', () => { it('returns the initial state by default', () => { - expect(reducer(undefined, {}).toJS()).toMatchObject({ + const state = reducer(undefined, {}); + expect(state.toJS()).toMatchObject({ mounted: 0, sensitive: false, spoiler: false, spoiler_text: '', - privacy: null, + privacy: 'public', text: '', focusDate: null, caretPosition: null, @@ -30,10 +30,10 @@ describe('compose reducer', () => { suggestions: [], default_privacy: 'public', default_sensitive: false, - idempotencyKey: null, tagHistory: [], content_type: 'text/markdown', }); + expect(state.get('idempotencyKey').length === 36); }); it('uses \'public\' scope as default', () => { @@ -132,23 +132,6 @@ describe('compose reducer', () => { }); }); - // it('should handle STORE_HYDRATE', () => { - // const state = ImmutableMap({ }); - // const action = { - // type: STORE_HYDRATE, - // state: ImmutableMap({ - // compose: true, - // text: 'newtext', - // }), - // }; - // expect(reducer(state, action)).toEqual(ImmutableMap({ - // state: ImmutableMap({ - // compose: true, - // text: 'newtext', - // }), - // })); - // }); - it('should handle COMPOSE_MOUNT', () => { const state = ImmutableMap({ mounted: 1 }); const action = { diff --git a/app/soapbox/reducers/compose.js b/app/soapbox/reducers/compose.js index ad5ea9b64..1e0b6d614 100644 --- a/app/soapbox/reducers/compose.js +++ b/app/soapbox/reducers/compose.js @@ -38,7 +38,6 @@ import { COMPOSE_POLL_SETTINGS_CHANGE, } from '../actions/compose'; import { TIMELINE_DELETE } from '../actions/timelines'; -import { STORE_HYDRATE } from '../actions/store'; import { REDRAFT } from '../actions/statuses'; import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS } from '../actions/me'; import { SETTING_CHANGE, FE_NAME } from '../actions/settings'; @@ -47,12 +46,13 @@ import uuid from '../uuid'; import { unescapeHTML } from '../utils/html'; const initialState = ImmutableMap({ + id: null, mounted: 0, sensitive: false, spoiler: false, spoiler_text: '', content_type: 'text/markdown', - privacy: null, + privacy: 'public', text: '', focusDate: null, caretPosition: null, @@ -69,7 +69,7 @@ const initialState = ImmutableMap({ default_privacy: 'public', default_sensitive: false, resetFileKey: Math.floor((Math.random() * 0x10000)), - idempotencyKey: null, + idempotencyKey: uuid(), tagHistory: ImmutableList(), }); @@ -178,16 +178,6 @@ const privacyPreference = (a, b) => { return order[Math.max(order.indexOf(a), order.indexOf(b), 0)]; }; -const hydrate = (state, hydratedState = ImmutableMap()) => { - state = clearAll(state.merge(hydratedState)); - - if (hydratedState.has('text')) { - state = state.set('text', hydratedState.get('text')); - } - - return state; -}; - const domParser = new DOMParser(); const expandMentions = status => { @@ -204,8 +194,6 @@ const expandMentions = status => { export default function compose(state = initialState, action) { let me, defaultPrivacy; switch(action.type) { - case STORE_HYDRATE: - return hydrate(state, action.state.get('compose')); case COMPOSE_MOUNT: return state.set('mounted', state.get('mounted') + 1); case COMPOSE_UNMOUNT: diff --git a/app/soapbox/reducers/index.js b/app/soapbox/reducers/index.js index 6f4abdafe..5ec2b581c 100644 --- a/app/soapbox/reducers/index.js +++ b/app/soapbox/reducers/index.js @@ -1,4 +1,6 @@ import { combineReducers } from 'redux-immutable'; +import { Map as ImmutableMap } from 'immutable'; +import { AUTH_LOGGED_OUT } from 'soapbox/actions/auth'; import dropdown_menu from './dropdown_menu'; import timelines from './timelines'; import meta from './meta'; @@ -48,7 +50,7 @@ import chat_messages from './chat_messages'; import chat_message_lists from './chat_message_lists'; import profile_hover_card from './profile_hover_card'; -const reducers = { +const appReducer = combineReducers({ dropdown_menu, timelines, meta, @@ -97,6 +99,27 @@ const reducers = { chat_messages, chat_message_lists, profile_hover_card, +}); + +// Clear the state (mostly) when the user logs out +const logOut = (state = ImmutableMap()) => { + const whitelist = ['instance', 'soapbox', 'custom_emojis']; + + return ImmutableMap( + whitelist.reduce((acc, curr) => { + acc[curr] = state.get(curr); + return acc; + }, {}) + ); }; -export default combineReducers(reducers); +const rootReducer = (state, action) => { + switch(action.type) { + case AUTH_LOGGED_OUT: + return appReducer(logOut(state), action); + default: + return appReducer(state, action); + } +}; + +export default rootReducer; diff --git a/app/soapbox/reducers/media_attachments.js b/app/soapbox/reducers/media_attachments.js index 1f7fe8cff..7e67805dd 100644 --- a/app/soapbox/reducers/media_attachments.js +++ b/app/soapbox/reducers/media_attachments.js @@ -1,4 +1,3 @@ -import { STORE_HYDRATE } from '../actions/store'; import { Map as ImmutableMap, List as ImmutableList, @@ -35,8 +34,6 @@ const initialState = ImmutableMap({ 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/soapbox/reducers/meta.js b/app/soapbox/reducers/meta.js index 6bd397c2c..c3f5062df 100644 --- a/app/soapbox/reducers/meta.js +++ b/app/soapbox/reducers/meta.js @@ -1,6 +1,5 @@ 'use strict'; -import { STORE_HYDRATE } from '../actions/store'; import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS } from 'soapbox/actions/me'; import { Map as ImmutableMap, fromJS } from 'immutable'; @@ -8,8 +7,6 @@ const initialState = ImmutableMap(); export default function meta(state = initialState, action) { switch(action.type) { - case STORE_HYDRATE: - return state.merge(action.state.get('meta')); case ME_FETCH_SUCCESS: case ME_PATCH_SUCCESS: const me = fromJS(action.me); diff --git a/app/soapbox/reducers/push_notifications.js b/app/soapbox/reducers/push_notifications.js index 317352b79..6b9001684 100644 --- a/app/soapbox/reducers/push_notifications.js +++ b/app/soapbox/reducers/push_notifications.js @@ -1,4 +1,3 @@ -import { STORE_HYDRATE } from '../actions/store'; import { SET_BROWSER_SUPPORT, SET_SUBSCRIPTION, CLEAR_SUBSCRIPTION, SET_ALERTS } from '../actions/push_notifications'; import Immutable from 'immutable'; @@ -17,21 +16,6 @@ const initialState = Immutable.Map({ 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({ diff --git a/app/soapbox/reducers/settings.js b/app/soapbox/reducers/settings.js index 1066716d7..be4f6b88d 100644 --- a/app/soapbox/reducers/settings.js +++ b/app/soapbox/reducers/settings.js @@ -1,11 +1,9 @@ import { SETTING_CHANGE, SETTING_SAVE, FE_NAME } from '../actions/settings'; import { NOTIFICATIONS_FILTER_SET } from '../actions/notifications'; -import { STORE_HYDRATE } from '../actions/store'; import { EMOJI_USE } from '../actions/emojis'; import { LIST_DELETE_SUCCESS, LIST_FETCH_FAIL } from '../actions/lists'; import { ME_FETCH_SUCCESS } from 'soapbox/actions/me'; import { Map as ImmutableMap, fromJS } from 'immutable'; -import uuid from '../uuid'; // Default settings are in action/settings.js // @@ -15,22 +13,12 @@ const initialState = ImmutableMap({ saved: true, }); -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 updateFrequentEmojis = (state, emoji) => state.update('frequentlyUsedEmojis', ImmutableMap(), map => map.update(emoji.id, 0, count => count + 1)).set('saved', false); const filterDeadListColumns = (state, listId) => state.update('columns', columns => columns.filterNot(column => column.get('id') === 'LIST' && column.get('params').get('id') === listId)); export default function settings(state = initialState, action) { switch(action.type) { - case STORE_HYDRATE: - return hydrate(state, action.state.get('settings')); case ME_FETCH_SUCCESS: const me = fromJS(action.me); let fePrefs = me.getIn(['pleroma', 'settings_store', FE_NAME], ImmutableMap());