Skip to content

Commit 85bd4ae

Browse files
Second pass
1 parent 210519c commit 85bd4ae

32 files changed

Lines changed: 169 additions & 155 deletions

src/components/Accessibility/hooks/useIncomingMessageAnnouncements.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { useCallback, useEffect, useRef } from 'react';
2-
import type { Channel, Event, MessageResponse } from 'stream-chat';
2+
import type { Channel, EventPayload, LocalMessage, MessageResponse } from 'stream-chat';
33

44
import { useAriaLiveAnnouncer } from '../useAriaLiveAnnouncer';
55
import { useTranslationContext } from '../../../context/TranslationContext';
66

77
const MESSAGE_ANNOUNCEMENT_THROTTLE_MS = 1000;
88

99
const isAnnounceableIncomingMessage = (
10-
message: MessageResponse,
10+
message: LocalMessage | MessageResponse,
1111
ownUserId?: string,
1212
): boolean => {
1313
const messageUserId = message.user?.id;
@@ -16,13 +16,15 @@ const isAnnounceableIncomingMessage = (
1616
return false;
1717
}
1818

19+
// TODO: message coming from the event does not have a status
20+
const status = (message as LocalMessage).status;
1921
return (
2022
message.type !== 'deleted' &&
2123
message.type !== 'ephemeral' &&
2224
message.type !== 'error' &&
2325
message.type !== 'system' &&
24-
message.status !== 'failed' &&
25-
message.status !== 'sending'
26+
status !== 'failed' &&
27+
status !== 'sending'
2628
);
2729
};
2830

