diff --git a/keyserver/src/responders/redux-state-responders.js b/keyserver/src/responders/redux-state-responders.js --- a/keyserver/src/responders/redux-state-responders.js +++ b/keyserver/src/responders/redux-state-responders.js @@ -70,6 +70,7 @@ tShape({ urlInfo: urlInfoValidator, excludedData: excludedDataValidator, + clientUpdatesCurrentAsOf: t.Number, }); const initialKeyserverInfoValidator = tShape({ @@ -95,7 +96,7 @@ viewer: Viewer, request: InitialReduxStateRequest, ): Promise { - const { urlInfo, excludedData } = request; + const { urlInfo, excludedData, clientUpdatesCurrentAsOf } = request; const useDatabase = viewer.loggedIn && canUseDatabaseOnWeb(viewer.userID); const hasNotAcknowledgedPoliciesPromise = hasAnyNotAcknowledgedPolicies( @@ -140,7 +141,10 @@ }; })(); const messageSelectionCriteria = { joinedThreads: true }; - const initialTime = Date.now(); + const serverUpdatesCurrentAsOf = + useDatabase && clientUpdatesCurrentAsOf + ? clientUpdatesCurrentAsOf + : Date.now(); const threadInfoPromise = fetchThreadInfos(viewer); const messageInfoPromise = fetchMessageInfos( @@ -158,7 +162,7 @@ const sessionIDPromise = (async () => { const calendarQuery = await calendarQueryPromise; if (viewer.loggedIn) { - await setNewSession(viewer, calendarQuery, initialTime); + await setNewSession(viewer, calendarQuery, serverUpdatesCurrentAsOf); } return viewer.sessionID; })(); @@ -197,7 +201,7 @@ { [ashoatKeyserverID]: mostRecentMessageTimestamp( rawMessageInfos, - initialTime, + serverUpdatesCurrentAsOf, ), }, threadInfos, @@ -219,7 +223,7 @@ return { entryInfos: _keyBy('id')(rawEntryInfos), daysToEntries: daysToEntriesFromEntryInfos(rawEntryInfos), - lastUserInteractionCalendar: initialTime, + lastUserInteractionCalendar: serverUpdatesCurrentAsOf, }; })(); const userInfosPromise = (async () => { @@ -303,7 +307,7 @@ })(); const currentAsOfPromise = (async () => { const hasNotAcknowledgedPolicies = await hasNotAcknowledgedPoliciesPromise; - return hasNotAcknowledgedPolicies ? 0 : initialTime; + return hasNotAcknowledgedPolicies ? 0 : serverUpdatesCurrentAsOf; })(); const pushApiPublicKeyPromise: Promise = (async () => { diff --git a/web/redux/action-types.js b/web/redux/action-types.js --- a/web/redux/action-types.js +++ b/web/redux/action-types.js @@ -26,15 +26,21 @@ ): ((input: InitialReduxStateRequest) => Promise) => async input => { const requests: { [string]: InitialReduxStateRequest } = {}; - const { urlInfo, excludedData } = input; + const { urlInfo, ...inputRest } = input; const { thread, inviteSecret, ...rest } = urlInfo; const threadKeyserverID = thread ? extractKeyserverIDFromID(thread) : null; for (const keyserverID of allKeyserverIDs) { if (keyserverID === threadKeyserverID) { - requests[keyserverID] = { urlInfo, excludedData }; + requests[keyserverID] = { + ...inputRest, + urlInfo, + }; } else { - requests[keyserverID] = { urlInfo: rest, excludedData }; + requests[keyserverID] = { + ...inputRest, + urlInfo: rest, + }; } } diff --git a/web/redux/initial-state-gate.js b/web/redux/initial-state-gate.js --- a/web/redux/initial-state-gate.js +++ b/web/redux/initial-state-gate.js @@ -6,6 +6,7 @@ import { setClientDBStoreActionType } from 'lib/actions/client-db-store-actions.js'; import type { ThreadStoreOperation } from 'lib/ops/thread-store-ops.js'; +import { updatesCurrentAsOfSelector } from 'lib/selectors/keyserver-selectors.js'; import { canUseDatabaseOnWeb } from 'lib/shared/web-database.js'; import type { RawThreadInfo } from 'lib/types/thread-types.js'; import { convertIDToNewSchema } from 'lib/utils/migration-utils.js'; @@ -42,6 +43,10 @@ }, [initError]); const isRehydrated = useSelector(state => !!state._persist?.rehydrated); + const clientUpdatesCurrentAsOf = useSelector( + updatesCurrentAsOfSelector(ashoatKeyserverID), + ); + const prevIsRehydrated = React.useRef(false); React.useEffect(() => { if (!prevIsRehydrated.current && isRehydrated) { @@ -61,6 +66,7 @@ const payload = await callGetInitialReduxState({ urlInfo, excludedData: { threadStore: !!clientDBStore.threadStore }, + clientUpdatesCurrentAsOf, }); const currentLoggedInUserID = payload.currentUserInfo?.anonymous @@ -113,7 +119,12 @@ } })(); } - }, [callGetInitialReduxState, dispatch, isRehydrated]); + }, [ + callGetInitialReduxState, + dispatch, + isRehydrated, + clientUpdatesCurrentAsOf, + ]); const initialStateLoaded = useSelector(state => state.initialStateLoaded); 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 @@ -15,7 +15,6 @@ import { mostRecentlyReadThreadSelector } from 'lib/selectors/thread-selectors.js'; import { isLoggedIn } from 'lib/selectors/user-selectors.js'; import { invalidSessionDowngrade } from 'lib/shared/session-utils.js'; -import { canUseDatabaseOnWeb } from 'lib/shared/web-database.js'; import type { Shape } from 'lib/types/core.js'; import type { CryptoStore } from 'lib/types/crypto-types.js'; import type { DraftStore } from 'lib/types/draft-types.js'; @@ -126,13 +125,9 @@ const { userInfos, keyserverInfos, ...rest } = action.payload; const newKeyserverInfos = { ...state.keyserverStore.keyserverInfos }; for (const keyserverID in keyserverInfos) { - const newUpdatesCurrentAsOf = canUseDatabaseOnWeb(rest.currentUserInfo.id) - ? newKeyserverInfos[keyserverID].updatesCurrentAsOf - : keyserverInfos[keyserverID].updatesCurrentAsOf; newKeyserverInfos[keyserverID] = { ...newKeyserverInfos[keyserverID], ...keyserverInfos[keyserverID], - updatesCurrentAsOf: newUpdatesCurrentAsOf, }; } return validateStateAndProcessDBOperations( diff --git a/web/types/redux-types.js b/web/types/redux-types.js --- a/web/types/redux-types.js +++ b/web/types/redux-types.js @@ -49,4 +49,5 @@ export type InitialReduxStateRequest = { +urlInfo: URLInfo, +excludedData: ExcludedData, + +clientUpdatesCurrentAsOf: number, };