diff --git a/lib/hooks/relationship-hooks.js b/lib/hooks/relationship-hooks.js --- a/lib/hooks/relationship-hooks.js +++ b/lib/hooks/relationship-hooks.js @@ -5,6 +5,7 @@ import { useNewThickThread } from './thread-hooks.js'; import { useUsersSupportThickThreads } from './user-identities-hooks.js'; +import { useWaitForConnection } from './wait-for-connection.js'; import { updateRelationships as serverUpdateRelationships } from '../actions/relationship-actions.js'; import { useLegacyAshoatKeyserverCall } from '../keyserver-conn/legacy-keyserver-call.js'; import { pendingToRealizedThreadIDsSelector } from '../selectors/thread-selectors.js'; @@ -89,6 +90,8 @@ const mapUsersSupportingThickThreads = useUsersSupportThickThreads(); + const waitForConnection = useWaitForConnection(); + const updateRelationshipsAndSendRobotext = React.useCallback( async (action: RelationshipAction, userIDs: $ReadOnlyArray) => { if (!viewerID) { @@ -97,6 +100,7 @@ ); return {}; } + await waitForConnection(); const usersSupportingThickThreads = await mapUsersSupportingThickThreads(userIDs); const planForUsers = new Map(); @@ -229,6 +233,7 @@ userInfos, rawThreadInfos, createNewThickThread, + waitForConnection, ], ); diff --git a/lib/hooks/wait-for-connection.js b/lib/hooks/wait-for-connection.js new file mode 100644 --- /dev/null +++ b/lib/hooks/wait-for-connection.js @@ -0,0 +1,44 @@ +// @flow + +import * as React from 'react'; + +import { connectionSelector } from '../selectors/keyserver-selectors.js'; +import { useTunnelbroker } from '../tunnelbroker/tunnelbroker-context.js'; +import { authoritativeKeyserverID } from '../utils/authoritative-keyserver.js'; +import { useSelector } from '../utils/redux-utils.js'; + +function useWaitForConnection(): () => Promise { + const { socketState } = useTunnelbroker(); + + const connection = useSelector( + connectionSelector(authoritativeKeyserverID()), + ); + + const resolveConnectionPromise = React.useRef void>(); + + const isConnectedOrUnreachable = React.useMemo(() => { + return ( + socketState.connected && + (connection?.unreachable || connection?.status === 'connected') + ); + }, [connection?.status, connection?.unreachable, socketState.connected]); + + React.useEffect(() => { + if (isConnectedOrUnreachable) { + resolveConnectionPromise.current?.(); + } + }, [isConnectedOrUnreachable]); + + const waitForConnection = React.useCallback((): Promise => { + if (isConnectedOrUnreachable) { + return Promise.resolve(); + } + return new Promise(resolve => { + resolveConnectionPromise.current = resolve; + }); + }, [isConnectedOrUnreachable]); + + return waitForConnection; +} + +export { useWaitForConnection };