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 @@ -355,7 +355,7 @@ messages: {}, threads: {}, local: {}, - currentAsOf: 0, + currentAsOf: { [ashoatKeyserverID]: 0 }, }; } const { messageStore: freshStore } = freshMessageStore( 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 @@ -72,10 +72,17 @@ action.type !== logInActionTypes.success && action.type !== siweAuthActionTypes.success ) { - if (messageStore.currentAsOf !== state.messageStore.currentAsOf) { + if ( + messageStore.currentAsOf[ashoatKeyserverID] !== + state.messageStore.currentAsOf[ashoatKeyserverID] + ) { messageStore = { ...messageStore, - currentAsOf: state.messageStore.currentAsOf, + currentAsOf: { + ...messageStore.currentAsOf, + [ashoatKeyserverID]: + state.messageStore.currentAsOf[ashoatKeyserverID], + }, }; } if ( diff --git a/lib/reducers/message-reducer.js b/lib/reducers/message-reducer.js --- a/lib/reducers/message-reducer.js +++ b/lib/reducers/message-reducer.js @@ -104,6 +104,7 @@ import { isDev } from '../utils/dev-utils.js'; import { translateClientDBThreadMessageInfos } from '../utils/message-ops-utils.js'; import { assertObjectsAreEqual } from '../utils/objects.js'; +import { ashoatKeyserverID } from '../utils/validation-utils.js'; const PROCESSED_MSG_STORE_INVARIANTS_DISABLED = !isDev; const _mapValuesWithKeys = _mapValues.convert({ cap: false }); @@ -217,7 +218,12 @@ return { messageStoreOperations, - messageStore: { messages, threads, local: {}, currentAsOf }, + messageStore: { + messages, + threads, + local: {}, + currentAsOf: { [ashoatKeyserverID]: currentAsOf }, + }, }; } @@ -611,7 +617,7 @@ const currentAsOf = Math.max( orderedNewMessageInfos.length > 0 ? orderedNewMessageInfos[0].time : 0, - updatedMessageStore.currentAsOf, + updatedMessageStore.currentAsOf[ashoatKeyserverID], ); newMessageOps.push({ @@ -630,7 +636,10 @@ messages: processedMessageStore.messages, threads, local, - currentAsOf, + currentAsOf: { + ...processedMessageStore.currentAsOf, + [ashoatKeyserverID]: currentAsOf, + }, }; assertMessageStoreThreadsAreEqual( diff --git a/lib/reducers/message-reducer.test.js b/lib/reducers/message-reducer.test.js --- a/lib/reducers/message-reducer.test.js +++ b/lib/reducers/message-reducer.test.js @@ -7,6 +7,7 @@ import { messageTypes } from '../types/message-types-enum.js'; import type { MessageStore } from '../types/message-types.js'; import { threadTypes } from '../types/thread-types-enum.js'; +import { ashoatKeyserverID } from '../utils/validation-utils.js'; const messageStoreBeforeMediaUpdate: MessageStore = { messages: { @@ -46,7 +47,7 @@ }, }, local: {}, - currentAsOf: 1639522292174, + currentAsOf: { [ashoatKeyserverID]: 1639522292174 }, }; describe('UPDATE_MULTIMEDIA_MESSAGE_MEDIA', () => { @@ -280,7 +281,7 @@ messages: {}, threads, local: {}, - currentAsOf: 1234567890123, + currentAsOf: { [ashoatKeyserverID]: 1234567890123 }, }, { type: 'SET_CLIENT_DB_STORE', 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 @@ -31,9 +31,13 @@ state.keyserverStore.keyserverInfos[ashoatKeyserverID]?.updatesCurrentAsOf ?? 0; +const currentAsOfSelector: (state: AppState) => number = (state: AppState) => + state.messageStore.currentAsOf[ashoatKeyserverID] ?? 0; + export { cookieSelector, cookiesSelector, sessionIDSelector, updatesCurrentAsOfSelector, + currentAsOfSelector, }; 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,7 +3,10 @@ import { createSelector } from 'reselect'; import t from 'tcomb'; -import { updatesCurrentAsOfSelector } from './keyserver-selectors.js'; +import { + updatesCurrentAsOfSelector, + currentAsOfSelector, +} from './keyserver-selectors.js'; import { currentCalendarQuery } from './nav-selectors.js'; import { serverEntryInfo, @@ -236,7 +239,7 @@ const sessionStateFuncSelector: ( state: AppState, ) => (calendarActive: boolean) => SessionState = createSelector( - (state: AppState) => state.messageStore.currentAsOf, + currentAsOfSelector, updatesCurrentAsOfSelector, currentCalendarQuery, ( diff --git a/lib/types/message-types.js b/lib/types/message-types.js --- a/lib/types/message-types.js +++ b/lib/types/message-types.js @@ -421,14 +421,14 @@ +messages: { +[id: string]: RawMessageInfo }, +threads: MessageStoreThreads, +local: { +[id: string]: LocalMessageInfo }, - +currentAsOf: number, + +currentAsOf: { +[keyserverID: string]: number }, }; export const messageStoreValidator: TInterface = tShape({ messages: t.dict(tID, rawMessageInfoValidator), threads: messageStoreThreadsValidator, local: t.dict(t.String, localMessageInfoValidator), - currentAsOf: t.Number, + currentAsOf: t.dict(t.String, t.Number), }); // We were initially using `number`s` for `thread`, `type`, `future_type`, etc. diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -671,6 +671,17 @@ }, }; }, + [46]: async state => { + const { currentAsOf } = state.messageStore; + + return { + ...state, + messageStore: { + ...state.messageStore, + currentAsOf: { [ashoatKeyserverID]: currentAsOf }, + }, + }; + }, }; // After migration 31, we'll no longer want to persist `messageStore.messages` @@ -692,7 +703,7 @@ }; type PersistedMessageStore = { +local: { +[id: string]: LocalMessageInfo }, - +currentAsOf: number, + +currentAsOf: { +[keyserverID: string]: number }, +threads: { +[threadID: string]: PersistedThreadMessageInfo }, }; @@ -765,7 +776,7 @@ 'storeLoaded', ], debug: __DEV__, - version: 45, + version: 46, 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 @@ -85,7 +85,7 @@ messages: {}, threads: {}, local: {}, - currentAsOf: 0, + currentAsOf: { [ashoatKeyserverID]: 0 }, }, storeLoaded: false, loadingStatuses: {}, diff --git a/native/selectors/account-selectors.js b/native/selectors/account-selectors.js --- a/native/selectors/account-selectors.js +++ b/native/selectors/account-selectors.js @@ -3,6 +3,7 @@ import { createSelector } from 'reselect'; import { logInExtraInfoSelector } from 'lib/selectors/account-selectors.js'; +import { currentAsOfSelector } from 'lib/selectors/keyserver-selectors.js'; import type { LogInExtraInfo } from 'lib/types/account-types.js'; import type { SignedIdentityKeysBlob } from 'lib/types/crypto-types.js'; import type { UserPolicies } from 'lib/types/policy-types.js'; @@ -43,7 +44,7 @@ const noDataAfterPolicyAcknowledgmentSelector: (state: AppState) => boolean = createSelector( (state: AppState) => state.connectivity, - (state: AppState) => state.messageStore.currentAsOf, + currentAsOfSelector, (state: AppState) => state.userPolicies, ( connectivity: ConnectivityInfo,