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[], 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) {