Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
Migrate BrowserStore to redux (#241)
Browse files Browse the repository at this point in the history
  • Loading branch information
jespino authored and jwilander committed Nov 7, 2017
1 parent 94632b0 commit 399de2b
Show file tree
Hide file tree
Showing 15 changed files with 616 additions and 116 deletions.
2 changes: 1 addition & 1 deletion actions/global_actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ export function emitUserLoggedOutEvent(redirectTo = '/', shouldSignalLogout = tr
}

export function clientLogout(redirectTo = '/') {
BrowserStore.clear();
BrowserStore.clear({exclude: [Constants.RECENT_EMOJI_KEY, '__landingPageSeen__', 'selected_teams']});
ErrorStore.clearLastError();
ChannelStore.clear();
stopPeriodicStatusUpdates();
Expand Down
81 changes: 81 additions & 0 deletions actions/storage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import {StorageTypes} from 'utils/constants';
import {getPrefix} from 'utils/storage_utils';

export function setItem(name, value) {
return async (dispatch, getState) => {
const state = getState();
const prefix = getPrefix(state);
dispatch({
type: StorageTypes.SET_ITEM,
data: {prefix, name, value}
}, getState);
return {data: true};
};
}

export function removeItem(name) {
return async (dispatch, getState) => {
const state = getState();
const prefix = getPrefix(state);
dispatch({
type: StorageTypes.REMOVE_ITEM,
data: {prefix, name}
}, getState);
return {data: true};
};
}

export function setGlobalItem(name, value) {
return async (dispatch, getState) => {
dispatch({
type: StorageTypes.SET_GLOBAL_ITEM,
data: {name, value}
}, getState);
return {data: true};
};
}

export function removeGlobalItem(name) {
return async (dispatch, getState) => {
dispatch({
type: StorageTypes.REMOVE_GLOBAL_ITEM,
data: {name}
}, getState);
return {data: true};
};
}

export function clear(options) {
return async (dispatch, getState) => {
dispatch({
type: StorageTypes.CLEAR,
data: options
}, getState);
return {data: false};
};
}

export function actionOnGlobalItemsWithPrefix(prefix, action) {
return async (dispatch, getState) => {
dispatch({
type: StorageTypes.ACTION_ON_GLOBAL_ITEMS_WITH_PREFIX,
data: {prefix, action}
}, getState);
return {data: false};
};
}

export function actionOnItemsWithPrefix(prefix, action) {
return async (dispatch, getState) => {
const state = getState();
const globalPrefix = getPrefix(state);
dispatch({
type: StorageTypes.ACTION_ON_ITEMS_WITH_PREFIX,
data: {globalPrefix, prefix, action}
}, getState);
return {data: false};
};
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"jquery": "3.2.1",
"key-mirror": "1.0.1",
"localforage": "1.5.0",
"localforage-observable": "1.4.0",
"marked": "mattermost/marked#17945726698a03420588acd55e5b38f692c03f31",
"match-at": "0.1.1",
"mattermost-redux": "1.0.1",
Expand Down Expand Up @@ -94,6 +95,7 @@
"raw-loader": "0.5.1",
"react-addons-test-utils": "15.6.2",
"react-test-renderer": "15",
"redux-persist-node-storage": "1.0.2",
"remote-redux-devtools": "0.5.12",
"remote-redux-devtools-on-debugger": "0.8.2",
"sass-loader": "6.0.6",
Expand Down
4 changes: 3 additions & 1 deletion reducers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

import plugins from './plugins';
import views from './views';
import storage from './storage';

export default {
views,
plugins
plugins,
storage
};
58 changes: 58 additions & 0 deletions reducers/storage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import {StorageTypes} from 'utils/constants';

export default function storage(state = {}, action) {
const nextState = {...state};
var key;

switch (action.type) {
case StorageTypes.SET_ITEM: {
nextState[action.data.prefix + action.data.name] = action.data.value;
return nextState;
}
case StorageTypes.REMOVE_ITEM: {
Reflect.deleteProperty(nextState, action.data.prefix + action.data.name);
return nextState;
}
case StorageTypes.SET_GLOBAL_ITEM: {
nextState[action.data.name] = action.data.value;
return nextState;
}
case StorageTypes.REMOVE_GLOBAL_ITEM: {
Reflect.deleteProperty(nextState, action.data.name);
return nextState;
}
case StorageTypes.CLEAR: {
var cleanState = {};
action.data.exclude.forEach((excluded) => {
if (state[excluded]) {
cleanState[excluded] = state[excluded];
}
});
return cleanState;
}
case StorageTypes.ACTION_ON_GLOBAL_ITEMS_WITH_PREFIX: {
for (key in state) {
if (key.lastIndexOf(action.data.prefix, 0) === 0) {
nextState[key] = action.data.action(key, state[key]);
}
}
return nextState;
}
case StorageTypes.ACTION_ON_ITEMS_WITH_PREFIX: {
var globalPrefix = action.data.globalPrefix;
var globalPrefixLen = action.data.globalPrefix.length;
for (key in state) {
if (key.lastIndexOf(globalPrefix + action.data.prefix, 0) === 0) {
var userkey = key.substring(globalPrefixLen);
nextState[key] = action.data.action(userkey, state[key]);
}
}
return nextState;
}
default:
return state;
}
}
23 changes: 23 additions & 0 deletions selectors/storage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import {getPrefix} from 'utils/storage_utils';

function getGlobalItem(state, name, defaultValue) {
if (state && state.storage && typeof state.storage[name] !== 'undefined' && state.storage[name] !== null) {
return state.storage[name];
}
return defaultValue;
}

export function makeGetItem(name, defaultValue) {
return (state) => {
return getGlobalItem(state, getPrefix(state) + name, defaultValue);
};
}

export function makeGetGlobalItem(name, defaultValue) {
return (state) => {
return getGlobalItem(state, name, defaultValue);
};
}
33 changes: 29 additions & 4 deletions store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import {batchActions} from 'redux-batched-actions';
import {createTransform, persistStore} from 'redux-persist';

import localForage from 'localforage';
import localForage from "localforage";
import { extendPrototype } from "localforage-observable";

import {General, RequestStatus} from 'mattermost-redux/constants';
import configureServiceStore from 'mattermost-redux/store';
Expand Down Expand Up @@ -34,7 +35,7 @@ const setTransforms = [
...teamSetTransform
];

export default function configureStore(initialState) {
export default function configureStore(initialState, persistorStorage = null) {
const setTransformer = createTransform(
(inboundState, key) => {
if (key === 'entities') {
Expand Down Expand Up @@ -68,13 +69,37 @@ export default function configureStore(initialState) {

const offlineOptions = {
persist: (store, options) => {
const persistor = persistStore(store, {storage: localForage, ...options}, () => {
const localforage = extendPrototype(localForage);
var storage = persistorStorage || localforage;
const KEY_PREFIX = "reduxPersist:";
const persistor = persistStore(store, {storage, keyPrefix: KEY_PREFIX, ...options}, () => {
store.dispatch({
type: General.STORE_REHYDRATION_COMPLETE,
complete: true
});
});

if (localforage === storage) {
localforage.ready(() => {
localforage.configObservables({
crossTabNotification: true,
});
var observable = localforage.newObservable({
crossTabNotification: true,
changeDetection: true
});
observable.subscribe({
next: (args) => {
if(args.key && args.key.indexOf(KEY_PREFIX) === 0){
var keyspace = args.key.substr(KEY_PREFIX.length)

var statePartial = {}
statePartial[keyspace] = args.newValue
persistor.rehydrate(statePartial, {serial: true})
}
}
})
})
}
let purging = false;

// check to see if the logout request was successful
Expand Down
Loading

0 comments on commit 399de2b

Please sign in to comment.