diff --git a/ui/component/app/index.js b/ui/component/app/index.js index e172b50d4..29594fdf3 100644 --- a/ui/component/app/index.js +++ b/ui/component/app/index.js @@ -1,7 +1,7 @@ import { hot } from 'react-hot-loader/root'; import { connect } from 'react-redux'; import { selectUploadCount } from 'lbryinc'; -import { selectGetSyncErrorMessage } from 'redux/selectors/sync'; +import { selectGetSyncErrorMessage, selectSyncFatalError } from 'redux/selectors/sync'; import { doFetchAccessToken, doUserSetReferrer } from 'redux/actions/user'; import { selectUser, selectAccessToken, selectUserVerifiedEmail } from 'redux/selectors/user'; import { selectUnclaimedRewards } from 'redux/selectors/rewards'; @@ -32,6 +32,7 @@ const select = state => ({ rewards: selectUnclaimedRewards(state), isAuthenticated: selectUserVerifiedEmail(state), currentModal: selectModal(state), + syncFatalError: selectSyncFatalError(state), }); const perform = dispatch => ({ diff --git a/ui/component/app/view.jsx b/ui/component/app/view.jsx index bc34edbf1..9557b90fe 100644 --- a/ui/component/app/view.jsx +++ b/ui/component/app/view.jsx @@ -34,6 +34,7 @@ import { STATUS_FAILING, STATUS_DOWN, } from 'web/effects/use-degraded-performance'; +import SyncFatalError from 'component/syncFatalError'; // @endif export const MAIN_WRAPPER_CLASS = 'main-wrapper'; // @if TARGET='app' @@ -81,6 +82,7 @@ type Props = { syncSubscribe: () => void, syncEnabled: boolean, currentModal: any, + syncFatalError: boolean, }; function App(props: Props) { @@ -106,6 +108,7 @@ function App(props: Props) { isAuthenticated, syncSubscribe, currentModal, + syncFatalError, } = props; const appRef = useRef(); @@ -303,6 +306,10 @@ function App(props: Props) { } // @endif + if (syncFatalError) { + return ; + } + return (
+ Try refreshing to fix the issue. If that doesn't work, email help@lbry.com for support.

} + actions={ +
+
+ } + /> +
+ ); +} diff --git a/ui/redux/actions/sync.js b/ui/redux/actions/sync.js index aea529385..5200348f7 100644 --- a/ui/redux/actions/sync.js +++ b/ui/redux/actions/sync.js @@ -224,15 +224,22 @@ export function doGetSync(passedPassword, callback) { handleCallback(error); } else { - // user doesn't have a synced wallet + const noWalletError = syncAttemptError && syncAttemptError.message === NO_WALLET_ERROR; + dispatch({ type: ACTIONS.GET_SYNC_COMPLETED, - data: { hasSyncedWallet: false, syncHash: null }, + data: { + hasSyncedWallet: false, + syncHash: null, + // If there was some unknown error, bail + fatalError: !noWalletError, + }, }); - // call sync_apply to get data to sync - // first time sync. use any string for old hash - if (syncAttemptError.message === NO_WALLET_ERROR) { + // user doesn't have a synced wallet + // call sync_apply to get data to sync + // first time sync. use any string for old hash + if (noWalletError) { Lbry.sync_apply({ password }) .then(({ hash: walletHash, data: syncApplyData }) => { dispatch(doSetSync('', walletHash, syncApplyData, password)); diff --git a/ui/redux/reducers/sync.js b/ui/redux/reducers/sync.js index 97d14cfc7..37a0d2261 100644 --- a/ui/redux/reducers/sync.js +++ b/ui/redux/reducers/sync.js @@ -16,6 +16,7 @@ const defaultState = { prefsReady: false, syncLocked: false, hashChanged: false, + fatalError: false, }; reducers[LBRY_REDUX_ACTIONS.USER_STATE_POPULATE] = state => { @@ -49,6 +50,7 @@ reducers[ACTIONS.GET_SYNC_COMPLETED] = (state, action) => hasSyncedWallet: action.data.hasSyncedWallet, getSyncIsPending: false, hashChanged: action.data.hashChanged, + fatalError: action.data.fatalError, }); reducers[ACTIONS.GET_SYNC_FAILED] = (state, action) => diff --git a/ui/redux/selectors/sync.js b/ui/redux/selectors/sync.js index f05f6a8ba..3076ad760 100644 --- a/ui/redux/selectors/sync.js +++ b/ui/redux/selectors/sync.js @@ -27,3 +27,5 @@ export const selectSyncApplyPasswordError = createSelector(selectState, state => export const selectSyncIsLocked = createSelector(selectState, state => state.syncLocked); export const selectPrefsReady = createSelector(selectState, state => state.prefsReady); + +export const selectSyncFatalError = createSelector(selectState, state => state.fatalError);