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) => {
const state = getState();
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;
// 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'
preferenceKey = syncEnabled && hasVerifiedEmail ? 'shared' : 'local';
// @endif
@ -648,7 +650,6 @@ export function doGetAndPopulatePreferences(syncId /* ?: number */) {
}
// @if TARGET='app'
const { settings } = savedPreferences.value;
if (settings) {
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 SHARED_PREFERENCE_VERSION = '0.1';
let oldShared = {};
let timeout;
export const buildSharedStateMiddleware = (
actions: Array<string>,
sharedStateFilters: {},
sharedStateCb?: (any) => void
) => ({ getState, dispatch }: { getState: () => { user: any, settings: any }, dispatch: (any) => void }) => (
next: ({}) => void
) => (action: { type: string, data: any }) => {
) => ({ getState, dispatch }: { getState: GetState, dispatch: Dispatch }) => (next: ({}) => void) => (action: {
type: string,
data: any,
}) => {
// 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') {
return next(action);
}
clearTimeout(timeout);
const actionResult = next(action);
// Call `getState` after calling `next` to ensure the state has updated in response to the action
function runPreferences() {
const nextState: { user: any, settings: any } = getState();
const syncEnabled =
nextState.settings && nextState.settings.clientSettings && nextState.settings.clientSettings.enable_sync;
const hasVerifiedEmail = nextState.user && nextState.user.user && nextState.user.user.has_verified_email;
const preferenceKey = syncEnabled && hasVerifiedEmail ? 'shared' : 'local';
const nextState = getState();
const syncEnabled = nextState?.settings?.clientSettings?.enable_sync;
const hasVerifiedEmail = nextState?.user?.user?.has_verified_email;
const prefsReady = nextState?.sync.prefsReady;
const preferenceKey = syncEnabled && hasVerifiedEmail && prefsReady ? 'shared' : 'local';
const shared = {};
Object.keys(sharedStateFilters).forEach((key) => {