import React from 'react'; import { setJSExceptionHandler } from 'react-native-exception-handler'; import { Provider, connect } from 'react-redux'; import { AppRegistry, Text, View, NativeModules } from 'react-native'; import { Lbry, claimsReducer, contentReducer, fileReducer, fileInfoReducer, notificationsReducer, publishReducer, searchReducer, tagsReducer, walletReducer, } from 'lbry-redux'; import { authReducer, blacklistReducer, costInfoReducer, filteredReducer, homepageReducer, rewardsReducer, subscriptionsReducer, syncReducer, userReducer, } from 'lbryinc'; import { createStore, applyMiddleware, compose } from 'redux'; import AppWithNavigationState, { AppNavigator, navigatorReducer, reactNavigationMiddleware, } from 'component/AppNavigator'; import { REHYDRATE, PURGE, persistCombineReducers, persistStore } from 'redux-persist'; import getStoredStateMigrateV4 from 'redux-persist/lib/integration/getStoredStateMigrateV4'; import FilesystemStorage from 'redux-persist-filesystem-storage'; import createCompressor from 'redux-persist-transform-compress'; import createFilter from 'redux-persist-transform-filter'; import moment from 'moment'; import drawerReducer from 'redux/reducers/drawer'; import settingsReducer from 'redux/reducers/settings'; import thunk from 'redux-thunk'; const globalExceptionHandler = (error, isFatal) => { if (error && NativeModules.Firebase) { NativeModules.Firebase.logException(isFatal, error.message ? error.message : 'No message', JSON.stringify(error)); } }; setJSExceptionHandler(globalExceptionHandler, true); 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 compressor = createCompressor(); const authFilter = createFilter('auth', ['authToken']); const contentFilter = createFilter('content', ['positions']); const saveClaimsFilter = createFilter('claims', ['claimsByUri']); const subscriptionsFilter = createFilter('subscriptions', ['enabledChannelNotifications', 'subscriptions']); const settingsFilter = createFilter('settings', ['clientSettings']); const tagsFilter = createFilter('tags', ['followedTags']); const walletFilter = createFilter('wallet', ['receiveAddress']); const v4PersistOptions = { whitelist: ['auth', 'claims', 'content', 'subscriptions', 'settings', 'tags', 'wallet'], // Order is important. Needs to be compressed last or other transforms can't // read the data transforms: [authFilter, saveClaimsFilter, subscriptionsFilter, settingsFilter, walletFilter, compressor], debounce: 10000, storage: FilesystemStorage, }; const persistOptions = Object.assign({}, v4PersistOptions, { key: 'primary', getStoredState: getStoredStateMigrateV4(v4PersistOptions), }); const reducers = persistCombineReducers(persistOptions, { auth: authReducer, blacklist: blacklistReducer, claims: claimsReducer, content: contentReducer, costInfo: costInfoReducer, drawer: drawerReducer, file: fileReducer, fileInfo: fileInfoReducer, filtered: filteredReducer, homepage: homepageReducer, nav: navigatorReducer, notifications: notificationsReducer, publish: publishReducer, rewards: rewardsReducer, settings: settingsReducer, search: searchReducer, subscriptions: subscriptionsReducer, sync: syncReducer, tags: tagsReducer, user: userReducer, wallet: walletReducer, }); const bulkThunk = createBulkThunkMiddleware(); const middleware = [thunk, bulkThunk, reactNavigationMiddleware]; // eslint-disable-next-line no-underscore-dangle const composeEnhancers = compose; const store = createStore( enableBatching(reducers), {}, // initial state, composeEnhancers(applyMiddleware(...middleware)) ); window.store = store; const persistor = persistStore(store, persistOptions, err => { if (err) { console.log('Unable to load saved SETTINGS'); } }); window.persistor = persistor; /* const persistFilter = { 'auth': ['authToken'], 'claims': ['byId', 'claimsByUri'], 'content': ['positions'], 'subscriptions': ['enabledChannelNotifications', 'subscriptions'], 'settings': ['clientSettings'], 'tags': ['followedTags'], 'wallet': ['receiveAddress'] }; store.subscribe(() => { const state = (({ auth, claims, content, subscriptions, settings, tags, wallet }) => ({ auth, claims, content, subscriptions, settings, tags, wallet }))(store.getState()); NativeModules.StatePersistor.update(state, persistFilter); }); */ // TODO: Find i18n module that is compatible with react-native global.__ = str => str; class LBRYApp extends React.Component { render() { return ( <Provider store={store}> <AppWithNavigationState /> </Provider> ); } } AppRegistry.registerComponent('LBRYApp', () => LBRYApp); export default LBRYApp;