6e13fcfbd3
users see welcome screen once and choose preference SETTINGS moved to redux took steps toward eliminating unwanted analytics in app based on preferences settings page update to privacy controls and copy persist welcome version default tv on cleanup clean up appstrings populate prefs app only wallet custody, app only router settings on startup welcome sync, 3p share sync, emojis bump redux cleanup fix app not building fix sync bug, remove tvWelcomeVersion cleanup disable internalshare setting while signed in
176 lines
5.6 KiB
JavaScript
176 lines
5.6 KiB
JavaScript
import * as ACTIONS from 'constants/action_types';
|
|
import { persistStore, persistReducer } from 'redux-persist';
|
|
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
|
|
import createCompressor from 'redux-persist-transform-compress';
|
|
import { createFilter, createBlacklistFilter } from 'redux-persist-transform-filter';
|
|
import localForage from 'localforage';
|
|
import { createStore, applyMiddleware, compose } from 'redux';
|
|
import thunk from 'redux-thunk';
|
|
import { createMemoryHistory, createBrowserHistory } from 'history';
|
|
import { routerMiddleware } from 'connected-react-router';
|
|
import createRootReducer from './reducers';
|
|
import { buildSharedStateMiddleware, ACTIONS as LBRY_REDUX_ACTIONS, SETTINGS } from 'lbry-redux';
|
|
import { doGetSync, selectUserVerifiedEmail } from 'lbryinc';
|
|
import { getSavedPassword } from 'util/saved-passwords';
|
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
|
import { generateInitialUrl } from 'util/url';
|
|
|
|
function isFunction(object) {
|
|
return typeof object === 'function';
|
|
}
|
|
|
|
function isNotFunction(object) {
|
|
return !isFunction(object);
|
|
}
|
|
|
|
function createBulkThunkMiddleware() {
|
|
return ({ dispatch, getState }) => next => action => {
|
|
if (action.type === 'BATCH_ACTIONS') {
|
|
action.actions.filter(isFunction).map(actionFn => actionFn(dispatch, getState));
|
|
}
|
|
return next(action);
|
|
};
|
|
}
|
|
|
|
function enableBatching(reducer) {
|
|
return function batchingReducer(state, action) {
|
|
switch (action.type) {
|
|
case 'BATCH_ACTIONS':
|
|
return action.actions.filter(isNotFunction).reduce(batchingReducer, state);
|
|
default:
|
|
return reducer(state, action);
|
|
}
|
|
};
|
|
}
|
|
|
|
const contentFilter = createFilter('content', ['positions', 'history']);
|
|
const fileInfoFilter = createFilter('fileInfo', [
|
|
'fileListPublishedSort',
|
|
'fileListDownloadedSort',
|
|
'fileListSubscriptionSort',
|
|
]);
|
|
const appFilter = createFilter('app', [
|
|
'hasClickedComment',
|
|
'searchOptionsExpanded',
|
|
'volume',
|
|
'muted',
|
|
'allowAnalytics',
|
|
'welcomeVersion',
|
|
]);
|
|
// We only need to persist the receiveAddress for the wallet
|
|
const walletFilter = createFilter('wallet', ['receiveAddress']);
|
|
const searchFilter = createFilter('search', ['options']);
|
|
const tagsFilter = createFilter('tags', ['followedTags']);
|
|
const subscriptionsFilter = createFilter('subscriptions', ['subscriptions']);
|
|
const blockedFilter = createFilter('blocked', ['blockedChannels']);
|
|
const settingsFilter = createBlacklistFilter('settings', ['loadedLanguages', 'language']);
|
|
const whiteListedReducers = [
|
|
'fileInfo',
|
|
'publish',
|
|
'wallet',
|
|
'tags',
|
|
'content',
|
|
'app',
|
|
'search',
|
|
'blocked',
|
|
'settings',
|
|
'subscriptions',
|
|
];
|
|
|
|
const transforms = [
|
|
fileInfoFilter,
|
|
walletFilter,
|
|
blockedFilter,
|
|
tagsFilter,
|
|
appFilter,
|
|
searchFilter,
|
|
tagsFilter,
|
|
contentFilter,
|
|
subscriptionsFilter,
|
|
settingsFilter,
|
|
createCompressor(),
|
|
];
|
|
|
|
const persistOptions = {
|
|
key: 'v0',
|
|
storage: localForage,
|
|
stateReconciler: autoMergeLevel2,
|
|
whitelist: whiteListedReducers,
|
|
// Order is important. Needs to be compressed last or other transforms can't
|
|
// read the data
|
|
transforms,
|
|
};
|
|
|
|
let history;
|
|
// @if TARGET='app'
|
|
history = createMemoryHistory({
|
|
initialEntries: [generateInitialUrl(window.location.hash)],
|
|
initialIndex: 0,
|
|
});
|
|
// @endif
|
|
// @if TARGET='web'
|
|
history = createBrowserHistory();
|
|
// @endif
|
|
|
|
const triggerSharedStateActions = [
|
|
ACTIONS.CHANNEL_SUBSCRIBE,
|
|
ACTIONS.CHANNEL_UNSUBSCRIBE,
|
|
LBRY_REDUX_ACTIONS.TOGGLE_TAG_FOLLOW,
|
|
LBRY_REDUX_ACTIONS.TOGGLE_BLOCK_CHANNEL,
|
|
LBRY_REDUX_ACTIONS.CREATE_CHANNEL_COMPLETED,
|
|
LBRY_REDUX_ACTIONS.SHARED_PREFERENCE_SET,
|
|
ACTIONS.SET_WELCOME_VERSION,
|
|
ACTIONS.SET_ALLOW_ANALYTICS,
|
|
];
|
|
|
|
/**
|
|
* source: the reducer name
|
|
* property: the property in the reducer-specific state
|
|
* transform: optional method to modify the value to be stored
|
|
*
|
|
* See https://github.com/lbryio/lbry-redux/blob/master/src/redux/middleware/shared-state.js for the source
|
|
* This is based off v0.1
|
|
* If lbry-redux changes to another version, this code will need to be changed when upgrading
|
|
*/
|
|
const sharedStateFilters = {
|
|
tags: { source: 'tags', property: 'followedTags' },
|
|
subscriptions: {
|
|
source: 'subscriptions',
|
|
property: 'subscriptions',
|
|
transform: function(value) {
|
|
return value.map(({ uri }) => uri);
|
|
},
|
|
},
|
|
blocked: { source: 'blocked', property: 'blockedChannels' },
|
|
settings: { source: 'settings', property: 'sharedPreferences' },
|
|
app_welcome_version: { source: 'app', property: 'welcomeVersion' },
|
|
sharing_3P: { source: 'app', property: 'allowAnalytics' },
|
|
};
|
|
|
|
const sharedStateCb = ({ dispatch, getState }) => {
|
|
const state = getState();
|
|
const syncEnabled = makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state);
|
|
const emailVerified = selectUserVerifiedEmail(state);
|
|
if (syncEnabled && emailVerified) {
|
|
getSavedPassword().then(savedPassword => {
|
|
dispatch(doGetSync(savedPassword));
|
|
});
|
|
}
|
|
};
|
|
|
|
const sharedStateMiddleware = buildSharedStateMiddleware(triggerSharedStateActions, sharedStateFilters, sharedStateCb);
|
|
const rootReducer = createRootReducer(history);
|
|
const persistedReducer = persistReducer(persistOptions, rootReducer);
|
|
const bulkThunk = createBulkThunkMiddleware();
|
|
const middleware = [sharedStateMiddleware, routerMiddleware(history), thunk, bulkThunk];
|
|
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
|
const store = createStore(
|
|
enableBatching(persistedReducer),
|
|
{}, // initial state
|
|
composeEnhancers(applyMiddleware(...middleware))
|
|
);
|
|
|
|
const persistor = persistStore(store);
|
|
window.persistor = persistor;
|
|
|
|
export { store, persistor, history, whiteListedReducers };
|