diff --git a/keyserver/src/responders/website-responders.js b/keyserver/src/responders/website-responders.js --- a/keyserver/src/responders/website-responders.js +++ b/keyserver/src/responders/website-responders.js @@ -186,7 +186,6 @@ ), }), messageStore: messageStoreValidator, - updatesCurrentAsOf: t.Number, loadingStatuses: t.irreducible('default loadingStatuses', _isEqual({})), calendarFilters: t.irreducible( 'defaultCalendarFilters', @@ -501,10 +500,18 @@ })(); const keyserverStorePromise = (async () => { - const sessionID = await sessionIDPromise; + const { sessionID, updatesCurrentAsOf } = await promiseAll({ + sessionID: sessionIDPromise, + updatesCurrentAsOf: currentAsOfPromise, + }); + return { keyserverInfos: { - [ashoatKeyserverID]: { cookie: undefined, sessionID }, + [ashoatKeyserverID]: { + cookie: undefined, + sessionID, + updatesCurrentAsOf, + }, }, }; })(); @@ -576,7 +583,6 @@ threadStore: threadStorePromise, userStore: userStorePromise, messageStore: messageStorePromise, - updatesCurrentAsOf: currentAsOfPromise, loadingStatuses: {}, calendarFilters: defaultCalendarFilters, communityPickerStore: { chat: null, calendar: null }, diff --git a/lib/reducers/keyserver-reducer.js b/lib/reducers/keyserver-reducer.js --- a/lib/reducers/keyserver-reducer.js +++ b/lib/reducers/keyserver-reducer.js @@ -1,8 +1,18 @@ // @flow -import { resetUserStateActionType } from '../actions/user-actions.js'; +import reduceUpdatesCurrentAsOf from './updates-reducer.js'; +import { siweAuthActionTypes } from '../actions/siwe-actions.js'; +import { + logInActionTypes, + resetUserStateActionType, +} from '../actions/user-actions.js'; import type { KeyserverStore } from '../types/keyserver-types'; import type { BaseAction } from '../types/redux-types.js'; +import { + fullStateSyncActionType, + incrementalStateSyncActionType, +} from '../types/socket-types.js'; +import { processUpdatesActionType } from '../types/update-types.js'; import { setNewSessionActionType } from '../utils/action-utils.js'; import { ashoatKeyserverID } from '../utils/validation-utils.js'; @@ -44,6 +54,28 @@ }, }; } + } else if ( + action.type === logInActionTypes.success || + action.type === siweAuthActionTypes.success || + action.type === fullStateSyncActionType || + action.type === incrementalStateSyncActionType || + action.type === processUpdatesActionType + ) { + const updatesCurrentAsOf = reduceUpdatesCurrentAsOf( + state.keyserverInfos[ashoatKeyserverID].updatesCurrentAsOf, + action, + ); + return { + ...state, + keyserverInfos: { + ...state.keyserverInfos, + [ashoatKeyserverID]: { + ...state.keyserverInfos[ashoatKeyserverID], + updatesCurrentAsOf, + }, + }, + }; } + return state; } diff --git a/lib/reducers/master-reducer.js b/lib/reducers/master-reducer.js --- a/lib/reducers/master-reducer.js +++ b/lib/reducers/master-reducer.js @@ -20,7 +20,6 @@ import reduceReportStore from './report-store-reducer.js'; import reduceServicesAccessToken from './services-access-token-reducer.js'; import { reduceThreadInfos } from './thread-reducer.js'; -import reduceUpdatesCurrentAsOf from './updates-reducer.js'; import reduceURLPrefix from './url-prefix-reducer.js'; import { reduceCurrentUserInfo, reduceUserInfos } from './user-reducer.js'; import { siweAuthActionTypes } from '../actions/siwe-actions.js'; @@ -35,6 +34,7 @@ incrementalStateSyncActionType, } from '../types/socket-types.js'; import type { StoreOperations } from '../types/store-ops-types.js'; +import { ashoatKeyserverID } from '../utils/validation-utils.js'; export default function baseReducer>( state: T, @@ -59,11 +59,11 @@ const { messageStoreOperations, messageStore: reducedMessageStore } = reduceMessageStore(state.messageStore, action, threadInfos); let messageStore = reducedMessageStore; - let updatesCurrentAsOf = reduceUpdatesCurrentAsOf( - state.updatesCurrentAsOf, - action, - ); + const connection = reduceConnectionInfo(state.connection, action); + + let keyserverStore = reduceKeyserverStore(state.keyserverStore, action); + if ( connection.status !== 'connected' && action.type !== incrementalStateSyncActionType && @@ -78,8 +78,18 @@ currentAsOf: state.messageStore.currentAsOf, }; } - if (updatesCurrentAsOf !== state.updatesCurrentAsOf) { - updatesCurrentAsOf = state.updatesCurrentAsOf; + if ( + keyserverStore.keyserverInfos[ashoatKeyserverID].updatesCurrentAsOf !== + state.keyserverStore.keyserverInfos[ashoatKeyserverID].updatesCurrentAsOf + ) { + const keyserverInfos = { ...keyserverStore.keyserverInfos }; + keyserverInfos[ashoatKeyserverID] = { + ...keyserverInfos[ashoatKeyserverID], + updatesCurrentAsOf: + state.keyserverStore.keyserverInfos[ashoatKeyserverID] + .updatesCurrentAsOf, + }; + keyserverStore = { ...keyserverStore, keyserverInfos }; } } @@ -105,7 +115,6 @@ threadStore, userStore: reduceUserInfos(state.userStore, action), messageStore, - updatesCurrentAsOf, urlPrefix: reduceURLPrefix(state.urlPrefix, action), calendarFilters: reduceCalendarFilters( state.calendarFilters, @@ -134,7 +143,7 @@ action, state.urlPrefix, ), - keyserverStore: reduceKeyserverStore(state.keyserverStore, action), + keyserverStore, }, storeOperations: { draftStoreOperations, diff --git a/lib/selectors/keyserver-selectors.js b/lib/selectors/keyserver-selectors.js --- a/lib/selectors/keyserver-selectors.js +++ b/lib/selectors/keyserver-selectors.js @@ -25,4 +25,15 @@ const sessionIDSelector: (state: AppState) => ?string = (state: AppState) => state.keyserverStore.keyserverInfos[ashoatKeyserverID]?.sessionID; -export { cookieSelector, cookiesSelector, sessionIDSelector }; +const updatesCurrentAsOfSelector: (state: AppState) => number = ( + state: AppState, +) => + state.keyserverStore.keyserverInfos[ashoatKeyserverID]?.updatesCurrentAsOf ?? + 0; + +export { + cookieSelector, + cookiesSelector, + sessionIDSelector, + updatesCurrentAsOfSelector, +}; diff --git a/lib/selectors/socket-selectors.js b/lib/selectors/socket-selectors.js --- a/lib/selectors/socket-selectors.js +++ b/lib/selectors/socket-selectors.js @@ -3,6 +3,7 @@ import { createSelector } from 'reselect'; import t from 'tcomb'; +import { updatesCurrentAsOfSelector } from './keyserver-selectors.js'; import { currentCalendarQuery } from './nav-selectors.js'; import { serverEntryInfo, @@ -236,7 +237,7 @@ state: AppState, ) => (calendarActive: boolean) => SessionState = createSelector( (state: AppState) => state.messageStore.currentAsOf, - (state: AppState) => state.updatesCurrentAsOf, + updatesCurrentAsOfSelector, currentCalendarQuery, ( messagesCurrentAsOf: number, diff --git a/lib/types/keyserver-types.js b/lib/types/keyserver-types.js --- a/lib/types/keyserver-types.js +++ b/lib/types/keyserver-types.js @@ -10,6 +10,7 @@ export type KeyserverInfo = { +cookie?: ?string, +sessionID?: ?string, + +updatesCurrentAsOf: number, // millisecond timestamp }; export type KeyserverStore = { @@ -20,6 +21,7 @@ tShape({ cookie: t.maybe(t.String), sessionID: t.maybe(t.String), + updatesCurrentAsOf: t.Number, }); export const keyserverStoreValidator: TInterface = diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js --- a/lib/types/redux-types.js +++ b/lib/types/redux-types.js @@ -124,7 +124,6 @@ +threadStore: ThreadStore, +userStore: UserStore, +messageStore: MessageStore, - +updatesCurrentAsOf: number, // millisecond timestamp +loadingStatuses: { [key: string]: { [idx: number]: LoadingStatus } }, +calendarFilters: $ReadOnlyArray, +urlPrefix: string, diff --git a/native/push/push-handler.react.js b/native/push/push-handler.react.js --- a/native/push/push-handler.react.js +++ b/native/push/push-handler.react.js @@ -11,6 +11,7 @@ setDeviceToken, } from 'lib/actions/device-actions.js'; import { saveMessagesActionType } from 'lib/actions/message-actions.js'; +import { updatesCurrentAsOfSelector } from 'lib/selectors/keyserver-selectors.js'; import { unreadCount, threadInfoSelector, @@ -641,7 +642,7 @@ state => state.notifPermissionAlertInfo, ); const connection = useSelector(state => state.connection); - const updatesCurrentAsOf = useSelector(state => state.updatesCurrentAsOf); + const updatesCurrentAsOf = useSelector(updatesCurrentAsOfSelector); const activeTheme = useSelector(state => state.globalThemeInfo.activeTheme); const loggedIn = useSelector(isLoggedIn); const navigateToThread = useNavigateToThread(); diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -654,6 +654,23 @@ keyserverStore: { keyserverInfos: { [ashoatKeyserverID]: { cookie } } }, }; }, + [45]: async state => { + const { updatesCurrentAsOf, keyserverStore, ...rest } = state; + + return { + ...rest, + keyserverStore: { + ...keyserverStore, + keyserverInfos: { + ...keyserverStore.keyserverInfos, + [ashoatKeyserverID]: { + ...keyserverStore.keyserverInfos[ashoatKeyserverID], + updatesCurrentAsOf, + }, + }, + }, + }; + }, }; // After migration 31, we'll no longer want to persist `messageStore.messages` @@ -748,7 +765,7 @@ 'storeLoaded', ], debug: __DEV__, - version: 44, + version: 45, transforms: [messageStoreMessagesBlocklistTransform, reportStoreTransform], migrate: (createAsyncMigrate(migrations, { debug: __DEV__ }): any), timeout: ((__DEV__ ? 0 : undefined): number | void), diff --git a/native/redux/redux-setup.js b/native/redux/redux-setup.js --- a/native/redux/redux-setup.js +++ b/native/redux/redux-setup.js @@ -30,6 +30,7 @@ import { reduxLoggerMiddleware } from 'lib/utils/action-logger.js'; import { setNewSessionActionType } from 'lib/utils/action-utils.js'; import { defaultNotifPermissionAlertInfo } from 'lib/utils/push-alerts.js'; +import { ashoatKeyserverID } from 'lib/utils/validation-utils.js'; import { updateDimensionsActiveType, @@ -87,7 +88,6 @@ currentAsOf: 0, }, storeLoaded: false, - updatesCurrentAsOf: 0, loadingStatuses: {}, calendarFilters: defaultCalendarFilters, deviceToken: null, @@ -121,7 +121,11 @@ links: {}, }, lastCommunicatedPlatformDetails: {}, - keyserverStore: { keyserverInfos: {} }, + keyserverStore: { + keyserverInfos: { + [ashoatKeyserverID]: { updatesCurrentAsOf: 0 }, + }, + }, }: AppState); function reducer(state: AppState = defaultState, action: Action) { diff --git a/native/redux/state-types.js b/native/redux/state-types.js --- a/native/redux/state-types.js +++ b/native/redux/state-types.js @@ -35,7 +35,6 @@ +userStore: UserStore, +messageStore: MessageStore, +storeLoaded: boolean, - +updatesCurrentAsOf: number, +loadingStatuses: { [key: string]: { [idx: number]: LoadingStatus } }, +calendarFilters: $ReadOnlyArray, +deviceToken: ?string, diff --git a/web/redux/redux-setup.js b/web/redux/redux-setup.js --- a/web/redux/redux-setup.js +++ b/web/redux/redux-setup.js @@ -76,7 +76,6 @@ +threadStore: ThreadStore, +userStore: UserStore, +messageStore: MessageStore, - +updatesCurrentAsOf: number, +loadingStatuses: { [key: string]: { [idx: number]: LoadingStatus } }, +calendarFilters: $ReadOnlyArray, +communityPickerStore: CommunityPickerStore,