From f8675b4110e3a06c32e3a26ad3609dc5b4a36a9c Mon Sep 17 00:00:00 2001 From: Andrew Bulat Date: Mon, 3 Jun 2024 05:50:28 +0100 Subject: [PATCH 1/2] Add type overload for `useChannelStateListener` Function code supports calling `useChannelStateListener` with options object and listener only, but there was not TypeScript type for such overload. --- src/platform/react-hooks/src/hooks/useChannelStateListener.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform/react-hooks/src/hooks/useChannelStateListener.ts b/src/platform/react-hooks/src/hooks/useChannelStateListener.ts index d69ce254f..b64d623d9 100644 --- a/src/platform/react-hooks/src/hooks/useChannelStateListener.ts +++ b/src/platform/react-hooks/src/hooks/useChannelStateListener.ts @@ -7,6 +7,8 @@ type ChannelStateListener = (stateChange: Ably.ChannelStateChange) => any; export function useChannelStateListener(channelName: string, listener?: ChannelStateListener); +export function useChannelStateListener(options: ChannelNameAndAblyId, listener?: ChannelStateListener); + export function useChannelStateListener( options: ChannelNameAndAblyId | string, state?: Ably.ChannelState | Ably.ChannelState[], From 73e526684ba43fc21afcdacb1ead63c99d48dacd Mon Sep 17 00:00:00 2001 From: Andrew Bulat Date: Mon, 3 Jun 2024 05:53:40 +0100 Subject: [PATCH 2/2] Fix `Unable to enter presence channel while in suspended state` for `usePresence` Similar to the fix in https://github.com/ably/ably-js/pull/1761 with `Connection closed` errors, we should avoid entering presence for specific channel states. Resolves #1780 --- src/platform/react-hooks/src/hooks/usePresence.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/platform/react-hooks/src/hooks/usePresence.ts b/src/platform/react-hooks/src/hooks/usePresence.ts index c4c7caf8f..d301c336a 100644 --- a/src/platform/react-hooks/src/hooks/usePresence.ts +++ b/src/platform/react-hooks/src/hooks/usePresence.ts @@ -5,6 +5,7 @@ import { useAbly } from './useAbly.js'; import { useChannelInstance } from './useChannelInstance.js'; import { useStateErrors } from './useStateErrors.js'; import { useConnectionStateListener } from './useConnectionStateListener.js'; +import { useChannelStateListener } from './useChannelStateListener.js'; export interface PresenceResult { updateStatus: (messageOrPresenceObject: T) => Promise; @@ -13,6 +14,7 @@ export interface PresenceResult { } const INACTIVE_CONNECTION_STATES: Ably.ConnectionState[] = ['suspended', 'closing', 'closed', 'failed']; +const INACTIVE_CHANNEL_STATES: Ably.ChannelState[] = ['failed', 'suspended', 'detaching']; export function usePresence( channelNameOrNameAndOptions: ChannelParameters, @@ -47,7 +49,16 @@ export function usePresence( useConnectionStateListener((stateChange) => { setConnectionState(stateChange.current); }); - const shouldNotEnterPresence = INACTIVE_CONNECTION_STATES.includes(connectionState) || skip; + + // similar to connection states, we should only attempt to enter presence when in certain + // channel states. + const [channelState, setChannelState] = useState(channel.state); + useChannelStateListener(params, (stateChange) => { + setChannelState(stateChange.current); + }); + + const shouldNotEnterPresence = + INACTIVE_CONNECTION_STATES.includes(connectionState) || INACTIVE_CHANNEL_STATES.includes(channelState) || skip; useEffect(() => { if (shouldNotEnterPresence) {