Sync: operate on 'local' until the first successful sync (#1835)

## Issue
https://github.com/OdyseeTeam/odysee-frontend/issues/1815#issuecomment-1178728712

When settings are changed before the first successful sync, the changes are on top of the default wallet preferences, and becomes the "latest". When sync is possible again later, the bad data is pushed to the cloud.

## Change
Continue to operate on 'local' until the first successful sync. Most of the GUI will warn (or even prevent) the user from changing settings in this scenario, so the amount of "discarded" changes in 'local' is minimal.
This commit is contained in:
infinite-persistence 2022-07-13 21:36:51 +08:00 committed by GitHub
parent 68ceb7f440
commit 5863ea8df4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 10 deletions

View file

@ -630,8 +630,10 @@ export function doGetAndPopulatePreferences(syncId /* ?: number */) {
return (dispatch, getState) => { return (dispatch, getState) => {
const state = getState(); const state = getState();
const syncEnabled = selectClientSetting(state, SETTINGS.ENABLE_SYNC); const syncEnabled = selectClientSetting(state, SETTINGS.ENABLE_SYNC);
const hasVerifiedEmail = state.user && state.user.user && state.user.user.has_verified_email; const hasVerifiedEmail = selectUserVerifiedEmail(state);
let preferenceKey; let preferenceKey;
// TODO: the logic should match `runPreferences`, but since this function is
// only hit as a successful sync callback, it doesn't matter for now.
// @if TARGET='app' // @if TARGET='app'
preferenceKey = syncEnabled && hasVerifiedEmail ? 'shared' : 'local'; preferenceKey = syncEnabled && hasVerifiedEmail ? 'shared' : 'local';
// @endif // @endif
@ -648,7 +650,6 @@ export function doGetAndPopulatePreferences(syncId /* ?: number */) {
} }
// @if TARGET='app' // @if TARGET='app'
const { settings } = savedPreferences.value; const { settings } = savedPreferences.value;
if (settings) { if (settings) {
Object.entries(settings).forEach(([key, val]) => { Object.entries(settings).forEach(([key, val]) => {

View file

@ -5,28 +5,33 @@ import { doPreferenceSet } from 'redux/actions/sync';
const RUN_PREFERENCES_DELAY_MS = 2000; const RUN_PREFERENCES_DELAY_MS = 2000;
const SHARED_PREFERENCE_VERSION = '0.1'; const SHARED_PREFERENCE_VERSION = '0.1';
let oldShared = {}; let oldShared = {};
let timeout; let timeout;
export const buildSharedStateMiddleware = ( export const buildSharedStateMiddleware = (
actions: Array<string>, actions: Array<string>,
sharedStateFilters: {}, sharedStateFilters: {},
sharedStateCb?: (any) => void sharedStateCb?: (any) => void
) => ({ getState, dispatch }: { getState: () => { user: any, settings: any }, dispatch: (any) => void }) => ( ) => ({ getState, dispatch }: { getState: GetState, dispatch: Dispatch }) => (next: ({}) => void) => (action: {
next: ({}) => void type: string,
) => (action: { type: string, data: any }) => { data: any,
}) => {
// We don't care if sync is disabled here, we always want to backup preferences to the wallet // We don't care if sync is disabled here, we always want to backup preferences to the wallet
if (!actions.includes(action.type) || typeof action === 'function') { if (!actions.includes(action.type) || typeof action === 'function') {
return next(action); return next(action);
} }
clearTimeout(timeout); clearTimeout(timeout);
const actionResult = next(action); const actionResult = next(action);
// Call `getState` after calling `next` to ensure the state has updated in response to the action // Call `getState` after calling `next` to ensure the state has updated in response to the action
function runPreferences() { function runPreferences() {
const nextState: { user: any, settings: any } = getState(); const nextState = getState();
const syncEnabled = const syncEnabled = nextState?.settings?.clientSettings?.enable_sync;
nextState.settings && nextState.settings.clientSettings && nextState.settings.clientSettings.enable_sync; const hasVerifiedEmail = nextState?.user?.user?.has_verified_email;
const hasVerifiedEmail = nextState.user && nextState.user.user && nextState.user.user.has_verified_email; const prefsReady = nextState?.sync.prefsReady;
const preferenceKey = syncEnabled && hasVerifiedEmail ? 'shared' : 'local'; const preferenceKey = syncEnabled && hasVerifiedEmail && prefsReady ? 'shared' : 'local';
const shared = {}; const shared = {};
Object.keys(sharedStateFilters).forEach((key) => { Object.keys(sharedStateFilters).forEach((key) => {