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 @@ -245,6 +245,10 @@ _persist: t.Nil, commServicesAccessToken: t.Nil, inviteLinksStore: inviteLinksStoreValidator, + lastCommunicatedPlatformDetails: t.irreducible( + 'default lastCommunicatedPlatformDetails', + _isEqual({}), + ), }); async function websiteResponder( @@ -584,6 +588,7 @@ _persist: null, commServicesAccessToken: null, inviteLinksStore: inviteLinksStorePromise, + lastCommunicatedPlatformDetails: {}, }); const validatedInitialReduxState = validateOutput( viewer.platformDetails, diff --git a/lib/actions/device-actions.js b/lib/actions/device-actions.js --- a/lib/actions/device-actions.js +++ b/lib/actions/device-actions.js @@ -35,9 +35,13 @@ }; }; +const updateLastCommunicatedPlatformDetailsActionType = + 'UPDATE_LAST_COMMUNICATED_PLATFORM_DETAILS'; + export { setDeviceTokenActionTypes, setDeviceToken, getVersionActionTypes, getVersion, + updateLastCommunicatedPlatformDetailsActionType, }; diff --git a/lib/hooks/toggle-unread-status.js b/lib/hooks/toggle-unread-status.js --- a/lib/hooks/toggle-unread-status.js +++ b/lib/hooks/toggle-unread-status.js @@ -38,10 +38,10 @@ setThreadUnreadStatusActionTypes, boundSetThreadUnreadStatus(request), undefined, - { + ({ threadID: threadInfo.id, unread: !currentUser.unread, - }, + }: { +threadID: string, +unread: boolean }), ); afterAction(); }, [ diff --git a/lib/reducers/last-communicated-platform-details-reducer.js b/lib/reducers/last-communicated-platform-details-reducer.js new file mode 100644 --- /dev/null +++ b/lib/reducers/last-communicated-platform-details-reducer.js @@ -0,0 +1,35 @@ +// @flow + +import { updateLastCommunicatedPlatformDetailsActionType } from '../actions/device-actions.js'; +import { siweAuthActionTypes } from '../actions/siwe-actions.js'; +import { + logInActionTypes, + registerActionTypes, +} from '../actions/user-actions.js'; +import type { LastCommunicatedPlatformDetails } from '../types/device-types'; +import type { BaseAction } from '../types/redux-types'; +import { getConfig } from '../utils/config.js'; + +export default function reduceLastCommunicatedPlatformDetails( + state: LastCommunicatedPlatformDetails, + action: BaseAction, + currentURLPrefix: string, +): LastCommunicatedPlatformDetails { + if ( + action.type === logInActionTypes.success || + action.type === siweAuthActionTypes.success || + action.type === registerActionTypes.success + ) { + return { + ...state, + [currentURLPrefix]: getConfig().platformDetails, + }; + } + if (action.type === updateLastCommunicatedPlatformDetailsActionType) { + return { + ...state, + ...action.payload, + }; + } + 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 @@ -8,6 +8,7 @@ import reduceEnabledApps from './enabled-apps-reducer.js'; import { reduceEntryInfos } from './entry-reducer.js'; import reduceInviteLinks from './invite-links-reducer.js'; +import reduceLastCommunicatedPlatformDetails from './last-communicated-platform-details-reducer.js'; import reduceLifecycleState from './lifecycle-state-reducer.js'; import { reduceLoadingStatuses } from './loading-reducer.js'; import reduceNextLocalID from './local-id-reducer.js'; @@ -127,6 +128,11 @@ action, ), inviteLinksStore: reduceInviteLinks(state.inviteLinksStore, action), + lastCommunicatedPlatformDetails: reduceLastCommunicatedPlatformDetails( + state.lastCommunicatedPlatformDetails, + action, + state.urlPrefix, + ), }, storeOperations: { draftStoreOperations, diff --git a/lib/shared/edit-messages-utils.js b/lib/shared/edit-messages-utils.js --- a/lib/shared/edit-messages-utils.js +++ b/lib/shared/edit-messages-utils.js @@ -11,6 +11,7 @@ SendEditMessageResult, RobotextMessageInfo, ComposableMessageInfo, + RawMessageInfo, } from '../types/message-types'; import { messageTypes } from '../types/message-types-enum.js'; import { threadPermissions } from '../types/thread-permission-types.js'; @@ -35,9 +36,10 @@ targetMessageID: messageID, text: newText, }); - return { + + return ({ newMessageInfos: result.newMessageInfos, - }; + }: { +newMessageInfos: $ReadOnlyArray }); })(); dispatchActionPromise(sendEditMessageActionTypes, editMessagePromise); diff --git a/lib/types/device-types.js b/lib/types/device-types.js --- a/lib/types/device-types.js +++ b/lib/types/device-types.js @@ -44,3 +44,7 @@ export type VersionResponse = { +codeVersion: number, }; + +export type LastCommunicatedPlatformDetails = { + +[urlPrefix: string]: PlatformDetails, +}; 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 @@ -17,7 +17,10 @@ UpdateUserAvatarResponse, } from './avatar-types.js'; import type { CryptoStore } from './crypto-types.js'; -import type { VersionResponse } from './device-types.js'; +import type { + VersionResponse, + LastCommunicatedPlatformDetails, +} from './device-types.js'; import type { ClientDBDraftInfo, DraftStore } from './draft-types.js'; import type { EnabledApps, SupportedApps } from './enabled-apps.js'; import type { @@ -134,6 +137,7 @@ deviceToken: ?string, +commServicesAccessToken: ?string, +inviteLinksStore: InviteLinksStore, + +lastCommunicatedPlatformDetails: LastCommunicatedPlatformDetails, ... }; @@ -1159,6 +1163,10 @@ +error: true, +payload: Error, +loadingInfo: LoadingInfo, + } + | { + +type: 'UPDATE_LAST_COMMUNICATED_PLATFORM_DETAILS', + +payload: LastCommunicatedPlatformDetails, }; export type ActionPayload = ?(Object | Array<*> | $ReadOnlyArray<*> | string); diff --git a/native/chat/toggle-pin-modal.react.js b/native/chat/toggle-pin-modal.react.js --- a/native/chat/toggle-pin-modal.react.js +++ b/native/chat/toggle-pin-modal.react.js @@ -8,6 +8,7 @@ toggleMessagePin, toggleMessagePinActionTypes, } from 'lib/actions/thread-actions.js'; +import type { RawMessageInfo } from 'lib/types/message-types.js'; import { type ThreadInfo } from 'lib/types/thread-types.js'; import { useServerCall, @@ -71,10 +72,10 @@ messageID: messageInfo.id, action: modalInfo.action, }); - return { + return ({ newMessageInfos: result.newMessageInfos, threadID: result.threadID, - }; + }: { +newMessageInfos: $ReadOnlyArray, +threadID: string }); }, [callToggleMessagePin, messageInfo.id, modalInfo.action]); const onPress = React.useCallback(() => { 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 @@ -122,6 +122,7 @@ inviteLinksStore: { links: {}, }, + lastCommunicatedPlatformDetails: {}, }: 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 @@ -3,6 +3,7 @@ import type { Orientations } from 'react-native-orientation-locker'; import type { PersistState } from 'redux-persist/es/types.js'; +import type { LastCommunicatedPlatformDetails } from 'lib/types/device-types.js'; import type { DraftStore } from 'lib/types/draft-types.js'; import type { EnabledApps } from 'lib/types/enabled-apps.js'; import type { EntryStore } from 'lib/types/entry-types.js'; @@ -59,4 +60,5 @@ userPolicies: UserPolicies, +commServicesAccessToken: ?string, +inviteLinksStore: InviteLinksStore, + +lastCommunicatedPlatformDetails: LastCommunicatedPlatformDetails, }; diff --git a/web/modals/chat/toggle-pin-modal.react.js b/web/modals/chat/toggle-pin-modal.react.js --- a/web/modals/chat/toggle-pin-modal.react.js +++ b/web/modals/chat/toggle-pin-modal.react.js @@ -10,6 +10,7 @@ import { useModalContext } from 'lib/components/modal-provider.react.js'; import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js'; import { modifyItemForResultScreen } from 'lib/shared/message-utils.js'; +import type { RawMessageInfo } from 'lib/types/message-types.js'; import type { ThreadInfo } from 'lib/types/thread-types.js'; import { useServerCall, @@ -80,10 +81,13 @@ messageID: messageInfo.id, action: modalInfo.action, }); - return { + return ({ newMessageInfos: result.newMessageInfos, threadID: result.threadID, - }; + }: { + +newMessageInfos: $ReadOnlyArray, + +threadID: string, + }); }; dispatchActionPromise( diff --git a/web/redux/persist.js b/web/redux/persist.js --- a/web/redux/persist.js +++ b/web/redux/persist.js @@ -64,6 +64,7 @@ 'cryptoStore', 'notifPermissionAlertInfo', 'commServicesAccessToken', + 'lastCommunicatedPlatformDetails', ]; const persistConfig: PersistConfig = { 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 @@ -18,6 +18,7 @@ OLMIdentityKeys, PickledOLMAccount, } from 'lib/types/crypto-types.js'; +import type { LastCommunicatedPlatformDetails } from 'lib/types/device-types.js'; import type { DraftStore } from 'lib/types/draft-types.js'; import type { EnabledApps } from 'lib/types/enabled-apps.js'; import type { EntryStore } from 'lib/types/entry-types.js'; @@ -98,6 +99,7 @@ _persist: ?PersistState, +commServicesAccessToken: ?string, +inviteLinksStore: InviteLinksStore, + +lastCommunicatedPlatformDetails: LastCommunicatedPlatformDetails, }; export type Action =