@@ -108,7 +110,7 @@ export const useIncomingMessageAnnouncements = ({
108110
return;
109111
}
110112

111-
const handleMessageNew = (event: Event) => {
113+
const handleMessageNew = (event: EventPayload<'message.new'>) => {
112114
const message = event.message;
113115
if (!message) return;
114116

src/components/Attachment/Attachment.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import React, { useMemo } from 'react';
2-
import type { SharedLocationResponse, Attachment as StreamAttachment } from 'stream-chat';
2+
import type { SharedLocationResponseData, Attachment as StreamAttachment } from 'stream-chat';
33
import {
44
isAudioAttachment,
55
isFileAttachment,
66
isImageAttachment,
77
isScrapedContent,
8-
isSharedLocationResponse,
8+
isSharedLocationResponseData,
99
isVideoAttachment,
1010
isVoiceRecordingAttachment,
1111
} from 'stream-chat';
@@ -29,7 +29,6 @@ import type { AudioProps } from './Audio';
2929
import type { VoiceRecordingProps } from './VoiceRecording';
3030
import type { CardProps } from './LinkPreview/Card';
3131
import type { FileAttachmentProps } from './FileAttachment';
32-
import type { GalleryItem } from '../Gallery';
3332
import type { UnsupportedAttachmentProps } from './UnsupportedAttachment';
3433
import type { ActionHandlerReturnType } from '../Message/hooks/useActionHandler';
3534
import type { GeolocationProps } from './Geolocation';
@@ -49,7 +48,7 @@ export const ATTACHMENT_GROUPS_ORDER = [
4948

5049
export type AttachmentProps = {
5150
/** The message attachments to render, see [attachment structure](https://getstream.io/chat/docs/javascript/message_format/?language=javascript) **/
52-
attachments: (StreamAttachment | SharedLocationResponse)[];
51+
attachments: (StreamAttachment | SharedLocationResponseData)[];
5352
/** The handler function to call when an action is performed on an attachment, examples include canceling a \/giphy command or shuffling the results. */
5453
actionHandler?: ActionHandlerReturnType;
5554
/**
@@ -120,10 +119,10 @@ const renderGroupedAttachments = ({
120119
attachments,
121120
...rest
122121
}: AttachmentProps): GroupedRenderedAttachment => {
123-
const mediaAttachments: GalleryItem[] = [];
122+
const mediaAttachments: StreamAttachment[] = [];
124123
const containers = attachments.reduce<GroupedRenderedAttachment>(
125124
(typeMap, attachment) => {
126-
if (isSharedLocationResponse(attachment)) {
125+
if (isSharedLocationResponseData(attachment)) {
127126
typeMap.geolocation.push(
128127
<GeolocationContainer
129128
{...rest}
@@ -151,7 +150,7 @@ const renderGroupedAttachments = ({
151150
isImageAttachment(attachment) ||
152151
isVideoAttachment(attachment, SUPPORTED_VIDEO_FORMATS)
153152
) {
154-
mediaAttachments.push(attachment as GalleryItem);
153+
mediaAttachments.push(attachment);
155154
} else if (
156155
isAudioAttachment(attachment) ||
157156
isVoiceRecordingAttachment(attachment) ||

src/components/Attachment/AttachmentContainer.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ import clsx from 'clsx';
99
import type {
1010
Attachment,
1111
LocalAttachment,
12-
SharedLocationResponse,
12+
SharedLocationResponseData,
1313
VideoAttachment as VideoAttachmentType,
1414
} from 'stream-chat';
1515
import {
1616
isAudioAttachment,
1717
isFileAttachment,
18-
isSharedLocationResponse,
18+
isSharedLocationResponseData,
1919
isVideoAttachment,
2020
isVoiceRecordingAttachment,
2121
} from 'stream-chat';
@@ -50,7 +50,7 @@ import { VideoAttachment } from './VideoAttachment';
5050
import type { AttachmentProps } from './Attachment';
5151

5252
export type AttachmentContainerProps = {
53-
attachment: Attachment | GalleryAttachment | SharedLocationResponse;
53+
attachment: Attachment | GalleryAttachment | SharedLocationResponseData;
5454
componentType: AttachmentComponentType;
5555
};
5656
export const AttachmentWithinContainer = ({
@@ -61,7 +61,7 @@ export const AttachmentWithinContainer = ({
6161
const isGAT = isGalleryAttachmentType(attachment);
6262
let extra = '';
6363

64-
if (!isGAT && !isSharedLocationResponse(attachment)) {
64+
if (!isGAT && !isSharedLocationResponseData(attachment)) {
6565
extra =
6666
componentType === 'card' && !attachment?.image_url && !attachment?.thumb_url
6767
? 'no-image'

src/components/Attachment/Geolocation.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { ComponentType } from 'react';
22
import { useEffect } from 'react';
33
import { useRef, useState } from 'react';
44
import React from 'react';
5-
import type { Coords, SharedLocationResponse } from 'stream-chat';
5+
import type { Coords, SharedLocationResponseData } from 'stream-chat';
66
import { useChatContext, useTranslationContext } from '../../context';
77
import { ExternalLinkIcon } from './icons';
88
import { IconLocation } from '../Icons';
@@ -11,7 +11,7 @@ import { Button } from '../Button';
1111
export type GeolocationMapProps = Coords;
1212

1313
export type GeolocationProps = {
14-
location: SharedLocationResponse;
14+
location: SharedLocationResponseData;
1515
GeolocationAttachmentMapPlaceholder?: ComponentType<GeolocationAttachmentMapPlaceholderProps>;
1616
GeolocationMap?: ComponentType<GeolocationMapProps>;
1717
};
@@ -95,7 +95,7 @@ export const Geolocation = ({
9595
};
9696

9797
export type GeolocationAttachmentMapPlaceholderProps = {
98-
location: SharedLocationResponse;
98+
location: SharedLocationResponseData;
9999
};
100100

101101
const DefaultGeolocationAttachmentMapPlaceholder = ({

src/components/Attachment/utils.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { ReactNode } from 'react';
2-
import type { Attachment, SharedLocationResponse } from 'stream-chat';
2+
import type { Attachment, SharedLocationResponseData } from 'stream-chat';
33
import type { ATTACHMENT_GROUPS_ORDER, AttachmentProps } from './Attachment';
44
import * as linkify from 'linkifyjs';
55

@@ -44,18 +44,20 @@ export type RenderMediaProps = Omit<AttachmentProps, 'attachments'> & {
4444
};
4545

4646
export type GeolocationContainerProps = Omit<AttachmentProps, 'attachments'> & {
47-
location: SharedLocationResponse;
47+
location: SharedLocationResponseData;
4848
};
4949

5050
// This identity function determines attachment type specific to React.
5151
// Once made sure other SDKs support the same logic, move to stream-chat-js
5252
export const isGalleryAttachmentType = (
53-
attachment: Attachment | GalleryAttachment,
53+
attachment: Attachment | GalleryAttachment | SharedLocationResponseData,
5454
): attachment is GalleryAttachment =>
5555
Array.isArray((attachment as GalleryAttachment).items);
5656

57-
export const isSvgAttachment = (attachment: Attachment) => {
58-
const filename = attachment.fallback || '';
57+
export const isSvgAttachment = (
58+
attachment: Attachment | GalleryAttachment | SharedLocationResponseData,
59+
) => {
60+
const filename = (attachment as Attachment).fallback || '';
5961
return filename.toLowerCase().endsWith('.svg');
6062
};
6163

src/components/Channel/Channel.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import clsx from 'clsx';
1212
import debounce from 'lodash.debounce';
1313
import throttle from 'lodash.throttle';
1414
import type {
15-
ChannelAPIResponse,
1615
ChannelMemberResponse,
1716
ChannelQueryOptions,
1817
ChannelState,
18+
ChannelStateResponseFields,
1919
DeleteMessageOptions,
2020
Event,
2121
EventAPIResponse,
@@ -625,7 +625,7 @@ const ChannelInner = (
625625

626626
const oldestID = oldestMessage?.id;
627627
const perPage = limit;
628-
let queryResponse: ChannelAPIResponse;
628+
let queryResponse: ChannelStateResponseFields;
629629

630630
try {
631631
queryResponse = await channel.query({
@@ -659,7 +659,7 @@ const ChannelInner = (
659659

660660
const newestId = newestMessage?.id;
661661
const perPage = limit;
662-
let queryResponse: ChannelAPIResponse;
662+
let queryResponse: ChannelStateResponseFields;
663663

664664
try {
665665
queryResponse = await channel.query({
Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,27 @@
1-
import type {
2-
LocalMessage,
3-
MessageResponse,
4-
StreamChat,
5-
UpdateMessageOptions,
6-
} from 'stream-chat';
1+
import type { MessageRequest, StreamChat, UpdateMessageOptions } from 'stream-chat';
72

83
import { useChatContext } from '../../../context/ChatContext';
94

105
type UpdateHandler = (
116
cid: string,
12-
updatedMessage: LocalMessage | MessageResponse,
7+
updatedMessage: MessageRequest,
138
options?: UpdateMessageOptions,
149
) => ReturnType<StreamChat['updateMessage']>;
1510

1611
export const useEditMessageHandler = (doUpdateMessageRequest?: UpdateHandler) => {
1712
const { channel, client } = useChatContext('useEditMessageHandler');
1813

19-
return (
20-
updatedMessage: LocalMessage | MessageResponse,
21-
options?: UpdateMessageOptions,
22-
) => {
14+
return (updatedMessage: MessageRequest, options?: UpdateMessageOptions) => {
2315
if (doUpdateMessageRequest && channel) {
2416
return Promise.resolve(
2517
doUpdateMessageRequest(channel.cid, updatedMessage, options),
2618
);
2719
}
28-
return client.updateMessage(updatedMessage, undefined, options);
20+
return client.updateMessage({
21+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
22+
id: updatedMessage.id!,
23+
message: updatedMessage,
24+
...options,
25+
});
2926
};
3027
};

src/components/Channel/utils.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import {
2-
type APIErrorResponse,
2+
type APIError,
33
type ChannelState,
4-
ErrorFromResponse,
54
type MessageResponse,
5+
StreamAPIError,
66
} from 'stream-chat';
77

88
/**
@@ -77,27 +77,27 @@ export const findInMsgSetByDate = (
7777
};
7878
/**
7979
* Compatibility adapter:
80-
* LocalMessage.error expects ErrorFromResponse<APIErrorResponse>, but some transport failures
80+
* LocalMessage.error expects StreamAPIError<APIError>, but some transport failures
8181
* (for example Axios ERR_NETWORK while offline) do not have an HTTP response payload.
8282
*/
8383
export const adaptMessageSendErrorToErrorFromResponse = (
8484
error: unknown,
85-
): ErrorFromResponse<APIErrorResponse> => {
86-
if (error instanceof ErrorFromResponse) {
85+
): StreamAPIError<APIError> => {
86+
if (error instanceof StreamAPIError) {
8787
return error;
8888
}
8989

9090
const fallbackMessage = error instanceof Error ? error.message : 'Message send failed';
9191
let message = fallbackMessage;
9292
let status = 0;
93-
let code: number | null = null;
93+
let code: number | undefined = undefined;
9494

9595
if (typeof error === 'object' && error !== null) {
9696
const maybeAxiosError = error as {
9797
code?: unknown;
9898
message?: unknown;
9999
name?: unknown;
100-
response?: ErrorFromResponse<APIErrorResponse>['response'];
100+
response?: StreamAPIError<APIError>['response'];
101101
status?: unknown;
102102
};
103103

@@ -108,8 +108,8 @@ export const adaptMessageSendErrorToErrorFromResponse = (
108108
: 'Network Error';
109109
status = maybeAxiosError.response?.status ?? 0;
110110

111-
return new ErrorFromResponse<APIErrorResponse>(message, {
112-
code: null,
111+
return new StreamAPIError<APIError>(message, {
112+
code: undefined,
113113
response:
114114
maybeAxiosError.response ??
115115
({
@@ -121,7 +121,7 @@ export const adaptMessageSendErrorToErrorFromResponse = (
121121
StatusCode: status,
122122
},
123123
status,
124-
} as ErrorFromResponse<APIErrorResponse>['response']),
124+
} as unknown as StreamAPIError<APIError>['response']),
125125
status,
126126
});
127127
}
@@ -147,7 +147,7 @@ export const adaptMessageSendErrorToErrorFromResponse = (
147147
}
148148
}
149149

150-
return new ErrorFromResponse<APIErrorResponse>(message, {
150+
return new StreamAPIError<APIError>(message, {
151151
code,
152152
response: {
153153
// Compatibility shim: this is an intentionally incomplete AxiosResponse-like object.
@@ -158,7 +158,7 @@ export const adaptMessageSendErrorToErrorFromResponse = (
158158
StatusCode: status,
159159
},
160160
status,
161-
} as ErrorFromResponse<APIErrorResponse>['response'],
161+
} as unknown as StreamAPIError<APIError>['response'],
162162
status,
163163
});
164164
};

src/components/ChannelList/ChannelListUI.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useRef } from 'react';
22
import type { PropsWithChildren } from 'react';
3-
import type { APIErrorResponse, Channel, StreamAPIError } from 'stream-chat';
3+
import type { APIError, Channel, StreamAPIError } from 'stream-chat';
44

55
import { LoadingChannels } from '../Loading/LoadingChannels';
66
import { NullComponent } from '../UtilityComponents';
@@ -9,7 +9,7 @@ import { useComponentContext, useTranslationContext } from '../../context';
99

1010
export type ChannelListUIProps = {
1111
/** Whether the channel query request returned an errored response */
12-
error: StreamAPIError<APIErrorResponse> | null;
12+
error: StreamAPIError<APIError> | null;
1313
/** The channels currently loaded in the list, only defined if `sendChannelsToList` on `ChannelList` is true */
1414
loadedChannels?: Channel[];
1515
/** Whether the channels are currently loading */

src/components/ChannelList/hooks/usePaginatedChannels.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
22
import uniqBy from 'lodash.uniqby';
33

44
import type {
5-
APIErrorResponse,
5+
APIError,
66
Channel,
77
ChannelFilters,
88
ChannelOptions,
@@ -167,7 +167,7 @@ export const usePaginatedChannels = (
167167
});
168168

169169
if (isFirstPage) {
170-
setError(error as StreamAPIError<APIErrorResponse>);
170+
setError(error as StreamAPIError<APIError>);
171171
}
172172
}
173173

0 commit comments

Comments
 (0)