diff --git a/ui/component/app/index.js b/ui/component/app/index.js index 32ea986f7..2827ded9b 100644 --- a/ui/component/app/index.js +++ b/ui/component/app/index.js @@ -12,7 +12,7 @@ import { selectThemePath, } from 'redux/selectors/settings'; import { selectIsUpgradeAvailable, selectAutoUpdateDownloaded } from 'redux/selectors/app'; -import { doSetLanguage, doUpdateSyncPref } from 'redux/actions/settings'; +import { doSetLanguage, doUpdateSyncPrefIfFalse } from 'redux/actions/settings'; import { doSyncSubscribe } from 'redux/actions/syncwrapper'; import { doDownloadUpgradeRequested, @@ -46,7 +46,7 @@ const perform = dispatch => ({ signIn: () => dispatch(doSignIn()), requestDownloadUpgrade: () => dispatch(doDownloadUpgradeRequested()), updatePreferences: () => dispatch(doGetAndPopulatePreferences()), - updateSyncPref: () => dispatch(doUpdateSyncPref()), + pushPrefsIfSyncFalse: () => dispatch(doUpdateSyncPrefIfFalse()), syncSubscribe: () => dispatch(doSyncSubscribe()), setReferrer: (referrer, doClaim) => dispatch(doUserSetReferrer(referrer, doClaim)), }); diff --git a/ui/component/app/view.jsx b/ui/component/app/view.jsx index 0f6de49a3..d238a8427 100644 --- a/ui/component/app/view.jsx +++ b/ui/component/app/view.jsx @@ -67,7 +67,7 @@ type Props = { isUpgradeAvailable: boolean, autoUpdateDownloaded: boolean, updatePreferences: () => Promise, - updateSyncPref: () => void, + pushPrefsIfSyncFalse: () => void, uploadCount: number, balance: ?number, syncError: ?string, @@ -99,7 +99,7 @@ function App(props: Props) { languages, setLanguage, updatePreferences, - updateSyncPref, + pushPrefsIfSyncFalse, rewards, setReferrer, isAuthenticated, @@ -237,6 +237,7 @@ function App(props: Props) { useEffect(() => { if (updatePreferences && readyForPrefs) { updatePreferences().then(() => { + // will pull and U_S_P; usp will make sure prefBox applied if false setReadyForSync(true); }); } @@ -245,19 +246,21 @@ function App(props: Props) { // ready for sync syncs, however after signin when hasVerifiedEmail, that syncs too. useEffect(() => { - if (readyForSync && hasVerifiedEmail) { - // Copy sync checkbox to settings and push to preferences - // before sync if false, after sync if true so as not to change timestamp. - if (signInSyncPref === false) { - updateSyncPref(); - } + // signInSyncPref is cleared after sharedState loop. + if (readyForSync && hasVerifiedEmail && signInSyncPref === undefined) { + // On sign-in, we get and apply all the information on whether to sync + // the checkbox, previous wallet settings, store rehydrate, etc + // Our app is up to date with the wallet + // Because the checkbox is applied last, make sure the wallet remembers if false: + // @if TARGET='app' + pushPrefsIfSyncFalse(); + // @endif + + // And try this in case we are syncing. syncSubscribe(); - if (signInSyncPref === true) { - updateSyncPref(); - } } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [readyForSync, hasVerifiedEmail, signInSyncPref, updateSyncPref, syncSubscribe]); + }, [readyForSync, hasVerifiedEmail, signInSyncPref, pushPrefsIfSyncFalse, syncSubscribe]); // We know someone is logging in or not when we get their user object {} // We'll use this to determine when it's time to pull preferences diff --git a/ui/redux/actions/settings.js b/ui/redux/actions/settings.js index 9428b23d3..271e0aadc 100644 --- a/ui/redux/actions/settings.js +++ b/ui/redux/actions/settings.js @@ -138,13 +138,14 @@ export function doSetClientSetting(key, value, pushPrefs) { }; } -export function doUpdateSyncPref() { +export function doUpdateSyncPrefIfFalse() { + // This is only called after manual signin to update the wallet + // that the sync preference is false return (dispatch, getState) => { - const { settings } = getState(); - const { syncEnabledPref } = settings || {}; - if (syncEnabledPref !== undefined) { - dispatch(doSetClientSetting(SETTINGS.ENABLE_SYNC, syncEnabledPref, true)); - dispatch(doSetSyncPref(undefined)); + const state = getState(); + const syncEnabled = makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state); + if (syncEnabled === false) { + dispatch(doPushSettingsToPrefs()); } }; } @@ -224,6 +225,7 @@ export function doExitSettingsPage() { return (dispatch, getState) => { dispatch(doSetSyncLock(false)); dispatch(doPushSettingsToPrefs()); + // syncSubscribe is restarted in store.js sharedStateCB if necessary }; } diff --git a/ui/redux/actions/syncwrapper.js b/ui/redux/actions/syncwrapper.js index 1bfb898ae..74b5fa7fe 100644 --- a/ui/redux/actions/syncwrapper.js +++ b/ui/redux/actions/syncwrapper.js @@ -1,7 +1,7 @@ // @flow import { doGetSync, selectGetSyncIsPending, selectSetSyncIsPending } from 'lbryinc'; import { SETTINGS } from 'lbry-redux'; -import { makeSelectClientSetting } from 'redux/selectors/settings'; +import { makeSelectClientSetting, selectSyncSigninPref } from 'redux/selectors/settings'; import { getSavedPassword } from 'util/saved-passwords'; import { doAnalyticsTagSync, doHandleSyncComplete } from 'redux/actions/app'; import { selectSyncIsLocked } from 'redux/selectors/app'; @@ -31,9 +31,10 @@ export function doSyncSubscribe() { if (syncTimer) clearInterval(syncTimer); const state = getState(); const hasVerifiedEmail = selectUserVerifiedEmail(state); + const signInSyncPref = selectSyncSigninPref(state); const syncEnabled = makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state); const syncLocked = selectSyncIsLocked(state); - if (hasVerifiedEmail && syncEnabled && !syncLocked) { + if (hasVerifiedEmail && syncEnabled && !syncLocked && signInSyncPref !== false) { dispatch(doGetSyncDesktop((error, hasNewData) => dispatch(doHandleSyncComplete(error, hasNewData)))); dispatch(doAnalyticsTagSync()); syncTimer = setInterval(() => { diff --git a/ui/redux/reducers/settings.js b/ui/redux/reducers/settings.js index 005fb7bf9..8ad323cb2 100644 --- a/ui/redux/reducers/settings.js +++ b/ui/redux/reducers/settings.js @@ -160,13 +160,22 @@ reducers[ACTIONS.SYNC_PREFERENCE_CHANGED] = (state, action) => { }; reducers[LBRY_REDUX_ACTIONS.USER_STATE_POPULATE] = (state, action) => { - const { clientSettings: currentClientSettings } = state; + const { clientSettings: currentClientSettings, syncEnabledPref } = state; const { settings: sharedPreferences } = action.data; + // we have to update the signin sync checkbox in here + // where we can simulataneously set the checkbox temp value to undefined, and + // update the sync setting before sync happens + // temp box must be undefined to trigger the items in the syncSubscribe effect + const syncSettingOrEmpty = syncEnabledPref !== undefined ? { enable_sync: syncEnabledPref } : {}; const selectedSettings = sharedPreferences ? getSubsetFromKeysArray(sharedPreferences, clientSyncKeys) : {}; - const mergedClientSettings = { ...currentClientSettings, ...selectedSettings }; + const mergedClientSettings = { ...currentClientSettings, ...selectedSettings, ...syncSettingOrEmpty }; const newSharedPreferences = sharedPreferences || {}; - return Object.assign({}, state, { sharedPreferences: newSharedPreferences, clientSettings: mergedClientSettings }); + return Object.assign({}, state, { + sharedPreferences: newSharedPreferences, + clientSettings: mergedClientSettings, + syncEnabledPref: undefined, + }); }; reducers[LBRY_REDUX_ACTIONS.SAVE_CUSTOM_WALLET_SERVERS] = (state, action) => { diff --git a/ui/redux/selectors/settings.js b/ui/redux/selectors/settings.js index 30479d1de..e137a5b80 100644 --- a/ui/redux/selectors/settings.js +++ b/ui/redux/selectors/settings.js @@ -11,7 +11,7 @@ export const selectFfmpegStatus = createSelector(selectDaemonStatus, status => s export const selectFindingFFmpeg = createSelector(selectState, state => state.findingFFmpeg || false); -export const selectSyncSigninPref = createSelector(selectState, state => state.syncEnabledPref || undefined); +export const selectSyncSigninPref = createSelector(selectState, state => state.syncEnabledPref); export const selectClientSettings = createSelector(selectState, state => state.clientSettings || {});