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 @@ -202,6 +202,23 @@ 'default notifPermissionAlertInfo', _isEqual(defaultNotifPermissionAlertInfo), ), + connection: tShape({ + status: tString('connecting'), + queuedActivityUpdates: t.irreducible( + 'default queuedActivityUpdates', + _isEqual([]), + ), + actualizedCalendarQuery: tShape({ + startDate: t.String, + endDate: t.String, + filters: t.irreducible( + 'default filters', + _isEqual(defaultCalendarFilters), + ), + }), + lateResponses: t.irreducible('default lateResponses', _isEqual([])), + showDisconnectedBar: tBool(false), + }), watchedThreadIDs: t.irreducible('default watchedThreadIDs', _isEqual([])), lifecycleState: tString('active'), enabledApps: t.irreducible( @@ -489,16 +506,10 @@ }; })(); - const connectionPromise = (async () => ({ - ...defaultConnectionInfo(viewer.platform ?? 'web', viewer.timeZone), - actualizedCalendarQuery: await calendarQueryPromise, - }))(); - const keyserverStorePromise = (async () => { - const { sessionID, updatesCurrentAsOf, connection } = await promiseAll({ + const { sessionID, updatesCurrentAsOf } = await promiseAll({ sessionID: sessionIDPromise, updatesCurrentAsOf: currentAsOfPromise, - connection: connectionPromise, }); return { @@ -508,7 +519,6 @@ sessionID, updatesCurrentAsOf, urlPrefix, - connection, }, }, }; @@ -585,6 +595,10 @@ communityPickerStore: { chat: null, calendar: null }, windowDimensions: { width: 0, height: 0 }, notifPermissionAlertInfo: defaultNotifPermissionAlertInfo, + connection: (async () => ({ + ...defaultConnectionInfo(viewer.platform ?? 'web', viewer.timeZone), + actualizedCalendarQuery: await calendarQueryPromise, + }))(), watchedThreadIDs: [], lifecycleState: 'active', enabledApps: defaultWebEnabledApps, diff --git a/lib/hooks/disconnected-bar.js b/lib/hooks/disconnected-bar.js --- a/lib/hooks/disconnected-bar.js +++ b/lib/hooks/disconnected-bar.js @@ -1,19 +1,16 @@ // @flow -import invariant from 'invariant'; import * as React from 'react'; import { useDispatch } from 'react-redux'; -import { connectionSelector } from '../selectors/keyserver-selectors.js'; import { updateDisconnectedBarActionType } from '../types/socket-types.js'; import { useSelector } from '../utils/redux-utils.js'; function useDisconnectedBarVisibilityHandler(networkConnected: boolean): void { const dispatch = useDispatch(); - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); - - const disconnected = connection.showDisconnectedBar; + const disconnected = useSelector( + state => state.connection.showDisconnectedBar, + ); const setDisconnected = React.useCallback( (newDisconnected: boolean) => { if (newDisconnected === disconnected) { @@ -36,8 +33,10 @@ }, [setDisconnected, networkConnected]); const prevConnectionStatusRef = React.useRef(); - const connectionStatus = connection.status; - const someRequestIsLate = connection.lateResponses.length !== 0; + const connectionStatus = useSelector(state => state.connection.status); + const someRequestIsLate = useSelector( + state => state.connection.lateResponses.length !== 0, + ); React.useEffect(() => { const prevConnectionStatus = prevConnectionStatusRef.current; prevConnectionStatusRef.current = connectionStatus; @@ -67,10 +66,12 @@ +disconnected: boolean, +shouldShowDisconnectedBar: boolean, } { - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); - const disconnected = connection.showDisconnectedBar; - const socketConnected = connection.status === 'connected'; + const disconnected = useSelector( + state => state.connection.showDisconnectedBar, + ); + const socketConnected = useSelector( + state => state.connection.status === 'connected', + ); const shouldShowDisconnectedBar = disconnected || !socketConnected; return { disconnected, shouldShowDisconnectedBar }; diff --git a/lib/reducers/connection-reducer.js b/lib/reducers/connection-reducer.js --- a/lib/reducers/connection-reducer.js +++ b/lib/reducers/connection-reducer.js @@ -10,7 +10,6 @@ logInActionTypes, registerActionTypes, } from '../actions/user-actions.js'; -import { connectionSelector } from '../selectors/keyserver-selectors.js'; import { queueActivityUpdatesActionType } from '../types/activity-types.js'; import { defaultCalendarQuery } from '../types/entry-types.js'; import { type BaseAction, rehydrateActionType } from '../types/redux-types.js'; @@ -94,15 +93,11 @@ actualizedCalendarQuery: action.payload.calendarQuery, }; } else if (action.type === rehydrateActionType) { - if (!action.payload) { - return state; - } - const connection = connectionSelector(action.payload); - if (!connection) { + if (!action.payload || !action.payload.connection) { return state; } return { - ...connection, + ...action.payload.connection, status: 'connecting', queuedActivityUpdates: [], lateResponses: [], 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,6 +1,5 @@ // @flow -import reduceConnectionInfo from './connection-reducer.js'; import reduceUpdatesCurrentAsOf from './updates-reducer.js'; import { siweAuthActionTypes } from '../actions/siwe-actions.js'; import { @@ -33,7 +32,7 @@ keyserverInfos[key] = { ...keyserverInfos[key], cookie: null }; } - state = { + return { ...state, keyserverInfos: { ...keyserverInfos, @@ -45,7 +44,7 @@ }; } else if (action.type === setNewSessionActionType) { if (action.payload.sessionChange.cookie !== undefined) { - state = { + return { ...state, keyserverInfos: { ...state.keyserverInfos, @@ -67,7 +66,7 @@ state.keyserverInfos[ashoatKeyserverID].updatesCurrentAsOf, action, ); - state = { + return { ...state, keyserverInfos: { ...state.keyserverInfos, @@ -78,7 +77,7 @@ }, }; } else if (action.type === setURLPrefix) { - state = { + return { ...state, keyserverInfos: { ...state.keyserverInfos, @@ -90,20 +89,5 @@ }; } - const connection = reduceConnectionInfo( - state.keyserverInfos[ashoatKeyserverID].connection, - action, - ); - state = { - ...state, - keyserverInfos: { - ...state.keyserverInfos, - [ashoatKeyserverID]: { - ...state.keyserverInfos[ashoatKeyserverID], - connection, - }, - }, - }; - 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 @@ -1,6 +1,7 @@ // @flow import reduceCalendarFilters from './calendar-filters-reducer.js'; +import reduceConnectionInfo from './connection-reducer.js'; import reduceDataLoaded from './data-loaded-reducer.js'; import { reduceDeviceToken } from './device-token-reducer.js'; import { reduceDraftStore } from './draft-reducer.js'; @@ -58,11 +59,12 @@ reduceMessageStore(state.messageStore, action, threadInfos); let messageStore = reducedMessageStore; + const connection = reduceConnectionInfo(state.connection, action); + let keyserverStore = reduceKeyserverStore(state.keyserverStore, action); if ( - keyserverStore.keyserverInfos[ashoatKeyserverID].connection.status !== - 'connected' && + connection.status !== 'connected' && action.type !== incrementalStateSyncActionType && action.type !== fullStateSyncActionType && action.type !== registerActionTypes.success && @@ -128,6 +130,7 @@ state.notifPermissionAlertInfo, action, ), + connection, lifecycleState: reduceLifecycleState(state.lifecycleState, action), enabledApps: reduceEnabledApps(state.enabledApps, action), reportStore, 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 @@ -4,7 +4,6 @@ import type { KeyserverInfo } from '../types/keyserver-types'; import type { AppState } from '../types/redux-types.js'; -import type { ConnectionInfo } from '../types/socket-types.js'; import { ashoatKeyserverID } from '../utils/validation-utils.js'; const cookieSelector: (state: AppState) => ?string = (state: AppState) => @@ -38,10 +37,6 @@ const urlPrefixSelector: (state: AppState) => ?string = (state: AppState) => state.keyserverStore.keyserverInfos[ashoatKeyserverID]?.urlPrefix; -const connectionSelector: (state: AppState) => ?ConnectionInfo = ( - state: AppState, -) => state.keyserverStore.keyserverInfos[ashoatKeyserverID]?.connection; - export { cookieSelector, cookiesSelector, @@ -49,5 +44,4 @@ updatesCurrentAsOfSelector, currentAsOfSelector, urlPrefixSelector, - connectionSelector, }; diff --git a/lib/selectors/server-calls.js b/lib/selectors/server-calls.js --- a/lib/selectors/server-calls.js +++ b/lib/selectors/server-calls.js @@ -6,14 +6,10 @@ cookieSelector, sessionIDSelector, urlPrefixSelector, - connectionSelector, } from './keyserver-selectors.js'; import type { LastCommunicatedPlatformDetails } from '../types/device-types.js'; import type { AppState } from '../types/redux-types.js'; -import type { - ConnectionInfo, - ConnectionStatus, -} from '../types/socket-types.js'; +import { type ConnectionStatus } from '../types/socket-types.js'; import { type CurrentUserInfo } from '../types/user-types.js'; export type ServerCallState = { @@ -21,7 +17,7 @@ +urlPrefix: ?string, +sessionID: ?string, +currentUserInfo: ?CurrentUserInfo, - +connectionStatus: ?ConnectionStatus, + +connectionStatus: ConnectionStatus, +lastCommunicatedPlatformDetails: LastCommunicatedPlatformDetails, }; @@ -31,21 +27,21 @@ urlPrefixSelector, sessionIDSelector, (state: AppState) => state.currentUserInfo, - connectionSelector, + (state: AppState) => state.connection.status, (state: AppState) => state.lastCommunicatedPlatformDetails, ( cookie: ?string, urlPrefix: ?string, sessionID: ?string, currentUserInfo: ?CurrentUserInfo, - connectionInfo: ?ConnectionInfo, + connectionStatus: ConnectionStatus, lastCommunicatedPlatformDetails: LastCommunicatedPlatformDetails, ) => ({ cookie, urlPrefix, sessionID, currentUserInfo, - connectionStatus: connectionInfo?.status, + connectionStatus, lastCommunicatedPlatformDetails, }), ); diff --git a/lib/socket/activity-handler.react.js b/lib/socket/activity-handler.react.js --- a/lib/socket/activity-handler.react.js +++ b/lib/socket/activity-handler.react.js @@ -1,6 +1,5 @@ // @flow -import invariant from 'invariant'; import * as React from 'react'; import { useDispatch } from 'react-redux'; @@ -8,7 +7,6 @@ updateActivityActionTypes, updateActivity, } from '../actions/activity-actions.js'; -import { connectionSelector } from '../selectors/keyserver-selectors.js'; import { getMostRecentNonLocalMessageID } from '../shared/message-utils.js'; import { threadIsPending } from '../shared/thread-utils.js'; import { queueActivityUpdatesActionType } from '../types/activity-types.js'; @@ -31,8 +29,7 @@ }, [activeThread]); const prevActiveThread = prevActiveThreadRef.current; - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); + const connection = useSelector(state => state.connection); const connectionStatus = connection.status; const prevConnectionStatusRef = React.useRef(); React.useEffect(() => { diff --git a/lib/socket/api-request-handler.react.js b/lib/socket/api-request-handler.react.js --- a/lib/socket/api-request-handler.react.js +++ b/lib/socket/api-request-handler.react.js @@ -4,7 +4,6 @@ import * as React from 'react'; import { InflightRequests } from './inflight-requests.js'; -import { connectionSelector } from '../selectors/keyserver-selectors.js'; import type { APIRequest } from '../types/endpoints.js'; import { clientSocketMessageTypes, @@ -36,7 +35,7 @@ // will wait for the response before shutting down. But if Socket starts // shutting down first, we'll have a problem. Note that this approach only // stops the race in fetchResponse below, and not in action-utils (which - // happens earlier via the registerActiveSocket call below), but empirically + // happens earlier via the registerActiveSocket call below), but empircally // that hasn't been an issue. // The reason I didn't rewrite this to happen in a single component is // because I want to maintain separation of concerns. Upcoming React Hooks @@ -93,8 +92,7 @@ const ConnectedAPIRequestHandler: React.ComponentType = React.memo(function ConnectedAPIRequestHandler(props) { - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); + const connection = useSelector(state => state.connection); return ; }); diff --git a/lib/socket/calendar-query-handler.react.js b/lib/socket/calendar-query-handler.react.js --- a/lib/socket/calendar-query-handler.react.js +++ b/lib/socket/calendar-query-handler.react.js @@ -1,6 +1,5 @@ // @flow -import invariant from 'invariant'; import _isEqual from 'lodash/fp/isEqual.js'; import * as React from 'react'; @@ -8,7 +7,6 @@ updateCalendarQueryActionTypes, updateCalendarQuery, } from '../actions/entry-actions.js'; -import { connectionSelector } from '../selectors/keyserver-selectors.js'; import { timeUntilCalendarRangeExpiration } from '../selectors/nav-selectors.js'; import { useIsAppForegrounded } from '../shared/lifecycle-utils.js'; import type { @@ -124,8 +122,7 @@ const ConnectedCalendarQueryHandler: React.ComponentType = React.memo(function ConnectedCalendarQueryHandler(props) { - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); + const connection = useSelector(state => state.connection); const lastUserInteractionCalendar = useSelector( state => state.entryStore.lastUserInteractionCalendar, ); diff --git a/lib/socket/request-response-handler.react.js b/lib/socket/request-response-handler.react.js --- a/lib/socket/request-response-handler.react.js +++ b/lib/socket/request-response-handler.react.js @@ -5,7 +5,6 @@ import { useDispatch } from 'react-redux'; import { InflightRequests } from './inflight-requests.js'; -import { connectionSelector } from '../selectors/keyserver-selectors.js'; import type { CalendarQuery } from '../types/entry-types.js'; import type { Dispatch } from '../types/redux-types.js'; import { @@ -137,9 +136,7 @@ const ConnectedRequestResponseHandler: React.ComponentType = React.memo(function ConnectedRequestResponseHandler(props) { - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); - + const connection = useSelector(state => state.connection); const dispatch = useDispatch(); return ( diff --git a/lib/socket/update-handler.react.js b/lib/socket/update-handler.react.js --- a/lib/socket/update-handler.react.js +++ b/lib/socket/update-handler.react.js @@ -1,11 +1,9 @@ // @flow -import invariant from 'invariant'; import * as React from 'react'; import { useEffect } from 'react'; import { useDispatch } from 'react-redux'; -import { connectionSelector } from '../selectors/keyserver-selectors.js'; import { type ClientSocketMessageWithoutID, type SocketListener, @@ -25,9 +23,7 @@ const { addListener, removeListener, sendMessage } = props; const dispatch = useDispatch(); - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); - const connectionStatus = connection.status; + const connectionStatus = useSelector(state => state.connection.status); const onMessage = React.useCallback( (message: ClientServerSocketMessage) => { if (message.type !== serverSocketMessageTypes.UPDATES) { 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 @@ -2,8 +2,6 @@ import t, { type TInterface } from 'tcomb'; -import { connectionInfoValidator } from './socket-types.js'; -import type { ConnectionInfo } from './socket-types.js'; import { tShape } from '../utils/validation-utils.js'; // Once we start using the cookie field on web, @@ -14,7 +12,6 @@ +sessionID?: ?string, +updatesCurrentAsOf: number, // millisecond timestamp +urlPrefix: string, - +connection: ConnectionInfo, }; export type KeyserverStore = { @@ -27,7 +24,6 @@ sessionID: t.maybe(t.String), updatesCurrentAsOf: t.Number, urlPrefix: t.String, - connection: connectionInfoValidator, }); 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 @@ -93,6 +93,7 @@ } from './search-types.js'; import type { SetSessionPayload } from './session-types.js'; import type { + ConnectionInfo, StateSyncFullActionPayload, StateSyncIncrementalActionPayload, UpdateConnectionStatusPayload, @@ -126,6 +127,7 @@ +loadingStatuses: { [key: string]: { [idx: number]: LoadingStatus } }, +calendarFilters: $ReadOnlyArray, +notifPermissionAlertInfo: NotifPermissionAlertInfo, + +connection: ConnectionInfo, +watchedThreadIDs: $ReadOnlyArray, +lifecycleState: LifecycleState, +enabledApps: EnabledApps, diff --git a/lib/utils/action-utils.js b/lib/utils/action-utils.js --- a/lib/utils/action-utils.js +++ b/lib/utils/action-utils.js @@ -431,16 +431,12 @@ const dispatch = useDispatch(); const serverCallState = useSelector(serverCallStateSelector); return React.useMemo(() => { - const { urlPrefix, connectionStatus } = serverCallState; - invariant( - !!urlPrefix && !!connectionStatus, - 'keyserver missing from keyserverStore', - ); + const { urlPrefix } = serverCallState; + invariant(urlPrefix, 'missing urlPrefix for given keyserver id'); return createBoundServerCallsSelector(serverCall)({ ...serverCallState, urlPrefix, - connectionStatus, dispatch, ...paramOverride, }); diff --git a/native/calendar/calendar.react.js b/native/calendar/calendar.react.js --- a/native/calendar/calendar.react.js +++ b/native/calendar/calendar.react.js @@ -24,7 +24,6 @@ updateCalendarQueryActionTypes, updateCalendarQuery, } from 'lib/actions/entry-actions.js'; -import { connectionSelector } from 'lib/selectors/keyserver-selectors.js'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; import { entryKey } from 'lib/shared/entry-utils.js'; import type { @@ -1069,9 +1068,7 @@ const calendarFilters = useSelector(state => state.calendarFilters); const dimensions = useSelector(derivedDimensionsInfoSelector); const loadingStatus = useSelector(loadingStatusSelector); - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); - const connectionStatus = connection.status; + const connectionStatus = useSelector(state => state.connection.status); const colors = useColors(); const styles = useStyles(unboundStyles); const indicatorStyle = useIndicatorStyle(); diff --git a/native/calendar/entry.react.js b/native/calendar/entry.react.js --- a/native/calendar/entry.react.js +++ b/native/calendar/entry.react.js @@ -28,7 +28,6 @@ concurrentModificationResetActionType, } from 'lib/actions/entry-actions.js'; import { registerFetchKey } from 'lib/reducers/loading-reducer.js'; -import { connectionSelector } from 'lib/selectors/keyserver-selectors.js'; import { colorIsDark } from 'lib/shared/color-utils.js'; import { entryKey } from 'lib/shared/entry-utils.js'; import { threadHasPermission } from 'lib/shared/thread-utils.js'; @@ -784,9 +783,9 @@ navContext, }), ); - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); - const online = connection.status === 'connected'; + const online = useSelector( + state => state.connection.status === 'connected', + ); const styles = useStyles(unboundStyles); const navigateToThread = useNavigateToThread(); diff --git a/native/media/encrypted-image.react.js b/native/media/encrypted-image.react.js --- a/native/media/encrypted-image.react.js +++ b/native/media/encrypted-image.react.js @@ -1,10 +1,8 @@ // @flow -import invariant from 'invariant'; import * as React from 'react'; import { MediaCacheContext } from 'lib/components/media-cache-provider.react.js'; -import { connectionSelector } from 'lib/selectors/keyserver-selectors.js'; import { decryptBase64, decryptMedia } from './encryption-utils.js'; import LoadableImage from './loadable-image.react.js'; @@ -35,9 +33,7 @@ const mediaCache = React.useContext(MediaCacheContext); const [source, setSource] = React.useState(null); - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); - const connectionStatus = connection.status; + const connectionStatus = useSelector(state => state.connection.status); const prevConnectionStatusRef = React.useRef(connectionStatus); const [attempt, setAttempt] = React.useState(0); const [errorOccured, setErrorOccured] = React.useState(false); diff --git a/native/media/remote-image.react.js b/native/media/remote-image.react.js --- a/native/media/remote-image.react.js +++ b/native/media/remote-image.react.js @@ -1,10 +1,8 @@ // @flow -import invariant from 'invariant'; import * as React from 'react'; import type { ImageSource } from 'react-native/Libraries/Image/ImageSource'; -import { connectionSelector } from 'lib/selectors/keyserver-selectors.js'; import { type ConnectionStatus } from 'lib/types/socket-types.js'; import LoadableImage from './loadable-image.react.js'; @@ -69,9 +67,7 @@ const ConnectedRemoteImage: React.ComponentType = React.memo(function ConnectedRemoteImage(props: BaseProps) { - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); - const connectionStatus = connection.status; + const connectionStatus = useSelector(state => state.connection.status); return ; }); 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 @@ -1,7 +1,6 @@ // @flow import * as Haptics from 'expo-haptics'; -import invariant from 'invariant'; import * as React from 'react'; import { Platform, LogBox } from 'react-native'; import { Notification as InAppNotification } from 'react-native-in-app-message'; @@ -12,10 +11,7 @@ setDeviceToken, } from 'lib/actions/device-actions.js'; import { saveMessagesActionType } from 'lib/actions/message-actions.js'; -import { - updatesCurrentAsOfSelector, - connectionSelector, -} from 'lib/selectors/keyserver-selectors.js'; +import { updatesCurrentAsOfSelector } from 'lib/selectors/keyserver-selectors.js'; import { unreadCount, threadInfoSelector, @@ -645,8 +641,7 @@ const notifPermissionAlertInfo = useSelector( state => state.notifPermissionAlertInfo, ); - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); + const connection = useSelector(state => state.connection); const updatesCurrentAsOf = useSelector(updatesCurrentAsOfSelector); const activeTheme = useSelector(state => state.globalThemeInfo.activeTheme); const loggedIn = useSelector(isLoggedIn); diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -716,6 +716,26 @@ }, }; }, + [49]: async state => { + const { keyserverStore, ...rest } = state; + + const { connection, ...keyserverRest } = + keyserverStore.keyserverInfos[ashoatKeyserverID]; + + return { + ...rest, + keyserverStore: { + ...keyserverStore, + keyserverInfos: { + ...keyserverStore.keyserverInfos, + [ashoatKeyserverID]: { + ...keyserverRest, + }, + }, + }, + connection, + }; + }, }; // After migration 31, we'll no longer want to persist `messageStore.messages` @@ -810,7 +830,7 @@ 'storeLoaded', ], debug: __DEV__, - version: 48, + version: 49, 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 @@ -94,6 +94,7 @@ dataLoaded: false, customServer: natNodeServer, notifPermissionAlertInfo: defaultNotifPermissionAlertInfo, + connection: defaultConnectionInfo(Platform.OS), watchedThreadIDs: [], lifecycleState: 'active', enabledApps: defaultEnabledApps, @@ -124,7 +125,6 @@ [ashoatKeyserverID]: { updatesCurrentAsOf: 0, urlPrefix: defaultURLPrefix, - connection: defaultConnectionInfo(Platform.OS), }, }, }, 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 @@ -15,6 +15,7 @@ import type { MessageStore } from 'lib/types/message-types.js'; import type { UserPolicies } from 'lib/types/policy-types.js'; import type { ReportStore } from 'lib/types/report-types.js'; +import type { ConnectionInfo } from 'lib/types/socket-types.js'; import type { ThreadStore } from 'lib/types/thread-types.js'; import type { CurrentUserInfo, UserStore } from 'lib/types/user-types.js'; import type { NotifPermissionAlertInfo } from 'lib/utils/push-alerts.js'; @@ -40,6 +41,7 @@ +dataLoaded: boolean, +customServer: ?string, +notifPermissionAlertInfo: NotifPermissionAlertInfo, + +connection: ConnectionInfo, +watchedThreadIDs: $ReadOnlyArray, +lifecycleState: LifecycleState, +enabledApps: EnabledApps, diff --git a/native/socket.react.js b/native/socket.react.js --- a/native/socket.react.js +++ b/native/socket.react.js @@ -9,7 +9,6 @@ import { cookieSelector, urlPrefixSelector, - connectionSelector, } from 'lib/selectors/keyserver-selectors.js'; import { isLoggedIn } from 'lib/selectors/user-selectors.js'; import { accountHasPassword } from 'lib/shared/account-utils.js'; @@ -46,8 +45,7 @@ const cookie = useSelector(cookieSelector); const urlPrefix = useSelector(urlPrefixSelector); invariant(urlPrefix, 'missing urlPrefix for given keyserver id'); - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); + const connection = useSelector(state => state.connection); const frozen = useSelector(state => state.frozen); const active = useSelector( state => isLoggedIn(state) && state.lifecycleState !== 'background', diff --git a/web/calendar/entry.react.js b/web/calendar/entry.react.js --- a/web/calendar/entry.react.js +++ b/web/calendar/entry.react.js @@ -18,7 +18,6 @@ useModalContext, type PushModal, } from 'lib/components/modal-provider.react.js'; -import { connectionSelector } from 'lib/selectors/keyserver-selectors.js'; import { threadInfoSelector } from 'lib/selectors/thread-selectors.js'; import { colorIsDark } from 'lib/shared/color-utils.js'; import { entryKey } from 'lib/shared/entry-utils.js'; @@ -473,9 +472,9 @@ !!(state.currentUserInfo && !state.currentUserInfo.anonymous && true), ); const calendarQuery = useSelector(nonThreadCalendarQuery); - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); - const online = connection.status === 'connected'; + const online = useSelector( + state => state.connection.status === 'connected', + ); const callCreateEntry = useServerCall(createEntry); const callSaveEntry = useServerCall(saveEntry); const callDeleteEntry = useServerCall(deleteEntry); 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 @@ -31,6 +31,7 @@ import type { UserPolicies } from 'lib/types/policy-types.js'; import type { BaseAction } from 'lib/types/redux-types.js'; import type { ReportStore } from 'lib/types/report-types.js'; +import type { ConnectionInfo } from 'lib/types/socket-types.js'; import type { ThreadStore } from 'lib/types/thread-types.js'; import type { CurrentUserInfo, UserStore } from 'lib/types/user-types.js'; import { setNewSessionActionType } from 'lib/utils/action-utils.js'; @@ -81,6 +82,7 @@ +windowDimensions: WindowDimensions, +deviceToken: ?string, +notifPermissionAlertInfo: NotifPermissionAlertInfo, + +connection: ConnectionInfo, +watchedThreadIDs: $ReadOnlyArray, +lifecycleState: LifecycleState, +enabledApps: EnabledApps, diff --git a/web/socket.react.js b/web/socket.react.js --- a/web/socket.react.js +++ b/web/socket.react.js @@ -9,7 +9,6 @@ import { cookieSelector, urlPrefixSelector, - connectionSelector, } from 'lib/selectors/keyserver-selectors.js'; import Socket, { type BaseSocketProps } from 'lib/socket/socket.react.js'; import { @@ -34,8 +33,7 @@ const cookie = useSelector(cookieSelector); const urlPrefix = useSelector(urlPrefixSelector); invariant(urlPrefix, 'missing urlPrefix for given keyserver id'); - const connection = useSelector(connectionSelector); - invariant(connection, 'keyserver missing from keyserverStore'); + const connection = useSelector(state => state.connection); const active = useSelector( state => !!state.currentUserInfo &&