Skip to content

Commit

Permalink
feat(): introduce useCreateChatClient hook
Browse files Browse the repository at this point in the history
  • Loading branch information
arnautov-anton committed Oct 13, 2023
1 parent 799bfb0 commit 88c43d9
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 0 deletions.
123 changes: 123 additions & 0 deletions src/components/Chat/hooks/useCreateChatClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { useEffect, useState } from 'react';

import {
DefaultGenerics,
ExtendableGenerics,
OwnUserResponse,
StreamChat,
TokenOrProvider,
UserResponse,
} from 'stream-chat';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const makeCancellable = <T extends (...functionArguments: any[]) => any>(
functionToCancel: T,
delay: number,
) => {
let timeout: NodeJS.Timeout | null = null;

Check warning on line 17 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L17

Added line #L17 was not covered by tests

const start = (...functionArguments: Parameters<T>) =>
new Promise<ReturnType<T>>((resolve, reject) => {

Check warning on line 20 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L19-L20

Added lines #L19 - L20 were not covered by tests
if (timeout) return reject(new Error('"start" has been already called'));
timeout = setTimeout(() => {
timeout = null;
try {
resolve(functionToCancel(...functionArguments));

Check warning on line 25 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L22-L25

Added lines #L22 - L25 were not covered by tests
} catch (error) {
reject(error);

Check warning on line 27 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L27

Added line #L27 was not covered by tests
}
}, delay);
});

const cancel = () => {

Check warning on line 32 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L32

Added line #L32 was not covered by tests
if (timeout === null) return;
clearTimeout(timeout);
timeout = null;

Check warning on line 35 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L34-L35

Added lines #L34 - L35 were not covered by tests
};

return [cancel, start] as const;

Check warning on line 38 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L38

Added line #L38 was not covered by tests
};

/**
* React hook to create, connect and return `StreamChat` client.
*/
export const useCreateChatClient = <SCG extends ExtendableGenerics = DefaultGenerics>({
apiKey,
tokenOrProvider,
userData,

Check warning on line 47 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L45-L47

Added lines #L45 - L47 were not covered by tests
}: {
apiKey: string;
tokenOrProvider: TokenOrProvider;
userData: OwnUserResponse<SCG> | UserResponse<SCG>;
}) => {
const [chatClient, setChatClient] = useState<StreamChat<SCG> | null>(null);

Check warning on line 53 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L53

Added line #L53 was not covered by tests

useEffect(() => {
const client = new StreamChat<SCG>(apiKey);
let didUserConnectInterrupt = false;

Check warning on line 57 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L55-L57

Added lines #L55 - L57 were not covered by tests

const connectionPromise = client.connectUser(userData, tokenOrProvider).then(() => {

Check warning on line 59 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L59

Added line #L59 was not covered by tests
if (!didUserConnectInterrupt) setChatClient(client);
});

return () => {
didUserConnectInterrupt = true;
setChatClient(null);
connectionPromise
.then(() => client.disconnectUser())

Check warning on line 67 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L63-L67

Added lines #L63 - L67 were not covered by tests
.then(() => {
console.log(`Connection for user "${userData.id}" has been closed`);

Check warning on line 69 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L69

Added line #L69 was not covered by tests
});
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [apiKey, userData.id, tokenOrProvider]);

return chatClient;

Check warning on line 75 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L75

Added line #L75 was not covered by tests
};

/**
* React hook to create, connect and return `StreamChat` client with debounced connector.
* Delays initial connection by the specified `cancellationTimeout` (defaults to 200 ms).
* Useful for applications where there's a need to switch users extremely fast without initiating connection.
*/
export const useCancelableCreateChatClient_UNSTABLE = <
SCG extends ExtendableGenerics = DefaultGenerics
>({
apiKey,

Check warning on line 86 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L86

Added line #L86 was not covered by tests
cancellationTimeout = 200,
tokenOrProvider,
userData,

Check warning on line 89 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L88-L89

Added lines #L88 - L89 were not covered by tests
}: {
apiKey: string;
tokenOrProvider: TokenOrProvider;
userData: OwnUserResponse<SCG> | UserResponse<SCG>;
cancellationTimeout?: number;
}) => {
const [chatClient, setChatClient] = useState<StreamChat<SCG> | null>(null);

Check warning on line 96 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L96

Added line #L96 was not covered by tests

useEffect(() => {
const client = new StreamChat<SCG>(apiKey);

Check warning on line 99 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L98-L99

Added lines #L98 - L99 were not covered by tests

let didUserConnectInterrupt = false;
const [cancel, start] = makeCancellable(client.connectUser, cancellationTimeout);
const connectionPromise = start(userData, tokenOrProvider).then(() => {

Check warning on line 103 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L101-L103

Added lines #L101 - L103 were not covered by tests
// in case user missed cancelation timeout
// but the connection has been initiated
if (!didUserConnectInterrupt) setChatClient(client);
});

return () => {
cancel();
didUserConnectInterrupt = true;
setChatClient(null);
connectionPromise
.then(() => client.disconnectUser())

Check warning on line 114 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L109-L114

Added lines #L109 - L114 were not covered by tests
.then(() => {
console.log(`Connection for user "${userData.id}" has been closed`);

Check warning on line 116 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L116

Added line #L116 was not covered by tests
});
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [apiKey, userData.id, tokenOrProvider]);

return chatClient;

Check warning on line 122 in src/components/Chat/hooks/useCreateChatClient.ts

View check run for this annotation

Codecov / codecov/patch

src/components/Chat/hooks/useCreateChatClient.ts#L122

Added line #L122 was not covered by tests
};
1 change: 1 addition & 0 deletions src/components/Chat/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './Chat';
export * from './hooks/useChat';
export * from './hooks/useCustomStyles';
export * from './hooks/useCreateChatClient';

0 comments on commit 88c43d9

Please sign in to comment.