From 6def297f985b76e660db3d3fa10dfd9d014e37c7 Mon Sep 17 00:00:00 2001 From: Piotr Suwala Date: Mon, 24 Oct 2022 11:52:48 +0200 Subject: [PATCH 1/9] chore: enable strict for tsc --- .gitignore | 2 ++ package.json | 2 +- tsconfig.json | 2 +- turbo.json | 5 +++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 7ce39b42e..60d8806bf 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,5 @@ npm-debug.log* yarn-debug.log* yarn-error.log* *.tsbuildinfo + +.idea diff --git a/package.json b/package.json index cc566c5f5..d4c7145cd 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "start": "concurrently \"cd packages/react && npm run build:watch\" \"cd samples/react/group-chat && npm run start\"", "start:rn": "concurrently \"cd packages/react-native && npm run build:watch\" \"cd samples/react-native/mobile-chat && npm run start\"", "test": "turbo run test", - "tsc": "turbo run tsc && echo" + "tsc": "turbo run tsc" }, "devDependencies": { "@commitlint/cli": "17.1.2", diff --git a/tsconfig.json b/tsconfig.json index 69703f95d..54f809164 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,6 @@ "esModuleInterop": true, "noEmit": true, "skipLibCheck": true, - "strict": false + "strict": true } } diff --git a/turbo.json b/turbo.json index 331d99fae..e32180efb 100644 --- a/turbo.json +++ b/turbo.json @@ -10,8 +10,9 @@ "outputs": ["dist/**"] }, "tsc": { - "dependsOn": ["build"], - "outputs": [] + "dependsOn": [], + "outputs": [], + "cache": false } } } From f6b4e9c65ec9e95d3a18b7cc57aa8db6403e42c9 Mon Sep 17 00:00:00 2001 From: Piotr Suwala Date: Mon, 24 Oct 2022 17:19:03 +0200 Subject: [PATCH 2/9] chore: fix some files --- packages/common/mock/pubnub-mock.ts | 104 ++++++++++-------- packages/common/package.json | 1 + .../common/src/channel-list/channel-list.tsx | 2 +- packages/common/src/chat/chat.tsx | 40 +++---- tsconfig.json | 3 +- yarn.lock | 5 + 6 files changed, 89 insertions(+), 66 deletions(-) diff --git a/packages/common/mock/pubnub-mock.ts b/packages/common/mock/pubnub-mock.ts index 887e6f558..974be742b 100644 --- a/packages/common/mock/pubnub-mock.ts +++ b/packages/common/mock/pubnub-mock.ts @@ -6,12 +6,20 @@ import type { PublishResponse, SignalResponse, SendFileResponse, + MessageActionEvent, + AddMessageActionParameters, + FetchMessagesParameters, + HereNowParameters, + PublishParameters, + SignalParameters, + GetAllMetadataParameters, } from "pubnub"; import { users, loremMessages as messages, workChannels as channels, } from "@pubnub/sample-chat-data"; +import { GetUUIDMetadataParameters, RemoveMessageActionParameters, SendFileParameters } from "pubnub"; export interface PubNubMockOptions { uuid?: string; @@ -21,9 +29,9 @@ export interface PubNubMockOptions { export function PubNubMock(options: PubNubMockOptions = {}): void { const uuid = options.uuid || "user_63ea15931d8541a3bd35e5b1f09087dc"; const listeners: ListenerParameters = {}; - const actions = []; + const actions: MessageActionEvent[] = []; - this.addMessageAction = (obj) => { + this.addMessageAction = (obj: AddMessageActionParameters) => { const action = { channel: obj.channel, data: { @@ -38,26 +46,28 @@ export function PubNubMock(options: PubNubMockOptions = {}): void { timetoken: Date.now() + "0000", }; actions.push(action); - listeners.messageAction(action); + listeners.messageAction && listeners.messageAction(action); return new Promise<{ data: MessageAction }>((resolve) => { resolve({ data: action.data }); }); }; - this.addListener = (obj) => { + this.addListener = (obj: ListenerParameters) => { Object.assign(listeners, obj); }; - this.removeListener = (obj) => { - Object.keys(obj).forEach((key) => delete listeners[key]); + this.removeListener = (obj: ListenerParameters) => { + Object.keys(obj).forEach((key) => delete listeners[key as keyof ListenerParameters]); }; - this.fetchMessages = async (args) => { + this.fetchMessages = async (args: FetchMessagesParameters) => { let messagesCopy = [...messages]; if (args.start) { - messagesCopy = messagesCopy.filter((m) => parseInt(m.timetoken) < parseInt(args.start)); + messagesCopy = messagesCopy.filter( + (m) => parseInt(m.timetoken) < parseInt(args.start as string) + ); } - messagesCopy = messagesCopy.slice(Math.max(messagesCopy.length - args.count, 0)); + messagesCopy = messagesCopy.slice(Math.max(messagesCopy.length - (args.count as number), 0)); return new Promise((resolve) => { resolve({ @@ -78,12 +88,14 @@ export function PubNubMock(options: PubNubMockOptions = {}): void { this.getSubscribedChannelGroups = () => []; - this.hereNow = (options) => { + this.hereNow = (options: HereNowParameters) => { return new Promise((resolve) => { + const channels = options.channels || []; + resolve({ - totalChannels: options.channels.length, - totalOccupancy: options.channels.length * users.length, - channels: options.channels + totalChannels: channels.length, + totalOccupancy: channels.length * users.length, + channels: channels .map((channel) => ({ name: channel, occupancy: users.length, @@ -94,7 +106,7 @@ export function PubNubMock(options: PubNubMockOptions = {}): void { }); }; - this.publish = (obj) => { + this.publish = (obj: PublishParameters) => { const message = { channel: obj.channel, actualChannel: obj.channel, @@ -102,12 +114,12 @@ export function PubNubMock(options: PubNubMockOptions = {}): void { message: obj.message, timetoken: Date.now() + "0000", publisher: uuid, - subscription: null, + subscription: "", uuid, actions: {}, }; messages.push(message); - listeners.message(message); + listeners.message && listeners.message(message); return new Promise((resolve) => { resolve({ timetoken: parseInt(Date.now() + "0000"), @@ -115,25 +127,29 @@ export function PubNubMock(options: PubNubMockOptions = {}): void { }); }; - this.removeMessageAction = (obj) => { + this.removeMessageAction = (obj: RemoveMessageActionParameters) => { const action = actions.find((a) => a.data.actionTimetoken === obj.actionTimetoken); + if (!action) { + return; + } const index = actions.indexOf(action); actions.splice(index, 1); action.event = "removed"; - listeners.messageAction(action); + listeners.messageAction && listeners.messageAction(action); return new Promise<{ data: unknown }>((resolve) => { resolve({ data: {} }); }); }; - this.signal = (args) => { - listeners.signal({ - channel: args.channel, - subscription: null, - timetoken: Date.now() + "0000", - message: args.message, - publisher: uuid, - }); + this.signal = (args: SignalParameters) => { + listeners.signal && + listeners.signal({ + channel: args.channel, + subscription: "", + timetoken: Date.now() + "0000", + message: args.message, + publisher: uuid, + }); return new Promise((resolve) => { resolve({ @@ -142,7 +158,7 @@ export function PubNubMock(options: PubNubMockOptions = {}): void { }); }; - this.sendFile = (args) => { + this.sendFile = (args: SendFileParameters) => { // TODO: generate file message return new Promise((resolve) => { @@ -155,51 +171,51 @@ export function PubNubMock(options: PubNubMockOptions = {}): void { }; this.objects = { - getAllUUIDMetadata: (options) => { + getAllUUIDMetadata: (options: GetAllMetadataParameters) => { const limit = options.limit || users.length; - const page = options.page.next || 0; - const offset = page * limit; + const page = options.page?.next || 0; + const offset = Number(page) * limit; return { data: users.slice(offset, offset + limit), totalCount: users.length, - next: page + 1, + next: (Number(page)) + 1, }; }, - getAllChannelMetadata: (options) => { + getAllChannelMetadata: (options: GetAllMetadataParameters) => { const limit = options.limit || channels.length; - const page = options.page.next || 0; - const offset = page * limit; + const page = options.page?.next || 0; + const offset = Number(page) * limit; return { data: channels.slice(offset, offset + limit), totalCount: channels.length, - next: page + 1, + next: Number(page) + 1, }; }, - getChannelMembers: (options) => { + getChannelMembers: (options: GetAllMetadataParameters) => { const limit = options.limit || users.length; - const page = options.page.next || 0; - const offset = page * limit; + const page = options.page?.next || 0; + const offset = Number(page) * limit; return { data: users.slice(offset, offset + limit), totalCount: users.length, - next: page + 1, + next: Number(page) + 1, }; }, - getMemberships: (options) => { + getMemberships: (options: GetAllMetadataParameters) => { const limit = options.limit || channels.length; - const page = options.page.next || 0; - const offset = page * limit; + const page = options.page?.next || 0; + const offset = Number(page) * limit; return { data: channels.slice(offset, offset + limit), totalCount: channels.length, - next: page + 1, + next: Number(page) + 1, }; }, - getUUIDMetadata: (args) => ({ + getUUIDMetadata: (args: GetUUIDMetadataParameters) => ({ data: users.find((u) => u.id === args.uuid), }), }; diff --git a/packages/common/package.json b/packages/common/package.json index e9dd9cfe6..a5a31403f 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -15,6 +15,7 @@ "@testing-library/jest-dom": "5.16.5", "@testing-library/react": "13.4.0", "@types/jest": "29.0.3", + "@types/lodash": "4.14.186", "@types/pubnub": "7.2.0", "@types/react": "18.0.20", "@types/react-dom": "18.0.6", diff --git a/packages/common/src/channel-list/channel-list.tsx b/packages/common/src/channel-list/channel-list.tsx index c5c199cda..47c25125a 100644 --- a/packages/common/src/channel-list/channel-list.tsx +++ b/packages/common/src/channel-list/channel-list.tsx @@ -40,7 +40,7 @@ export const useChannelListCore = (props: CommonChannelListProps) => { const channelSorter = (a: ChannelEntity, b: ChannelEntity) => { if (props.sort) return props.sort(a, b); - return a?.name?.localeCompare(b.name, "en", { sensitivity: "base" }); + return a?.name?.localeCompare(b.name as string, "en", { sensitivity: "base" }); }; const channelFromString = (channel: ChannelEntity | string) => { diff --git a/packages/common/src/chat/chat.tsx b/packages/common/src/chat/chat.tsx index cf2901315..61b5349ba 100644 --- a/packages/common/src/chat/chat.tsx +++ b/packages/common/src/chat/chat.tsx @@ -91,7 +91,7 @@ export class Chat extends Component { timeout: 0, exponentialFactor: 1, }, - onError: (): void => null, + onError: (): void => void 0, }; static getDerivedStateFromError(error: Error): { error: Error } { @@ -161,7 +161,7 @@ export const ChatInternal: FC = (props: ChatProps) => { const retryOnError = useCallback( async (fn: () => Promise): Promise => { - const { maxRetries, timeout, exponentialFactor } = retryOptionsProp; + const { maxRetries, timeout, exponentialFactor } = retryOptionsProp as RetryOptions; for (let i = 0; i < maxRetries; i++) { try { return await fn(); @@ -179,7 +179,7 @@ export const ChatInternal: FC = (props: ChatProps) => { */ const handleMessage = useCallback( - (message: MessageEnvelope) => { + (message: Required>) => { try { setMessages((messages) => { const messagesClone = cloneDeep(messages) || {}; @@ -189,8 +189,8 @@ export const ChatInternal: FC = (props: ChatProps) => { }); if (onMessageProp) onMessageProp(message); - } catch (e) { - onErrorProp(e); + } catch (e: any) { + onErrorProp && onErrorProp(e); } }, [onMessageProp, onErrorProp, setMessages] @@ -209,8 +209,8 @@ export const ChatInternal: FC = (props: ChatProps) => { } if (onSignalProp) onSignalProp(signal); - } catch (e) { - onErrorProp(e); + } catch (e: any) { + onErrorProp && onErrorProp(e); } }, [onSignalProp, onErrorProp, setTypingIndicator] @@ -220,8 +220,8 @@ export const ChatInternal: FC = (props: ChatProps) => { (event: PresenceEvent) => { try { if (onPresenceProp) onPresenceProp(event); - } catch (e) { - onErrorProp(e); + } catch (e: any) { + onErrorProp && onErrorProp(e); } }, [onPresenceProp, onErrorProp] @@ -233,8 +233,8 @@ export const ChatInternal: FC = (props: ChatProps) => { if (event.message.type === "membership" && onMembershipProp) onMembershipProp(event); if (event.message.type === "channel" && onChannelProp) onChannelProp(event); if (event.message.type === "uuid" && onUserProp) onUserProp(event); - } catch (e) { - onErrorProp(e); + } catch (e: any) { + onErrorProp && onErrorProp(e); } }, [onMembershipProp, onChannelProp, onUserProp, onErrorProp] @@ -244,7 +244,7 @@ export const ChatInternal: FC = (props: ChatProps) => { (action: MessageActionEvent) => { try { setMessages((messages) => { - if (!messages || !messages[action.channel]) return; + if (!messages || !messages[action.channel]) return messages; const { channel, event } = action; const { type, value, actionTimetoken, messageTimetoken, uuid } = action.data; @@ -268,8 +268,8 @@ export const ChatInternal: FC = (props: ChatProps) => { }); if (onMessageActionProp) onMessageActionProp(action); - } catch (e) { - onErrorProp(e); + } catch (e: any) { + onErrorProp && onErrorProp(e); } }, [onMessageActionProp, onErrorProp, setMessages] @@ -288,8 +288,8 @@ export const ChatInternal: FC = (props: ChatProps) => { }); if (onFileProp) onFileProp(event); - } catch (e) { - onErrorProp(e); + } catch (e: any) { + onErrorProp && onErrorProp(e); } }, [onFileProp, onErrorProp, setMessages] @@ -299,8 +299,8 @@ export const ChatInternal: FC = (props: ChatProps) => { (event: StatusEvent) => { try { if (onStatusProp) onStatusProp(event); - } catch (e) { - onErrorProp(e); + } catch (e: any) { + onErrorProp && onErrorProp(e); } }, [onStatusProp, onErrorProp] @@ -408,8 +408,8 @@ export const ChatInternal: FC = (props: ChatProps) => { try { pubnub.addListener(listener); - } catch (e) { - onErrorProp(e); + } catch (e: any) { + onErrorProp && onErrorProp(e); } return () => { diff --git a/tsconfig.json b/tsconfig.json index 54f809164..1fe714ab7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,7 @@ "esModuleInterop": true, "noEmit": true, "skipLibCheck": true, - "strict": true + "strict": true, + "noImplicitThis": false } } diff --git a/yarn.lock b/yarn.lock index e3eeba5c1..2b1356c06 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3191,6 +3191,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/lodash@4.14.186": + version "4.14.186" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.186.tgz#862e5514dd7bd66ada6c70ee5fce844b06c8ee97" + integrity sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw== + "@types/minimatch@*": version "5.1.2" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" From ddffab57cb59688ef0d0c02840ae1edffd80a47b Mon Sep 17 00:00:00 2001 From: Piotr Suwala Date: Tue, 25 Oct 2022 12:13:54 +0200 Subject: [PATCH 3/9] chore: update types in chat.tsx and pubnub mock --- package.json | 2 +- packages/common/mock/pubnub-mock.ts | 12 ++++-- packages/common/src/chat/chat.tsx | 67 +++++++++++++++-------------- tsconfig.json | 2 +- 4 files changed, 44 insertions(+), 39 deletions(-) diff --git a/package.json b/package.json index d4c7145cd..cc566c5f5 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "start": "concurrently \"cd packages/react && npm run build:watch\" \"cd samples/react/group-chat && npm run start\"", "start:rn": "concurrently \"cd packages/react-native && npm run build:watch\" \"cd samples/react-native/mobile-chat && npm run start\"", "test": "turbo run test", - "tsc": "turbo run tsc" + "tsc": "turbo run tsc && echo" }, "devDependencies": { "@commitlint/cli": "17.1.2", diff --git a/packages/common/mock/pubnub-mock.ts b/packages/common/mock/pubnub-mock.ts index 974be742b..8e6d6cc7f 100644 --- a/packages/common/mock/pubnub-mock.ts +++ b/packages/common/mock/pubnub-mock.ts @@ -13,13 +13,15 @@ import type { PublishParameters, SignalParameters, GetAllMetadataParameters, + GetUUIDMetadataParameters, + RemoveMessageActionParameters, + SendFileParameters, } from "pubnub"; import { users, loremMessages as messages, workChannels as channels, } from "@pubnub/sample-chat-data"; -import { GetUUIDMetadataParameters, RemoveMessageActionParameters, SendFileParameters } from "pubnub"; export interface PubNubMockOptions { uuid?: string; @@ -78,6 +80,8 @@ export function PubNubMock(options: PubNubMockOptions = {}): void { }); }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/ban-ts-comment + // @ts-ignore this.getFileUrl = ({ channel, id, name }) => { return `https://images.ctfassets.net/3prze68gbwl1/76L8lpo46Hu4WvNr9kJvkE/15bade65538769e12a12d95bff1df776/pubnub-logo-docs.svg`; }; @@ -99,7 +103,7 @@ export function PubNubMock(options: PubNubMockOptions = {}): void { .map((channel) => ({ name: channel, occupancy: users.length, - occupants: users.map((u) => ({ uuid: u.id })), + occupants: users.map((u: { id: string }) => ({ uuid: u.id })), })) .reduce((obj, item) => ({ ...obj, [item["name"]]: item }), {}), }); @@ -179,7 +183,7 @@ export function PubNubMock(options: PubNubMockOptions = {}): void { return { data: users.slice(offset, offset + limit), totalCount: users.length, - next: (Number(page)) + 1, + next: Number(page) + 1, }; }, getAllChannelMetadata: (options: GetAllMetadataParameters) => { @@ -216,7 +220,7 @@ export function PubNubMock(options: PubNubMockOptions = {}): void { }; }, getUUIDMetadata: (args: GetUUIDMetadataParameters) => ({ - data: users.find((u) => u.id === args.uuid), + data: users.find((u: { id: string | undefined }) => u.id === args.uuid), }), }; diff --git a/packages/common/src/chat/chat.tsx b/packages/common/src/chat/chat.tsx index 61b5349ba..9bbeb9f85 100644 --- a/packages/common/src/chat/chat.tsx +++ b/packages/common/src/chat/chat.tsx @@ -135,13 +135,13 @@ export const ChatInternal: FC = (props: ChatProps) => { const { children: childrenProp, - theme: themeProp, + theme: themeProp = "light", currentChannel: currentChannelProp, - channels: channelsProp, - channelGroups: channelGroupsProp, + channels: channelsProp = [], + channelGroups: channelGroupsProp = [], enablePresence: enablePresenceProp, - users: usersProp, - typingIndicatorTimeout: typingIndicatorTimeoutProp, + users: usersProp = [], + typingIndicatorTimeout: typingIndicatorTimeoutProp = 10, retryOptions: retryOptionsProp, onMessage: onMessageProp, onSignal: onSignalProp, @@ -152,7 +152,7 @@ export const ChatInternal: FC = (props: ChatProps) => { onMembership: onMembershipProp, onFile: onFileProp, onStatus: onStatusProp, - onError: onErrorProp, + onError: onErrorProp = () => null, } = props; /** @@ -160,7 +160,7 @@ export const ChatInternal: FC = (props: ChatProps) => { */ const retryOnError = useCallback( - async (fn: () => Promise): Promise => { + async (fn: () => Promise): Promise => { const { maxRetries, timeout, exponentialFactor } = retryOptionsProp as RetryOptions; for (let i = 0; i < maxRetries; i++) { try { @@ -189,8 +189,8 @@ export const ChatInternal: FC = (props: ChatProps) => { }); if (onMessageProp) onMessageProp(message); - } catch (e: any) { - onErrorProp && onErrorProp(e); + } catch (e) { + onErrorProp(e as Error); } }, [onMessageProp, onErrorProp, setMessages] @@ -209,8 +209,8 @@ export const ChatInternal: FC = (props: ChatProps) => { } if (onSignalProp) onSignalProp(signal); - } catch (e: any) { - onErrorProp && onErrorProp(e); + } catch (e) { + onErrorProp(e as Error); } }, [onSignalProp, onErrorProp, setTypingIndicator] @@ -220,8 +220,8 @@ export const ChatInternal: FC = (props: ChatProps) => { (event: PresenceEvent) => { try { if (onPresenceProp) onPresenceProp(event); - } catch (e: any) { - onErrorProp && onErrorProp(e); + } catch (e) { + onErrorProp(e as Error); } }, [onPresenceProp, onErrorProp] @@ -233,8 +233,8 @@ export const ChatInternal: FC = (props: ChatProps) => { if (event.message.type === "membership" && onMembershipProp) onMembershipProp(event); if (event.message.type === "channel" && onChannelProp) onChannelProp(event); if (event.message.type === "uuid" && onUserProp) onUserProp(event); - } catch (e: any) { - onErrorProp && onErrorProp(e); + } catch (e) { + onErrorProp(e as Error); } }, [onMembershipProp, onChannelProp, onUserProp, onErrorProp] @@ -261,15 +261,15 @@ export const ChatInternal: FC = (props: ChatProps) => { const newActions = actions.filter((a) => a.actionTimetoken !== actionTimetoken); newActions.length ? setDeep(message, ["actions", type, value], newActions) - : delete message.actions[type][value]; + : delete message.actions?.[type]?.[value]; } return messagesClone; }); if (onMessageActionProp) onMessageActionProp(action); - } catch (e: any) { - onErrorProp && onErrorProp(e); + } catch (e) { + onErrorProp(e as Error); } }, [onMessageActionProp, onErrorProp, setMessages] @@ -288,8 +288,8 @@ export const ChatInternal: FC = (props: ChatProps) => { }); if (onFileProp) onFileProp(event); - } catch (e: any) { - onErrorProp && onErrorProp(e); + } catch (e) { + onErrorProp(e as Error); } }, [onFileProp, onErrorProp, setMessages] @@ -299,8 +299,8 @@ export const ChatInternal: FC = (props: ChatProps) => { (event: StatusEvent) => { try { if (onStatusProp) onStatusProp(event); - } catch (e: any) { - onErrorProp && onErrorProp(e); + } catch (e) { + onErrorProp(e as Error); } }, [onStatusProp, onErrorProp] @@ -343,7 +343,7 @@ export const ChatInternal: FC = (props: ChatProps) => { }, [retryOnError, setRetryFunction]); /** - * Lifecycle: use currentChannel for subscriptions when neither channels or channelGroups is passed + * Lifecycle: use currentChannel for subscriptions when neither channels nor channelGroups is passed */ useEffect(() => { @@ -385,7 +385,7 @@ export const ChatInternal: FC = (props: ChatProps) => { }); } } catch (e) { - onErrorProp(e); + onErrorProp(e as Error); } }, [channels, channelGroups, enablePresenceProp, onErrorProp, pubnub]); @@ -397,19 +397,20 @@ export const ChatInternal: FC = (props: ChatProps) => { if (!pubnub) return; const listener = { - message: (m) => handleMessage(m), - messageAction: (m) => handleAction(m), - presence: (e) => handlePresenceEvent(e), - objects: (e) => handleObjectsEvent(e), - signal: (e) => handleSignalEvent(e), - file: (e) => handleFileEvent(e), - status: (e) => handleStatusEvent(e), + message: (m: Required>) => + handleMessage(m), + messageAction: (m: MessageActionEvent) => handleAction(m), + presence: (e: PresenceEvent) => handlePresenceEvent(e), + objects: (e: BaseObjectsEvent) => handleObjectsEvent(e), + signal: (e: SignalEvent) => handleSignalEvent(e), + file: (e: FileEvent) => handleFileEvent(e), + status: (e: StatusEvent) => handleStatusEvent(e), }; try { pubnub.addListener(listener); - } catch (e: any) { - onErrorProp && onErrorProp(e); + } catch (e) { + onErrorProp && onErrorProp(e as Error); } return () => { diff --git a/tsconfig.json b/tsconfig.json index 1fe714ab7..d6136d985 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,7 @@ "esModuleInterop": true, "noEmit": true, "skipLibCheck": true, - "strict": true, + "strict": false, "noImplicitThis": false } } From 12da2efcdd15f3ea72c6f8e30e2e3f4407a766dd Mon Sep 17 00:00:00 2001 From: Piotr Suwala Date: Tue, 25 Oct 2022 12:19:53 +0200 Subject: [PATCH 4/9] chore: update types in chat.tsx and pubnub mock --- packages/common/src/chat/chat.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/src/chat/chat.tsx b/packages/common/src/chat/chat.tsx index 9bbeb9f85..3efd7b152 100644 --- a/packages/common/src/chat/chat.tsx +++ b/packages/common/src/chat/chat.tsx @@ -410,7 +410,7 @@ export const ChatInternal: FC = (props: ChatProps) => { try { pubnub.addListener(listener); } catch (e) { - onErrorProp && onErrorProp(e as Error); + onErrorProp(e as Error); } return () => { From 572be77480f597a368e04eed330b1a87a1c432a1 Mon Sep 17 00:00:00 2001 From: Piotr Suwala Date: Tue, 25 Oct 2022 13:54:44 +0200 Subject: [PATCH 5/9] chore: WIP --- packages/common/src/helpers.ts | 2 +- packages/common/src/hooks/use-channel-members.ts | 14 +++++++------- packages/common/src/hooks/use-channels.ts | 14 +++++++------- tsconfig.json | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/common/src/helpers.ts b/packages/common/src/helpers.ts index 7070b4db4..03a4ed3d2 100644 --- a/packages/common/src/helpers.ts +++ b/packages/common/src/helpers.ts @@ -8,7 +8,7 @@ export const getNameInitials = (name: string): string => { return initials.toUpperCase(); }; -export const getPredefinedColor = (uuid: string): string => { +export const getPredefinedColor = (uuid: string): string | undefined => { if (!uuid || !uuid.length) return; const colors = ["#80deea", "#9fa7df", "#aed581", "#ce93d8", "#ef9a9a", "#ffab91", "#ffe082"]; const sum = uuid diff --git a/packages/common/src/hooks/use-channel-members.ts b/packages/common/src/hooks/use-channel-members.ts index 19bfd1bd9..b3be3ea77 100644 --- a/packages/common/src/hooks/use-channel-members.ts +++ b/packages/common/src/hooks/use-channel-members.ts @@ -1,18 +1,18 @@ import { useState, useEffect, useMemo } from "react"; -import { GetChannelMembersParameters } from "pubnub"; +import { GetChannelMembersParameters, ObjectsEvent } from "pubnub"; import { usePubNub } from "pubnub-react"; import { merge, cloneDeep } from "lodash"; import { UserEntity } from "../types"; -type HookReturnValue = [UserEntity[], () => void, () => void, number, Error]; +type HookReturnValue = [UserEntity[], () => void, () => void, number | undefined, Error]; export const useChannelMembers = (options: GetChannelMembersParameters): HookReturnValue => { const jsonOptions = JSON.stringify(options); const pubnub = usePubNub(); const [members, setMembers] = useState([]); - const [totalCount, setTotalCount] = useState(0); - const [page, setPage] = useState(""); + const [totalCount, setTotalCount] = useState(0); + const [page, setPage] = useState(""); const [error, setError] = useState(); const [doFetch, setDoFetch] = useState(true); @@ -59,7 +59,7 @@ export const useChannelMembers = (options: GetChannelMembersParameters): HookRet setPage(response.next); } catch (e) { setDoFetch(false); - setError(e); + setError(e as Error); } } @@ -70,7 +70,7 @@ export const useChannelMembers = (options: GetChannelMembersParameters): HookRet useEffect(() => { const listener = { - objects: (event) => { + objects: (event: ObjectsEvent) => { const message = event.message; if (message.type !== "membership") return; @@ -99,5 +99,5 @@ export const useChannelMembers = (options: GetChannelMembersParameters): HookRet }; }, [pubnub, paginatedOptions.channel]); - return [members, fetchMoreMembers, resetHook, totalCount, error]; + return [members, fetchMoreMembers, resetHook, totalCount, error as Error]; }; diff --git a/packages/common/src/hooks/use-channels.ts b/packages/common/src/hooks/use-channels.ts index 774b4d61d..5d00bd295 100644 --- a/packages/common/src/hooks/use-channels.ts +++ b/packages/common/src/hooks/use-channels.ts @@ -1,17 +1,17 @@ import { useState, useEffect } from "react"; -import { GetAllMetadataParameters } from "pubnub"; +import { GetAllMetadataParameters, ObjectsEvent } from "pubnub"; import { usePubNub } from "pubnub-react"; import { merge, cloneDeep } from "lodash"; import { ChannelEntity } from "../types"; -type HookReturnValue = [ChannelEntity[], () => void, number, Error]; +type HookReturnValue = [ChannelEntity[], () => void, number | undefined, Error]; export const useChannels = (options: GetAllMetadataParameters = {}): HookReturnValue => { const pubnub = usePubNub(); const [channels, setChannels] = useState([]); - const [page, setPage] = useState(""); - const [totalCount, setTotalCount] = useState(0); + const [page, setPage] = useState(""); + const [totalCount, setTotalCount] = useState(0); const [error, setError] = useState(); const [doFetch, setDoFetch] = useState(true); @@ -39,7 +39,7 @@ export const useChannels = (options: GetAllMetadataParameters = {}): HookReturnV setPage(response.next); } catch (e) { setDoFetch(false); - setError(e); + setError(e as Error); } } @@ -50,7 +50,7 @@ export const useChannels = (options: GetAllMetadataParameters = {}): HookReturnV useEffect(() => { const listener = { - objects: (event) => { + objects: (event: ObjectsEvent) => { const message = event.message; if (message.type !== "channel") return; @@ -79,5 +79,5 @@ export const useChannels = (options: GetAllMetadataParameters = {}): HookReturnV }; }, [pubnub]); - return [channels, fetchMoreChannels, totalCount, error]; + return [channels, fetchMoreChannels, totalCount, error as Error]; }; diff --git a/tsconfig.json b/tsconfig.json index d6136d985..1fe714ab7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,7 @@ "esModuleInterop": true, "noEmit": true, "skipLibCheck": true, - "strict": false, + "strict": true, "noImplicitThis": false } } From 0867a28c4063b46631d29d4147ae57c3fb817c60 Mon Sep 17 00:00:00 2001 From: Piotr Suwala Date: Wed, 26 Oct 2022 14:16:19 +0200 Subject: [PATCH 6/9] chore: fix more types --- .../common/src/hooks/use-channel-members.ts | 10 +++++----- packages/common/src/hooks/use-channels.ts | 6 +++--- packages/common/src/hooks/use-messages.ts | 3 +++ packages/common/src/hooks/use-presence.ts | 8 ++++---- packages/common/src/hooks/use-subscribe.ts | 8 ++++++-- .../common/src/hooks/use-user-memberships.ts | 14 +++++++------- packages/common/src/hooks/use-user.ts | 14 +++++++------- packages/common/src/hooks/use-users.ts | 12 ++++++------ .../common/src/member-list/member-list.tsx | 4 ++-- .../common/src/message-input/message-input.tsx | 18 ++++++++++-------- .../common/src/message-list/message-list.tsx | 14 +++++++------- packages/common/src/state-atoms.ts | 10 ++++++---- .../src/typing-indicator/typing-indicator.tsx | 2 +- .../common/test/use-channel-members.test.tsx | 7 +++++-- packages/common/test/use-channels.test.tsx | 7 +++++-- packages/common/test/use-presence.test.tsx | 7 +++++-- .../common/test/use-user-memberships.test.tsx | 7 +++++-- packages/common/test/use-user.test.tsx | 7 +++++-- .../react/src/message-list/message-list.tsx | 8 ++++++-- .../src/components/create-chat-modal.tsx | 1 + tsconfig.json | 3 +-- 21 files changed, 100 insertions(+), 70 deletions(-) diff --git a/packages/common/src/hooks/use-channel-members.ts b/packages/common/src/hooks/use-channel-members.ts index b3be3ea77..39aff67dc 100644 --- a/packages/common/src/hooks/use-channel-members.ts +++ b/packages/common/src/hooks/use-channel-members.ts @@ -4,15 +4,15 @@ import { usePubNub } from "pubnub-react"; import { merge, cloneDeep } from "lodash"; import { UserEntity } from "../types"; -type HookReturnValue = [UserEntity[], () => void, () => void, number | undefined, Error]; +type HookReturnValue = [UserEntity[], () => void, () => void, number, Error]; export const useChannelMembers = (options: GetChannelMembersParameters): HookReturnValue => { const jsonOptions = JSON.stringify(options); const pubnub = usePubNub(); const [members, setMembers] = useState([]); - const [totalCount, setTotalCount] = useState(0); - const [page, setPage] = useState(""); + const [totalCount, setTotalCount] = useState(0); + const [page, setPage] = useState(""); const [error, setError] = useState(); const [doFetch, setDoFetch] = useState(true); @@ -55,8 +55,8 @@ export const useChannelMembers = (options: GetChannelMembersParameters): HookRet ...members, ...(response.data.map((m) => m.uuid) as UserEntity[]), ]); - setTotalCount(response.totalCount); - setPage(response.next); + setTotalCount(response.totalCount || 0); + setPage(response.next || ""); } catch (e) { setDoFetch(false); setError(e as Error); diff --git a/packages/common/src/hooks/use-channels.ts b/packages/common/src/hooks/use-channels.ts index 5d00bd295..977e2c8e0 100644 --- a/packages/common/src/hooks/use-channels.ts +++ b/packages/common/src/hooks/use-channels.ts @@ -4,14 +4,14 @@ import { usePubNub } from "pubnub-react"; import { merge, cloneDeep } from "lodash"; import { ChannelEntity } from "../types"; -type HookReturnValue = [ChannelEntity[], () => void, number | undefined, Error]; +type HookReturnValue = [ChannelEntity[], () => void, number, Error]; export const useChannels = (options: GetAllMetadataParameters = {}): HookReturnValue => { const pubnub = usePubNub(); const [channels, setChannels] = useState([]); const [page, setPage] = useState(""); - const [totalCount, setTotalCount] = useState(0); + const [totalCount, setTotalCount] = useState(0); const [error, setError] = useState(); const [doFetch, setDoFetch] = useState(true); @@ -35,7 +35,7 @@ export const useChannels = (options: GetAllMetadataParameters = {}): HookReturnV if (ignoreRequest) return; setDoFetch(false); setChannels((channels) => [...channels, ...response.data]); - setTotalCount(response.totalCount); + setTotalCount(response.totalCount || 0); setPage(response.next); } catch (e) { setDoFetch(false); diff --git a/packages/common/src/hooks/use-messages.ts b/packages/common/src/hooks/use-messages.ts index 4a48b6bd5..f99007bbc 100644 --- a/packages/common/src/hooks/use-messages.ts +++ b/packages/common/src/hooks/use-messages.ts @@ -1,3 +1,6 @@ +// This file is unused so there is no need to keep it ts-checked +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-nocheck import { useState, useEffect, useRef } from "react"; import { FetchMessagesParameters, MessageActionEvent, MessageEvent } from "pubnub"; import { usePubNub } from "pubnub-react"; diff --git a/packages/common/src/hooks/use-presence.ts b/packages/common/src/hooks/use-presence.ts index 6e2de4db4..7cd1b8a4e 100644 --- a/packages/common/src/hooks/use-presence.ts +++ b/packages/common/src/hooks/use-presence.ts @@ -1,5 +1,5 @@ import { useState, useEffect } from "react"; -import { HereNowParameters, HereNowResponse } from "pubnub"; +import { HereNowParameters, HereNowResponse, PresenceEvent } from "pubnub"; import { usePubNub } from "pubnub-react"; import { cloneDeep } from "lodash"; @@ -39,7 +39,7 @@ export const usePresence = (options: HereNowParameters = {}): HookReturnValue => setPresence(response.channels); } catch (e) { setDoFetch(false); - setError(e); + setError(e as Error); } } @@ -50,7 +50,7 @@ export const usePresence = (options: HereNowParameters = {}): HookReturnValue => useEffect(() => { const listener = { - presence: (event) => { + presence: (event: PresenceEvent) => { setPresence((presence) => { const presenceClone = cloneDeep(presence); if (!presenceClone[event.channel]) @@ -97,5 +97,5 @@ export const usePresence = (options: HereNowParameters = {}): HookReturnValue => }; }, [pubnub, options.includeUUIDs]); - return [presence, resetHook, total, error]; + return [presence, resetHook, total, error as Error]; }; diff --git a/packages/common/src/hooks/use-subscribe.ts b/packages/common/src/hooks/use-subscribe.ts index 44b784091..f5b6be7e0 100644 --- a/packages/common/src/hooks/use-subscribe.ts +++ b/packages/common/src/hooks/use-subscribe.ts @@ -17,10 +17,14 @@ export const useSubscribe = (options: SubscribeParameters = {}): (() => void) => const currentGroups = pubnub.getSubscribedChannelGroups() || []; const subscribeChannels = options.channels.filter((c) => !currentSubscriptions.includes(c)); - const unsubscribeChannels = currentSubscriptions.filter((c) => !options.channels.includes(c)); + const unsubscribeChannels = currentSubscriptions.filter( + (c) => !(options.channels as string[]).includes(c) + ); const subscribeGroups = options.channelGroups.filter((c) => !currentGroups.includes(c)); - const unsubscribeGroups = currentGroups.filter((c) => !options.channelGroups.includes(c)); + const unsubscribeGroups = currentGroups.filter( + (c) => !(options.channelGroups as string[]).includes(c) + ); if (subscribeChannels.length || subscribeGroups.length) { pubnub.subscribe({ diff --git a/packages/common/src/hooks/use-user-memberships.ts b/packages/common/src/hooks/use-user-memberships.ts index 88185c3f9..1aca7146c 100644 --- a/packages/common/src/hooks/use-user-memberships.ts +++ b/packages/common/src/hooks/use-user-memberships.ts @@ -1,18 +1,18 @@ import { useState, useEffect, useMemo } from "react"; -import { GetMembershipsParametersv2 } from "pubnub"; +import { GetMembershipsParametersv2, ObjectsEvent } from "pubnub"; import { usePubNub } from "pubnub-react"; import { merge, cloneDeep } from "lodash"; import { ChannelEntity } from "../types"; -type HookReturnValue = [ChannelEntity[], () => void, () => void, number, Error]; +type HookReturnValue = [ChannelEntity[], () => void, () => void, number | undefined, Error]; export const useUserMemberships = (options: GetMembershipsParametersv2 = {}): HookReturnValue => { const jsonOptions = JSON.stringify(options); const pubnub = usePubNub(); const [channels, setChannels] = useState([]); - const [totalCount, setTotalCount] = useState(0); - const [page, setPage] = useState(""); + const [totalCount, setTotalCount] = useState(0); + const [page, setPage] = useState(""); const [error, setError] = useState(); const [doFetch, setDoFetch] = useState(true); @@ -59,7 +59,7 @@ export const useUserMemberships = (options: GetMembershipsParametersv2 = {}): Ho setPage(response.next); } catch (e) { setDoFetch(false); - setError(e); + setError(e as Error); } } @@ -70,7 +70,7 @@ export const useUserMemberships = (options: GetMembershipsParametersv2 = {}): Ho useEffect(() => { const listener = { - objects: (event) => { + objects: (event: ObjectsEvent) => { const message = event.message; if (message.type !== "membership") return; @@ -100,5 +100,5 @@ export const useUserMemberships = (options: GetMembershipsParametersv2 = {}): Ho }; }, [pubnub, paginatedOptions.uuid]); - return [channels, fetchMoreMemberships, resetHook, totalCount, error]; + return [channels, fetchMoreMemberships, resetHook, totalCount, error as Error]; }; diff --git a/packages/common/src/hooks/use-user.ts b/packages/common/src/hooks/use-user.ts index d39dd37e5..a1c286bd0 100644 --- a/packages/common/src/hooks/use-user.ts +++ b/packages/common/src/hooks/use-user.ts @@ -1,14 +1,14 @@ import { useState, useEffect } from "react"; -import { GetUUIDMetadataParameters } from "pubnub"; +import { GetUUIDMetadataParameters, ObjectsEvent } from "pubnub"; import { usePubNub } from "pubnub-react"; import { cloneDeep } from "lodash"; import { UserEntity } from "../types"; -export const useUser = (options: GetUUIDMetadataParameters = {}): [UserEntity, Error] => { +export const useUser = (options: GetUUIDMetadataParameters = {}): [UserEntity | null, Error] => { const jsonOptions = JSON.stringify(options); const pubnub = usePubNub(); - const [user, setUser] = useState(null); + const [user, setUser] = useState(null); const [error, setError] = useState(); const [doFetch, setDoFetch] = useState(true); @@ -34,7 +34,7 @@ export const useUser = (options: GetUUIDMetadataParameters = {}): [UserEntity, E setUser(response.data); } catch (e) { setDoFetch(false); - setError(e); + setError(e as Error); } } @@ -45,14 +45,14 @@ export const useUser = (options: GetUUIDMetadataParameters = {}): [UserEntity, E useEffect(() => { const listener = { - objects: (event) => { + objects: (event: ObjectsEvent) => { const message = event.message; if (message.type !== "uuid") return; setUser((user) => { const userCopy = cloneDeep(user); - if (message.data.id == user.id) { + if (message.data.id == userCopy?.id) { Object.assign(userCopy, message.data); } @@ -68,5 +68,5 @@ export const useUser = (options: GetUUIDMetadataParameters = {}): [UserEntity, E }; }, [pubnub]); - return [user, error]; + return [user, error as Error]; }; diff --git a/packages/common/src/hooks/use-users.ts b/packages/common/src/hooks/use-users.ts index 2e0f1a133..9c8cc8983 100644 --- a/packages/common/src/hooks/use-users.ts +++ b/packages/common/src/hooks/use-users.ts @@ -1,5 +1,5 @@ import { useState, useEffect } from "react"; -import { GetAllMetadataParameters } from "pubnub"; +import { GetAllMetadataParameters, ObjectsEvent } from "pubnub"; import { usePubNub } from "pubnub-react"; import { merge, cloneDeep } from "lodash"; import { UserEntity } from "../types"; @@ -35,11 +35,11 @@ export const useUsers = (options: GetAllMetadataParameters = {}): HookReturnValu if (ignoreRequest) return; setDoFetch(false); setUsers((users) => [...users, ...response.data]); - setTotalCount(response.totalCount); - setPage(response.next); + setTotalCount(response.totalCount || 0); + setPage(response.next || ""); } catch (e) { setDoFetch(false); - setError(e); + setError(e as Error); } } @@ -50,7 +50,7 @@ export const useUsers = (options: GetAllMetadataParameters = {}): HookReturnValu useEffect(() => { const listener = { - objects: (event) => { + objects: (event: ObjectsEvent) => { const message = event.message; if (message.type !== "uuid") return; @@ -79,5 +79,5 @@ export const useUsers = (options: GetAllMetadataParameters = {}): HookReturnValu }; }, [pubnub]); - return [users, fetchMoreUsers, totalCount, error]; + return [users, fetchMoreUsers, totalCount, error as Error]; }; diff --git a/packages/common/src/member-list/member-list.tsx b/packages/common/src/member-list/member-list.tsx index dba5a8e76..c3faf07be 100644 --- a/packages/common/src/member-list/member-list.tsx +++ b/packages/common/src/member-list/member-list.tsx @@ -46,7 +46,7 @@ export const useMemberListCore = (props: CommonMemberListProps) => { return props.presentMembers?.includes(uuid); }; - const memberSorter = (a, b) => { + const memberSorter = (a: UserEntity, b: UserEntity) => { if (props.sort) return props.sort(a, b); if (isOwnMember(a.id)) return -1; @@ -55,7 +55,7 @@ export const useMemberListCore = (props: CommonMemberListProps) => { if (isPresentMember(a.id) && !isPresentMember(b.id)) return -1; if (isPresentMember(b.id) && !isPresentMember(a.id)) return 1; - return a.name.localeCompare(b.name, "en", { sensitivity: "base" }); + return a.name?.localeCompare(b.name as string, "en", { sensitivity: "base" }); }; const memberFromString = (member: UserEntity | string) => { diff --git a/packages/common/src/message-input/message-input.tsx b/packages/common/src/message-input/message-input.tsx index b2b235f94..57c24a9c9 100644 --- a/packages/common/src/message-input/message-input.tsx +++ b/packages/common/src/message-input/message-input.tsx @@ -47,7 +47,7 @@ export const useMessageInputCore = (props: CommonMessageInputProps) => { const pubnub = usePubNub(); const [text, setText] = useState(props.draftMessage || ""); - const [file, setFile] = useState(null); + const [file, setFile] = useState(null); const [typingIndicatorSent, setTypingIndicatorSent] = useState(false); const [loader, setLoader] = useState(false); const [users] = useAtom(UsersMetaAtom); @@ -92,7 +92,7 @@ export const useMessageInputCore = (props: CommonMessageInputProps) => { if (props.typingIndicator) stopTypingIndicator(); clearInput(); } catch (e) { - onError(e); + onError(e as Error); } finally { setLoader(false); } @@ -105,7 +105,7 @@ export const useMessageInputCore = (props: CommonMessageInputProps) => { const message = { message: { type: "typing_on" }, channel }; pubnub.signal(message); } catch (e) { - onError(e); + onError(e as Error); } }; @@ -116,7 +116,7 @@ export const useMessageInputCore = (props: CommonMessageInputProps) => { const message = { message: { type: "typing_off" }, channel }; pubnub.signal(message); } catch (e) { - onError(e); + onError(e as Error); } }; @@ -137,17 +137,19 @@ export const useMessageInputCore = (props: CommonMessageInputProps) => { props.onChange && props.onChange(newText); setText(newText); } catch (e) { - onError(e); + onError(e as Error); } }; const handleFileChange = (event: ChangeEvent) => { try { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore const file = event.target.files[0]; setFile(file); setText(file.name); } catch (e) { - onError(e); + onError(e as Error); } }; @@ -155,7 +157,7 @@ export const useMessageInputCore = (props: CommonMessageInputProps) => { /* Lifecycle */ useEffect(() => { - let timer = null; + let timer: ReturnType | null = null; if (typingIndicatorSent) { timer = setTimeout(() => { @@ -163,7 +165,7 @@ export const useMessageInputCore = (props: CommonMessageInputProps) => { }, (typingIndicatorTimeout - 1) * 1000); } - return () => clearTimeout(timer); + return () => clearTimeout(timer as ReturnType); }, [typingIndicatorSent, typingIndicatorTimeout]); return { diff --git a/packages/common/src/message-list/message-list.tsx b/packages/common/src/message-list/message-list.tsx index 7553fa466..fcfee0cf8 100644 --- a/packages/common/src/message-list/message-list.tsx +++ b/packages/common/src/message-list/message-list.tsx @@ -106,14 +106,14 @@ export const useMessageListCore = (props: CommonMessageListProps) => { try { const url = pubnub.getFileUrl({ - channel: envelope.channel, + channel: envelope.channel as string, id: envelope.message.file.id, name: envelope.message.file.name, }); envelope.message.file.url = url; } catch (e) { - onError(e); + onError(e as Error); } finally { return envelope; } @@ -141,7 +141,7 @@ export const useMessageListCore = (props: CommonMessageListProps) => { setMessages(allMessages); setPaginationEnd(!allMessages.length || newMessages.length !== props.fetchMessages); } catch (e) { - onError(e); + onError(e as Error); } finally { setFetchingMessages(false); } @@ -158,7 +158,7 @@ export const useMessageListCore = (props: CommonMessageListProps) => { setPaginationEnd, ]); - const addReaction = (reaction: string, messageTimetoken) => { + const addReaction = (reaction: string, messageTimetoken: string) => { try { pubnub.addMessageAction({ channel, @@ -169,15 +169,15 @@ export const useMessageListCore = (props: CommonMessageListProps) => { }, }); } catch (e) { - onError(e); + onError(e as Error); } }; - const removeReaction = (reaction: string, messageTimetoken, actionTimetoken) => { + const removeReaction = (reaction: string, messageTimetoken: string, actionTimetoken: string) => { try { pubnub.removeMessageAction({ channel, messageTimetoken, actionTimetoken }); } catch (e) { - onError(e); + onError(e as Error); } }; diff --git a/packages/common/src/state-atoms.ts b/packages/common/src/state-atoms.ts index 92a0adea6..9d86893dc 100644 --- a/packages/common/src/state-atoms.ts +++ b/packages/common/src/state-atoms.ts @@ -8,11 +8,13 @@ export const SubscribeChannelGroupsAtom = atom([]); export const UsersMetaAtom = atom([]); export const MessagesAtom = atom<{ [channel: string]: MessageEnvelope[] }>({}); export const PaginationAtom = atom<{ [channel: string]: boolean }>({}); -export const TypingIndicatorAtom = atom({}); +export const TypingIndicatorAtom = atom<{ [key: string]: string }>({}); export const TypingIndicatorTimeoutAtom = atom(10); -export const RetryFunctionAtom = atom<{ function: (fn: () => Promise) => Promise }>({ - function: () => null, +export const RetryFunctionAtom = atom<{ + function: (fn: () => Promise) => Promise; +}>({ + function: () => Promise.resolve(null) as never, }); export const ErrorFunctionAtom = atom<{ function: (error: Error) => unknown }>({ @@ -34,7 +36,7 @@ export const CurrentChannelPaginationAtom = atom( ) ); -export const CurrentChannelTypingIndicatorAtom = atom( +export const CurrentChannelTypingIndicatorAtom = atom<{ [key: string]: string }, unknown>( (get) => get(TypingIndicatorAtom)[get(CurrentChannelAtom)] || {}, (get, set, value) => set( diff --git a/packages/common/src/typing-indicator/typing-indicator.tsx b/packages/common/src/typing-indicator/typing-indicator.tsx index 3e36a6ef5..33d3005ea 100644 --- a/packages/common/src/typing-indicator/typing-indicator.tsx +++ b/packages/common/src/typing-indicator/typing-indicator.tsx @@ -27,7 +27,7 @@ export const useTypingIndicatorCore = (props: CommonTypingIndicatorProps) => { const [users] = useAtom(UsersMetaAtom); const [typingIndicators] = useAtom(CurrentChannelTypingIndicatorAtom); const [typingIndicatorTimeout] = useAtom(TypingIndicatorTimeoutAtom); - const [activeUUIDs, setActiveUUIDs] = useState([]); + const [activeUUIDs, setActiveUUIDs] = useState([]); const typingIndicatorsRef = useRef(typingIndicators); if (!isEqual(typingIndicatorsRef.current, typingIndicators)) { diff --git a/packages/common/test/use-channel-members.test.tsx b/packages/common/test/use-channel-members.test.tsx index 90c9dc055..7910d9b3f 100644 --- a/packages/common/test/use-channel-members.test.tsx +++ b/packages/common/test/use-channel-members.test.tsx @@ -6,8 +6,11 @@ import { useChannelMembers } from "../src/hooks"; import { PubNubMock } from "../mock/pubnub-mock"; import users from "../../../data/users/users.json"; -const pubnub = new PubNubMock({}); -const wrapper = ({ children }) => {children}; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const pubnub = new (PubNubMock as any)({}); +const wrapper = ({ children }: { children: React.ReactNode | React.ReactNode[] | null }) => ( + {children} +); describe("useChannelMembers", () => { test("fetches and returns the full list of memberships", async () => { diff --git a/packages/common/test/use-channels.test.tsx b/packages/common/test/use-channels.test.tsx index d797518ed..147455926 100644 --- a/packages/common/test/use-channels.test.tsx +++ b/packages/common/test/use-channels.test.tsx @@ -6,8 +6,11 @@ import { useChannels } from "../src/hooks"; import { PubNubMock } from "../mock/pubnub-mock"; import channels from "../../../data/channels/work.json"; -const pubnub = new PubNubMock({}); -const wrapper = ({ children }) => {children}; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const pubnub = new (PubNubMock as any)({}); +const wrapper = ({ children }: { children: React.ReactNode | React.ReactNode[] | null }) => ( + {children} +); describe("useChannels", () => { test("fetches and returns the full list of channels", async () => { diff --git a/packages/common/test/use-presence.test.tsx b/packages/common/test/use-presence.test.tsx index cac52e476..43ce7b63e 100644 --- a/packages/common/test/use-presence.test.tsx +++ b/packages/common/test/use-presence.test.tsx @@ -6,8 +6,11 @@ import { usePresence } from "../src/hooks"; import { PubNubMock } from "../mock/pubnub-mock"; import users from "../../../data/users/users.json"; -const pubnub = new PubNubMock({}); -const wrapper = ({ children }) => {children}; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const pubnub = new (PubNubMock as any)({}); +const wrapper = ({ children }: { children: React.ReactNode | React.ReactNode[] | null }) => ( + {children} +); describe("usePresence", () => { test("fetches and returns presence data for a single channel", async () => { diff --git a/packages/common/test/use-user-memberships.test.tsx b/packages/common/test/use-user-memberships.test.tsx index 02c4fd035..d7a09dbca 100644 --- a/packages/common/test/use-user-memberships.test.tsx +++ b/packages/common/test/use-user-memberships.test.tsx @@ -6,8 +6,11 @@ import { useUserMemberships } from "../src/hooks"; import { PubNubMock } from "../mock/pubnub-mock"; import channels from "../../../data/channels/work.json"; -const pubnub = new PubNubMock({}); -const wrapper = ({ children }) => {children}; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const pubnub = new (PubNubMock as any)({}); +const wrapper = ({ children }: { children: React.ReactNode | React.ReactNode[] | null }) => ( + {children} +); describe("useUserMemberships", () => { test("fetches and returns the full list of memberships", async () => { diff --git a/packages/common/test/use-user.test.tsx b/packages/common/test/use-user.test.tsx index 54b49acef..217fc59eb 100644 --- a/packages/common/test/use-user.test.tsx +++ b/packages/common/test/use-user.test.tsx @@ -6,8 +6,11 @@ import { useUser } from "../src/hooks"; import { PubNubMock } from "../mock/pubnub-mock"; import users from "../../../data/users/users.json"; -const pubnub = new PubNubMock({}); -const wrapper = ({ children }) => {children}; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const pubnub = new (PubNubMock as any)({}); +const wrapper = ({ children }: { children: React.ReactNode | React.ReactNode[] | null }) => ( + {children} +); describe("useUser", () => { test("fetches and returns given user", async () => { diff --git a/packages/react/src/message-list/message-list.tsx b/packages/react/src/message-list/message-list.tsx index 75eee8be4..7bb736e95 100644 --- a/packages/react/src/message-list/message-list.tsx +++ b/packages/react/src/message-list/message-list.tsx @@ -298,8 +298,12 @@ export const MessageList: FC = (props: MessageListProps) => { data-tooltip={tooltipContent} onClick={() => { userReaction - ? removeReaction(reaction, envelope.timetoken, userReaction.actionTimetoken) - : addReaction(reaction, envelope.timetoken); + ? removeReaction( + reaction, + envelope.timetoken as string, + userReaction.actionTimetoken as string + ) + : addReaction(reaction, envelope.timetoken as string); }} > {reaction} {instancesLimited.length} diff --git a/samples/react/group-chat/src/components/create-chat-modal.tsx b/samples/react/group-chat/src/components/create-chat-modal.tsx index 8c8ce1281..57d26a0bf 100644 --- a/samples/react/group-chat/src/components/create-chat-modal.tsx +++ b/samples/react/group-chat/src/components/create-chat-modal.tsx @@ -32,6 +32,7 @@ export const CreateChatModal = ({ setCurrentChannel, hideModal, }: CreateChatModalProps): JSX.Element => { + console.log('currentUser', currentUser) const pubnub = usePubNub(); const [creatingChannel, setCreatingChannel] = useState(false); const [showGroups, setShowGroups] = useState(false); diff --git a/tsconfig.json b/tsconfig.json index 1fe714ab7..69703f95d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,6 @@ "esModuleInterop": true, "noEmit": true, "skipLibCheck": true, - "strict": true, - "noImplicitThis": false + "strict": false } } From abf3342577a1dc40e5b7605de2889d556cc00b39 Mon Sep 17 00:00:00 2001 From: Piotr Suwala Date: Wed, 26 Oct 2022 14:44:14 +0200 Subject: [PATCH 7/9] chore: fix more tsc --- .../group-chat/src/components/create-chat-modal.tsx | 13 +++++++------ .../group-chat/src/components/report-user-modal.tsx | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/samples/react/group-chat/src/components/create-chat-modal.tsx b/samples/react/group-chat/src/components/create-chat-modal.tsx index 57d26a0bf..03fa6e89f 100644 --- a/samples/react/group-chat/src/components/create-chat-modal.tsx +++ b/samples/react/group-chat/src/components/create-chat-modal.tsx @@ -10,7 +10,7 @@ import { interface CreateChatModalProps { users: UserEntity[]; - currentUser: UserEntity; + currentUser: UserEntity | null; setCurrentChannel: (channel: Pick) => void; hideModal: () => void; } @@ -32,7 +32,6 @@ export const CreateChatModal = ({ setCurrentChannel, hideModal, }: CreateChatModalProps): JSX.Element => { - console.log('currentUser', currentUser) const pubnub = usePubNub(); const [creatingChannel, setCreatingChannel] = useState(false); const [showGroups, setShowGroups] = useState(false); @@ -60,11 +59,11 @@ export const CreateChatModal = ({ if (user) { /** 1-on-1 chat */ const users = [currentUser, user]; - uuids = users.map((m) => m.id).sort(); + uuids = users.map((m) => m?.id).sort(); channel = `direct.${uuids.join("@")}`; remoteData = { name: users - .map((m) => m.name) + .map((m) => m?.name) .sort() .join(" and "), custom, @@ -76,12 +75,12 @@ export const CreateChatModal = ({ } else { /** Group chat */ const users = [currentUser, ...selectedUsers]; - uuids = users.map((m) => m.id).sort(); + uuids = users.map((m) => m?.id).sort(); channel = `group.${randomHex}`; const name = channelName || users - .map((m) => m.name?.split(" ")[0]) + .map((m) => m?.name?.split(" ")[0]) .sort() .join(", "); remoteData = { name, custom }; @@ -89,6 +88,8 @@ export const CreateChatModal = ({ } await pubnub.objects.setChannelMetadata({ channel, data: remoteData }); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore await pubnub.objects.setChannelMembers({ channel, uuids }); setCurrentChannel({ id: channel, ...localData }); setCreatingChannel(false); diff --git a/samples/react/group-chat/src/components/report-user-modal.tsx b/samples/react/group-chat/src/components/report-user-modal.tsx index 5c71349f5..45546a677 100644 --- a/samples/react/group-chat/src/components/report-user-modal.tsx +++ b/samples/react/group-chat/src/components/report-user-modal.tsx @@ -3,7 +3,7 @@ import { usePubNub } from "pubnub-react"; import { MessageEnvelope, UserEntity } from "@pubnub/react-chat-components"; interface ReportUserModalProps { - currentUser: UserEntity; + currentUser: UserEntity | null; reportedMessage?: MessageEnvelope; hideModal: () => void; users: UserEntity[]; @@ -73,7 +73,7 @@ export const ReportUserModal = ({ ...existingMetadata, flag: true, flaggedAt: Date.now(), - flaggedBy: `${currentUser.name} (${currentUser.id})`, + flaggedBy: `${currentUser?.name} (${currentUser?.id})`, reason, }, }, From 934b5f0502183d31d24fea7b4f05f62523e977e6 Mon Sep 17 00:00:00 2001 From: Piotr Suwala Date: Wed, 9 Nov 2022 11:04:46 +0100 Subject: [PATCH 8/9] chore: update types --- packages/common/src/channel-list/channel-list.tsx | 4 ++-- samples/react/group-chat/src/components/report-user-modal.tsx | 4 ++-- samples/react/group-chat/src/moderated-chat.tsx | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/common/src/channel-list/channel-list.tsx b/packages/common/src/channel-list/channel-list.tsx index 47c25125a..573078a20 100644 --- a/packages/common/src/channel-list/channel-list.tsx +++ b/packages/common/src/channel-list/channel-list.tsx @@ -40,7 +40,7 @@ export const useChannelListCore = (props: CommonChannelListProps) => { const channelSorter = (a: ChannelEntity, b: ChannelEntity) => { if (props.sort) return props.sort(a, b); - return a?.name?.localeCompare(b.name as string, "en", { sensitivity: "base" }); + return a.name?.localeCompare(b.name as string, "en", { sensitivity: "base" }) as number; }; const channelFromString = (channel: ChannelEntity | string) => { @@ -48,7 +48,7 @@ export const useChannelListCore = (props: CommonChannelListProps) => { return { id: channel, name: channel, - }; + } as ChannelEntity; } return channel; }; diff --git a/samples/react/group-chat/src/components/report-user-modal.tsx b/samples/react/group-chat/src/components/report-user-modal.tsx index 45546a677..5c71349f5 100644 --- a/samples/react/group-chat/src/components/report-user-modal.tsx +++ b/samples/react/group-chat/src/components/report-user-modal.tsx @@ -3,7 +3,7 @@ import { usePubNub } from "pubnub-react"; import { MessageEnvelope, UserEntity } from "@pubnub/react-chat-components"; interface ReportUserModalProps { - currentUser: UserEntity | null; + currentUser: UserEntity; reportedMessage?: MessageEnvelope; hideModal: () => void; users: UserEntity[]; @@ -73,7 +73,7 @@ export const ReportUserModal = ({ ...existingMetadata, flag: true, flaggedAt: Date.now(), - flaggedBy: `${currentUser?.name} (${currentUser?.id})`, + flaggedBy: `${currentUser.name} (${currentUser.id})`, reason, }, }, diff --git a/samples/react/group-chat/src/moderated-chat.tsx b/samples/react/group-chat/src/moderated-chat.tsx index b398df655..b4e655f3b 100644 --- a/samples/react/group-chat/src/moderated-chat.tsx +++ b/samples/react/group-chat/src/moderated-chat.tsx @@ -15,6 +15,7 @@ import { useChannelMembers, useChannels, usePresence, + UserEntity, useUser, useUserMemberships, useUsers, @@ -188,7 +189,7 @@ export default function ModeratedChat(): JSX.Element { {showReportUserModal && ( setShowReportUserModal(false), users: allUsers, From c33272ba3e0da19841d6c5d52997c93156d733ca Mon Sep 17 00:00:00 2001 From: Piotr Suwala Date: Wed, 9 Nov 2022 11:38:29 +0100 Subject: [PATCH 9/9] chore: update types --- packages/common/src/channel-list/channel-list.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/src/channel-list/channel-list.tsx b/packages/common/src/channel-list/channel-list.tsx index 573078a20..062feb0dd 100644 --- a/packages/common/src/channel-list/channel-list.tsx +++ b/packages/common/src/channel-list/channel-list.tsx @@ -40,7 +40,7 @@ export const useChannelListCore = (props: CommonChannelListProps) => { const channelSorter = (a: ChannelEntity, b: ChannelEntity) => { if (props.sort) return props.sort(a, b); - return a.name?.localeCompare(b.name as string, "en", { sensitivity: "base" }) as number; + return a?.name?.localeCompare(b.name as string, "en", { sensitivity: "base" }) as number; }; const channelFromString = (channel: ChannelEntity | string) => {