Skip to content
This repository has been archived by the owner on Oct 30, 2023. It is now read-only.

[SDK-3801] feat: skip param for usePresence and useChannel #81

Merged
merged 3 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions sample-app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ import './App.css';

function App() {
const [messages, updateMessages] = useState<Types.Message[]>([]);
const { channel, ably } = useChannel('your-channel-name', (message) => {
updateMessages((prev) => [...prev, message]);
});
const [skip, setSkip] = useState(false);
const { channel, ably } = useChannel(
{ channelName: 'your-channel-name', skip },
(message) => {
updateMessages((prev) => [...prev, message]);
}
);

const { presenceData, updateStatus } = usePresence(
'your-channel-name',
{ channelName: 'your-channel-name', skip },
{ foo: 'bar' },
(update) => {
console.log(update);
Expand All @@ -38,7 +42,7 @@ function App() {
undefined | Types.ErrorInfo
>();

useChannelStateListener('your-channel-name', 'detached', (stateChange) => {
useChannelStateListener('your-channel-name', (stateChange) => {
setAblyErr(JSON.stringify(stateChange.reason));
setChannelState(stateChange.current);
setPreviousChannelState(stateChange.previous);
Expand Down Expand Up @@ -80,6 +84,10 @@ function App() {
<ConnectionState />
</div>
<div style={{ marginLeft: '250px' }}>
<h2>Skip</h2>
<button onClick={() => setSkip(!skip)}>
Toggle skip param
</button>
<h2>Channel detach</h2>
<button onClick={() => channel.detach()}>Detach</button>
<button onClick={() => ably.close()}>Close</button>
Expand Down
2 changes: 2 additions & 0 deletions src/AblyReactHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export type ChannelNameAndOptions = {
options?: Types.ChannelOptions;
id?: string;
subscribeOnly?: boolean;
skip?: boolean;

onConnectionError?: (error: Types.ErrorInfo) => unknown;
onChannelError?: (error: Types.ErrorInfo) => unknown;
};
Expand Down
2 changes: 1 addition & 1 deletion src/fakes/ably.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ export class ChannelPresence {

public unsubscribe(clientId: string, key: string) {
const subsForClient = this.subscriptionsPerClient.get(clientId);
subsForClient.set(key, []);
subsForClient?.set(key, []);
}

private triggerSubs(subType: string, data: any) {
Expand Down
40 changes: 33 additions & 7 deletions src/hooks/useChannel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ describe('useChannel', () => {
);

await act(async () => {
otherClient.channels.get('blah').publish({ text: 'message text' });
await otherClient.channels
.get('blah')
.publish({ text: 'message text' });
});

const messageUl = screen.getAllByRole('messages')[0];
Expand All @@ -61,8 +63,12 @@ describe('useChannel', () => {
);

await act(async () => {
otherClient.channels.get('blah').publish({ text: 'message text1' });
otherClient.channels.get('blah').publish({ text: 'message text2' });
await otherClient.channels
.get('blah')
.publish({ text: 'message text1' });
await otherClient.channels
.get('blah')
.publish({ text: 'message text2' });
});

const messageUl = screen.getAllByRole('messages')[0];
Expand All @@ -82,8 +88,12 @@ describe('useChannel', () => {
);

await act(async () => {
ablyClient.channels.get('blah').publish({ text: 'message text1' });
otherClient.channels.get('bleh').publish({ text: 'message text2' });
await ablyClient.channels
.get('blah')
.publish({ text: 'message text1' });
await otherClient.channels
.get('bleh')
.publish({ text: 'message text2' });
});

const messageUl = screen.getAllByRole('messages')[0];
Expand Down Expand Up @@ -143,6 +153,22 @@ describe('useChannel', () => {
expect(onConnectionError).toHaveBeenCalledWith(reason);
});

it('skip param', async () => {
renderInCtxProvider(
ablyClient,
<UseChannelComponent skip={true}></UseChannelComponent>
);

await act(async () => {
await otherClient.channels
.get('blah')
.publish({ text: 'message text' });
});

const messageUl = screen.getAllByRole('messages')[0];
expect(messageUl.childElementCount).toBe(0);
});

it('should use the latest version of the message callback', async () => {
let callbackCount = 0;

Expand Down Expand Up @@ -220,9 +246,9 @@ const UseChannelComponentMultipleClients = () => {
return <ul role="messages">{messagePreviews}</ul>;
};

const UseChannelComponent = () => {
const UseChannelComponent = ({ skip }: { skip?: boolean }) => {
const [messages, updateMessages] = useState<Types.Message[]>([]);
useChannel('blah', (message) => {
useChannel({ channelName: 'blah', skip }, (message) => {
updateMessages((prev) => [...prev, message]);
});

Expand Down
11 changes: 7 additions & 4 deletions src/hooks/useChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function useChannel(

const ably = useAbly(channelHookOptions.id);

const { channelName, options: channelOptions } = channelHookOptions;
const { channelName, options: channelOptions, skip } = channelHookOptions;

const channelEvent =
typeof eventOrCallback === 'string' ? eventOrCallback : null;
Expand Down Expand Up @@ -75,11 +75,14 @@ export function useChannel(
const subscribeArgs: SubscribeArgs =
channelEvent === null ? [listener] : [channelEvent, listener];

handleChannelMount(channel, ...subscribeArgs);
if (!skip) {
handleChannelMount(channel, ...subscribeArgs);
}

return () => {
handleChannelUnmount(channel, ...subscribeArgs);
!skip && handleChannelUnmount(channel, ...subscribeArgs);
};
}, [channelEvent, channel]);
}, [channelEvent, channel, skip]);

return { channel, ably, connectionError, channelError };
}
Expand Down
21 changes: 19 additions & 2 deletions src/hooks/usePresence.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ describe('usePresence', () => {
expect(values).toContain(`"data":{"foo":"bar"}`);
});

it('skip param', async () => {
renderInCtxProvider(
ablyClient,
<UsePresenceComponent skip={true}></UsePresenceComponent>
);

await act(async () => {
await wait(2);
});

const values = screen.getByRole('presence').innerHTML;
expect(values).to.not.contain(`"bar"`);
});

it('usePresence works with multiple clients', async () => {
renderInCtxProvider(
ablyClient,
Expand Down Expand Up @@ -180,8 +194,11 @@ describe('usePresence', () => {
});
});

const UsePresenceComponent = () => {
const { presenceData, updateStatus } = usePresence(testChannelName, 'bar');
const UsePresenceComponent = ({ skip }: { skip?: boolean }) => {
const { presenceData, updateStatus } = usePresence(
{ channelName: testChannelName, skip },
'bar'
);

const presentUsers = presenceData.map((presence, index) => {
return (
Expand Down
5 changes: 3 additions & 2 deletions src/hooks/usePresence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export function usePresence<T = any>(
: params.subscribeOnly;

const channel = ably.channels.get(params.channelName, params.options);
const skip = params.skip;

const { connectionError, channelError } = useStateErrors(params);

Expand Down Expand Up @@ -75,14 +76,14 @@ export function usePresence<T = any>(
};

const useEffectHook = () => {
onMount();
!skip && onMount();
return () => {
onUnmount();
};
};

// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(useEffectHook, []);
useEffect(useEffectHook, [skip]);

const updateStatus = useCallback(
(messageOrPresenceObject: T) => {
Expand Down