From 6c1f94d8343cd3b93ddaa2dcc8905e7a090a163d Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Fri, 7 Mar 2025 15:07:30 +0100 Subject: [PATCH 01/60] chore: modify gh workflows --- .github/workflows/check-pr.yml | 1 + .github/workflows/lint-pr-title.yml | 1 + .github/workflows/sample-distribution.yml | 10 +++++----- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index 1c78fed42a..f6553b02a5 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -6,6 +6,7 @@ on: - develop - main - 'v[0-9]+.[0-9]+.[0-9]+*beta*' + - V7 types: [opened, synchronize] jobs: diff --git a/.github/workflows/lint-pr-title.yml b/.github/workflows/lint-pr-title.yml index ebb5e856ad..5ea99347d7 100644 --- a/.github/workflows/lint-pr-title.yml +++ b/.github/workflows/lint-pr-title.yml @@ -5,6 +5,7 @@ on: branches: - develop - 'v[0-9]+.[0-9]+.[0-9]+' + - V7 types: [opened, edited, synchronize] jobs: diff --git a/.github/workflows/sample-distribution.yml b/.github/workflows/sample-distribution.yml index 1073f11080..51a3b2b2f5 100644 --- a/.github/workflows/sample-distribution.yml +++ b/.github/workflows/sample-distribution.yml @@ -13,7 +13,7 @@ on: jobs: build_and_deploy_ios_testflight_qa: - name: Build SampleApp iOS and Deploy-${{ github.ref == 'refs/heads/develop' }} + name: Build SampleApp iOS and Deploy-${{ github.ref == 'refs/heads/V7' }} runs-on: [macos-14] steps: - name: Connect Bot @@ -38,14 +38,14 @@ jobs: bundle exec pod install - name: Build and release Testflight QA working-directory: examples/SampleApp - run: bundle exec fastlane deploy_to_testflight_qa deploy:${{ github.ref == 'refs/heads/develop' }}; + run: bundle exec fastlane deploy_to_testflight_qa deploy:${{ github.ref == 'refs/heads/V7' }}; env: MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }} APPSTORE_API_KEY: ${{ secrets.APPSTORE_API_KEY }} build_and_deploy_android_s3: - name: Build SampleApp Android and Deploy-${{ github.ref == 'refs/heads/develop' }} + name: Build SampleApp Android and Deploy-${{ github.ref == 'refs/heads/V7' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -66,13 +66,13 @@ jobs: rm -rf $HOME/.gradle/caches/ && ./gradlew assembleRelease - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 - if: ${{ github.ref == 'refs/heads/develop' }} + if: ${{ github.ref == 'refs/heads/V7' }} with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1 - name: Upload APK - if: ${{ github.ref == 'refs/heads/develop' }} + if: ${{ github.ref == 'refs/heads/V7' }} # https://getstream.io/downloads/rn-sample-app.apk run: | cp examples/SampleApp/android/app/build/outputs/apk/release/app-release.apk rn-sample-app.apk From e443cafe9e1a018e9f736802766d08ec4dd370dc Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj <31964049+isekovanic@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:43:29 +0100 Subject: [PATCH 02/60] feat: removal of StreamChatGenerics (#2993) * feat: remove StreamChatGenerics and introduce interface merging * fix: some of the outstanding todos * chore: add default interfaces * chore: remove SCG from sample app * fix: remove redundant types * fix: remove type module * fix: change the way interface declaration is consumed * fix: ignore ts complaints for interface declaration * chore: migrate TypescriptMessagingApp away from SCG * chore: migrate the Expo sample app away from SCG * fix: commit missing files * fix: revert mistaken change * fix: add resolutions for symlinked libs --- examples/ExpoMessaging/app/index.tsx | 3 +- .../ExpoMessaging/components/ChatWrapper.tsx | 5 +- examples/ExpoMessaging/context/AppContext.tsx | 15 +- examples/ExpoMessaging/custom-types.d.ts | 41 +++ examples/ExpoMessaging/package.json | 3 + examples/ExpoMessaging/types.ts | 23 -- examples/ExpoMessaging/yarn.lock | 177 +++++------ examples/SampleApp/App.tsx | 11 +- examples/SampleApp/src/ChatUsers.ts | 3 +- .../src/components/AddMemberBottomSheet.tsx | 4 +- .../src/components/ChannelInfoOverlay.tsx | 11 +- .../src/components/ChannelPreview.tsx | 6 +- .../MessageSearch/MessageSearchList.tsx | 6 +- .../NewDirectMessagingSendButton.tsx | 30 +- .../src/components/UnreadCountBadge.tsx | 2 +- .../src/components/UserInfoOverlay.tsx | 5 +- .../components/UserSearch/SelectedUserTag.tsx | 3 +- .../components/UserSearch/UserGridItem.tsx | 4 +- .../UserSearch/UserSearchResults.tsx | 11 +- .../UserSearch/UserSearchResultsGrid.tsx | 5 +- examples/SampleApp/src/context/AppContext.ts | 4 +- .../src/context/BottomSheetOverlayContext.tsx | 5 +- .../src/context/ChannelInfoOverlayContext.tsx | 6 +- .../src/context/UserInfoOverlayContext.tsx | 6 +- examples/SampleApp/src/custom-types.d.ts | 45 +++ .../src/hooks/useChannelMembersStatus.ts | 4 +- examples/SampleApp/src/hooks/useChatClient.ts | 8 +- .../src/hooks/usePaginatedAttachments.ts | 6 +- .../src/hooks/usePaginatedPinnedMessages.ts | 5 +- .../src/hooks/usePaginatedSearchedMessages.ts | 5 +- .../SampleApp/src/hooks/usePaginatedUsers.ts | 25 +- .../src/screens/ChannelFilesScreen.tsx | 15 +- .../src/screens/ChannelImagesScreen.tsx | 10 +- .../src/screens/ChannelListScreen.tsx | 16 +- .../SampleApp/src/screens/ChannelScreen.tsx | 10 +- .../src/screens/GroupChannelDetailsScreen.tsx | 6 +- .../SampleApp/src/screens/MentionsScreen.tsx | 7 +- .../src/screens/NewDirectMessagingScreen.tsx | 7 +- .../src/screens/SharedGroupsScreen.tsx | 10 +- .../SampleApp/src/screens/ThreadScreen.tsx | 22 +- examples/SampleApp/src/types.ts | 52 +--- .../SampleApp/src/utils/RootNavigation.ts | 4 +- examples/SampleApp/src/utils/base.tsx | 1 + .../src/utils/getUserActivityStatus.ts | 5 +- examples/SampleApp/yarn.lock | 86 ++---- examples/TypeScriptMessaging/App.tsx | 46 +-- .../TypeScriptMessaging/custom-types.d.ts | 41 +++ examples/TypeScriptMessaging/ios/Podfile.lock | 2 +- .../TypeScriptMessaging/useStreamChatTheme.ts | 2 +- examples/TypeScriptMessaging/yarn.lock | 86 ++---- package/expo-package/yarn.lock | 151 ++++++---- package/native-package/yarn.lock | 165 +++++----- package/package.json | 2 +- .../AITypingIndicatorView.tsx | 15 +- .../AITypingIndicatorView/hooks/useAIState.ts | 26 +- .../src/components/Attachment/Attachment.tsx | 44 +-- .../Attachment/AttachmentActions.tsx | 34 +-- package/src/components/Attachment/Card.tsx | 50 +--- .../components/Attachment/FileAttachment.tsx | 35 +-- .../Attachment/FileAttachmentGroup.tsx | 45 +-- package/src/components/Attachment/Gallery.tsx | 72 ++--- .../components/Attachment/GalleryImage.tsx | 14 +- package/src/components/Attachment/Giphy.tsx | 50 ++-- .../utils/buildGallery/buildGallery.ts | 7 +- .../buildGallery/buildGalleryOfSingleImage.ts | 18 +- .../buildGallery/buildGalleryOfThreeImages.ts | 12 +- .../buildGallery/buildGalleryOfTwoImages.ts | 8 +- .../utils/buildGallery/buildThumbnail.ts | 13 +- .../utils/buildGallery/buildThumbnailGrid.ts | 8 +- .../Attachment/utils/getAspectRatio.ts | 6 +- .../AutoCompleteInput/AutoCompleteInput.tsx | 54 +--- .../AutoCompleteSuggestionCommandIcon.tsx | 7 +- .../AutoCompleteSuggestionHeader.tsx | 32 +- .../AutoCompleteSuggestionItem.tsx | 39 ++- .../AutoCompleteSuggestionList.tsx | 51 ++-- package/src/components/Channel/Channel.tsx | 282 ++++++++---------- .../Channel/hooks/useChannelDataState.ts | 97 +++--- .../Channel/hooks/useCreateChannelContext.ts | 9 +- .../useCreateInputMessageInputContext.ts | 9 +- .../Channel/hooks/useCreateMessagesContext.ts | 9 +- .../hooks/useCreateOwnCapabilitiesContext.ts | 7 +- .../useCreatePaginatedMessageListContext.ts | 10 +- .../Channel/hooks/useCreateThreadContext.ts | 7 +- .../Channel/hooks/useCreateTypingContext.ts | 9 +- .../hooks/useMessageListPagination.tsx | 74 +++-- .../components/ChannelList/ChannelList.tsx | 80 +++-- .../ChannelList/ChannelListMessenger.tsx | 49 +-- .../useAddedToChannelNotification.ts | 36 +-- .../hooks/listeners/useChannelDeleted.ts | 28 +- .../hooks/listeners/useChannelHidden.ts | 28 +- .../listeners/useChannelMemberUpdated.ts | 40 ++- .../hooks/listeners/useChannelTruncated.ts | 31 +- .../hooks/listeners/useChannelUpdated.ts | 30 +- .../hooks/listeners/useChannelVisible.ts | 38 +-- .../hooks/listeners/useNewMessage.ts | 40 ++- .../listeners/useNewMessageNotification.ts | 34 +-- .../useRemovedFromChannelNotification.ts | 27 +- .../hooks/listeners/useUserPresence.ts | 24 +- .../hooks/useChannelMembershipState.ts | 18 +- .../hooks/useCreateChannelsContext.ts | 9 +- .../ChannelList/hooks/usePaginatedChannels.ts | 31 +- .../hooks/useSelectedChannelState.ts | 26 +- .../ChannelList/hooks/utils/index.ts | 43 +-- package/src/components/ChannelList/utils.ts | 32 +- .../ChannelPreview/ChannelAvatar.tsx | 20 +- .../ChannelPreview/ChannelPreview.tsx | 20 +- .../ChannelPreview/ChannelPreviewMessage.tsx | 14 +- .../ChannelPreviewMessenger.tsx | 37 +-- .../ChannelPreview/ChannelPreviewStatus.tsx | 15 +- .../ChannelPreview/ChannelPreviewTitle.tsx | 11 +- .../ChannelPreviewUnreadCount.tsx | 14 +- .../useChannelPreviewDisplayName.test.tsx | 2 +- .../useLatestMessagePreview.test.tsx | 1 - .../hooks/useChannelPreviewData.ts | 18 +- .../hooks/useChannelPreviewDisplayAvatar.ts | 17 +- .../hooks/useChannelPreviewDisplayName.ts | 17 +- .../hooks/useChannelPreviewDisplayPresence.ts | 17 +- .../ChannelPreview/hooks/useIsChannelMuted.ts | 10 +- .../hooks/useLatestMessagePreview.ts | 80 ++--- package/src/components/Chat/Chat.tsx | 35 +-- .../Chat/hooks/handleEventToSyncDB.ts | 9 +- .../components/Chat/hooks/useAppSettings.ts | 7 +- .../Chat/hooks/useCreateChatClient.ts | 10 +- .../Chat/hooks/useCreateChatContext.ts | 9 +- .../src/components/Chat/hooks/useIsOnline.ts | 11 +- .../components/Chat/hooks/useMutedUsers.ts | 14 +- .../components/Chat/hooks/useSyncDatabase.ts | 14 +- .../components/ImageGallery/ImageGallery.tsx | 64 ++-- .../__tests__/ImageGallery.test.tsx | 2 +- .../__tests__/ImageGalleryFooter.test.tsx | 2 +- .../__tests__/ImageGalleryHeader.test.tsx | 2 +- .../__tests__/ImageGalleryOverlay.test.tsx | 2 +- .../components/ImageGalleryFooter.tsx | 48 ++- .../components/ImageGalleryHeader.tsx | 36 +-- .../ImageGallery/components/ImageGrid.tsx | 54 +--- package/src/components/Message/Message.tsx | 122 +++----- .../Message/MessageSimple/MessageAvatar.tsx | 36 +-- .../Message/MessageSimple/MessageBounce.tsx | 39 +-- .../Message/MessageSimple/MessageContent.tsx | 44 ++- .../Message/MessageSimple/MessageDeleted.tsx | 36 +-- .../MessageSimple/MessageEditedTimestamp.tsx | 15 +- .../Message/MessageSimple/MessageFooter.tsx | 41 +-- .../MessageSimple/MessagePinnedHeader.tsx | 14 +- .../Message/MessageSimple/MessageReplies.tsx | 36 +-- .../MessageSimple/MessageRepliesAvatars.tsx | 17 +- .../Message/MessageSimple/MessageSimple.tsx | 38 +-- .../Message/MessageSimple/MessageStatus.tsx | 30 +- .../MessageSimple/MessageTextContainer.tsx | 49 +-- .../ReactionList/ReactionListBottom.tsx | 35 +-- .../ReactionList/ReactionListTop.tsx | 33 +- .../MessageSimple/StreamingMessageView.tsx | 14 +- .../MessageSimple/utils/renderText.tsx | 20 +- .../Message/hooks/useCreateMessageContext.ts | 10 +- .../Message/hooks/useMessageActionHandlers.ts | 15 +- .../Message/hooks/useMessageActions.tsx | 26 +- .../Message/hooks/useMessageData.ts | 16 +- .../Message/hooks/useProcessReactions.ts | 38 +-- .../Message/hooks/useStreamingMessage.ts | 13 +- .../Message/utils/messageActions.ts | 18 +- .../components/MessageInput/AttachButton.tsx | 11 +- .../MessageInput/CommandsButton.tsx | 30 +- .../MessageInput/FileUploadPreview.tsx | 40 +-- .../MessageInput/ImageUploadPreview.tsx | 36 +-- .../components/MessageInput/InputButtons.tsx | 32 +- .../components/MessageInput/MessageInput.tsx | 63 ++-- .../components/MessageInput/SendButton.tsx | 29 +- .../ShowThreadMessageInChannelButton.tsx | 13 +- .../AudioRecorder/AudioRecorder.tsx | 34 +-- .../AudioRecorder/AudioRecordingButton.tsx | 33 +- .../AudioRecordingInProgress.tsx | 33 +- .../components/InputEditingStateHeader.tsx | 15 +- .../components/InputGiphySearch.tsx | 18 +- .../components/InputReplyStateHeader.tsx | 13 +- .../MessageInput/hooks/useCooldown.ts | 12 +- .../InlineLoadingMoreIndicator.tsx | 8 +- .../InlineLoadingMoreRecentIndicator.tsx | 8 +- ...InlineLoadingMoreRecentThreadIndicator.tsx | 8 +- .../components/MessageList/MessageList.tsx | 166 +++++------ .../components/MessageList/MessageSystem.tsx | 13 +- .../components/MessageList/StickyHeader.tsx | 5 +- .../MessageList/TypingIndicator.tsx | 7 +- .../MessageList/TypingIndicatorContainer.tsx | 34 +-- .../__tests__/useMessageList.test.tsx | 2 +- .../MessageList/hooks/useLastReadData.ts | 18 +- .../MessageList/hooks/useMessageList.ts | 53 ++-- .../useShouldScrollToRecentOnNewOwnMessage.ts | 9 +- .../MessageList/hooks/useTypingString.ts | 11 +- .../MessageList/utils/filterTypingUsers.ts | 21 +- .../MessageList/utils/getDateSeparators.ts | 15 +- .../MessageList/utils/getGroupStyles.ts | 26 +- .../utils/getLastReceivedMessage.ts | 7 +- .../MessageList/utils/getReadStates.ts | 13 +- .../components/MessageMenu/MessageMenu.tsx | 19 +- .../MessageMenu/MessageReactionPicker.tsx | 14 +- .../MessageMenu/MessageUserReactions.tsx | 10 +- .../MessageMenu/MessageUserReactionsItem.tsx | 15 +- .../MessageMenu/hooks/useFetchReactions.ts | 15 +- package/src/components/Poll/Poll.tsx | 15 +- .../src/components/Poll/components/Button.tsx | 14 +- .../Poll/components/PollAnswersList.tsx | 7 +- .../PollResults/PollOptionFullResults.tsx | 12 +- .../components/PollResults/PollResultItem.tsx | 20 +- .../src/components/Poll/hooks/usePollState.ts | 16 +- package/src/components/Reply/Reply.tsx | 61 ++-- package/src/components/Thread/Thread.tsx | 44 +-- .../__snapshots__/Thread.test.js.snap | 3 - .../components/ThreadFooterComponent.tsx | 36 +-- .../src/components/ThreadList/ThreadList.tsx | 8 +- .../channelContext/ChannelContext.tsx | 42 +-- .../channelsContext/ChannelsContext.tsx | 42 ++- .../ChannelsStateContext.tsx | 62 ++-- .../channelsStateContext/useChannelState.ts | 39 +-- .../src/contexts/chatContext/ChatContext.tsx | 29 +- .../contexts/debugContext/DebugContext.tsx | 33 +- .../ImageGalleryContext.tsx | 28 +- .../messageContext/MessageContext.tsx | 34 +-- .../MessageInputContext.tsx | 141 ++++----- .../__tests__/MessageInputContext.test.tsx | 19 +- .../__tests__/isValidMessage.test.tsx | 12 +- .../__tests__/pickFile.test.tsx | 12 +- .../__tests__/removeFile.test.tsx | 12 +- .../__tests__/removeImage.test.tsx | 12 +- .../__tests__/sendMessage.test.tsx | 12 +- .../__tests__/sendMessageAsync.test.tsx | 11 +- .../__tests__/updateMessage.test.tsx | 16 +- .../__tests__/uploadFile.test.tsx | 12 +- .../__tests__/uploadImage.test.tsx | 12 +- .../useMessageDetailsForState.test.tsx | 2 +- .../hooks/useCreateMessageInputContext.ts | 10 +- .../hooks/useMessageDetailsForState.ts | 15 +- .../messagesContext/MessagesContext.tsx | 144 ++++----- .../overlayContext/OverlayContext.tsx | 7 +- .../overlayContext/OverlayProvider.tsx | 10 +- .../PaginatedMessageListContext.tsx | 19 +- .../src/contexts/pollContext/pollContext.tsx | 16 +- .../suggestionsContext/SuggestionsContext.tsx | 87 ++---- .../contexts/threadContext/ThreadContext.tsx | 30 +- .../threadsContext/ThreadListItemContext.tsx | 26 +- .../threadsContext/ThreadsContext.tsx | 24 +- .../contexts/typingContext/TypingContext.tsx | 21 +- package/src/hooks/useTranslatedMessage.ts | 7 +- .../src/mock-builders/api/channelMocks.tsx | 2 - package/src/store/apis/getChannelMessages.ts | 9 +- package/src/store/apis/getChannels.ts | 15 +- .../store/apis/getChannelsForFilterSort.ts | 12 +- package/src/store/apis/getMembers.ts | 13 +- package/src/store/apis/getReactions.ts | 9 +- .../store/apis/getReactionsforFilterSort.ts | 12 +- package/src/store/apis/getReads.ts | 13 +- .../queries/selectChannelIdsForFilterSort.ts | 9 +- package/src/store/apis/updatePollMessage.ts | 9 +- .../apis/upsertChannelDataFromChannel.ts | 7 +- .../apis/utils/convertFilterSortToQuery.ts | 10 +- .../store/mappers/mapChannelDataToStorable.ts | 8 +- .../src/store/mappers/mapChannelToStorable.ts | 10 +- .../src/store/mappers/mapMemberToStorable.ts | 7 +- .../src/store/mappers/mapReadToStorable.ts | 7 +- .../src/store/mappers/mapStorableToChannel.ts | 10 +- .../src/store/mappers/mapStorableToMember.ts | 7 +- .../src/store/mappers/mapStorableToMessage.ts | 11 +- .../src/store/mappers/mapStorableToPoll.ts | 9 +- .../store/mappers/mapStorableToReaction.ts | 8 +- .../src/store/mappers/mapStorableToRead.ts | 8 +- .../src/store/mappers/mapStorableToUser.ts | 7 +- .../types/stream-chat-common-custom-data.d.ts | 42 +++ package/src/types/types.ts | 90 +++--- package/src/utils/ACITriggerSettings.ts | 57 ++-- package/src/utils/DBSyncManager.ts | 37 +-- package/src/utils/addReactionToLocalState.ts | 10 +- package/src/utils/i18n/Streami18n.ts | 6 +- package/src/utils/queryMembers.ts | 55 ++-- package/src/utils/queryUsers.ts | 25 +- .../src/utils/removeReactionFromLocalState.ts | 10 +- package/src/utils/removeReservedFields.ts | 12 +- package/src/utils/utils.ts | 82 ++--- package/yarn.lock | 46 +-- 276 files changed, 2727 insertions(+), 4497 deletions(-) create mode 100644 examples/ExpoMessaging/custom-types.d.ts delete mode 100644 examples/ExpoMessaging/types.ts create mode 100644 examples/SampleApp/src/custom-types.d.ts create mode 100644 examples/TypeScriptMessaging/custom-types.d.ts create mode 100644 package/src/types/stream-chat-common-custom-data.d.ts diff --git a/examples/ExpoMessaging/app/index.tsx b/examples/ExpoMessaging/app/index.tsx index 66f64105f7..9487a9d1f8 100644 --- a/examples/ExpoMessaging/app/index.tsx +++ b/examples/ExpoMessaging/app/index.tsx @@ -3,7 +3,6 @@ import { ChannelList } from 'stream-chat-expo'; import { useContext, useMemo } from 'react'; import { Stack, useRouter } from 'expo-router'; import { ChannelSort } from 'stream-chat'; -import { StreamChatGenerics } from '../types'; import { AppContext } from '../context/AppContext'; import { user } from '../constants'; @@ -11,7 +10,7 @@ const filters = { members: { $in: [user.id] }, type: 'messaging', }; -const sort: ChannelSort = { last_updated: -1 }; +const sort: ChannelSort = { last_updated: -1 }; const options = { state: true, watch: true, diff --git a/examples/ExpoMessaging/components/ChatWrapper.tsx b/examples/ExpoMessaging/components/ChatWrapper.tsx index e803bbc48f..736acafbfa 100644 --- a/examples/ExpoMessaging/components/ChatWrapper.tsx +++ b/examples/ExpoMessaging/components/ChatWrapper.tsx @@ -1,4 +1,4 @@ -import React, { PropsWithChildren } from 'react'; +import React, { PropsWithChildren, useRef } from 'react'; import { Chat, OverlayProvider, @@ -7,7 +7,6 @@ import { useCreateChatClient, } from 'stream-chat-expo'; import { AuthProgressLoader } from './AuthProgressLoader'; -import { StreamChatGenerics } from '../types'; import { STREAM_API_KEY, user, userToken } from '../constants'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useStreamChatTheme } from '../useStreamChatTheme'; @@ -34,7 +33,7 @@ export const ChatWrapper = ({ children }: PropsWithChildren<{}>) => { } return ( - + | undefined; - setChannel: React.Dispatch | undefined>>; + channel: ChannelType | undefined; + setChannel: React.Dispatch>; setThread: React.Dispatch< - React.SetStateAction['thread'] | undefined> + React.SetStateAction >; - thread: ThreadContextValue['thread'] | undefined; + thread: ThreadContextValue['thread'] | undefined; }; export const AppContext = createContext({ @@ -20,9 +19,9 @@ export const AppContext = createContext({ }); export const AppProvider = ({ children }: PropsWithChildren) => { - const [channel, setChannel] = useState | undefined>(undefined); + const [channel, setChannel] = useState(undefined); const [thread, setThread] = useState< - ThreadContextValue['thread'] | undefined + ThreadContextValue['thread'] | undefined >(undefined); return ( diff --git a/examples/ExpoMessaging/custom-types.d.ts b/examples/ExpoMessaging/custom-types.d.ts new file mode 100644 index 0000000000..fb15477e17 --- /dev/null +++ b/examples/ExpoMessaging/custom-types.d.ts @@ -0,0 +1,41 @@ +import { + DefaultAttachmentType, + DefaultMessageType, + DefaultChannelType, + DefaultCommandType, + DefaultEventType, + DefaultMemberType, + DefaultPollOptionType, + DefaultPollType, + DefaultReactionType, + DefaultThreadType, + DefaultUserType, +} from 'stream-chat-expo'; + +declare module 'stream-chat' { + /* eslint-disable @typescript-eslint/no-empty-object-type */ + + interface CustomAttachmentData extends DefaultAttachmentType {} + + interface CustomChannelData extends DefaultChannelType {} + + interface CustomCommandData extends DefaultCommandType {} + + interface CustomEventData extends DefaultEventType {} + + interface CustomMemberData extends DefaultMemberType {} + + interface CustomUserData extends DefaultUserType {} + + interface CustomMessageData extends DefaultMessageType {} + + interface CustomPollOptionData extends DefaultPollOptionType {} + + interface CustomPollData extends DefaultPollType {} + + interface CustomReactionData extends DefaultReactionType {} + + interface CustomThreadData extends DefaultThreadType {} + + /* eslint-enable @typescript-eslint/no-empty-object-type */ +} diff --git a/examples/ExpoMessaging/package.json b/examples/ExpoMessaging/package.json index d60f1de309..34a3a68621 100644 --- a/examples/ExpoMessaging/package.json +++ b/examples/ExpoMessaging/package.json @@ -46,5 +46,8 @@ "@rnx-kit/metro-config": "^2.0.1", "@rnx-kit/metro-resolver-symlinks": "^0.2.1" }, + "resolutions": { + "@types/react": "^19.0.0" + }, "private": true } diff --git a/examples/ExpoMessaging/types.ts b/examples/ExpoMessaging/types.ts deleted file mode 100644 index 6607eb8e63..0000000000 --- a/examples/ExpoMessaging/types.ts +++ /dev/null @@ -1,23 +0,0 @@ -export type LocalAttachmentType = Record; -export type LocalChannelType = Record; -export type LocalCommandType = string; -export type LocalEventType = Record; -export type LocalMessageType = Record; -export type LocalReactionType = Record; -export type LocalUserType = Record; -export type LocalPollOptionType = Record; -export type LocalPollType = Record; -export type LocalMemberType = Record; - -export type StreamChatGenerics = { - attachmentType: LocalAttachmentType; - channelType: LocalChannelType; - commandType: LocalCommandType; - eventType: LocalEventType; - memberType: LocalMemberType; - messageType: LocalMessageType; - pollOptionType: LocalPollOptionType; - pollType: LocalPollType; - reactionType: LocalReactionType; - userType: LocalUserType; -}; diff --git a/examples/ExpoMessaging/yarn.lock b/examples/ExpoMessaging/yarn.lock index 422188b1e7..0b8c9da5fe 100644 --- a/examples/ExpoMessaging/yarn.lock +++ b/examples/ExpoMessaging/yarn.lock @@ -1507,13 +1507,6 @@ dependencies: regenerator-runtime "^0.13.11" -"@babel/runtime@^7.16.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.20.0": - version "7.22.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.3.tgz#0a7fce51d43adbf0f7b517a71f4c3aaca92ebcbb" - integrity sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ== - dependencies: - regenerator-runtime "^0.13.11" - "@babel/runtime@^7.17.2": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12" @@ -1521,6 +1514,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.18.6", "@babel/runtime@^7.20.0": + version "7.22.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.3.tgz#0a7fce51d43adbf0f7b517a71f4c3aaca92ebcbb" + integrity sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ== + dependencies: + regenerator-runtime "^0.13.11" + "@babel/template@^7.20.7", "@babel/template@^7.21.9": version "7.21.9" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.21.9.tgz#bf8dad2859130ae46088a99c1f265394877446fb" @@ -2881,13 +2881,19 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/jsonwebtoken@~9.0.0": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#9eeb56c76dd555039be2a3972218de5bd3b8d83e" - integrity sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q== +"@types/jsonwebtoken@^9.0.8": + version "9.0.9" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3" + integrity sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ== dependencies: + "@types/ms" "*" "@types/node" "*" +"@types/ms@*": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78" + integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== + "@types/node-forge@^1.3.0": version "1.3.11" resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" @@ -2900,34 +2906,22 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.5.tgz#26d295f3570323b2837d322180dfbf1ba156fefb" integrity sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ== -"@types/prop-types@*": - version "15.7.5" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" - integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== - -"@types/react@>=16.0.0": - version "18.2.7" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.7.tgz#dfb4518042a3117a045b8c222316f83414a783b3" - integrity sha512-ojrXpSH2XFCmHm7Jy3q44nXDyN54+EYKP2lBhJ2bqfyPj6cIUW/FZW/Csdia34NQgq7KYcAlHi5184m4X88+yw== +"@types/react@>=16.0.0", "@types/react@^19.0.0": + version "19.0.10" + resolved "https://registry.yarnpkg.com/@types/react/-/react-19.0.10.tgz#d0c66dafd862474190fe95ce11a68de69ed2b0eb" + integrity sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g== dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" csstype "^3.0.2" -"@types/scheduler@*": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" - integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== - "@types/stack-utils@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== -"@types/ws@^7.4.0": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== +"@types/ws@^8.5.14": + version "8.18.0" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" + integrity sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw== dependencies: "@types/node" "*" @@ -5148,10 +5142,10 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== +isomorphic-ws@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== istanbul-lib-coverage@^3.2.0: version "3.2.2" @@ -5407,15 +5401,21 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonwebtoken@~9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz#d0faf9ba1cc3a56255fe49c0961a67e520c1926d" - integrity sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw== +jsonwebtoken@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" + integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== dependencies: jws "^3.2.2" - lodash "^4.17.21" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" ms "^2.1.1" - semver "^7.3.8" + semver "^7.5.4" jwa@^1.4.1: version "1.4.1" @@ -5567,6 +5567,41 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash.throttle@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" @@ -7053,7 +7088,7 @@ semver@^7.1.3, semver@~7.6.3: resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== -semver@^7.3.5, semver@^7.3.8: +semver@^7.3.5: version "7.5.1" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== @@ -7358,58 +7393,23 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -stream-chat-react-native-core@6.6.6: - version "6.6.6" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.6.6.tgz#d701beb9652f0a5851286f752d8c4fdadb3e0603" - integrity sha512-sfBtWz4K4OzhFDMRaPF2xMj7aP9FQU4dMN1XCsmRT07hyYn6iEviECxNttYvoRLB1zNdeja5cL63IDY3UZSpAQ== - dependencies: - "@gorhom/bottom-sheet" "^5.1.1" - dayjs "1.10.5" - emoji-regex "^10.3.0" - i18next "^21.6.14" - intl-pluralrules "^2.0.1" - linkifyjs "^4.1.1" - lodash-es "4.17.21" - mime-types "^2.1.34" - path "0.12.7" - react-native-markdown-package "1.8.2" - react-native-url-polyfill "^1.3.0" - stream-chat "^8.57.5" - use-sync-external-store "^1.4.0" - "stream-chat-react-native-core@link:../../package": version "0.0.0" uid "" -stream-chat@^8.57.5: - version "8.57.5" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.57.5.tgz#1b49b7504371e19a539465e2ae5dc86aa3269637" - integrity sha512-ndcbH/zGzUIAhZLGn1owVV8MeNvVfWITIlhAhfmnsV7RLoo/eiGFEuP4aNoG1YRos/g9xJQ7TEmKpz8xYqo13w== +stream-chat@9.0.0-rc.4: + version "9.0.0-rc.4" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.4.tgz#30ffd324069cd012372014efe3a6d94bf264963a" + integrity sha512-kVlDls6TXEWAlAQf6WLwNv3wDwVo0y9J536+NS8PFmkJKkBNfD9RGAbb4SuZNxeEpd+kAy3861vxspB1mpFEmQ== dependencies: - "@babel/runtime" "^7.16.3" - "@types/jsonwebtoken" "~9.0.0" - "@types/ws" "^7.4.0" + "@types/jsonwebtoken" "^9.0.8" + "@types/ws" "^8.5.14" axios "^1.6.0" base64-js "^1.5.1" form-data "^4.0.0" - isomorphic-ws "^4.0.1" - jsonwebtoken "~9.0.0" - ws "^7.5.10" - -stream-chat@^8.57.6: - version "8.57.6" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.57.6.tgz#dd3a4a0a024ee44bfa6ae7ca15648e6c9f2e498f" - integrity sha512-+zkC5DtxvdkEBAv7dCzzO4WWosjaM15EjsH3q4xD1nX/yf2qT6BMhPJguM+CUWxwlFh32X0KR+ARtD0ChPqtnA== - dependencies: - "@babel/runtime" "^7.16.3" - "@types/jsonwebtoken" "~9.0.0" - "@types/ws" "^7.4.0" - axios "^1.6.0" - base64-js "^1.5.1" - form-data "^4.0.0" - isomorphic-ws "^4.0.1" - jsonwebtoken "~9.0.0" - ws "^7.5.10" + isomorphic-ws "^5.0.0" + jsonwebtoken "^9.0.2" + ws "^8.18.1" stream-slice@^0.1.2: version "0.1.2" @@ -8100,6 +8100,11 @@ ws@^8.12.1: resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== +ws@^8.18.1: + version "8.18.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" + integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== + xcode@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/xcode/-/xcode-3.0.1.tgz#3efb62aac641ab2c702458f9a0302696146aa53c" diff --git a/examples/SampleApp/App.tsx b/examples/SampleApp/App.tsx index 509d92ab0c..467e316fac 100644 --- a/examples/SampleApp/App.tsx +++ b/examples/SampleApp/App.tsx @@ -47,7 +47,6 @@ if (__DEV__) { import type { StackNavigatorParamList, - StreamChatGenerics, UserSelectorParamList, } from './src/types'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; @@ -171,21 +170,23 @@ const DrawerNavigator: React.FC = () => ( ); +const isMessageAIGenerated = (message: MessageType) => !!message.ai_generated; + const DrawerNavigatorWrapper: React.FC<{ - chatClient: StreamChat; + chatClient: StreamChat; }> = ({ chatClient }) => { const { bottom } = useSafeAreaInsets(); const streamChatTheme = useStreamChatTheme(); return ( - bottomInset={bottom} value={{ style: streamChatTheme }}> - + + !!message.ai_generated} + isMessageAIGenerated={isMessageAIGenerated} > diff --git a/examples/SampleApp/src/ChatUsers.ts b/examples/SampleApp/src/ChatUsers.ts index 6b1b37be5c..dec7d186c1 100644 --- a/examples/SampleApp/src/ChatUsers.ts +++ b/examples/SampleApp/src/ChatUsers.ts @@ -1,5 +1,4 @@ import { UserResponse } from 'stream-chat'; -import { StreamChatGenerics } from './types'; export const USER_TOKENS: Record = { e2etest1: @@ -27,7 +26,7 @@ export const USER_TOKENS: Record = { rodolphe: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoicm9kb2xwaGUifQ.tLl-I8ADBhTKB-x5FB9jK4-am0dELLXgydM6VN9rTL8', }; -export const USERS: Record> = { +export const USERS: Record = { neil: { id: 'neil', image: 'https://ca.slack-edge.com/T02RM6X6B-U01173D1D5J-0dead6eea6ea-512', diff --git a/examples/SampleApp/src/components/AddMemberBottomSheet.tsx b/examples/SampleApp/src/components/AddMemberBottomSheet.tsx index f3e4d00800..8239fa2155 100644 --- a/examples/SampleApp/src/components/AddMemberBottomSheet.tsx +++ b/examples/SampleApp/src/components/AddMemberBottomSheet.tsx @@ -21,8 +21,6 @@ import { usePaginatedUsers } from '../hooks/usePaginatedUsers'; import type { UserResponse } from 'stream-chat'; -import { StreamChatGenerics } from '../types'; - const styles = StyleSheet.create({ container: { height: 300, @@ -94,7 +92,7 @@ export const AddMemberBottomSheet: React.FC = () => { return null; } - const addMember = async (user: UserResponse) => { + const addMember = async (user: UserResponse) => { setAddMemberQueryInProgress(true); try { diff --git a/examples/SampleApp/src/components/ChannelInfoOverlay.tsx b/examples/SampleApp/src/components/ChannelInfoOverlay.tsx index 7c58473d77..ea95c21fbb 100644 --- a/examples/SampleApp/src/components/ChannelInfoOverlay.tsx +++ b/examples/SampleApp/src/components/ChannelInfoOverlay.tsx @@ -29,6 +29,7 @@ import { useTheme, useViewport, } from 'stream-chat-react-native'; +import { ChannelMemberResponse } from 'stream-chat'; import { useAppOverlayContext } from '../context/AppOverlayContext'; import { useBottomSheetOverlayContext } from '../context/BottomSheetOverlayContext'; @@ -224,9 +225,9 @@ export const ChannelInfoOverlay = (props: ChannelInfoOverlayProps) => { : 0; const channelName = channel ? channel.data?.name || - Object.values(channel.state.members) + Object.values(channel.state.members) .slice(0) - .reduce((returnString, currentMember, index, originalArray) => { + .reduce((returnString, currentMember, index, originalArray) => { const returnStringLength = returnString.length; const currentMemberName = currentMember.user?.name || currentMember.user?.id || 'Unknown User'; @@ -246,7 +247,7 @@ export const ChannelInfoOverlay = (props: ChannelInfoOverlayProps) => { }, '') : ''; const otherMembers = channel - ? Object.values(channel.state.members).filter((member) => member.user?.id !== clientId) + ? Object.values(channel.state.members).filter((member) => member.user?.id !== clientId) : []; return ( @@ -292,14 +293,14 @@ export const ChannelInfoOverlay = (props: ChannelInfoOverlayProps) => { ? 'Online' : `Last Seen ${dayjs(otherMembers[0].user?.last_active).fromNow()}` : `${Object.keys(channel.state.members).length} Members, ${ - Object.values(channel.state.members).filter( + Object.values(channel.state.members).filter( (member) => !!member.user?.online, ).length } Online`} (channel.state.members) .map((member) => member.user) .sort((a, b) => !!a?.online && !b?.online diff --git a/examples/SampleApp/src/components/ChannelPreview.tsx b/examples/SampleApp/src/components/ChannelPreview.tsx index a129eaec59..eab30d5f08 100644 --- a/examples/SampleApp/src/components/ChannelPreview.tsx +++ b/examples/SampleApp/src/components/ChannelPreview.tsx @@ -22,7 +22,7 @@ import { useChannelInfoOverlayContext } from '../context/ChannelInfoOverlayConte import type { StackNavigationProp } from '@react-navigation/stack'; -import type { StackNavigatorParamList, StreamChatGenerics } from '../types'; +import type { StackNavigatorParamList } from '../types'; import { ChannelState } from 'stream-chat'; const styles = StyleSheet.create({ @@ -71,7 +71,7 @@ const CustomChannelPreviewStatus = ( ); }; -export const ChannelPreview: React.FC> = ( +export const ChannelPreview: React.FC = ( props, ) => { const { channel } = props; @@ -82,7 +82,7 @@ export const ChannelPreview: React.FC(); + const { client } = useChatContext(); const navigation = useNavigation(); diff --git a/examples/SampleApp/src/components/MessageSearch/MessageSearchList.tsx b/examples/SampleApp/src/components/MessageSearch/MessageSearchList.tsx index 0df48bad0f..b3e91999c3 100644 --- a/examples/SampleApp/src/components/MessageSearch/MessageSearchList.tsx +++ b/examples/SampleApp/src/components/MessageSearch/MessageSearchList.tsx @@ -8,7 +8,7 @@ import { DEFAULT_PAGINATION_LIMIT } from '../../utils/constants'; import type { MessageResponse } from 'stream-chat'; -import type { StackNavigatorParamList, StreamChatGenerics } from '../../types'; +import type { StackNavigatorParamList } from '../../types'; dayjs.extend(calendar); @@ -52,13 +52,13 @@ export type MessageSearchListProps = { EmptySearchIndicator: React.ComponentType; loading: boolean; loadMore: () => void; - messages: MessageResponse[] | undefined; + messages: MessageResponse[] | undefined; refreshing?: boolean; refreshList?: () => void; showResultCount?: boolean; }; export const MessageSearchList: React.FC = React.forwardRef( - (props, scrollRef: React.Ref> | null>) => { + (props, scrollRef: React.Ref | null>) => { const { EmptySearchIndicator, loading, diff --git a/examples/SampleApp/src/components/NewDirectMessagingSendButton.tsx b/examples/SampleApp/src/components/NewDirectMessagingSendButton.tsx index 0d1037e5ec..07f4e93bc0 100644 --- a/examples/SampleApp/src/components/NewDirectMessagingSendButton.tsx +++ b/examples/SampleApp/src/components/NewDirectMessagingSendButton.tsx @@ -4,7 +4,6 @@ import { TouchableOpacity } from 'react-native-gesture-handler'; import { useNavigation } from '@react-navigation/core'; import { - DefaultStreamChatGenerics, MessageInputContextValue, Search, SendRight, @@ -16,20 +15,15 @@ import { import { NewDirectMessagingScreenNavigationProp } from '../screens/NewDirectMessagingScreen'; -import { StreamChatGenerics as LocalStreamChatGenerics } from '../types'; import { useUserSearchContext } from '../context/UserSearchContext'; import { useAppContext } from '../context/AppContext'; -type NewDirectMessagingSendButtonPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'giphyActive' | 'sendMessage'> & { +type NewDirectMessagingSendButtonPropsWithContext = Pick & { /** Disables the button */ disabled: boolean; }; -const SendButtonWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: NewDirectMessagingSendButtonPropsWithContext, +const SendButtonWithContext = ( + props: NewDirectMessagingSendButtonPropsWithContext, ) => { const { disabled = false, giphyActive, sendMessage } = props; const { @@ -53,9 +47,9 @@ const SendButtonWithContext = < ); }; -const areEqual = ( - prevProps: NewDirectMessagingSendButtonPropsWithContext, - nextProps: NewDirectMessagingSendButtonPropsWithContext, +const areEqual = ( + prevProps: NewDirectMessagingSendButtonPropsWithContext, + nextProps: NewDirectMessagingSendButtonPropsWithContext, ) => { const { disabled: prevDisabled, @@ -91,20 +85,18 @@ const MemoizedNewDirectMessagingSendButton = React.memo( areEqual, ) as typeof SendButtonWithContext; -export type SendButtonProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type SendButtonProps = Partial; /** * UI Component for send button in MessageInput component. */ -export const NewDirectMessagingSendButton = (props: SendButtonProps) => { +export const NewDirectMessagingSendButton = (props: SendButtonProps) => { const { chatClient } = useAppContext(); const navigation = useNavigation(); - const { channel } = useChannelContext(); + const { channel } = useChannelContext(); const { selectedUserIds, reset } = useUserSearchContext(); - const { giphyActive, text } = useMessageInputContext(); + const { giphyActive, text } = useMessageInputContext(); const sendMessage = async () => { if (!channel) { @@ -133,7 +125,7 @@ export const NewDirectMessagingSendButton = (props: SendButtonProps + export const ThreadsUnreadCountBadge: React.FC = () => { const { chatClient } = useAppContext(); - const { unreadCount } = useStateStore(chatClient?.threads?.state, selector); + const { unreadCount } = useStateStore(chatClient?.threads?.state, selector) ?? { unreadCount: 0 }; return ; }; diff --git a/examples/SampleApp/src/components/UserInfoOverlay.tsx b/examples/SampleApp/src/components/UserInfoOverlay.tsx index 90831ccca2..a0f9f59598 100644 --- a/examples/SampleApp/src/components/UserInfoOverlay.tsx +++ b/examples/SampleApp/src/components/UserInfoOverlay.tsx @@ -35,7 +35,6 @@ import { useAppOverlayContext } from '../context/AppOverlayContext'; import { useBottomSheetOverlayContext } from '../context/BottomSheetOverlayContext'; import { useUserInfoOverlayContext } from '../context/UserInfoOverlayContext'; -import type { StreamChatGenerics } from '../types'; import { useAppContext } from '../context/AppContext'; import { UserResponse } from 'stream-chat'; @@ -105,7 +104,7 @@ export const UserInfoOverlay = (props: UserInfoOverlayProps) => { const { overlayOpacity, visible } = props; const { chatClient } = useAppContext(); const { overlay, setOverlay } = useAppOverlayContext(); - const { client } = useChatContext(); + const { client } = useChatContext(); const { setData } = useBottomSheetOverlayContext(); const { data, reset } = useUserInfoOverlayContext(); const { vh } = useViewport(); @@ -298,7 +297,6 @@ export const UserInfoOverlay = (props: UserInfoOverlayProps) => { // Check if the channel already exists. const channels = await client.queryChannels({ - distinct: true, members, }); @@ -351,7 +349,6 @@ export const UserInfoOverlay = (props: UserInfoOverlayProps) => { // Check if the channel already exists. const channels = await client.queryChannels({ - distinct: true, members, }); diff --git a/examples/SampleApp/src/components/UserSearch/SelectedUserTag.tsx b/examples/SampleApp/src/components/UserSearch/SelectedUserTag.tsx index c1ae1d5f8f..4ea60b956e 100644 --- a/examples/SampleApp/src/components/UserSearch/SelectedUserTag.tsx +++ b/examples/SampleApp/src/components/UserSearch/SelectedUserTag.tsx @@ -4,7 +4,6 @@ import { useTheme } from 'stream-chat-react-native'; import type { UserResponse } from 'stream-chat'; -import type { StreamChatGenerics } from '../../types'; const styles = StyleSheet.create({ tagContainer: { @@ -29,7 +28,7 @@ const styles = StyleSheet.create({ type SelectedUserTagProps = { index: number; onPress: () => void; - tag: UserResponse; + tag: UserResponse; disabled?: boolean; }; diff --git a/examples/SampleApp/src/components/UserSearch/UserGridItem.tsx b/examples/SampleApp/src/components/UserSearch/UserGridItem.tsx index fdb7afa4ca..c61449e923 100644 --- a/examples/SampleApp/src/components/UserSearch/UserGridItem.tsx +++ b/examples/SampleApp/src/components/UserSearch/UserGridItem.tsx @@ -5,7 +5,6 @@ import { Avatar, Close, useTheme } from 'stream-chat-react-native'; import type { UserResponse } from 'stream-chat'; -import type { StreamChatGenerics } from '../../types'; const presenceIndicator = { cx: 7, cy: 7, r: 5 }; @@ -40,7 +39,7 @@ const styles = StyleSheet.create({ export type UserGridItemProps = { onPress: () => void; - user: UserResponse; + user: UserResponse; removeButton?: boolean; }; @@ -57,7 +56,6 @@ export const UserGridItem: React.FC = ({ return ( []; + results?: UserResponse[]; showOnlineStatus?: boolean; - toggleSelectedUser?: (user: UserResponse) => void; + toggleSelectedUser?: (user: UserResponse) => void; }; export const UserSearchResults: React.FC = ({ @@ -87,7 +86,7 @@ export const UserSearchResults: React.FC = ({ } = useUserSearchContext(); const [sections, setSections] = useState< Array<{ - data: UserResponse[]; + data: UserResponse[]; title: string; }> >([]); @@ -113,7 +112,7 @@ export const UserSearchResults: React.FC = ({ useEffect(() => { const newSections: { [key: string]: { - data: UserResponse[]; + data: UserResponse[]; title: string; }; } = {}; @@ -204,7 +203,7 @@ export const UserSearchResults: React.FC = ({ }, ]} > - + ) => void; - results: UserResponse[]; + onPress: (user: UserResponse) => void; + results: UserResponse[]; gridSize?: number; loading?: boolean; loadMore?: () => void; diff --git a/examples/SampleApp/src/context/AppContext.ts b/examples/SampleApp/src/context/AppContext.ts index f50d94f24d..0ca2b2300a 100644 --- a/examples/SampleApp/src/context/AppContext.ts +++ b/examples/SampleApp/src/context/AppContext.ts @@ -2,10 +2,10 @@ import React from 'react'; import type { StreamChat } from 'stream-chat'; -import type { LoginConfig, StreamChatGenerics } from '../types'; +import type { LoginConfig } from '../types'; type AppContextType = { - chatClient: StreamChat | null; + chatClient: StreamChat | null; loginUser: (config: LoginConfig) => void; logout: () => void; switchUser: (userId?: string) => void; diff --git a/examples/SampleApp/src/context/BottomSheetOverlayContext.tsx b/examples/SampleApp/src/context/BottomSheetOverlayContext.tsx index 437b4f668a..16bb3f3110 100644 --- a/examples/SampleApp/src/context/BottomSheetOverlayContext.tsx +++ b/examples/SampleApp/src/context/BottomSheetOverlayContext.tsx @@ -2,14 +2,13 @@ import React, { PropsWithChildren, useContext, useState } from 'react'; import type { ChannelContextValue } from 'stream-chat-react-native'; -import type { StreamChatGenerics } from '../types'; export const isAddMemberBottomSheetData = ( data: BottomSheetOverlayData, -): data is Pick, 'channel'> => 'channel' in data; +): data is Pick => 'channel' in data; export type BottomSheetOverlayData = - | Pick, 'channel'> + | Pick | { onConfirm: () => void; title: string; diff --git a/examples/SampleApp/src/context/ChannelInfoOverlayContext.tsx b/examples/SampleApp/src/context/ChannelInfoOverlayContext.tsx index 59646feb63..dc73658fea 100644 --- a/examples/SampleApp/src/context/ChannelInfoOverlayContext.tsx +++ b/examples/SampleApp/src/context/ChannelInfoOverlayContext.tsx @@ -4,7 +4,7 @@ import { ChannelState } from 'stream-chat'; import type { StackNavigationProp } from '@react-navigation/stack'; import type { ChannelContextValue } from 'stream-chat-react-native'; -import type { StackNavigatorParamList, StreamChatGenerics } from '../types'; +import type { StackNavigatorParamList } from '../types'; type ChannelListScreenNavigationProp = StackNavigationProp< StackNavigatorParamList, @@ -12,10 +12,10 @@ type ChannelListScreenNavigationProp = StackNavigationProp< >; export type ChannelInfoOverlayData = Partial< - Pick, 'channel'> + Pick > & { clientId?: string; - membership?: ChannelState['membership']; + membership?: ChannelState['membership']; navigation?: ChannelListScreenNavigationProp; }; diff --git a/examples/SampleApp/src/context/UserInfoOverlayContext.tsx b/examples/SampleApp/src/context/UserInfoOverlayContext.tsx index f905fb380a..da5ebdb4a5 100644 --- a/examples/SampleApp/src/context/UserInfoOverlayContext.tsx +++ b/examples/SampleApp/src/context/UserInfoOverlayContext.tsx @@ -4,7 +4,7 @@ import type { StackNavigationProp } from '@react-navigation/stack'; import type { ChannelState } from 'stream-chat'; import type { ChannelContextValue } from 'stream-chat-react-native'; -import type { StackNavigatorParamList, StreamChatGenerics } from '../types'; +import type { StackNavigatorParamList } from '../types'; type GroupChannelDetailsScreenNavigationProp = StackNavigationProp< StackNavigatorParamList, @@ -12,9 +12,9 @@ type GroupChannelDetailsScreenNavigationProp = StackNavigationProp< >; export type UserInfoOverlayData = Partial< - Pick, 'channel'> + Pick > & { - member?: ChannelState['members'][0]; + member?: ChannelState['members'][0]; navigation?: GroupChannelDetailsScreenNavigationProp; }; diff --git a/examples/SampleApp/src/custom-types.d.ts b/examples/SampleApp/src/custom-types.d.ts new file mode 100644 index 0000000000..ac568a4d1d --- /dev/null +++ b/examples/SampleApp/src/custom-types.d.ts @@ -0,0 +1,45 @@ +import { + DefaultAttachmentType, + DefaultMessageType, + DefaultChannelType, + DefaultCommandType, + DefaultEventType, + DefaultMemberType, + DefaultPollOptionType, + DefaultPollType, + DefaultReactionType, + DefaultThreadType, + DefaultUserType, +} from 'stream-chat-react-native'; + +declare module 'stream-chat' { + /* eslint-disable @typescript-eslint/no-empty-object-type */ + + interface CustomAttachmentData extends DefaultAttachmentType { + id?: string; + } + + interface CustomChannelData extends DefaultChannelType {} + + interface CustomCommandData extends DefaultCommandType {} + + interface CustomEventData extends DefaultEventType {} + + interface CustomMemberData extends DefaultMemberType {} + + interface CustomUserData extends DefaultUserType {} + + interface CustomMessageData extends DefaultMessageType { + ai_generated?: boolean; + } + + interface CustomPollOptionData extends DefaultPollOptionType {} + + interface CustomPollData extends DefaultPollType {} + + interface CustomReactionData extends DefaultReactionType {} + + interface CustomThreadData extends DefaultThreadType {} + + /* eslint-enable @typescript-eslint/no-empty-object-type */ +} diff --git a/examples/SampleApp/src/hooks/useChannelMembersStatus.ts b/examples/SampleApp/src/hooks/useChannelMembersStatus.ts index e7fc8dc6a8..92db54fbf7 100644 --- a/examples/SampleApp/src/hooks/useChannelMembersStatus.ts +++ b/examples/SampleApp/src/hooks/useChannelMembersStatus.ts @@ -5,9 +5,7 @@ import { getUserActivityStatus } from '../utils/getUserActivityStatus'; import type { Channel } from 'stream-chat'; -import type { StreamChatGenerics } from '../types'; - -export const useChannelMembersStatus = (channel: Channel) => { +export const useChannelMembersStatus = (channel: Channel) => { const watchersCount = channel.state.watcher_count; const memberCount = channel?.data?.member_count; diff --git a/examples/SampleApp/src/hooks/useChatClient.ts b/examples/SampleApp/src/hooks/useChatClient.ts index e22502c72b..7e11e8235a 100644 --- a/examples/SampleApp/src/hooks/useChatClient.ts +++ b/examples/SampleApp/src/hooks/useChatClient.ts @@ -6,7 +6,7 @@ import { SqliteClient } from 'stream-chat-react-native'; import { USER_TOKENS, USERS } from '../ChatUsers'; import AsyncStore from '../utils/AsyncStore'; -import type { LoginConfig, StreamChatGenerics } from '../types'; +import type { LoginConfig } from '../types'; import { PermissionsAndroid, Platform } from 'react-native'; const messaging = getMessaging(); @@ -30,10 +30,10 @@ const requestAndroidPermission = async () => { }; export const useChatClient = () => { - const [chatClient, setChatClient] = useState | null>(null); + const [chatClient, setChatClient] = useState(null); const [isConnecting, setIsConnecting] = useState(true); - const unsubscribePushListenersRef = useRef<() => void>(); + const unsubscribePushListenersRef = useRef<() => void>(undefined); /** * @param config the user login config @@ -42,7 +42,7 @@ export const useChatClient = () => { const loginUser = async (config: LoginConfig) => { // unsubscribe from previous push listeners unsubscribePushListenersRef.current?.(); - const client = StreamChat.getInstance(config.apiKey, { + const client = StreamChat.getInstance(config.apiKey, { timeout: 6000, // logger: (type, msg) => console.log(type, msg) }); diff --git a/examples/SampleApp/src/hooks/usePaginatedAttachments.ts b/examples/SampleApp/src/hooks/usePaginatedAttachments.ts index 6a845c5396..54413afe4e 100644 --- a/examples/SampleApp/src/hooks/usePaginatedAttachments.ts +++ b/examples/SampleApp/src/hooks/usePaginatedAttachments.ts @@ -4,10 +4,8 @@ import { useAppContext } from '../context/AppContext'; import type { Channel, MessageResponse } from 'stream-chat'; -import type { StreamChatGenerics } from '../types'; - export const usePaginatedAttachments = ( - channel: Channel, + channel: Channel, attachmentType: string, ) => { const { chatClient } = useAppContext(); @@ -15,7 +13,7 @@ export const usePaginatedAttachments = ( const hasMoreResults = useRef(true); const queryInProgress = useRef(false); const [loading, setLoading] = useState(true); - const [messages, setMessages] = useState[]>([]); + const [messages, setMessages] = useState([]); const fetchAttachments = async () => { if (queryInProgress.current) { diff --git a/examples/SampleApp/src/hooks/usePaginatedPinnedMessages.ts b/examples/SampleApp/src/hooks/usePaginatedPinnedMessages.ts index fbdaa8d319..2cfa5d73d9 100644 --- a/examples/SampleApp/src/hooks/usePaginatedPinnedMessages.ts +++ b/examples/SampleApp/src/hooks/usePaginatedPinnedMessages.ts @@ -4,17 +4,16 @@ import { useAppContext } from '../context/AppContext'; import type { Channel, MessageResponse } from 'stream-chat'; -import type { StreamChatGenerics } from '../types'; import { DEFAULT_PAGINATION_LIMIT } from '../utils/constants'; -export const usePaginatedPinnedMessages = (channel: Channel) => { +export const usePaginatedPinnedMessages = (channel: Channel) => { const { chatClient } = useAppContext(); const offset = useRef(0); const hasMoreResults = useRef(true); const queryInProgress = useRef(false); const [loading, setLoading] = useState(true); const [error, setError] = useState(false); - const [messages, setMessages] = useState[]>([]); + const [messages, setMessages] = useState([]); const fetchPinnedMessages = async () => { if (queryInProgress.current) { diff --git a/examples/SampleApp/src/hooks/usePaginatedSearchedMessages.ts b/examples/SampleApp/src/hooks/usePaginatedSearchedMessages.ts index 017f3e975d..d7c2757b29 100644 --- a/examples/SampleApp/src/hooks/usePaginatedSearchedMessages.ts +++ b/examples/SampleApp/src/hooks/usePaginatedSearchedMessages.ts @@ -4,16 +4,15 @@ import { useAppContext } from '../context/AppContext'; import type { MessageFilters, MessageResponse } from 'stream-chat'; -import type { StreamChatGenerics } from '../types'; import { DEFAULT_PAGINATION_LIMIT } from '../utils/constants'; export const usePaginatedSearchedMessages = ( - messageFilters: string | MessageFilters = {}, + messageFilters: string | MessageFilters = {}, ) => { const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [error, setError] = useState(false); - const [messages, setMessages] = useState[]>(); + const [messages, setMessages] = useState(); const offset = useRef(0); const hasMoreResults = useRef(true); const queryInProgress = useRef(false); diff --git a/examples/SampleApp/src/hooks/usePaginatedUsers.ts b/examples/SampleApp/src/hooks/usePaginatedUsers.ts index d36ab1c75d..3b375f4461 100644 --- a/examples/SampleApp/src/hooks/usePaginatedUsers.ts +++ b/examples/SampleApp/src/hooks/usePaginatedUsers.ts @@ -4,41 +4,40 @@ import { useAppContext } from '../context/AppContext'; import type { UserFilters, UserResponse } from 'stream-chat'; -import type { StreamChatGenerics } from '../types'; export type PaginatedUsers = { clearText: () => void; - initialResults: UserResponse[] | null; + initialResults: UserResponse[] | null; loading: boolean; loadMore: () => void; onChangeSearchText: (newText: string) => void; onFocusInput: () => void; removeUser: (index: number) => void; reset: () => void; - results: UserResponse[]; + results: UserResponse[]; searchText: string; selectedUserIds: string[]; - selectedUsers: UserResponse[]; + selectedUsers: UserResponse[]; setInitialResults: React.Dispatch< - React.SetStateAction[] | null> + React.SetStateAction >; - setResults: React.Dispatch[]>>; + setResults: React.Dispatch>; setSearchText: React.Dispatch>; - setSelectedUsers: React.Dispatch[]>>; - toggleUser: (user: UserResponse) => void; + setSelectedUsers: React.Dispatch>; + toggleUser: (user: UserResponse) => void; }; export const usePaginatedUsers = (): PaginatedUsers => { const { chatClient } = useAppContext(); - const [initialResults, setInitialResults] = useState[] | null>( + const [initialResults, setInitialResults] = useState( null, ); const [loading, setLoading] = useState(true); - const [results, setResults] = useState[]>([]); + const [results, setResults] = useState([]); const [searchText, setSearchText] = useState(''); const [selectedUserIds, setSelectedUserIds] = useState([]); - const [selectedUsers, setSelectedUsers] = useState[]>([]); + const [selectedUsers, setSelectedUsers] = useState([]); const hasMoreResults = useRef(true); const offset = useRef(0); @@ -51,7 +50,7 @@ export const usePaginatedUsers = (): PaginatedUsers => { setSelectedUsers([]); }; - const addUser = (user: UserResponse) => { + const addUser = (user: UserResponse) => { setSelectedUsers([...selectedUsers, user]); setSelectedUserIds((prevSelectedUserIds) => { prevSelectedUserIds.push(user.id); @@ -79,7 +78,7 @@ export const usePaginatedUsers = (): PaginatedUsers => { }); }; - const toggleUser = (user: UserResponse) => { + const toggleUser = (user: UserResponse) => { if (!user.id) { return; } diff --git a/examples/SampleApp/src/screens/ChannelFilesScreen.tsx b/examples/SampleApp/src/screens/ChannelFilesScreen.tsx index a47c9d54d1..cde55c465a 100644 --- a/examples/SampleApp/src/screens/ChannelFilesScreen.tsx +++ b/examples/SampleApp/src/screens/ChannelFilesScreen.tsx @@ -1,11 +1,10 @@ import React, { useEffect, useState } from 'react'; -import { SectionList, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import { Alert, SectionList, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import Dayjs from 'dayjs'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { FileIcon, getFileSizeDisplayText, - goToURL, ThemeProvider, useTheme, } from 'stream-chat-react-native'; @@ -17,7 +16,7 @@ import { File } from '../icons/File'; import type { RouteProp } from '@react-navigation/native'; import type { Attachment } from 'stream-chat'; -import type { StackNavigatorParamList, StreamChatGenerics } from '../types'; +import type { StackNavigatorParamList } from '../types'; const styles = StyleSheet.create({ container: { @@ -90,7 +89,7 @@ export const ChannelFilesScreen: React.FC = ({ const [sections, setSections] = useState< Array<{ - data: Attachment[]; + data: Attachment[]; title: string; }> >([]); @@ -99,7 +98,7 @@ export const ChannelFilesScreen: React.FC = ({ const newSections: Record< string, { - data: Attachment[]; + data: Attachment[]; title: string; } > = {}; @@ -139,14 +138,16 @@ export const ChannelFilesScreen: React.FC = ({ {(sections.length > 0 || !loading) && ( - > + contentContainerStyle={styles.sectionContentContainer} ListEmptyComponent={EmptyListComponent} onEndReached={loadMore} renderItem={({ index, item: attachment, section }) => ( goToURL(attachment.asset_url)} + onPress={() => { + Alert.alert('Not implemented.'); + }} style={{ borderBottomColor: border, borderBottomWidth: index === section.data.length - 1 ? 0 : 1, diff --git a/examples/SampleApp/src/screens/ChannelImagesScreen.tsx b/examples/SampleApp/src/screens/ChannelImagesScreen.tsx index e1914ebc9a..fd124f72a4 100644 --- a/examples/SampleApp/src/screens/ChannelImagesScreen.tsx +++ b/examples/SampleApp/src/screens/ChannelImagesScreen.tsx @@ -26,7 +26,7 @@ import { Picture } from '../icons/Picture'; import type { RouteProp } from '@react-navigation/native'; import type { Attachment } from 'stream-chat'; -import type { StackNavigatorParamList, StreamChatGenerics } from '../types'; +import type { StackNavigatorParamList } from '../types'; const screen = Dimensions.get('screen').width; @@ -70,7 +70,7 @@ export const ChannelImagesScreen: React.FC = ({ messages: images, setMessages: setImages, setSelectedMessage: setImage, - } = useImageGalleryContext(); + } = useImageGalleryContext(); const { setOverlay } = useOverlayContext(); const { loading, loadMore, messages } = usePaginatedAttachments(channel, 'image'); const { @@ -110,9 +110,9 @@ export const ChannelImagesScreen: React.FC = ({ * Photos array created from all currently available * photo attachments */ - const photos = messages.reduce((acc: Photo[], cur) => { + const photos = messages.reduce((acc: Photo[], cur) => { const attachmentImages = - (cur.attachments as Attachment[])?.filter( + (cur.attachments as Attachment[])?.filter( (attachment) => attachment.type === 'image' && !attachment.title_link && @@ -151,7 +151,7 @@ export const ChannelImagesScreen: React.FC = ({ */ const imageString = messagesWithImages .map((message) => - (message.attachments as Attachment[]) + (message.attachments as Attachment[]) .map((attachment) => attachment.image_url || attachment.thumb_url || '') .join(), ) diff --git a/examples/SampleApp/src/screens/ChannelListScreen.tsx b/examples/SampleApp/src/screens/ChannelListScreen.tsx index 7662df6e58..b1aa577a47 100644 --- a/examples/SampleApp/src/screens/ChannelListScreen.tsx +++ b/examples/SampleApp/src/screens/ChannelListScreen.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo, useRef, useState } from 'react'; +import React, { RefObject, useCallback, useMemo, useRef, useState } from 'react'; import { FlatList, FlatListProps, @@ -19,8 +19,6 @@ import { usePaginatedSearchedMessages } from '../hooks/usePaginatedSearchedMessa import type { ChannelSort } from 'stream-chat'; -import type { StreamChatGenerics } from '../types'; - const styles = StyleSheet.create({ channelListContainer: { height: '100%', @@ -61,7 +59,7 @@ const baseFilters = { type: 'messaging', }; -const sort: ChannelSort = [ +const sort: ChannelSort = [ { pinned_at: -1 }, { last_message_at: -1 }, { updated_at: -1 }, @@ -85,7 +83,7 @@ export const ChannelListScreen: React.FC = () => { } = useTheme(); const searchInputRef = useRef(null); - const scrollRef = useRef> | null>(null); + const scrollRef = useRef | null>(null); const [searchInputText, setSearchInputText] = useState(''); const [searchQuery, setSearchQuery] = useState(''); @@ -104,7 +102,7 @@ export const ChannelListScreen: React.FC = () => { [chatClientUserId], ); - useScrollToTop(scrollRef); + useScrollToTop(scrollRef as RefObject>); // eslint-disable-next-line react/no-unstable-nested-components const EmptySearchIndicator = () => ( @@ -116,7 +114,7 @@ export const ChannelListScreen: React.FC = () => { ); - const additionalFlatListProps = useMemo>>>( + const additionalFlatListProps = useMemo>>( () => ({ getItemLayout: (_: unknown, index: number) => ({ index, @@ -138,7 +136,7 @@ export const ChannelListScreen: React.FC = () => { ); const setScrollRef = useCallback( - () => (ref: FlatList> | null) => { + () => (ref: FlatList | null) => { scrollRef.current = ref; }, [], @@ -217,7 +215,7 @@ export const ChannelListScreen: React.FC = () => { )} - + ; + channel: StreamChatChannel; }; const ChannelHeader: React.FC = ({ channel }) => { @@ -115,12 +115,12 @@ export const ChannelScreen: React.FC = ({ }, } = useTheme(); - const [channel, setChannel] = useState | undefined>( + const [channel, setChannel] = useState( channelFromProp, ); const [selectedThread, setSelectedThread] = - useState['thread']>(); + useState(); useEffect(() => { const initChannel = async () => { @@ -160,7 +160,7 @@ export const ChannelScreen: React.FC = ({ thread={selectedThread} > - + { setSelectedThread(thread); navigation.navigate('ThreadScreen', { diff --git a/examples/SampleApp/src/screens/GroupChannelDetailsScreen.tsx b/examples/SampleApp/src/screens/GroupChannelDetailsScreen.tsx index 77f5a8582b..2bddc63cb2 100644 --- a/examples/SampleApp/src/screens/GroupChannelDetailsScreen.tsx +++ b/examples/SampleApp/src/screens/GroupChannelDetailsScreen.tsx @@ -38,7 +38,7 @@ import { getUserActivityStatus } from '../utils/getUserActivityStatus'; import type { StackNavigationProp } from '@react-navigation/stack'; import type { Channel, UserResponse } from 'stream-chat'; -import type { StackNavigatorParamList, StreamChatGenerics } from '../types'; +import type { StackNavigatorParamList } from '../types'; import { Pin } from '../icons/Pin'; import { NewGroupIcon } from '../icons/NewGroupIcon'; @@ -177,7 +177,7 @@ export const GroupChannelDetailsScreen: React.FC = ({ const [textInputFocused, setTextInputFocused] = useState(false); const membersStatus = useChannelMembersStatus(channel); - const displayName = useChannelPreviewDisplayName(channel, 30); + const displayName = useChannelPreviewDisplayName(channel, 30); const allMembersLength = allMembers.length; useEffect(() => { @@ -368,7 +368,7 @@ export const GroupChannelDetailsScreen: React.FC = ({ await channel.update({ ...channel.data, name: groupName, - } as Parameters['update']>[0]); + } as Parameters[0]); if (textInputRef.current) { textInputRef.current.blur(); } diff --git a/examples/SampleApp/src/screens/MentionsScreen.tsx b/examples/SampleApp/src/screens/MentionsScreen.tsx index d1367d9dac..11c01155bd 100644 --- a/examples/SampleApp/src/screens/MentionsScreen.tsx +++ b/examples/SampleApp/src/screens/MentionsScreen.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useRef } from 'react'; +import React, { RefObject, useMemo, useRef } from 'react'; import { FlatList, StyleSheet, Text, View } from 'react-native'; import { AtMentions, useTheme } from 'stream-chat-react-native'; import { MessageResponse } from 'stream-chat'; @@ -12,7 +12,6 @@ import type { StackNavigationProp } from '@react-navigation/stack'; import type { BottomTabNavigatorParamList } from '../types'; import { useAppContext } from '../context/AppContext'; -import type { StreamChatGenerics } from '../types'; const styles = StyleSheet.create({ container: { @@ -64,9 +63,9 @@ export const MentionsScreen: React.FC = () => { [chatClient], ); - const scrollRef = useRef> | null>(null); + const scrollRef = useRef | null>(null); - useScrollToTop(scrollRef); + useScrollToTop(scrollRef as RefObject>); const { loading, loadMore, messages, refreshing, refreshList } = usePaginatedSearchedMessages(messageFilters); diff --git a/examples/SampleApp/src/screens/NewDirectMessagingScreen.tsx b/examples/SampleApp/src/screens/NewDirectMessagingScreen.tsx index 306f81cdb9..228129e300 100644 --- a/examples/SampleApp/src/screens/NewDirectMessagingScreen.tsx +++ b/examples/SampleApp/src/screens/NewDirectMessagingScreen.tsx @@ -22,7 +22,7 @@ import type { StackNavigationProp } from '@react-navigation/stack'; import type { Channel as StreamChatChannel } from 'stream-chat'; import { NewDirectMessagingSendButton } from '../components/NewDirectMessagingSendButton'; -import type { StackNavigatorParamList, StreamChatGenerics } from '../types'; +import type { StackNavigatorParamList } from '../types'; const styles = StyleSheet.create({ container: { @@ -136,7 +136,7 @@ export const NewDirectMessagingScreen: React.FC = const messageInputRef = useRef(null); const searchInputRef = useRef(null); - const currentChannel = useRef>(); + const currentChannel = useRef(undefined); const isDraft = useRef(true); const [focusOnMessageInput, setFocusOnMessageInput] = useState(false); @@ -163,7 +163,6 @@ export const NewDirectMessagingScreen: React.FC = // Check if the channel already exists. const channels = await chatClient.queryChannels({ - distinct: true, members, }); @@ -312,7 +311,7 @@ export const NewDirectMessagingScreen: React.FC = }, ]} > - + { setFocusOnMessageInput(true); diff --git a/examples/SampleApp/src/screens/SharedGroupsScreen.tsx b/examples/SampleApp/src/screens/SharedGroupsScreen.tsx index bc082eedbb..c0c0894e97 100644 --- a/examples/SampleApp/src/screens/SharedGroupsScreen.tsx +++ b/examples/SampleApp/src/screens/SharedGroupsScreen.tsx @@ -18,7 +18,7 @@ import { ScreenHeader } from '../components/ScreenHeader'; import { useAppContext } from '../context/AppContext'; import { Contacts } from '../icons/Contacts'; -import type { StackNavigatorParamList, StreamChatGenerics } from '../types'; +import type { StackNavigatorParamList } from '../types'; const styles = StyleSheet.create({ container: { @@ -54,7 +54,7 @@ const styles = StyleSheet.create({ }, }); -type CustomPreviewProps = ChannelPreviewMessengerProps; +type CustomPreviewProps = ChannelPreviewMessengerProps; const CustomPreview: React.FC = ({ channel }) => { const { chatClient } = useAppContext(); @@ -107,16 +107,12 @@ const CustomPreview: React.FC = ({ channel }) => { {displayAvatar.images ? ( ) : ( { ); }; -type ListComponentProps = ChannelListMessengerProps; +type ListComponentProps = ChannelListMessengerProps; // If the length of channels is 1, which means we only got 1:1-distinct channel, // And we don't want to show 1:1-distinct channel in this list. diff --git a/examples/SampleApp/src/screens/ThreadScreen.tsx b/examples/SampleApp/src/screens/ThreadScreen.tsx index d5df5d40ff..56985986ac 100644 --- a/examples/SampleApp/src/screens/ThreadScreen.tsx +++ b/examples/SampleApp/src/screens/ThreadScreen.tsx @@ -3,8 +3,9 @@ import { StyleSheet, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { Channel, + MessageType, Thread, - ThreadContextValue, + ThreadType, useAttachmentPickerContext, useTheme, useTypingString, @@ -15,8 +16,8 @@ import { ScreenHeader } from '../components/ScreenHeader'; import type { RouteProp } from '@react-navigation/native'; -import type { StackNavigatorParamList, StreamChatGenerics } from '../types'; -import { ThreadState } from 'stream-chat'; +import type { StackNavigatorParamList } from '../types'; +import { ThreadState, UserResponse } from 'stream-chat'; const selector = (nextValue: ThreadState) => ({ parentMessage: nextValue.parentMessage }) as const; @@ -33,20 +34,17 @@ type ThreadScreenProps = { }; export type ThreadHeaderProps = { - thread: ThreadContextValue['thread']; + thread: MessageType | ThreadType; }; const ThreadHeader: React.FC = ({ thread }) => { const typing = useTypingString(); - let subtitleText = thread?.user?.name; + let subtitleText = ((thread as MessageType)?.user as UserResponse)?.name; const { parentMessage } = - useStateStore( - (thread?.threadInstance as ThreadContextValue['threadInstance'])?.state, - selector, - ) || {}; + useStateStore((thread as ThreadType)?.threadInstance?.state, selector) || {}; if (subtitleText == null) { - subtitleText = parentMessage?.user?.name; + subtitleText = (parentMessage?.user as UserResponse)?.name; } return ( @@ -78,7 +76,7 @@ export const ThreadScreen: React.FC = ({ return ( - + = ({ > - /> + diff --git a/examples/SampleApp/src/types.ts b/examples/SampleApp/src/types.ts index 02bf4e24bf..762f90ec7d 100644 --- a/examples/SampleApp/src/types.ts +++ b/examples/SampleApp/src/types.ts @@ -1,39 +1,7 @@ -import type { Immutable } from 'seamless-immutable'; import type { Channel, UserResponse } from 'stream-chat'; -import type { ThreadContextValue } from 'stream-chat-react-native'; +import type { MessageType, ThreadType } from 'stream-chat-react-native'; import type { Theme } from '@react-navigation/native'; -export type LocalAttachmentType = { - file_size?: number; - mime_type?: string; -}; -export type LocalChannelType = Record; -export type LocalCommandType = string & {}; -export type LocalEventType = Record; -export type LocalMessageType = Record; -export type LocalReactionType = Record; -export type LocalUserType = { - image?: string; -}; -type LocalPollOptionType = Record; -type LocalPollType = Record; -type LocalMemberType = Record; - -export type StreamChatGenerics = { - attachmentType: LocalAttachmentType; - channelType: LocalChannelType; - commandType: LocalCommandType; - eventType: LocalEventType; - memberType: LocalMemberType; - messageType: LocalMessageType; - pollOptionType: LocalPollOptionType; - pollType: LocalPollType; - reactionType: LocalReactionType; - userType: LocalUserType; -} - -// export type StreamChatGenerics = DefaultGenerics; - export type DrawerNavigatorParamList = { HomeScreen: undefined; UserSelectorScreen: undefined; @@ -41,36 +9,36 @@ export type DrawerNavigatorParamList = { export type StackNavigatorParamList = { ChannelFilesScreen: { - channel: Channel; + channel: Channel; }; ChannelImagesScreen: { - channel: Channel; + channel: Channel; }; ChannelListScreen: undefined; ChannelPinnedMessagesScreen: { - channel: Channel; + channel: Channel; }; ChannelScreen: { - channel?: Channel; + channel?: Channel; channelId?: string; messageId?: string; }; GroupChannelDetailsScreen: { - channel: Channel; + channel: Channel; }; MessagingScreen: undefined; NewDirectMessagingScreen: undefined; NewGroupChannelAddMemberScreen: undefined; NewGroupChannelAssignNameScreen: undefined; OneOnOneChannelDetailScreen: { - channel: Channel; + channel: Channel; }; SharedGroupsScreen: { - user: Immutable> | UserResponse; + user: UserResponse; }; ThreadScreen: { - channel: Channel; - thread: ThreadContextValue['thread']; + channel: Channel; + thread: MessageType | ThreadType; }; }; diff --git a/examples/SampleApp/src/utils/RootNavigation.ts b/examples/SampleApp/src/utils/RootNavigation.ts index 1684b85393..381ca2d436 100644 --- a/examples/SampleApp/src/utils/RootNavigation.ts +++ b/examples/SampleApp/src/utils/RootNavigation.ts @@ -2,7 +2,8 @@ import React from 'react'; import { CommonActions, NavigationContainerRef } from '@react-navigation/native'; import { StackNavigatorParamList } from '../types'; -export const RootNavigationRef = React.createRef(); +export const RootNavigationRef = + React.createRef>(); export const navigateToChannel = (channelId: string | null | undefined) => { if (!channelId || !RootNavigationRef.current) { @@ -27,7 +28,6 @@ export const navigateToChannel = (channelId: string | null | undefined) => { } else { // navigate to channel screen return CommonActions.navigate({ - key: `${Date.now()}`, name: 'ChannelScreen', params: { channelId }, }); diff --git a/examples/SampleApp/src/utils/base.tsx b/examples/SampleApp/src/utils/base.tsx index 71907384da..7c50c2bfb5 100644 --- a/examples/SampleApp/src/utils/base.tsx +++ b/examples/SampleApp/src/utils/base.tsx @@ -9,6 +9,7 @@ export type IconProps = Partial & dark?: boolean; height?: number; width?: number; + scale?: number; }; export const RootSvg = (props: IconProps) => { const { backgroundFill = 'none', children, height = 24, width = 24 } = props; diff --git a/examples/SampleApp/src/utils/getUserActivityStatus.ts b/examples/SampleApp/src/utils/getUserActivityStatus.ts index d9eeeaa591..df839c08e8 100644 --- a/examples/SampleApp/src/utils/getUserActivityStatus.ts +++ b/examples/SampleApp/src/utils/getUserActivityStatus.ts @@ -1,15 +1,12 @@ import Dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; -import { StreamChatGenerics } from '../types'; - -import type { Immutable } from 'seamless-immutable'; import type { UserResponse } from 'stream-chat'; Dayjs.extend(relativeTime); export const getUserActivityStatus = ( - user?: Immutable> | UserResponse, + user?: UserResponse, ) => { if (!user) { return ''; diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index ce929aba6a..5ab94d949a 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -989,7 +989,7 @@ pirates "^4.0.6" source-map-support "^0.5.16" -"@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.25.0", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.17.2", "@babel/runtime@^7.25.0", "@babel/runtime@^7.8.4": version "7.26.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.9.tgz#aa4c6facc65b9cb3f87d75125ffd47781b475433" integrity sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg== @@ -2558,10 +2558,10 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/jsonwebtoken@~9.0.0": - version "9.0.8" - resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.8.tgz#313490052801edfb031bb32b6bbd77cc9f230852" - integrity sha512-7fx54m60nLFUVYlxAB1xpe9CBWX2vSrk50Y6ogRJ1v5xxtba7qXTg5BgYDN5dq+yuQQ9HaVlHJyAAt1/mxryFg== +"@types/jsonwebtoken@^9.0.8": + version "9.0.9" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3" + integrity sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ== dependencies: "@types/ms" "*" "@types/node" "*" @@ -2609,10 +2609,10 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== -"@types/ws@^7.4.0": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== +"@types/ws@^8.5.14": + version "8.18.0" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" + integrity sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw== dependencies: "@types/node" "*" @@ -5224,10 +5224,10 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== +isomorphic-ws@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" @@ -5768,7 +5768,7 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonwebtoken@~9.0.0: +jsonwebtoken@^9.0.2: version "9.0.2" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== @@ -7530,25 +7530,6 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat-react-native-core@6.6.6: - version "6.6.6" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.6.6.tgz#d701beb9652f0a5851286f752d8c4fdadb3e0603" - integrity sha512-sfBtWz4K4OzhFDMRaPF2xMj7aP9FQU4dMN1XCsmRT07hyYn6iEviECxNttYvoRLB1zNdeja5cL63IDY3UZSpAQ== - dependencies: - "@gorhom/bottom-sheet" "^5.1.1" - dayjs "1.10.5" - emoji-regex "^10.3.0" - i18next "^21.6.14" - intl-pluralrules "^2.0.1" - linkifyjs "^4.1.1" - lodash-es "4.17.21" - mime-types "^2.1.34" - path "0.12.7" - react-native-markdown-package "1.8.2" - react-native-url-polyfill "^1.3.0" - stream-chat "^8.57.5" - use-sync-external-store "^1.4.0" - "stream-chat-react-native-core@link:../../package": version "0.0.0" uid "" @@ -7557,35 +7538,19 @@ stream-chat-react-native-core@6.6.6: version "0.0.0" uid "" -stream-chat@^8.57.5: - version "8.57.5" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.57.5.tgz#1b49b7504371e19a539465e2ae5dc86aa3269637" - integrity sha512-ndcbH/zGzUIAhZLGn1owVV8MeNvVfWITIlhAhfmnsV7RLoo/eiGFEuP4aNoG1YRos/g9xJQ7TEmKpz8xYqo13w== +stream-chat@9.0.0-rc.4: + version "9.0.0-rc.4" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.4.tgz#30ffd324069cd012372014efe3a6d94bf264963a" + integrity sha512-kVlDls6TXEWAlAQf6WLwNv3wDwVo0y9J536+NS8PFmkJKkBNfD9RGAbb4SuZNxeEpd+kAy3861vxspB1mpFEmQ== dependencies: - "@babel/runtime" "^7.16.3" - "@types/jsonwebtoken" "~9.0.0" - "@types/ws" "^7.4.0" + "@types/jsonwebtoken" "^9.0.8" + "@types/ws" "^8.5.14" axios "^1.6.0" base64-js "^1.5.1" form-data "^4.0.0" - isomorphic-ws "^4.0.1" - jsonwebtoken "~9.0.0" - ws "^7.5.10" - -stream-chat@^8.57.6: - version "8.57.6" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.57.6.tgz#dd3a4a0a024ee44bfa6ae7ca15648e6c9f2e498f" - integrity sha512-+zkC5DtxvdkEBAv7dCzzO4WWosjaM15EjsH3q4xD1nX/yf2qT6BMhPJguM+CUWxwlFh32X0KR+ARtD0ChPqtnA== - dependencies: - "@babel/runtime" "^7.16.3" - "@types/jsonwebtoken" "~9.0.0" - "@types/ws" "^7.4.0" - axios "^1.6.0" - base64-js "^1.5.1" - form-data "^4.0.0" - isomorphic-ws "^4.0.1" - jsonwebtoken "~9.0.0" - ws "^7.5.10" + isomorphic-ws "^5.0.0" + jsonwebtoken "^9.0.2" + ws "^8.18.1" strict-uri-encode@^2.0.0: version "2.0.0" @@ -8238,6 +8203,11 @@ ws@^7, ws@^7.5.10: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== +ws@^8.18.1: + version "8.18.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" + integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== + y18n@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" diff --git a/examples/TypeScriptMessaging/App.tsx b/examples/TypeScriptMessaging/App.tsx index 36cb7032cd..3135dd4dd7 100644 --- a/examples/TypeScriptMessaging/App.tsx +++ b/examples/TypeScriptMessaging/App.tsx @@ -27,30 +27,6 @@ import { AuthProgressLoader } from './AuthProgressLoader'; LogBox.ignoreAllLogs(true); -type LocalAttachmentType = Record; -type LocalChannelType = Record; -type LocalCommandType = string; -type LocalEventType = Record; -type LocalMessageType = Record; -type LocalReactionType = Record; -type LocalUserType = Record; -type LocalPollOptionType = Record; -type LocalPollType = Record; -type LocalMemberType = Record; - -type StreamChatGenerics = { - attachmentType: LocalAttachmentType; - channelType: LocalChannelType; - commandType: LocalCommandType; - eventType: LocalEventType; - memberType: LocalMemberType; - messageType: LocalMessageType; - pollOptionType: LocalPollOptionType; - pollType: LocalPollType; - reactionType: LocalReactionType; - userType: LocalUserType; -}; - const options = { presence: true, state: true, @@ -77,7 +53,7 @@ const filters = { type: 'messaging', }; -const sort: ChannelSort = [ +const sort: ChannelSort = [ { pinned_at: -1 }, { last_message_at: -1 }, { updated_at: -1 }, @@ -102,7 +78,7 @@ const ChannelListScreen: React.FC = ({ navigation }) => return ( - + { setChannel(channel); @@ -150,7 +126,7 @@ const ChannelScreen: React.FC = ({ navigation }) => { thread={thread} > - + { setThread(selectedThread); if (channel?.id) { @@ -200,7 +176,7 @@ const ThreadScreen: React.FC = ({ navigation }) => { justifyContent: 'flex-start', }} > - onThreadDismount={() => setThread(null)} /> + setThread(null)} /> @@ -215,12 +191,12 @@ type NavigationParamsList = ChannelRoute & ChannelListRoute & ThreadRoute; const Stack = createStackNavigator(); type AppContextType = { - channel: ChannelType | undefined; - setChannel: React.Dispatch | undefined>>; + channel: ChannelType | undefined; + setChannel: React.Dispatch>; setThread: React.Dispatch< - React.SetStateAction['thread'] | undefined> + React.SetStateAction >; - thread: ThreadContextValue['thread'] | undefined; + thread: ThreadContextValue['thread'] | undefined; }; const AppContext = React.createContext({} as AppContextType); @@ -241,7 +217,7 @@ const App = () => { } return ( - + { }; export default () => { - const [channel, setChannel] = useState>(); - const [thread, setThread] = useState['thread']>(); + const [channel, setChannel] = useState(); + const [thread, setThread] = useState(); const theme = useStreamChatTheme(); const colorScheme = useColorScheme(); diff --git a/examples/TypeScriptMessaging/custom-types.d.ts b/examples/TypeScriptMessaging/custom-types.d.ts new file mode 100644 index 0000000000..f8641bab5f --- /dev/null +++ b/examples/TypeScriptMessaging/custom-types.d.ts @@ -0,0 +1,41 @@ +import { + DefaultAttachmentType, + DefaultMessageType, + DefaultChannelType, + DefaultCommandType, + DefaultEventType, + DefaultMemberType, + DefaultPollOptionType, + DefaultPollType, + DefaultReactionType, + DefaultThreadType, + DefaultUserType, +} from 'stream-chat-react-native'; + +declare module 'stream-chat' { + /* eslint-disable @typescript-eslint/no-empty-object-type */ + + interface CustomAttachmentData extends DefaultAttachmentType {} + + interface CustomChannelData extends DefaultChannelType {} + + interface CustomCommandData extends DefaultCommandType {} + + interface CustomEventData extends DefaultEventType {} + + interface CustomMemberData extends DefaultMemberType {} + + interface CustomUserData extends DefaultUserType {} + + interface CustomMessageData extends DefaultMessageType {} + + interface CustomPollOptionData extends DefaultPollOptionType {} + + interface CustomPollData extends DefaultPollType {} + + interface CustomReactionData extends DefaultReactionType {} + + interface CustomThreadData extends DefaultThreadType {} + + /* eslint-enable @typescript-eslint/no-empty-object-type */ +} diff --git a/examples/TypeScriptMessaging/ios/Podfile.lock b/examples/TypeScriptMessaging/ios/Podfile.lock index d529a65c0e..d6bc699fcd 100644 --- a/examples/TypeScriptMessaging/ios/Podfile.lock +++ b/examples/TypeScriptMessaging/ios/Podfile.lock @@ -2409,4 +2409,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 6b7a4b74915b42bfe4ffddaf67cbf5e7a2bfeab3 -COCOAPODS: 1.14.3 +COCOAPODS: 1.16.2 diff --git a/examples/TypeScriptMessaging/useStreamChatTheme.ts b/examples/TypeScriptMessaging/useStreamChatTheme.ts index 8c64521d70..0802c9ce30 100644 --- a/examples/TypeScriptMessaging/useStreamChatTheme.ts +++ b/examples/TypeScriptMessaging/useStreamChatTheme.ts @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { useColorScheme } from 'react-native'; import type { DeepPartial, Theme } from 'stream-chat-react-native'; -const getChatStyle = (colorScheme: string): DeepPartial => ({ +const getChatStyle = (colorScheme: string | null | undefined): DeepPartial => ({ avatar: { image: { height: 32, diff --git a/examples/TypeScriptMessaging/yarn.lock b/examples/TypeScriptMessaging/yarn.lock index 81b1407854..46c86fd953 100644 --- a/examples/TypeScriptMessaging/yarn.lock +++ b/examples/TypeScriptMessaging/yarn.lock @@ -989,7 +989,7 @@ pirates "^4.0.6" source-map-support "^0.5.16" -"@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.25.0", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.17.2", "@babel/runtime@^7.25.0", "@babel/runtime@^7.8.4": version "7.26.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.9.tgz#aa4c6facc65b9cb3f87d75125ffd47781b475433" integrity sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg== @@ -2047,10 +2047,10 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/jsonwebtoken@~9.0.0": - version "9.0.8" - resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.8.tgz#313490052801edfb031bb32b6bbd77cc9f230852" - integrity sha512-7fx54m60nLFUVYlxAB1xpe9CBWX2vSrk50Y6ogRJ1v5xxtba7qXTg5BgYDN5dq+yuQQ9HaVlHJyAAt1/mxryFg== +"@types/jsonwebtoken@^9.0.8": + version "9.0.9" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3" + integrity sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ== dependencies: "@types/ms" "*" "@types/node" "*" @@ -2098,10 +2098,10 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== -"@types/ws@^7.4.0": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== +"@types/ws@^8.5.14": + version "8.18.0" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" + integrity sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw== dependencies: "@types/node" "*" @@ -4657,10 +4657,10 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== +isomorphic-ws@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" @@ -5201,7 +5201,7 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonwebtoken@~9.0.0: +jsonwebtoken@^9.0.2: version "9.0.2" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== @@ -6921,25 +6921,6 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat-react-native-core@6.6.6: - version "6.6.6" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.6.6.tgz#d701beb9652f0a5851286f752d8c4fdadb3e0603" - integrity sha512-sfBtWz4K4OzhFDMRaPF2xMj7aP9FQU4dMN1XCsmRT07hyYn6iEviECxNttYvoRLB1zNdeja5cL63IDY3UZSpAQ== - dependencies: - "@gorhom/bottom-sheet" "^5.1.1" - dayjs "1.10.5" - emoji-regex "^10.3.0" - i18next "^21.6.14" - intl-pluralrules "^2.0.1" - linkifyjs "^4.1.1" - lodash-es "4.17.21" - mime-types "^2.1.34" - path "0.12.7" - react-native-markdown-package "1.8.2" - react-native-url-polyfill "^1.3.0" - stream-chat "^8.57.5" - use-sync-external-store "^1.4.0" - "stream-chat-react-native-core@link:../../package": version "0.0.0" uid "" @@ -6948,35 +6929,19 @@ stream-chat-react-native-core@6.6.6: version "0.0.0" uid "" -stream-chat@^8.57.5: - version "8.57.5" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.57.5.tgz#1b49b7504371e19a539465e2ae5dc86aa3269637" - integrity sha512-ndcbH/zGzUIAhZLGn1owVV8MeNvVfWITIlhAhfmnsV7RLoo/eiGFEuP4aNoG1YRos/g9xJQ7TEmKpz8xYqo13w== +stream-chat@9.0.0-rc.4: + version "9.0.0-rc.4" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.4.tgz#30ffd324069cd012372014efe3a6d94bf264963a" + integrity sha512-kVlDls6TXEWAlAQf6WLwNv3wDwVo0y9J536+NS8PFmkJKkBNfD9RGAbb4SuZNxeEpd+kAy3861vxspB1mpFEmQ== dependencies: - "@babel/runtime" "^7.16.3" - "@types/jsonwebtoken" "~9.0.0" - "@types/ws" "^7.4.0" + "@types/jsonwebtoken" "^9.0.8" + "@types/ws" "^8.5.14" axios "^1.6.0" base64-js "^1.5.1" form-data "^4.0.0" - isomorphic-ws "^4.0.1" - jsonwebtoken "~9.0.0" - ws "^7.5.10" - -stream-chat@^8.57.6: - version "8.57.6" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.57.6.tgz#dd3a4a0a024ee44bfa6ae7ca15648e6c9f2e498f" - integrity sha512-+zkC5DtxvdkEBAv7dCzzO4WWosjaM15EjsH3q4xD1nX/yf2qT6BMhPJguM+CUWxwlFh32X0KR+ARtD0ChPqtnA== - dependencies: - "@babel/runtime" "^7.16.3" - "@types/jsonwebtoken" "~9.0.0" - "@types/ws" "^7.4.0" - axios "^1.6.0" - base64-js "^1.5.1" - form-data "^4.0.0" - isomorphic-ws "^4.0.1" - jsonwebtoken "~9.0.0" - ws "^7.5.10" + isomorphic-ws "^5.0.0" + jsonwebtoken "^9.0.2" + ws "^8.18.1" strict-uri-encode@^2.0.0: version "2.0.0" @@ -7610,6 +7575,11 @@ ws@^7, ws@^7.5.10: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== +ws@^8.18.1: + version "8.18.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" + integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== + y18n@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index fae918baa2..11508bdd3a 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -1094,13 +1094,6 @@ pirates "^4.0.6" source-map-support "^0.5.16" -"@babel/runtime@^7.16.3": - version "7.22.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.3.tgz#0a7fce51d43adbf0f7b517a71f4c3aaca92ebcbb" - integrity sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ== - dependencies: - regenerator-runtime "^0.13.11" - "@babel/runtime@^7.17.2", "@babel/runtime@^7.20.0": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12" @@ -1795,13 +1788,19 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== -"@types/jsonwebtoken@~9.0.0": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#9eeb56c76dd555039be2a3972218de5bd3b8d83e" - integrity sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q== +"@types/jsonwebtoken@^9.0.8": + version "9.0.9" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3" + integrity sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ== dependencies: + "@types/ms" "*" "@types/node" "*" +"@types/ms@*": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78" + integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== + "@types/node-forge@^1.3.0": version "1.3.11" resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" @@ -1821,10 +1820,10 @@ dependencies: csstype "^3.0.2" -"@types/ws@^7.4.0": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== +"@types/ws@^8.5.14": + version "8.18.0" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" + integrity sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw== dependencies: "@types/node" "*" @@ -3351,10 +3350,10 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== +isomorphic-ws@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== jackspeak@^3.1.2: version "3.4.0" @@ -3461,15 +3460,21 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonwebtoken@~9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz#d0faf9ba1cc3a56255fe49c0961a67e520c1926d" - integrity sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw== +jsonwebtoken@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" + integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== dependencies: jws "^3.2.2" - lodash "^4.17.21" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" ms "^2.1.1" - semver "^7.3.8" + semver "^7.5.4" jwa@^1.4.1: version "1.4.1" @@ -3609,6 +3614,41 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash@^4.17.15, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -4343,11 +4383,6 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - regenerator-runtime@^0.14.0: version "0.14.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" @@ -4532,7 +4567,7 @@ semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.5, semver@^7.3.8: +semver@^7.3.5: version "7.5.1" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== @@ -4733,39 +4768,23 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" integrity sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg== -stream-chat-react-native-core@6.6.6: - version "6.6.6" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.6.6.tgz#d701beb9652f0a5851286f752d8c4fdadb3e0603" - integrity sha512-sfBtWz4K4OzhFDMRaPF2xMj7aP9FQU4dMN1XCsmRT07hyYn6iEviECxNttYvoRLB1zNdeja5cL63IDY3UZSpAQ== - dependencies: - "@gorhom/bottom-sheet" "^5.1.1" - dayjs "1.10.5" - emoji-regex "^10.3.0" - i18next "^21.6.14" - intl-pluralrules "^2.0.1" - linkifyjs "^4.1.1" - lodash-es "4.17.21" - mime-types "^2.1.34" - path "0.12.7" - react-native-markdown-package "1.8.2" - react-native-url-polyfill "^1.3.0" - stream-chat "^8.57.5" - use-sync-external-store "^1.4.0" - -stream-chat@^8.57.5: - version "8.57.5" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.57.5.tgz#1b49b7504371e19a539465e2ae5dc86aa3269637" - integrity sha512-ndcbH/zGzUIAhZLGn1owVV8MeNvVfWITIlhAhfmnsV7RLoo/eiGFEuP4aNoG1YRos/g9xJQ7TEmKpz8xYqo13w== - dependencies: - "@babel/runtime" "^7.16.3" - "@types/jsonwebtoken" "~9.0.0" - "@types/ws" "^7.4.0" +"stream-chat-react-native-core@link:..": + version "0.0.0" + uid "" + +stream-chat@9.0.0-rc.4: + version "9.0.0-rc.4" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.4.tgz#30ffd324069cd012372014efe3a6d94bf264963a" + integrity sha512-kVlDls6TXEWAlAQf6WLwNv3wDwVo0y9J536+NS8PFmkJKkBNfD9RGAbb4SuZNxeEpd+kAy3861vxspB1mpFEmQ== + dependencies: + "@types/jsonwebtoken" "^9.0.8" + "@types/ws" "^8.5.14" axios "^1.6.0" base64-js "^1.5.1" form-data "^4.0.0" - isomorphic-ws "^4.0.1" - jsonwebtoken "~9.0.0" - ws "^7.5.10" + isomorphic-ws "^5.0.0" + jsonwebtoken "^9.0.2" + ws "^8.18.1" "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" @@ -5236,16 +5255,16 @@ ws@^6.2.3: dependencies: async-limiter "~1.0.0" -ws@^7.5.10: - version "7.5.10" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" - integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== - ws@^8.12.1: version "8.17.1" resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== +ws@^8.18.1: + version "8.18.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" + integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== + xcode@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/xcode/-/xcode-3.0.1.tgz#3efb62aac641ab2c702458f9a0302696146aa53c" diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 723b03e359..a2084c513a 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -759,13 +759,6 @@ pirates "^4.0.6" source-map-support "^0.5.16" -"@babel/runtime@^7.16.3": - version "7.22.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.3.tgz#0a7fce51d43adbf0f7b517a71f4c3aaca92ebcbb" - integrity sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ== - dependencies: - regenerator-runtime "^0.13.11" - "@babel/runtime@^7.17.2": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12" @@ -1252,13 +1245,19 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jsonwebtoken@~9.0.0": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#9eeb56c76dd555039be2a3972218de5bd3b8d83e" - integrity sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q== +"@types/jsonwebtoken@^9.0.8": + version "9.0.9" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3" + integrity sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ== dependencies: + "@types/ms" "*" "@types/node" "*" +"@types/ms@*": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78" + integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== + "@types/node-forge@^1.3.0": version "1.3.11" resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" @@ -1283,10 +1282,10 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== -"@types/ws@^7.4.0": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== +"@types/ws@^8.5.14": + version "8.18.0" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" + integrity sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw== dependencies: "@types/node" "*" @@ -2234,10 +2233,10 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== +isomorphic-ws@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== istanbul-lib-coverage@^3.2.0: version "3.2.2" @@ -2421,15 +2420,21 @@ json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonwebtoken@~9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz#d0faf9ba1cc3a56255fe49c0961a67e520c1926d" - integrity sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw== +jsonwebtoken@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" + integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== dependencies: jws "^3.2.2" - lodash "^4.17.21" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" ms "^2.1.1" - semver "^7.3.8" + semver "^7.5.4" jwa@^1.4.1: version "1.4.1" @@ -2496,12 +2501,47 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash.throttle@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== -lodash@^4.17.15, lodash@^4.17.21: +lodash@^4.17.15: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -2520,13 +2560,6 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -3167,7 +3200,7 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.2: +regenerator-runtime@^0.13.2: version "0.13.11" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== @@ -3277,12 +3310,10 @@ semver@^7.1.3: resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== -semver@^7.3.8: - version "7.5.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" - integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== - dependencies: - lru-cache "^6.0.0" +semver@^7.5.4: + version "7.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" + integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== send@0.19.0: version "0.19.0" @@ -3409,39 +3440,23 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat-react-native-core@6.6.6: - version "6.6.6" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.6.6.tgz#d701beb9652f0a5851286f752d8c4fdadb3e0603" - integrity sha512-sfBtWz4K4OzhFDMRaPF2xMj7aP9FQU4dMN1XCsmRT07hyYn6iEviECxNttYvoRLB1zNdeja5cL63IDY3UZSpAQ== - dependencies: - "@gorhom/bottom-sheet" "^5.1.1" - dayjs "1.10.5" - emoji-regex "^10.3.0" - i18next "^21.6.14" - intl-pluralrules "^2.0.1" - linkifyjs "^4.1.1" - lodash-es "4.17.21" - mime-types "^2.1.34" - path "0.12.7" - react-native-markdown-package "1.8.2" - react-native-url-polyfill "^1.3.0" - stream-chat "^8.57.5" - use-sync-external-store "^1.4.0" - -stream-chat@^8.57.5: - version "8.57.5" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.57.5.tgz#1b49b7504371e19a539465e2ae5dc86aa3269637" - integrity sha512-ndcbH/zGzUIAhZLGn1owVV8MeNvVfWITIlhAhfmnsV7RLoo/eiGFEuP4aNoG1YRos/g9xJQ7TEmKpz8xYqo13w== - dependencies: - "@babel/runtime" "^7.16.3" - "@types/jsonwebtoken" "~9.0.0" - "@types/ws" "^7.4.0" +"stream-chat-react-native-core@link:..": + version "0.0.0" + uid "" + +stream-chat@9.0.0-rc.4: + version "9.0.0-rc.4" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.4.tgz#30ffd324069cd012372014efe3a6d94bf264963a" + integrity sha512-kVlDls6TXEWAlAQf6WLwNv3wDwVo0y9J536+NS8PFmkJKkBNfD9RGAbb4SuZNxeEpd+kAy3861vxspB1mpFEmQ== + dependencies: + "@types/jsonwebtoken" "^9.0.8" + "@types/ws" "^8.5.14" axios "^1.6.0" base64-js "^1.5.1" form-data "^4.0.0" - isomorphic-ws "^4.0.1" - jsonwebtoken "~9.0.0" - ws "^7.5.10" + isomorphic-ws "^5.0.0" + jsonwebtoken "^9.0.2" + ws "^8.18.1" string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" @@ -3697,6 +3712,11 @@ ws@^7.5.10: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== +ws@^8.18.1: + version "8.18.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" + integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -3707,11 +3727,6 @@ yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" diff --git a/package/package.json b/package/package.json index d2a383e6c6..ca3186e7db 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "^8.57.6", + "stream-chat": "9.0.0-rc.4", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/src/components/AITypingIndicatorView/AITypingIndicatorView.tsx b/package/src/components/AITypingIndicatorView/AITypingIndicatorView.tsx index 1709b8fcad..5082512924 100644 --- a/package/src/components/AITypingIndicatorView/AITypingIndicatorView.tsx +++ b/package/src/components/AITypingIndicatorView/AITypingIndicatorView.tsx @@ -7,21 +7,16 @@ import { Channel } from 'stream-chat'; import { AIStates, useAIState } from './hooks/useAIState'; import { useChannelContext, useTheme, useTranslationContext } from '../../contexts'; -import type { DefaultStreamChatGenerics } from '../../types/types'; -export type AITypingIndicatorViewProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - channel?: Channel; +export type AITypingIndicatorViewProps = { + channel?: Channel; }; -export const AITypingIndicatorView = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const AITypingIndicatorView = ({ channel: channelFromProps, -}: AITypingIndicatorViewProps) => { +}: AITypingIndicatorViewProps) => { const { t } = useTranslationContext(); - const { channel: channelFromContext } = useChannelContext(); + const { channel: channelFromContext } = useChannelContext(); const channel = channelFromProps || channelFromContext; const { aiState } = useAIState(channel); const allowedStates = { diff --git a/package/src/components/AITypingIndicatorView/hooks/useAIState.ts b/package/src/components/AITypingIndicatorView/hooks/useAIState.ts index 2c7f9c4258..de0ad7ae93 100644 --- a/package/src/components/AITypingIndicatorView/hooks/useAIState.ts +++ b/package/src/components/AITypingIndicatorView/hooks/useAIState.ts @@ -3,7 +3,6 @@ import { useEffect, useState } from 'react'; import { AIState, Channel, Event } from 'stream-chat'; import { useChatContext } from '../../../contexts'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; export const AIStates = { Error: 'AI_STATE_ERROR', @@ -18,12 +17,8 @@ export const AIStates = { * @param {Channel} channel - The channel for which we want to know the AI state. * @returns {{ aiState: AIState }} The current AI state for the given channel. */ -export const useAIState = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel?: Channel, -): { aiState: AIState } => { - const { isOnline } = useChatContext(); +export const useAIState = (channel?: Channel): { aiState: AIState } => { + const { isOnline } = useChatContext(); const [aiState, setAiState] = useState(AIStates.Idle); @@ -38,16 +33,13 @@ export const useAIState = < return; } - const indicatorChangedListener = channel.on( - 'ai_indicator.update', - (event: Event) => { - const { cid } = event; - const state = event.ai_state as AIState; - if (channel.cid === cid) { - setAiState(state); - } - }, - ); + const indicatorChangedListener = channel.on('ai_indicator.update', (event: Event) => { + const { cid } = event; + const state = event.ai_state as AIState; + if (channel.cid === cid) { + setAiState(state); + } + }); const indicatorClearedListener = channel.on('ai_indicator.clear', (event) => { const { cid } = event; diff --git a/package/src/components/Attachment/Attachment.tsx b/package/src/components/Attachment/Attachment.tsx index a7894b55f3..07ab1d6cda 100644 --- a/package/src/components/Attachment/Attachment.tsx +++ b/package/src/components/Attachment/Attachment.tsx @@ -13,14 +13,12 @@ import { } from '../../contexts/messagesContext/MessagesContext'; import { isVideoPlayerAvailable } from '../../native'; -import { DefaultStreamChatGenerics, FileTypes } from '../../types/types'; +import { FileTypes } from '../../types/types'; export type ActionHandler = (name: string, value: string) => void; -export type AttachmentPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick< - MessagesContextValue, +export type AttachmentPropsWithContext = Pick< + MessagesContextValue, | 'AttachmentActions' | 'Card' | 'FileAttachment' @@ -34,14 +32,10 @@ export type AttachmentPropsWithContext< /** * The attachment to render */ - attachment: AttachmentType; + attachment: AttachmentType; }; -const AttachmentWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AttachmentPropsWithContext, -) => { +const AttachmentWithContext = (props: AttachmentPropsWithContext) => { const { attachment, AttachmentActions, @@ -68,7 +62,7 @@ const AttachmentWithContext = < <> {hasAttachmentActions && ( - + )} ); @@ -79,7 +73,7 @@ const AttachmentWithContext = < <> {hasAttachmentActions && ( - + )} ) : ( @@ -99,7 +93,8 @@ const AttachmentWithContext = < return ( <> - + {/** TODO: Please rethink this, the fix is temporary. */} + ); } else { @@ -107,10 +102,7 @@ const AttachmentWithContext = < } }; -const areEqual = ( - prevProps: AttachmentPropsWithContext, - nextProps: AttachmentPropsWithContext, -) => { +const areEqual = (prevProps: AttachmentPropsWithContext, nextProps: AttachmentPropsWithContext) => { const { attachment: prevAttachment, isAttachmentEqual, @@ -145,11 +137,9 @@ const MemoizedAttachment = React.memo( areEqual, ) as typeof AttachmentWithContext; -export type AttachmentProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial< +export type AttachmentProps = Partial< Pick< - MessagesContextValue, + MessagesContextValue, | 'AttachmentActions' | 'Card' | 'FileAttachment' @@ -161,16 +151,12 @@ export type AttachmentProps< | 'isAttachmentEqual' > > & - Pick, 'attachment'>; + Pick; /** * Attachment - The message attachment */ -export const Attachment = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AttachmentProps, -) => { +export const Attachment = (props: AttachmentProps) => { const { attachment, AttachmentActions: PropAttachmentActions, @@ -193,7 +179,7 @@ export const Attachment = < isAttachmentEqual, myMessageTheme: ContextMyMessageTheme, UrlPreview: ContextUrlPreview, - } = useMessagesContext(); + } = useMessagesContext(); if (!attachment) { return null; diff --git a/package/src/components/Attachment/AttachmentActions.tsx b/package/src/components/Attachment/AttachmentActions.tsx index f594d5375e..a860772f15 100644 --- a/package/src/components/Attachment/AttachmentActions.tsx +++ b/package/src/components/Attachment/AttachmentActions.tsx @@ -17,8 +17,6 @@ import { } from '../../contexts/messageContext/MessageContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - const styles = StyleSheet.create({ actionButton: { borderRadius: 20, @@ -33,10 +31,8 @@ const styles = StyleSheet.create({ }, }); -export type AttachmentActionsPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'actions'> & - Pick, 'handleAction'> & { +export type AttachmentActionsPropsWithContext = Pick & + Pick & { styles?: Partial<{ actionButton: StyleProp; buttonText: StyleProp; @@ -44,11 +40,7 @@ export type AttachmentActionsPropsWithContext< }>; }; -const AttachmentActionsWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AttachmentActionsPropsWithContext, -) => { +const AttachmentActionsWithContext = (props: AttachmentActionsPropsWithContext) => { const { actions, handleAction, styles: stylesProp = {} } = props; const { @@ -116,9 +108,9 @@ const AttachmentActionsWithContext = < ); }; -const areEqual = ( - prevProps: AttachmentActionsPropsWithContext, - nextProps: AttachmentActionsPropsWithContext, +const areEqual = ( + prevProps: AttachmentActionsPropsWithContext, + nextProps: AttachmentActionsPropsWithContext, ) => { const { actions: prevActions } = prevProps; const { actions: nextActions } = nextProps; @@ -133,21 +125,15 @@ const MemoizedAttachmentActions = React.memo( areEqual, ) as typeof AttachmentActionsWithContext; -export type AttachmentActionsProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Attachment & - Partial, 'handleAction'>>; +export type AttachmentActionsProps = Attachment & + Partial>; /** * AttachmentActions - The actions you can take on an attachment. * Actions in combination with attachments can be used to build [commands](https://getstream.io/chat/docs/#channel_commands). */ -export const AttachmentActions = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AttachmentActionsProps, -) => { - const { handleAction } = useMessageContext(); +export const AttachmentActions = (props: AttachmentActionsProps) => { + const { handleAction } = useMessageContext(); return ; }; diff --git a/package/src/components/Attachment/Card.tsx b/package/src/components/Attachment/Card.tsx index 09e9bca733..ed8582bc9d 100644 --- a/package/src/components/Attachment/Card.tsx +++ b/package/src/components/Attachment/Card.tsx @@ -27,7 +27,7 @@ import { } from '../../contexts/messagesContext/MessagesContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { Play } from '../../icons/Play'; -import { DefaultStreamChatGenerics, FileTypes } from '../../types/types'; +import { FileTypes } from '../../types/types'; import { makeImageCompatibleUrl } from '../../utils/utils'; import { ImageBackground } from '../UIComponents/ImageBackground'; @@ -82,16 +82,11 @@ const styles = StyleSheet.create({ }, }); -export type CardPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Attachment & +export type CardPropsWithContext = Attachment & Pick & + Pick & Pick< - MessageContextValue, - 'onLongPress' | 'onPress' | 'onPressIn' | 'preventPress' - > & - Pick< - MessagesContextValue, + MessagesContextValue, 'additionalPressableProps' | 'CardCover' | 'CardFooter' | 'CardHeader' | 'myMessageTheme' > & { channelId: string | undefined; @@ -110,11 +105,7 @@ export type CardPropsWithContext< }>; }; -const CardWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: CardPropsWithContext, -) => { +const CardWithContext = (props: CardPropsWithContext) => { const { additionalPressableProps, author_name, @@ -289,10 +280,7 @@ const CardWithContext = < ); }; -const areEqual = ( - prevProps: CardPropsWithContext, - nextProps: CardPropsWithContext, -) => { +const areEqual = (prevProps: CardPropsWithContext, nextProps: CardPropsWithContext) => { const { myMessageTheme: prevMyMessageTheme } = prevProps; const { myMessageTheme: nextMyMessageTheme } = nextProps; @@ -307,17 +295,12 @@ const areEqual = = Attachment & +export type CardProps = Attachment & Partial< - Pick, 'ImageComponent'> & - Pick< - MessageContextValue, - 'onLongPress' | 'onPress' | 'onPressIn' | 'myMessageTheme' - > & + Pick & + Pick & Pick< - MessagesContextValue, + MessagesContextValue, 'additionalPressableProps' | 'CardCover' | 'CardFooter' | 'CardHeader' > >; @@ -325,16 +308,11 @@ export type CardProps< /** * UI component for card in attachments. */ -export const Card = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: CardProps, -) => { - const { ImageComponent } = useChatContext(); - const { message, onLongPress, onPress, onPressIn, preventPress } = - useMessageContext(); +export const Card = (props: CardProps) => { + const { ImageComponent } = useChatContext(); + const { message, onLongPress, onPress, onPressIn, preventPress } = useMessageContext(); const { additionalPressableProps, CardCover, CardFooter, CardHeader, myMessageTheme } = - useMessagesContext(); + useMessagesContext(); return ( = Pick< - MessageContextValue, +export type FileAttachmentPropsWithContext = Pick< + MessageContextValue, 'onLongPress' | 'onPress' | 'onPressIn' | 'preventPress' > & Pick< - MessagesContextValue, + MessagesContextValue, 'additionalPressableProps' | 'AttachmentActions' | 'FileAttachmentIcon' > & { /** The attachment to render */ - attachment: Attachment; + attachment: Attachment; attachmentSize?: number; styles?: Partial<{ container: StyleProp; @@ -59,11 +56,7 @@ export type FileAttachmentPropsWithContext< }>; }; -const FileAttachmentWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: FileAttachmentPropsWithContext, -) => { +const FileAttachmentWithContext = (props: FileAttachmentPropsWithContext) => { const { additionalPressableProps, attachment, @@ -149,22 +142,16 @@ const FileAttachmentWithContext = < ); }; -export type FileAttachmentProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial, 'attachment'>> & - Pick, 'attachment'>; - -export const FileAttachment = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: FileAttachmentProps, -) => { - const { onLongPress, onPress, onPressIn, preventPress } = useMessageContext(); +export type FileAttachmentProps = Partial> & + Pick; + +export const FileAttachment = (props: FileAttachmentProps) => { + const { onLongPress, onPress, onPressIn, preventPress } = useMessageContext(); const { additionalPressableProps, AttachmentActions = AttachmentActionsDefault, FileAttachmentIcon = FileIconDefault, - } = useMessagesContext(); + } = useMessagesContext(); return ( = Pick, 'files'> & - Pick, 'Attachment' | 'AudioAttachment'> & { +export type FileAttachmentGroupPropsWithContext = Pick & + Pick & { /** * The unique id for the message with file attachments */ @@ -33,19 +31,13 @@ export type FileAttachmentGroupPropsWithContext< }>; }; -type FilesToDisplayType< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Attachment & { +type FilesToDisplayType = Attachment & { duration: number; paused: boolean; progress: number; }; -const FileAttachmentGroupWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: FileAttachmentGroupPropsWithContext, -) => { +const FileAttachmentGroupWithContext = (props: FileAttachmentGroupPropsWithContext) => { const { Attachment, AudioAttachment, files, messageId, styles: stylesProp = {} } = props; const [filesToDisplay, setFilesToDisplay] = useState([]); @@ -108,7 +100,7 @@ const FileAttachmentGroupWithContext = < {filesToDisplay.map((file, index) => ( ( - prevProps: FileAttachmentGroupPropsWithContext, - nextProps: FileAttachmentGroupPropsWithContext, +const areEqual = ( + prevProps: FileAttachmentGroupPropsWithContext, + nextProps: FileAttachmentGroupPropsWithContext, ) => { const { files: prevFiles } = prevProps; const { files: nextFiles } = nextProps; @@ -159,22 +151,17 @@ const MemoizedFileAttachmentGroup = React.memo( areEqual, ) as typeof FileAttachmentGroupWithContext; -export type FileAttachmentGroupProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial, 'messageId'>> & - Pick, 'messageId'>; +export type FileAttachmentGroupProps = Partial< + Omit +> & + Pick; -export const FileAttachmentGroup = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: FileAttachmentGroupProps, -) => { +export const FileAttachmentGroup = (props: FileAttachmentGroupProps) => { const { files: propFiles, messageId } = props; - const { files: contextFiles } = useMessageContext(); + const { files: contextFiles } = useMessageContext(); - const { Attachment = AttachmentDefault, AudioAttachment } = - useMessagesContext(); + const { Attachment = AttachmentDefault, AudioAttachment } = useMessagesContext(); const files = propFiles || contextFiles; diff --git a/package/src/components/Attachment/Gallery.tsx b/package/src/components/Attachment/Gallery.tsx index f5a7d3d492..13e26f59b4 100644 --- a/package/src/components/Attachment/Gallery.tsx +++ b/package/src/components/Attachment/Gallery.tsx @@ -33,14 +33,15 @@ import { import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { useLoadingImage } from '../../hooks/useLoadingImage'; import { isVideoPlayerAvailable } from '../../native'; -import { DefaultStreamChatGenerics, FileTypes } from '../../types/types'; +import { FileTypes } from '../../types/types'; import { getUrlWithoutParams } from '../../utils/utils'; -export type GalleryPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'setSelectedMessage' | 'setMessages'> & +export type GalleryPropsWithContext = Pick< + ImageGalleryContextValue, + 'setSelectedMessage' | 'setMessages' +> & Pick< - MessageContextValue, + MessageContextValue, | 'alignment' | 'groupStyles' | 'images' @@ -52,7 +53,7 @@ export type GalleryPropsWithContext< | 'threadList' > & Pick< - MessagesContextValue, + MessagesContextValue, | 'additionalPressableProps' | 'legacyImageViewerSwipeBehaviour' | 'VideoThumbnail' @@ -75,14 +76,10 @@ export type GalleryPropsWithContext< * * TODO: Fix circular dependencies of imports */ - message?: MessageType; + message?: MessageType; }; -const GalleryWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: GalleryPropsWithContext, -) => { +const GalleryWithContext = (props: GalleryPropsWithContext) => { const { additionalPressableProps, alignment, @@ -234,9 +231,7 @@ const GalleryWithContext = < ); }; -type GalleryThumbnailProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +type GalleryThumbnailProps = { borderRadius: { borderBottomLeftRadius: number; borderBottomRightRadius: number; @@ -244,31 +239,26 @@ type GalleryThumbnailProps< borderTopRightRadius: number; }; colIndex: number; - imagesAndVideos: Attachment[]; + imagesAndVideos: Attachment[]; invertedDirections: boolean; - message: MessageType; + message: MessageType; numOfColumns: number; numOfRows: number; rowIndex: number; thumbnail: Thumbnail; } & Pick< - MessagesContextValue, + MessagesContextValue, | 'additionalPressableProps' | 'legacyImageViewerSwipeBehaviour' | 'VideoThumbnail' | 'ImageLoadingIndicator' | 'ImageLoadingFailedIndicator' > & - Pick, 'setSelectedMessage' | 'setMessages'> & - Pick< - MessageContextValue, - 'onLongPress' | 'onPress' | 'onPressIn' | 'preventPress' - > & + Pick & + Pick & Pick; -const GalleryThumbnail = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +const GalleryThumbnail = ({ additionalPressableProps, borderRadius, colIndex, @@ -290,7 +280,7 @@ const GalleryThumbnail = < setSelectedMessage, thumbnail, VideoThumbnail, -}: GalleryThumbnailProps) => { +}: GalleryThumbnailProps) => { const { theme: { colors: { overlay }, @@ -419,15 +409,13 @@ const GalleryThumbnail = < ); }; -const GalleryImageThumbnail = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +const GalleryImageThumbnail = ({ borderRadius, ImageLoadingFailedIndicator, ImageLoadingIndicator, thumbnail, }: Pick< - GalleryThumbnailProps, + GalleryThumbnailProps, 'ImageLoadingFailedIndicator' | 'ImageLoadingIndicator' | 'thumbnail' | 'borderRadius' >) => { const { @@ -494,10 +482,7 @@ const GalleryImageThumbnail = < ); }; -const areEqual = ( - prevProps: GalleryPropsWithContext, - nextProps: GalleryPropsWithContext, -) => { +const areEqual = (prevProps: GalleryPropsWithContext, nextProps: GalleryPropsWithContext) => { const { groupStyles: prevGroupStyles, hasThreadReplies: prevHasThreadReplies, @@ -566,18 +551,12 @@ const areEqual = = Partial>; +export type GalleryProps = Partial; /** * UI component for card in attachments. */ -export const Gallery = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: GalleryProps, -) => { +export const Gallery = (props: GalleryProps) => { const { additionalPressableProps: propAdditionalPressableProps, alignment: propAlignment, @@ -599,8 +578,7 @@ export const Gallery = < VideoThumbnail: PropVideoThumbnail, } = props; - const { setMessages, setSelectedMessage: contextSetSelectedMessage } = - useImageGalleryContext(); + const { setMessages, setSelectedMessage: contextSetSelectedMessage } = useImageGalleryContext(); const { alignment: contextAlignment, groupStyles: contextGroupStyles, @@ -612,7 +590,7 @@ export const Gallery = < preventPress: contextPreventPress, threadList: contextThreadList, videos: contextVideos, - } = useMessageContext(); + } = useMessageContext(); const { additionalPressableProps: contextAdditionalPressableProps, ImageLoadingFailedIndicator: ContextImageLoadingFailedIndicator, @@ -620,7 +598,7 @@ export const Gallery = < legacyImageViewerSwipeBehaviour, myMessageTheme: contextMyMessageTheme, VideoThumbnail: ContextVideoThumnbnail, - } = useMessagesContext(); + } = useMessagesContext(); const { setOverlay: contextSetOverlay } = useOverlayContext(); const images = propImages || contextImages; diff --git a/package/src/components/Attachment/GalleryImage.tsx b/package/src/components/Attachment/GalleryImage.tsx index 44fc81f7a2..75328eece0 100644 --- a/package/src/components/Attachment/GalleryImage.tsx +++ b/package/src/components/Attachment/GalleryImage.tsx @@ -3,12 +3,10 @@ import { Image, ImageProps } from 'react-native'; import { ChatContextValue, useChatContext } from '../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { getUrlWithoutParams, isLocalUrl, makeImageCompatibleUrl } from '../../utils/utils'; -export type GalleryImageWithContextProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = GalleryImageProps & Pick, 'ImageComponent'>; +export type GalleryImageWithContextProps = GalleryImageProps & + Pick; export const GalleryImageWithContext = (props: GalleryImageWithContextProps) => { const { ImageComponent = Image, uri, ...rest } = props; @@ -47,12 +45,8 @@ export type GalleryImageProps = Omit & { uri: string; }; -export const GalleryImage = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: GalleryImageProps, -) => { - const { ImageComponent } = useChatContext(); +export const GalleryImage = (props: GalleryImageProps) => { + const { ImageComponent } = useChatContext(); return ; }; diff --git a/package/src/components/Attachment/Giphy.tsx b/package/src/components/Attachment/Giphy.tsx index 29eda46dce..cc60590399 100644 --- a/package/src/components/Attachment/Giphy.tsx +++ b/package/src/components/Attachment/Giphy.tsx @@ -24,7 +24,7 @@ import { import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { useLoadingImage } from '../../hooks/useLoadingImage'; import { GiphyIcon, GiphyLightning } from '../../icons'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { makeImageCompatibleUrl } from '../../utils/utils'; const styles = StyleSheet.create({ @@ -134,11 +134,12 @@ const styles = StyleSheet.create({ }, }); -export type GiphyPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'setSelectedMessage' | 'setMessages'> & +export type GiphyPropsWithContext = Pick< + ImageGalleryContextValue, + 'setSelectedMessage' | 'setMessages' +> & Pick< - MessageContextValue, + MessageContextValue, | 'handleAction' | 'isMyMessage' | 'message' @@ -147,22 +148,18 @@ export type GiphyPropsWithContext< | 'onPressIn' | 'preventPress' > & - Pick, 'ImageComponent'> & + Pick & Pick< - MessagesContextValue, + MessagesContextValue, | 'giphyVersion' | 'additionalPressableProps' | 'ImageLoadingIndicator' | 'ImageLoadingFailedIndicator' > & { - attachment: Attachment; + attachment: Attachment; } & Pick; -const GiphyWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: GiphyPropsWithContext, -) => { +const GiphyWithContext = (props: GiphyPropsWithContext) => { const { additionalPressableProps, attachment, @@ -389,10 +386,7 @@ const GiphyWithContext = < ); }; -const areEqual = ( - prevProps: GiphyPropsWithContext, - nextProps: GiphyPropsWithContext, -) => { +const areEqual = (prevProps: GiphyPropsWithContext, nextProps: GiphyPropsWithContext) => { const { attachment: { actions: prevActions, image_url: prevImageUrl, thumb_url: prevThumbUrl }, giphyVersion: prevGiphyVersion, @@ -448,31 +442,25 @@ const areEqual = = Partial> & { - attachment: Attachment; +export type GiphyProps = Partial & { + attachment: Attachment; }; /** * UI component for card in attachments. */ -export const Giphy = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: GiphyProps, -) => { +export const Giphy = (props: GiphyProps) => { const { handleAction, isMyMessage, message, onLongPress, onPress, onPressIn, preventPress } = - useMessageContext(); - const { ImageComponent } = useChatContext(); - const { additionalPressableProps, giphyVersion } = useMessagesContext(); - const { setMessages, setSelectedMessage } = useImageGalleryContext(); + useMessageContext(); + const { ImageComponent } = useChatContext(); + const { additionalPressableProps, giphyVersion } = useMessagesContext(); + const { setMessages, setSelectedMessage } = useImageGalleryContext(); const { setOverlay } = useOverlayContext(); const { ImageLoadingFailedIndicator: ContextImageLoadingFailedIndicator, ImageLoadingIndicator: ContextImageLoadingIndicator, - } = useMessagesContext(); + } = useMessagesContext(); const ImageLoadingFailedIndicator = ContextImageLoadingFailedIndicator || props.ImageLoadingFailedIndicator; const ImageLoadingIndicator = ContextImageLoadingIndicator || props.ImageLoadingIndicator; diff --git a/package/src/components/Attachment/utils/buildGallery/buildGallery.ts b/package/src/components/Attachment/utils/buildGallery/buildGallery.ts index dc2c6659c0..ad2622b0fb 100644 --- a/package/src/components/Attachment/utils/buildGallery/buildGallery.ts +++ b/package/src/components/Attachment/utils/buildGallery/buildGallery.ts @@ -12,7 +12,6 @@ import { chatConfigContextDefaultvalue, ChatConfigContextValue, } from '../../../../contexts/chatConfigContext/ChatConfigContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; /** * Builds and returns a gallery of optimized images to be rendered on UI. @@ -30,14 +29,12 @@ import type { DefaultStreamChatGenerics } from '../../../../types/types'; * * @return {GallerySizeAndThumbnailGrid} */ -export function buildGallery< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export function buildGallery({ images, resizableCDNHosts = chatConfigContextDefaultvalue.resizableCDNHosts, sizeConfig, }: Pick & { - images: Attachment[]; + images: Attachment[]; sizeConfig: GallerySizeConfig; }): GallerySizeAndThumbnailGrid { if (images.length === 1) { diff --git a/package/src/components/Attachment/utils/buildGallery/buildGalleryOfSingleImage.ts b/package/src/components/Attachment/utils/buildGallery/buildGalleryOfSingleImage.ts index f7a6a39c72..209d526645 100644 --- a/package/src/components/Attachment/utils/buildGallery/buildGalleryOfSingleImage.ts +++ b/package/src/components/Attachment/utils/buildGallery/buildGalleryOfSingleImage.ts @@ -5,7 +5,7 @@ import { buildThumbnail } from './buildThumbnail'; import type { GallerySizeAndThumbnailGrid, GallerySizeConfig } from './types'; import { ChatConfigContextValue } from '../../../../contexts/chatConfigContext/ChatConfigContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; + import { getAspectRatio } from '../getAspectRatio'; /** @@ -20,9 +20,13 @@ function clamp(number: number, min: number, max: number) { return Math.min(Math.max(number, min), max); } -function getContainerSize< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ image, sizeConfig }: { image: Attachment; sizeConfig: GallerySizeConfig }) { +function getContainerSize({ + image, + sizeConfig, +}: { + image: Attachment; + sizeConfig: GallerySizeConfig; +}) { const { original_height: height, original_width: width } = image; const { gridHeight, gridWidth, maxHeight, maxWidth, minHeight, minWidth } = sizeConfig; @@ -64,14 +68,12 @@ function getContainerSize< }; } -export function buildGalleryOfSingleImage< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export function buildGalleryOfSingleImage({ image, resizableCDNHosts, sizeConfig, }: Pick & { - image: Attachment; + image: Attachment; sizeConfig: GallerySizeConfig; }): GallerySizeAndThumbnailGrid { const container = getContainerSize({ diff --git a/package/src/components/Attachment/utils/buildGallery/buildGalleryOfThreeImages.ts b/package/src/components/Attachment/utils/buildGallery/buildGalleryOfThreeImages.ts index adbd7b5928..2f49e854d5 100644 --- a/package/src/components/Attachment/utils/buildGallery/buildGalleryOfThreeImages.ts +++ b/package/src/components/Attachment/utils/buildGallery/buildGalleryOfThreeImages.ts @@ -5,7 +5,7 @@ import { buildThumbnailGrid } from './buildThumbnailGrid'; import type { GallerySizeAndThumbnailGrid, GallerySizeConfig } from './types'; import { ChatConfigContextValue } from '../../../../contexts/chatConfigContext/ChatConfigContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; + import { getAspectRatio } from '../getAspectRatio'; /** function to move item to the front of the array */ @@ -20,14 +20,12 @@ function moveToFront(array: T[], item: T): T[] { return newArray; } -export function buildGalleryOfThreeImages< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export function buildGalleryOfThreeImages({ images, resizableCDNHosts, sizeConfig, }: Pick & { - images: Attachment[]; + images: Attachment[]; sizeConfig: GallerySizeConfig; }): GallerySizeAndThumbnailGrid { // Find the most ladscape and most portrait image. @@ -57,9 +55,9 @@ export function buildGalleryOfThreeImages< landscapeImageAspectRatio: 1, portraitImageAspectRatio: 1, } as { - landscapeImage: Attachment; + landscapeImage: Attachment; landscapeImageAspectRatio: number; - portraitImage: Attachment; + portraitImage: Attachment; portraitImageAspectRatio: number; }, ); diff --git a/package/src/components/Attachment/utils/buildGallery/buildGalleryOfTwoImages.ts b/package/src/components/Attachment/utils/buildGallery/buildGalleryOfTwoImages.ts index 1e30968584..7240aaed92 100644 --- a/package/src/components/Attachment/utils/buildGallery/buildGalleryOfTwoImages.ts +++ b/package/src/components/Attachment/utils/buildGallery/buildGalleryOfTwoImages.ts @@ -5,17 +5,15 @@ import { buildThumbnailGrid } from './buildThumbnailGrid'; import type { GallerySizeAndThumbnailGrid, GallerySizeConfig } from './types'; import { ChatConfigContextValue } from '../../../../contexts/chatConfigContext/ChatConfigContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; + import { getAspectRatio } from '../getAspectRatio'; -export function buildGalleryOfTwoImages< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export function buildGalleryOfTwoImages({ images, resizableCDNHosts, sizeConfig, }: Pick & { - images: Attachment[]; + images: Attachment[]; sizeConfig: GallerySizeConfig; }): GallerySizeAndThumbnailGrid { const aspectRatio1 = getAspectRatio(images[0]); diff --git a/package/src/components/Attachment/utils/buildGallery/buildThumbnail.ts b/package/src/components/Attachment/utils/buildGallery/buildThumbnail.ts index 0dbe2dd8ab..3132979a58 100644 --- a/package/src/components/Attachment/utils/buildGallery/buildThumbnail.ts +++ b/package/src/components/Attachment/utils/buildGallery/buildThumbnail.ts @@ -5,29 +5,24 @@ import type { Attachment } from 'stream-chat'; import type { Thumbnail } from './types'; import { ChatConfigContextValue } from '../../../../contexts/chatConfigContext/ChatConfigContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; import { getResizedImageUrl } from '../../../../utils/getResizedImageUrl'; import { getUrlOfImageAttachment } from '../../../../utils/getUrlOfImageAttachment'; -export type BuildThumbnailProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick & { +export type BuildThumbnailProps = Pick & { height: number; - image: Attachment; + image: Attachment; width: number; resizeMode?: ImageResizeMode; }; -export function buildThumbnail< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export function buildThumbnail({ height, image, resizableCDNHosts, resizeMode, width, -}: BuildThumbnailProps): Thumbnail { +}: BuildThumbnailProps): Thumbnail { const { original_height: originalImageHeight, original_width: originalImageWidth } = image; // Only resize if the original image is larger than the thumbnail container size. diff --git a/package/src/components/Attachment/utils/buildGallery/buildThumbnailGrid.ts b/package/src/components/Attachment/utils/buildGallery/buildThumbnailGrid.ts index 0a6f9e1e74..0b7e015fd7 100644 --- a/package/src/components/Attachment/utils/buildGallery/buildThumbnailGrid.ts +++ b/package/src/components/Attachment/utils/buildGallery/buildThumbnailGrid.ts @@ -5,8 +5,6 @@ import type { GallerySizeAndThumbnailGrid, GallerySizeConfig, ThumbnailGrid } fr import { ChatConfigContextValue } from '../../../../contexts/chatConfigContext/ChatConfigContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; - /** * Builds a grid of thumbnail images from image attachments. * This function take a object parameter with following properties: @@ -135,9 +133,7 @@ import type { DefaultStreamChatGenerics } from '../../../../types/types'; * * @return {GallerySizeAndThumbnailGrid} */ -export function buildThumbnailGrid< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export function buildThumbnailGrid({ grid, images, invertedDirections = false, @@ -145,7 +141,7 @@ export function buildThumbnailGrid< sizeConfig, }: Pick & { grid: number[][]; - images: Attachment[]; + images: Attachment[]; invertedDirections: boolean; sizeConfig: GallerySizeConfig; }): GallerySizeAndThumbnailGrid { diff --git a/package/src/components/Attachment/utils/getAspectRatio.ts b/package/src/components/Attachment/utils/getAspectRatio.ts index 86dceaa996..410a0d3cfc 100644 --- a/package/src/components/Attachment/utils/getAspectRatio.ts +++ b/package/src/components/Attachment/utils/getAspectRatio.ts @@ -1,6 +1,6 @@ import type { Attachment } from 'stream-chat'; -import { DefaultStreamChatGenerics, FileTypes } from '../../../types/types'; +import { FileTypes } from '../../../types/types'; /** * Returns the aspect ratio of an image attachment. @@ -8,9 +8,7 @@ import { DefaultStreamChatGenerics, FileTypes } from '../../../types/types'; * @param image Image attachment. * @returns {number} */ -export function getAspectRatio< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->(attachment: Attachment) { +export function getAspectRatio(attachment: Attachment) { if (!(attachment.type === FileTypes.Image || attachment.type === FileTypes.Video)) { throw new Error( 'getAspectRatio() can only be called on an image attachment or video thumbnail', diff --git a/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx b/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx index df602a0034..db0bd739c4 100644 --- a/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx +++ b/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx @@ -27,7 +27,7 @@ import { useTranslationContext, } from '../../contexts/translationContext/TranslationContext'; import type { Emoji } from '../../emoji-data'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { isCommandTrigger, isEmojiTrigger, @@ -51,11 +51,9 @@ const computeCaretPosition = (token: string, startOfTokenPosition: number) => const isCommand = (text: string) => text[0] === '/' && text.split(' ').length <= 1; -type AutoCompleteInputPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'giphyEnabled'> & +type AutoCompleteInputPropsWithContext = Pick & Pick< - MessageInputContextValue, + MessageInputContextValue, | 'additionalTextInputProps' | 'autoCompleteSuggestionsLimit' | 'giphyActive' @@ -69,10 +67,7 @@ type AutoCompleteInputPropsWithContext< | 'text' | 'triggerSettings' > & - Pick< - SuggestionsContextValue, - 'closeSuggestions' | 'openSuggestions' | 'updateSuggestions' - > & + Pick & Pick & { /** * This is currently passed in from MessageInput to avoid rerenders @@ -81,15 +76,9 @@ type AutoCompleteInputPropsWithContext< cooldownActive?: boolean; }; -export type AutoCompleteInputProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type AutoCompleteInputProps = Partial; -const AutoCompleteInputWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AutoCompleteInputPropsWithContext, -) => { +const AutoCompleteInputWithContext = (props: AutoCompleteInputPropsWithContext) => { const { additionalTextInputProps, autoCompleteSuggestionsLimit, @@ -160,7 +149,7 @@ const AutoCompleteInputWithContext = < const triggerSetting = triggerSettings[trigger]; if (triggerSetting) { await triggerSetting.dataProvider( - query as SuggestionUser['name'], + query as SuggestionUser['name'], text, (data, queryCallback) => { if (query === queryCallback) { @@ -182,7 +171,7 @@ const AutoCompleteInputWithContext = < const triggerSetting = triggerSettings[trigger]; if (triggerSetting) { await triggerSetting.dataProvider( - query as SuggestionCommand['name'], + query as SuggestionCommand['name'], text, (data, queryCallback) => { if (query !== queryCallback) { @@ -226,13 +215,7 @@ const AutoCompleteInputWithContext = < selectionEnd.current = end; }; - const onSelectSuggestion = ({ - item, - trigger, - }: { - item: Suggestion; - trigger: Trigger; - }) => { + const onSelectSuggestion = ({ item, trigger }: { item: Suggestion; trigger: Trigger }) => { if (!trigger || !triggerSettings[trigger]) { return; } @@ -434,9 +417,9 @@ const AutoCompleteInputWithContext = < ); }; -const areEqual = ( - prevProps: AutoCompleteInputPropsWithContext, - nextProps: AutoCompleteInputPropsWithContext, +const areEqual = ( + prevProps: AutoCompleteInputPropsWithContext, + nextProps: AutoCompleteInputPropsWithContext, ) => { const { cooldownActive: prevCooldownActive, @@ -479,12 +462,8 @@ const MemoizedAutoCompleteInput = React.memo( areEqual, ) as typeof AutoCompleteInputWithContext; -export const AutoCompleteInput = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AutoCompleteInputProps, -) => { - const { giphyEnabled } = useChannelContext(); +export const AutoCompleteInput = (props: AutoCompleteInputProps) => { + const { giphyEnabled } = useChannelContext(); const { additionalTextInputProps, autoCompleteSuggestionsLimit, @@ -498,9 +477,8 @@ export const AutoCompleteInput = < setInputBoxRef, text, triggerSettings, - } = useMessageInputContext(); - const { closeSuggestions, openSuggestions, updateSuggestions } = - useSuggestionsContext(); + } = useMessageInputContext(); + const { closeSuggestions, openSuggestions, updateSuggestions } = useSuggestionsContext(); const { t } = useTranslationContext(); return ( diff --git a/package/src/components/AutoCompleteInput/AutoCompleteSuggestionCommandIcon.tsx b/package/src/components/AutoCompleteInput/AutoCompleteSuggestionCommandIcon.tsx index fbd1dabf17..a1b155a9a6 100644 --- a/package/src/components/AutoCompleteInput/AutoCompleteSuggestionCommandIcon.tsx +++ b/package/src/components/AutoCompleteInput/AutoCompleteSuggestionCommandIcon.tsx @@ -4,7 +4,6 @@ import { StyleSheet, View } from 'react-native'; import type { SuggestionCommand } from '../../contexts/suggestionsContext/SuggestionsContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { Flag, GiphyIcon, Imgur, Lightning, Mute, Sound, UserAdd, UserDelete } from '../../icons'; -import type { DefaultStreamChatGenerics } from '../../types/types'; const styles = StyleSheet.create({ iconContainer: { @@ -17,12 +16,10 @@ const styles = StyleSheet.create({ }, }); -export const AutoCompleteSuggestionCommandIcon = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const AutoCompleteSuggestionCommandIcon = ({ name, }: { - name: SuggestionCommand['name']; + name: SuggestionCommand['name']; }) => { const { theme: { diff --git a/package/src/components/AutoCompleteInput/AutoCompleteSuggestionHeader.tsx b/package/src/components/AutoCompleteInput/AutoCompleteSuggestionHeader.tsx index 9c3579d4cb..b5233d93fd 100644 --- a/package/src/components/AutoCompleteInput/AutoCompleteSuggestionHeader.tsx +++ b/package/src/components/AutoCompleteInput/AutoCompleteSuggestionHeader.tsx @@ -7,11 +7,11 @@ import { useTranslationContext } from '../../contexts/translationContext/Transla import { Lightning } from '../../icons/Lightning'; import { Smile } from '../../icons/Smile'; -import type { DefaultStreamChatGenerics } from '../../types/types'; -export type AutoCompleteSuggestionHeaderPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'triggerType' | 'queryText'>; +export type AutoCompleteSuggestionHeaderPropsWithContext = Pick< + SuggestionsContextValue, + 'triggerType' | 'queryText' +>; const styles = StyleSheet.create({ container: { @@ -25,12 +25,10 @@ const styles = StyleSheet.create({ }, }); -const AutoCompleteSuggestionHeaderWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +const AutoCompleteSuggestionHeaderWithContext = ({ queryText, triggerType, -}: AutoCompleteSuggestionHeaderPropsWithContext) => { +}: AutoCompleteSuggestionHeaderPropsWithContext) => { const { t } = useTranslationContext(); const { theme: { @@ -68,9 +66,9 @@ const AutoCompleteSuggestionHeaderWithContext = < } }; -const areEqual = ( - prevProps: AutoCompleteSuggestionHeaderPropsWithContext, - nextProps: AutoCompleteSuggestionHeaderPropsWithContext, +const areEqual = ( + prevProps: AutoCompleteSuggestionHeaderPropsWithContext, + nextProps: AutoCompleteSuggestionHeaderPropsWithContext, ) => { const { queryText: prevQueryText, triggerType: prevType } = prevProps; const { queryText: nextQueryText, triggerType: nextType } = nextProps; @@ -92,15 +90,11 @@ const MemoizedAutoCompleteSuggestionHeader = React.memo( areEqual, ) as typeof AutoCompleteSuggestionHeaderWithContext; -export type AutoCompleteSuggestionHeaderProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = AutoCompleteSuggestionHeaderPropsWithContext; +export type AutoCompleteSuggestionHeaderProps = AutoCompleteSuggestionHeaderPropsWithContext; -export const AutoCompleteSuggestionHeader = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AutoCompleteSuggestionHeaderProps, -) => ; +export const AutoCompleteSuggestionHeader = (props: AutoCompleteSuggestionHeaderProps) => ( + +); AutoCompleteSuggestionHeader.displayName = 'AutoCompleteSuggestionHeader{messageInput{suggestions{Header}}}'; diff --git a/package/src/components/AutoCompleteInput/AutoCompleteSuggestionItem.tsx b/package/src/components/AutoCompleteInput/AutoCompleteSuggestionItem.tsx index 215a874933..0ae12208e0 100644 --- a/package/src/components/AutoCompleteInput/AutoCompleteSuggestionItem.tsx +++ b/package/src/components/AutoCompleteInput/AutoCompleteSuggestionItem.tsx @@ -12,13 +12,14 @@ import type { import { useTheme } from '../../contexts/themeContext/ThemeContext'; import type { Emoji } from '../../emoji-data'; import { AtMentions } from '../../icons/AtMentions'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { Avatar } from '../Avatar/Avatar'; -export type AutoCompleteSuggestionItemPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick & { - itemProps: Suggestion; +export type AutoCompleteSuggestionItemPropsWithContext = Pick< + SuggestionsContextValue, + 'triggerType' +> & { + itemProps: Suggestion; }; const styles = StyleSheet.create({ @@ -55,12 +56,10 @@ const styles = StyleSheet.create({ }, }); -const AutoCompleteSuggestionItemWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +const AutoCompleteSuggestionItemWithContext = ({ itemProps, triggerType, -}: AutoCompleteSuggestionItemPropsWithContext) => { +}: AutoCompleteSuggestionItemPropsWithContext) => { const { theme: { colors: { accent_blue, black, grey }, @@ -75,7 +74,7 @@ const AutoCompleteSuggestionItemWithContext = < } = useTheme(); if (triggerType === 'mention') { - const { id, image, name, online } = itemProps as SuggestionUser; + const { id, image, name, online } = itemProps as SuggestionUser; return ( @@ -100,7 +99,7 @@ const AutoCompleteSuggestionItemWithContext = < ); } else if (triggerType === 'command') { - const { args, name } = itemProps as SuggestionCommand; + const { args, name } = itemProps as SuggestionCommand; return ( @@ -117,9 +116,9 @@ const AutoCompleteSuggestionItemWithContext = < } }; -const areEqual = ( - prevProps: AutoCompleteSuggestionItemPropsWithContext, - nextProps: AutoCompleteSuggestionItemPropsWithContext, +const areEqual = ( + prevProps: AutoCompleteSuggestionItemPropsWithContext, + nextProps: AutoCompleteSuggestionItemPropsWithContext, ) => { const { itemProps: prevItemProps, triggerType: prevType } = prevProps; const { itemProps: nextItemProps, triggerType: nextType } = nextProps; @@ -139,15 +138,11 @@ const MemoizedAutoCompleteSuggestionItem = React.memo( areEqual, ) as typeof AutoCompleteSuggestionItemWithContext; -export type AutoCompleteSuggestionItemProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = AutoCompleteSuggestionItemPropsWithContext; +export type AutoCompleteSuggestionItemProps = AutoCompleteSuggestionItemPropsWithContext; -export const AutoCompleteSuggestionItem = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AutoCompleteSuggestionItemProps, -) => ; +export const AutoCompleteSuggestionItem = (props: AutoCompleteSuggestionItemProps) => ( + +); AutoCompleteSuggestionItem.displayName = 'AutoCompleteSuggestionItem{messageInput{suggestions{Item}}}'; diff --git a/package/src/components/AutoCompleteInput/AutoCompleteSuggestionList.tsx b/package/src/components/AutoCompleteInput/AutoCompleteSuggestionList.tsx index 2ccce9ec41..d2ec40e117 100644 --- a/package/src/components/AutoCompleteInput/AutoCompleteSuggestionList.tsx +++ b/package/src/components/AutoCompleteInput/AutoCompleteSuggestionList.tsx @@ -20,25 +20,23 @@ import { useSuggestionsContext, } from '../../contexts/suggestionsContext/SuggestionsContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; const AUTO_COMPLETE_SUGGESTION_LIST_HEADER_HEIGHT = 50; -type AutoCompleteSuggestionListComponentProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick & { +type AutoCompleteSuggestionListComponentProps = Pick< + SuggestionsContextValue, + 'queryText' | 'triggerType' +> & { active: boolean; - data: Suggestion[]; - onSelect: (item: Suggestion) => void; + data: Suggestion[]; + onSelect: (item: Suggestion) => void; }; -export type AutoCompleteSuggestionListPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick< - SuggestionsContextValue, +export type AutoCompleteSuggestionListPropsWithContext = Pick< + SuggestionsContextValue, 'AutoCompleteSuggestionHeader' | 'AutoCompleteSuggestionItem' > & - AutoCompleteSuggestionListComponentProps; + AutoCompleteSuggestionListComponentProps; const SuggestionsItem = (props: PressableProps) => { const { children, style: propsStyle, ...pressableProps } = props; @@ -57,10 +55,8 @@ const SuggestionsItem = (props: PressableProps) => { SuggestionsItem.displayName = 'SuggestionsHeader{messageInput{suggestions}}'; -export const AutoCompleteSuggestionListWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AutoCompleteSuggestionListPropsWithContext, +export const AutoCompleteSuggestionListWithContext = ( + props: AutoCompleteSuggestionListPropsWithContext, ) => { const [itemHeight, setItemHeight] = useState(0); const { @@ -98,7 +94,7 @@ export const AutoCompleteSuggestionListWithContext = < // eslint-disable-next-line react-hooks/exhaustive-deps }, [itemHeight, data.length]); - const renderItem = ({ item }: { item: Suggestion }) => { + const renderItem = ({ item }: { item: Suggestion }) => { switch (triggerType) { case 'command': case 'mention': @@ -145,9 +141,9 @@ export const AutoCompleteSuggestionListWithContext = < ); }; -const areEqual = ( - prevProps: AutoCompleteSuggestionListPropsWithContext, - nextProps: AutoCompleteSuggestionListPropsWithContext, +const areEqual = ( + prevProps: AutoCompleteSuggestionListPropsWithContext, + nextProps: AutoCompleteSuggestionListPropsWithContext, ) => { const { active: prevActive, @@ -190,22 +186,13 @@ const MemoizedAutoCompleteSuggestionList = React.memo( areEqual, ) as typeof AutoCompleteSuggestionListWithContext; -export type AutoCompleteSuggestionListProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = AutoCompleteSuggestionListComponentProps & { +export type AutoCompleteSuggestionListProps = AutoCompleteSuggestionListComponentProps & { AutoCompleteSuggestionHeader?: React.ComponentType; - AutoCompleteSuggestionItem?: React.ComponentType< - AutoCompleteSuggestionItemProps - >; + AutoCompleteSuggestionItem?: React.ComponentType; }; -export const AutoCompleteSuggestionList = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AutoCompleteSuggestionListProps, -) => { - const { AutoCompleteSuggestionHeader, AutoCompleteSuggestionItem } = - useSuggestionsContext(); +export const AutoCompleteSuggestionList = (props: AutoCompleteSuggestionListProps) => { + const { AutoCompleteSuggestionHeader, AutoCompleteSuggestionItem } = useSuggestionsContext(); return ( = Pick, 'channel'> & +export type ChannelPropsWithContext = Pick & Partial< Pick< - ChannelContextValue, + ChannelContextValue, | 'EmptyStateIndicator' | 'enableMessageGroupingByUser' | 'enforceUniqueReaction' @@ -260,30 +259,27 @@ export type ChannelPropsWithContext< | 'StickyHeader' > > & - Pick, 'client' | 'enableOfflineSupport'> & + Pick & Partial< Omit< - InputMessageInputContextValue, + InputMessageInputContextValue, 'quotedMessage' | 'editing' | 'clearEditingState' | 'clearQuotedMessageState' | 'sendMessage' > > & Partial< Pick< - SuggestionsContextValue, + SuggestionsContextValue, 'AutoCompleteSuggestionHeader' | 'AutoCompleteSuggestionItem' | 'AutoCompleteSuggestionList' > > & Pick & Partial< - Pick< - PaginatedMessageListContextValue, - 'messages' | 'loadingMore' | 'loadingMoreRecent' - > + Pick > & - Pick, 'threadMessages' | 'setThreadMessages'> & + Pick & Partial< Pick< - MessagesContextValue, + MessagesContextValue, | 'additionalPressableProps' | 'Attachment' | 'AttachmentActions' @@ -377,10 +373,10 @@ export type ChannelPropsWithContext< | 'StreamingMessageView' > > & - Partial, 'isMessageAIGenerated'>> & - Partial, 'allowThreadMessagesInChannel'>> & { + Partial> & + Partial> & { shouldSyncChannel: boolean; - thread: ThreadType; + thread: ThreadType; /** * Additional props passed to keyboard avoiding view */ @@ -399,7 +395,7 @@ export type ChannelPropsWithContext< * @param channel Channel object */ doMarkReadRequest?: ( - channel: ChannelType, + channel: ChannelType, setChannelUnreadUiState?: (state: ChannelUnreadState) => void, ) => void; /** @@ -409,8 +405,8 @@ export type ChannelPropsWithContext< */ doSendMessageRequest?: ( channelId: string, - messageData: StreamMessage, - ) => Promise>; + messageData: StreamMessage, + ) => Promise; /** * Overrides the Stream default update message request (Advanced usage only) * @param channelId @@ -418,8 +414,8 @@ export type ChannelPropsWithContext< */ doUpdateMessageRequest?: ( channelId: string, - updatedMessage: Parameters['updateMessage']>[0], - ) => ReturnType['updateMessage']>; + updatedMessage: Parameters[0], + ) => ReturnType; /** * When true, messageList will be scrolled at first unread message, when opened. */ @@ -477,11 +473,7 @@ export type ChannelPropsWithContext< > >; -const ChannelWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: PropsWithChildren>, -) => { +const ChannelWithContext = (props: PropsWithChildren) => { const { additionalKeyboardAvoidingViewProps, additionalPressableProps, @@ -692,13 +684,11 @@ const ChannelWithContext = < }, } = useTheme(); const [deleted, setDeleted] = useState(false); - const [editing, setEditing] = useState | undefined>(undefined); + const [editing, setEditing] = useState(undefined); const [error, setError] = useState(false); - const [lastRead, setLastRead] = useState['lastRead']>(); - const [quotedMessage, setQuotedMessage] = useState | undefined>( - undefined, - ); - const [thread, setThread] = useState | null>(threadProps || null); + const [lastRead, setLastRead] = useState(); + const [quotedMessage, setQuotedMessage] = useState(undefined); + const [thread, setThread] = useState(threadProps || null); const [threadHasMore, setThreadHasMore] = useState(true); const [threadLoadingMore, setThreadLoadingMore] = useState(false); const [channelUnreadState, setChannelUnreadState] = useState( @@ -725,7 +715,7 @@ const ChannelWithContext = < setRead, setTyping, state: channelState, - } = useChannelDataState(channel); + } = useChannelDataState(channel); const { copyMessagesStateFromChannel, @@ -736,7 +726,7 @@ const ChannelWithContext = < loadMore, loadMoreRecent, state: channelMessagesState, - } = useMessageListPagination({ + } = useMessageListPagination({ channel, }); @@ -764,7 +754,7 @@ const ChannelWithContext = < [channel, copyChannelStateThrottlingTime, copyMessagesStateFromChannel, copyStateFromChannel], ); - const handleEvent: EventHandler = (event) => { + const handleEvent: EventHandler = (event) => { if (shouldSyncChannel) { /** * Ignore user.watching.start and user.watching.stop as we should not copy the entire state when @@ -901,7 +891,7 @@ const ChannelWithContext = < * Subscription to the Notification mark_read event. */ useEffect(() => { - const handleEvent: EventHandler = (event) => { + const handleEvent: EventHandler = (event) => { if (channel.cid === event.cid) { setRead(channel); } @@ -926,14 +916,12 @@ const ChannelWithContext = < }, [threadPropsExists, shouldSyncChannel]); const handleAppBackground = useCallback(() => { - const channelData = channel.data as - | Extract - | undefined; + const channelData = channel.data; if (channelData?.own_capabilities?.includes('send-typing-events')) { channel.sendEvent({ parent_id: thread?.id, type: 'typing.stop', - } as StreamEvent); + } as StreamEvent); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [thread?.id, channelId]); @@ -943,7 +931,7 @@ const ChannelWithContext = < /** * CHANNEL METHODS */ - const markRead: ChannelContextValue['markRead'] = throttle( + const markRead: ChannelContextValue['markRead'] = throttle( async (options?: MarkReadFunctionOptions) => { const { updateChannelUnreadState = true } = options ?? {}; if (!channel || channel?.disconnected || !clientChannelConfig?.read_events) { @@ -1021,13 +1009,13 @@ const ChannelWithContext = < }); } - const parseMessage = (message: FormatMessageResponse) => + const parseMessage = (message: FormatMessageResponse) => ({ ...message, created_at: message.created_at.toString(), pinned_at: message.pinned_at?.toString(), updated_at: message.updated_at?.toString(), - }) as unknown as MessageResponse; + }) as unknown as MessageResponse; try { if (!thread) { @@ -1121,44 +1109,45 @@ const ChannelWithContext = < } }; - const loadChannelAroundMessage: ChannelContextValue['loadChannelAroundMessage'] = - async ({ messageId: messageIdToLoadAround }): Promise => { - if (!messageIdToLoadAround) { - return; - } - try { - if (thread) { - setThreadLoadingMore(true); - try { - await channel.state.loadMessageIntoState(messageIdToLoadAround, thread.id); - setThreadLoadingMore(false); - setThreadMessages(channel.state.threads[thread.id]); - if (setTargetedMessage) { - setTargetedMessage(messageIdToLoadAround); - } - } catch (err) { - if (err instanceof Error) { - setError(err); - } else { - setError(true); - } - setThreadLoadingMore(false); + const loadChannelAroundMessage: ChannelContextValue['loadChannelAroundMessage'] = async ({ + messageId: messageIdToLoadAround, + }): Promise => { + if (!messageIdToLoadAround) { + return; + } + try { + if (thread) { + setThreadLoadingMore(true); + try { + await channel.state.loadMessageIntoState(messageIdToLoadAround, thread.id); + setThreadLoadingMore(false); + setThreadMessages(channel.state.threads[thread.id]); + if (setTargetedMessage) { + setTargetedMessage(messageIdToLoadAround); } - } else { - await loadChannelAroundMessageFn({ - messageId: messageIdToLoadAround, - setTargetedMessage, - }); + } catch (err) { + if (err instanceof Error) { + setError(err); + } else { + setError(true); + } + setThreadLoadingMore(false); } - } catch (err) { - console.warn('Loading channel around message failed with error:', err); + } else { + await loadChannelAroundMessageFn({ + messageId: messageIdToLoadAround, + setTargetedMessage, + }); } - }; + } catch (err) { + console.warn('Loading channel around message failed with error:', err); + } + }; /** * MESSAGE METHODS */ - const updateMessage: MessagesContextValue['updateMessage'] = ( + const updateMessage: MessagesContextValue['updateMessage'] = ( updatedMessage, extraState = {}, ) => { @@ -1175,10 +1164,7 @@ const ChannelWithContext = < } }; - const replaceMessage = ( - oldMessage: MessageResponse, - newMessage: MessageResponse, - ) => { + const replaceMessage = (oldMessage: MessageResponse, newMessage: MessageResponse) => { if (channel) { channel.state.removeMessage(oldMessage); channel.state.addMessageSorted(newMessage, true); @@ -1195,11 +1181,10 @@ const ChannelWithContext = < attachments, mentioned_users, parent_id, - poll, poll_id, text, ...extraFields - }: Partial>) => { + }: Partial) => { // Exclude following properties from message.user within message preview, // since they could be long arrays and have no meaning as sender of message. // Storing such large value within user's table may cause sqlite queries to crash. @@ -1218,7 +1203,6 @@ const ChannelWithContext = < id: userId, })) || [], parent_id, - poll, poll_id, reactions: [], status: MessageStatusTypes.SENDING, @@ -1229,7 +1213,7 @@ const ChannelWithContext = < id: client.userID, }, ...extraFields, - } as unknown as MessageResponse; + } as unknown as MessageResponse; /** * This is added to the message for local rendering prior to the message @@ -1241,13 +1225,12 @@ const ChannelWithContext = < (message) => message.id === preview.quoted_message_id, ); - preview.quoted_message = - quotedMessage as MessageResponse['quoted_message']; + preview.quoted_message = quotedMessage as MessageResponse['quoted_message']; } return preview; }; - const uploadPendingAttachments = async (message: MessageResponse) => { + const uploadPendingAttachments = async (message: MessageResponse) => { const updatedMessage = { ...message }; if (updatedMessage.attachments?.length) { for (let i = 0; i < updatedMessage.attachments?.length; i++) { @@ -1317,10 +1300,7 @@ const ChannelWithContext = < return updatedMessage; }; - const sendMessageRequest = async ( - message: MessageResponse, - retrying?: boolean, - ) => { + const sendMessageRequest = async (message: MessageResponse, retrying?: boolean) => { try { const updatedMessage = await uploadPendingAttachments(message); const extraFields = omit(updatedMessage, [ @@ -1358,9 +1338,9 @@ const ChannelWithContext = < parent_id, text: patchMessageTextCommand(text ?? '', mentionedUserIds), ...extraFields, - } as StreamMessage; + } as StreamMessage; - let messageResponse = {} as SendMessageAPIResponse; + let messageResponse = {} as SendMessageAPIResponse; if (doSendMessageRequest) { messageResponse = await doSendMessageRequest(channel?.cid || '', messageData); } else if (channel) { @@ -1398,9 +1378,7 @@ const ChannelWithContext = < } }; - const sendMessage: InputMessageInputContextValue['sendMessage'] = async ( - message, - ) => { + const sendMessage: InputMessageInputContextValue['sendMessage'] = async (message) => { if (channel?.state?.filterErrorMessages) { channel.state.filterErrorMessages(); } @@ -1429,9 +1407,7 @@ const ChannelWithContext = < await sendMessageRequest(messagePreview); }; - const retrySendMessage: MessagesContextValue['retrySendMessage'] = async ( - message, - ) => { + const retrySendMessage: MessagesContextValue['retrySendMessage'] = async (message) => { const statusPendingMessage = { ...message, status: MessageStatusTypes.SENDING, @@ -1441,47 +1417,38 @@ const ChannelWithContext = < // For bounced messages, we don't need to update the message, instead always send a new message. if (!isBouncedMessage(message)) { - updateMessage(messageWithoutReservedFields as MessageResponse); + updateMessage(messageWithoutReservedFields as MessageResponse); } - await sendMessageRequest( - messageWithoutReservedFields as MessageResponse, - true, - ); + await sendMessageRequest(messageWithoutReservedFields as MessageResponse, true); }; - const editMessage: InputMessageInputContextValue['editMessage'] = ( - updatedMessage, - ) => + const editMessage: InputMessageInputContextValue['editMessage'] = (updatedMessage) => doUpdateMessageRequest ? doUpdateMessageRequest(channel?.cid || '', updatedMessage) : client.updateMessage(updatedMessage); - const setEditingState: MessagesContextValue['setEditingState'] = ( - message, - ) => { + const setEditingState: MessagesContextValue['setEditingState'] = (message) => { clearQuotedMessageState(); setEditing(message); }; - const setQuotedMessageState: MessagesContextValue['setQuotedMessageState'] = ( + const setQuotedMessageState: MessagesContextValue['setQuotedMessageState'] = ( messageOrBoolean, ) => { setQuotedMessage(messageOrBoolean); }; - const clearEditingState: InputMessageInputContextValue['clearEditingState'] = - () => setEditing(undefined); + const clearEditingState: InputMessageInputContextValue['clearEditingState'] = () => + setEditing(undefined); - const clearQuotedMessageState: InputMessageInputContextValue['clearQuotedMessageState'] = - () => setQuotedMessage(undefined); + const clearQuotedMessageState: InputMessageInputContextValue['clearQuotedMessageState'] = () => + setQuotedMessage(undefined); /** * Removes the message from local state */ - const removeMessage: MessagesContextValue['removeMessage'] = async ( - message, - ) => { + const removeMessage: MessagesContextValue['removeMessage'] = async (message) => { if (channel) { channel.state.removeMessage(message); copyMessagesStateFromChannel(channel); @@ -1503,11 +1470,11 @@ const ChannelWithContext = < throw new Error('Channel has not been initialized'); } - const payload: Parameters['sendReaction']> = [ + const payload: Parameters = [ messageId, { type, - } as Reaction, + } as Reaction, { enforce_unique: enforceUniqueReaction }, ]; @@ -1516,7 +1483,7 @@ const ChannelWithContext = < return; } - addReactionToLocalState({ + addReactionToLocalState({ channel, enforceUniqueReaction, messageId, @@ -1526,7 +1493,7 @@ const ChannelWithContext = < copyMessagesStateFromChannel(channel); - const sendReactionResponse = await DBSyncManager.queueTask({ + const sendReactionResponse = await DBSyncManager.queueTask({ client, task: { channelId: channel.id, @@ -1541,9 +1508,7 @@ const ChannelWithContext = < } }; - const deleteMessage: MessagesContextValue['deleteMessage'] = async ( - message, - ) => { + const deleteMessage: MessagesContextValue['deleteMessage'] = async (message) => { if (!channel.id) { throw new Error('Channel has not been initialized yet'); } @@ -1565,13 +1530,13 @@ const ChannelWithContext = < ...message, cid: channel.cid, deleted_at: new Date().toISOString(), - type: 'deleted', + type: 'deleted' as MessageLabel, }; updateMessage(updatedMessage); threadInstance?.upsertReplyLocally({ message: updatedMessage }); - const data = await DBSyncManager.queueTask({ + const data = await DBSyncManager.queueTask({ client, task: { channelId: channel.id, @@ -1588,7 +1553,7 @@ const ChannelWithContext = < } }; - const deleteReaction: MessagesContextValue['deleteReaction'] = async ( + const deleteReaction: MessagesContextValue['deleteReaction'] = async ( type: string, messageId: string, ) => { @@ -1612,7 +1577,7 @@ const ChannelWithContext = < copyMessagesStateFromChannel(channel); - await DBSyncManager.queueTask({ + await DBSyncManager.queueTask({ client, task: { channelId: channel.id, @@ -1627,7 +1592,7 @@ const ChannelWithContext = < /** * THREAD METHODS */ - const openThread: ThreadContextValue['openThread'] = useCallback( + const openThread: ThreadContextValue['openThread'] = useCallback( (message) => { setThread(message); @@ -1643,7 +1608,7 @@ const ChannelWithContext = < [channel, setThread], ); - const closeThread: ThreadContextValue['closeThread'] = useCallback(() => { + const closeThread: ThreadContextValue['closeThread'] = useCallback(() => { setThread(null); setThreadMessages([]); }, [setThread, setThreadMessages]); @@ -1651,10 +1616,7 @@ const ChannelWithContext = < // hard limit to prevent you from scrolling faster than 1 page per 2 seconds const loadMoreThreadFinished = useRef( debounce( - ( - newThreadHasMore: boolean, - updatedThreadMessages: ChannelState['threads'][string], - ) => { + (newThreadHasMore: boolean, updatedThreadMessages: ChannelState['threads'][string]) => { setThreadHasMore(newThreadHasMore); setThreadLoadingMore(false); setThreadMessages(updatedThreadMessages); @@ -1664,7 +1626,7 @@ const ChannelWithContext = < ), ).current; - const loadMoreThread: ThreadContextValue['loadMoreThread'] = async () => { + const loadMoreThread: ThreadContextValue['loadMoreThread'] = async () => { if (threadLoadingMore || !thread?.id) { return; } @@ -1710,7 +1672,7 @@ const ChannelWithContext = < overrideCapabilities: overrideOwnCapabilities, }); - const channelContext = useCreateChannelContext({ + const channelContext = useCreateChannelContext({ channel, channelUnreadState, disabled: !!channel?.data?.frozen, @@ -1755,11 +1717,10 @@ const ChannelWithContext = < // but it is definitely not trivial, especially considering it depends on other inline functions that // are not wrapped in a useCallback() themselves hence creating a huge cascading change. Can be removed // once our memoization issues are fixed in most places in the app or we move to a reactive state store. - const sendMessageRef = - useRef['sendMessage']>(sendMessage); + const sendMessageRef = useRef(sendMessage); sendMessageRef.current = sendMessage; - const inputMessageInputContext = useCreateInputMessageInputContext({ + const inputMessageInputContext = useCreateInputMessageInputContext({ additionalTextInputProps, asyncMessagesLockDistance, asyncMessagesMinimumPressDuration, @@ -1992,14 +1953,14 @@ const ChannelWithContext = < keyboardVerticalOffset={keyboardVerticalOffset} {...additionalKeyboardAvoidingViewProps} > - value={channelContext}> + - value={typingContext}> - value={messageListContext}> - value={messagesContext}> - value={threadContext}> - value={suggestionsContext}> - value={inputMessageInputContext}> + + + + + + {children} @@ -2013,11 +1974,9 @@ const ChannelWithContext = < ); }; -export type ChannelProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial, 'channel' | 'thread'>> & - Pick, 'channel'> & { - thread?: MessageType | ThreadType | null; +export type ChannelProps = Partial> & + Pick & { + thread?: MessageType | ThreadType | null; }; /** @@ -2028,35 +1987,30 @@ export type ChannelProps< * * @example ./Channel.md */ -export const Channel = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: PropsWithChildren>, -) => { - const { client, enableOfflineSupport, isMessageAIGenerated } = - useChatContext(); +export const Channel = (props: PropsWithChildren) => { + const { client, enableOfflineSupport, isMessageAIGenerated } = useChatContext(); const { t } = useTranslationContext(); const threadFromProps = props?.thread; + const threadInstance = (threadFromProps as ThreadType)?.threadInstance as Thread; const threadMessage = ( - threadFromProps?.threadInstance ? threadFromProps.thread : threadFromProps - ) as MessageType; - const threadInstance = threadFromProps?.threadInstance as Thread; + threadInstance ? (threadFromProps as ThreadType).thread : threadFromProps + ) as MessageType; - const thread: ThreadType = { + const thread: ThreadType = { thread: threadMessage, threadInstance, }; const shouldSyncChannel = threadMessage?.id ? !!props.threadList : true; - const { setThreadMessages, threadMessages } = useChannelState( + const { setThreadMessages, threadMessages } = useChannelState( props.channel, props.threadList ? threadMessage?.id : undefined, ); return ( - + = { +export type ChannelMessagesState = { hasMore?: boolean; hasMoreNewer?: boolean; loading?: boolean; loadingMore?: boolean; loadingMoreRecent?: boolean; - messages?: StreamChannelState['messages']; - pinnedMessages?: StreamChannelState['pinnedMessages']; + messages?: StreamChannelState['messages']; + pinnedMessages?: StreamChannelState['pinnedMessages']; targetedMessageId?: string; }; /** * The ChannelThreadState object */ -export type ChannelThreadState< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - thread: MessageType | null; +export type ChannelThreadState = { + thread: MessageType | null; threadHasMore?: boolean; threadLoadingMore?: boolean; - threadMessages?: StreamChannelState['messages']; + threadMessages?: StreamChannelState['messages']; }; /** * The ChannelState object */ -export type ChannelState< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = ChannelMessagesState & { - members?: StreamChannelState['members']; - read?: StreamChannelState['read']; - typing?: StreamChannelState['typing']; +export type ChannelState = ChannelMessagesState & { + members?: StreamChannelState['members']; + read?: StreamChannelState['read']; + typing?: StreamChannelState['typing']; watcherCount?: number; - watchers?: StreamChannelState['watchers']; + watchers?: StreamChannelState['watchers']; }; /** * The useChannelMessageDataState hook that handles the state for the channel messages. */ -export const useChannelMessageDataState = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, -) => { - const [state, setState] = useState>({ +export const useChannelMessageDataState = (channel: Channel) => { + const [state, setState] = useState({ hasMore: true, hasMoreNewer: false, loading: false, @@ -81,7 +70,7 @@ export const useChannelMessageDataState = < targetedMessageId: undefined, }); - const copyMessagesStateFromChannel = useCallback((channel: Channel) => { + const copyMessagesStateFromChannel = useCallback((channel: Channel) => { setState((prev) => ({ ...prev, messages: [...channel.state.messages], @@ -89,18 +78,15 @@ export const useChannelMessageDataState = < })); }, []); - const loadInitialMessagesStateFromChannel = useCallback( - (channel: Channel, hasMore: boolean) => { - setState((prev) => ({ - ...prev, - hasMore, - loading: false, - messages: [...channel.state.messages], - pinnedMessages: [...channel.state.pinnedMessages], - })); - }, - [], - ); + const loadInitialMessagesStateFromChannel = useCallback((channel: Channel, hasMore: boolean) => { + setState((prev) => ({ + ...prev, + hasMore, + loading: false, + messages: [...channel.state.messages], + pinnedMessages: [...channel.state.pinnedMessages], + })); + }, []); const jumpToLatestMessage = useCallback(() => { setState((prev) => ({ @@ -120,17 +106,14 @@ export const useChannelMessageDataState = < })); }, []); - const loadMoreFinished = useCallback( - (hasMore: boolean, messages: ChannelState['messages']) => { - setState((prev) => ({ - ...prev, - hasMore, - loadingMore: false, - messages, - })); - }, - [], - ); + const loadMoreFinished = useCallback((hasMore: boolean, messages: ChannelState['messages']) => { + setState((prev) => ({ + ...prev, + hasMore, + loadingMore: false, + messages, + })); + }, []); const setLoadingMore = useCallback((loadingMore: boolean) => { setState((prev) => ({ @@ -154,7 +137,7 @@ export const useChannelMessageDataState = < }, []); const loadMoreRecentFinished = useCallback( - (hasMoreNewer: boolean, messages: ChannelState['messages']) => { + (hasMoreNewer: boolean, messages: ChannelState['messages']) => { setState((prev) => ({ ...prev, hasMoreNewer, @@ -182,12 +165,8 @@ export const useChannelMessageDataState = < /** * The useChannelThreadState hook that handles the state for the channel member, read, typing, watchers, etc. */ -export const useChannelDataState = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, -) => { - const [state, setState] = useState>({ +export const useChannelDataState = (channel: Channel) => { + const [state, setState] = useState({ members: channel.state.members, read: channel.state.read, typing: {}, @@ -196,7 +175,7 @@ export const useChannelDataState = < }); const initStateFromChannel = useCallback( - (channel: Channel) => { + (channel: Channel) => { setState({ ...state, members: { ...channel.state.members }, @@ -209,7 +188,7 @@ export const useChannelDataState = < [state], ); - const copyStateFromChannel = useCallback((channel: Channel) => { + const copyStateFromChannel = useCallback((channel: Channel) => { setState((prev) => ({ ...prev, members: { ...channel.state.members }, @@ -219,14 +198,14 @@ export const useChannelDataState = < })); }, []); - const setRead = useCallback((channel: Channel) => { + const setRead = useCallback((channel: Channel) => { setState((prev) => ({ ...prev, read: { ...channel.state.read }, // Synchronize the read state from the channel })); }, []); - const setTyping = useCallback((channel: Channel) => { + const setTyping = useCallback((channel: Channel) => { setState((prev) => ({ ...prev, typing: { ...channel.state.typing }, // Synchronize the typing state from the channel diff --git a/package/src/components/Channel/hooks/useCreateChannelContext.ts b/package/src/components/Channel/hooks/useCreateChannelContext.ts index 8b42af61b8..28549db215 100644 --- a/package/src/components/Channel/hooks/useCreateChannelContext.ts +++ b/package/src/components/Channel/hooks/useCreateChannelContext.ts @@ -1,11 +1,8 @@ import { useMemo } from 'react'; import type { ChannelContextValue } from '../../../contexts/channelContext/ChannelContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; -export const useCreateChannelContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useCreateChannelContext = ({ channel, channelUnreadState, disabled, @@ -39,7 +36,7 @@ export const useCreateChannelContext = < uploadAbortControllerRef, watcherCount, watchers, -}: ChannelContextValue) => { +}: ChannelContextValue) => { const channelId = channel?.id; const lastReadTime = lastRead?.getTime(); const membersLength = Object.keys(members).length; @@ -49,7 +46,7 @@ export const useCreateChannelContext = < const readUsersLastReads = readUsers.map(({ last_read }) => last_read.toISOString()).join(); const stringifiedChannelUnreadState = JSON.stringify(channelUnreadState); - const channelContext: ChannelContextValue = useMemo( + const channelContext: ChannelContextValue = useMemo( () => ({ channel, channelUnreadState, diff --git a/package/src/components/Channel/hooks/useCreateInputMessageInputContext.ts b/package/src/components/Channel/hooks/useCreateInputMessageInputContext.ts index 949e8cf852..80e9154f94 100644 --- a/package/src/components/Channel/hooks/useCreateInputMessageInputContext.ts +++ b/package/src/components/Channel/hooks/useCreateInputMessageInputContext.ts @@ -1,11 +1,8 @@ import { useMemo } from 'react'; import type { InputMessageInputContextValue } from '../../../contexts/messageInputContext/MessageInputContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; -export const useCreateInputMessageInputContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useCreateInputMessageInputContext = ({ additionalTextInputProps, asyncMessagesLockDistance, asyncMessagesMinimumPressDuration, @@ -66,7 +63,7 @@ export const useCreateInputMessageInputContext = < StartAudioRecordingButton, StopMessageStreamingButton, UploadProgressIndicator, -}: InputMessageInputContextValue & { +}: InputMessageInputContextValue & { /** * To ensure we allow re-render, when channel is changed */ @@ -75,7 +72,7 @@ export const useCreateInputMessageInputContext = < const editingDep = editing ? editing.id : ''; const quotedMessageId = quotedMessage ? quotedMessage.id : ''; - const inputMessageInputContext: InputMessageInputContextValue = useMemo( + const inputMessageInputContext: InputMessageInputContextValue = useMemo( () => ({ additionalTextInputProps, asyncMessagesLockDistance, diff --git a/package/src/components/Channel/hooks/useCreateMessagesContext.ts b/package/src/components/Channel/hooks/useCreateMessagesContext.ts index c9f04578a6..2306739d2d 100644 --- a/package/src/components/Channel/hooks/useCreateMessagesContext.ts +++ b/package/src/components/Channel/hooks/useCreateMessagesContext.ts @@ -1,11 +1,8 @@ import { useMemo } from 'react'; import type { MessagesContextValue } from '../../../contexts/messagesContext/MessagesContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; -export const useCreateMessagesContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useCreateMessagesContext = ({ additionalPressableProps, Attachment, AttachmentActions, @@ -111,7 +108,7 @@ export const useCreateMessagesContext = < updateMessage, UrlPreview, VideoThumbnail, -}: MessagesContextValue & { +}: MessagesContextValue & { /** * To ensure we allow re-render, when channel is changed */ @@ -122,7 +119,7 @@ export const useCreateMessagesContext = < const messageContentOrderValue = messageContentOrder.join(); const supportedReactionsLength = supportedReactions?.length; - const messagesContext: MessagesContextValue = useMemo( + const messagesContext: MessagesContextValue = useMemo( () => ({ additionalPressableProps, Attachment, diff --git a/package/src/components/Channel/hooks/useCreateOwnCapabilitiesContext.ts b/package/src/components/Channel/hooks/useCreateOwnCapabilitiesContext.ts index 2446129f26..4d5236656a 100644 --- a/package/src/components/Channel/hooks/useCreateOwnCapabilitiesContext.ts +++ b/package/src/components/Channel/hooks/useCreateOwnCapabilitiesContext.ts @@ -7,15 +7,12 @@ import { OwnCapabilitiesContextValue, OwnCapability, } from '../../../contexts/ownCapabilitiesContext/OwnCapabilitiesContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; -export const useCreateOwnCapabilitiesContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useCreateOwnCapabilitiesContext = ({ channel, overrideCapabilities, }: { - channel: Channel; + channel: Channel; overrideCapabilities?: Partial; }) => { const [own_capabilities, setOwnCapabilites] = useState( diff --git a/package/src/components/Channel/hooks/useCreatePaginatedMessageListContext.ts b/package/src/components/Channel/hooks/useCreatePaginatedMessageListContext.ts index 1e8e46a613..920175183a 100644 --- a/package/src/components/Channel/hooks/useCreatePaginatedMessageListContext.ts +++ b/package/src/components/Channel/hooks/useCreatePaginatedMessageListContext.ts @@ -1,12 +1,10 @@ import { useMemo } from 'react'; import type { PaginatedMessageListContextValue } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { reduceMessagesToString } from '../../../utils/utils'; -export const useCreatePaginatedMessageListContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useCreatePaginatedMessageListContext = ({ channelId, hasMore, loadingMore, @@ -17,12 +15,12 @@ export const useCreatePaginatedMessageListContext = < messages, setLoadingMore, setLoadingMoreRecent, -}: PaginatedMessageListContextValue & { +}: PaginatedMessageListContextValue & { channelId?: string; }) => { const messagesStr = reduceMessagesToString(messages); - const paginatedMessagesContext: PaginatedMessageListContextValue = useMemo( + const paginatedMessagesContext: PaginatedMessageListContextValue = useMemo( () => ({ hasMore, loadingMore, diff --git a/package/src/components/Channel/hooks/useCreateThreadContext.ts b/package/src/components/Channel/hooks/useCreateThreadContext.ts index 098a9a814a..43addaafe8 100644 --- a/package/src/components/Channel/hooks/useCreateThreadContext.ts +++ b/package/src/components/Channel/hooks/useCreateThreadContext.ts @@ -2,7 +2,6 @@ import { ThreadState } from 'stream-chat'; import type { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext'; import { useStateStore } from '../../../hooks'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; const selector = (nextValue: ThreadState) => ({ @@ -11,9 +10,7 @@ const selector = (nextValue: ThreadState) => latestReplies: nextValue.replies, }) as const; -export const useCreateThreadContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useCreateThreadContext = ({ allowThreadMessagesInChannel, closeThread, loadMoreThread, @@ -25,7 +22,7 @@ export const useCreateThreadContext = < threadInstance, threadLoadingMore, threadMessages, -}: ThreadContextValue) => { +}: ThreadContextValue) => { const { isLoadingNext, isLoadingPrev, latestReplies } = useStateStore(threadInstance?.state, selector) ?? {}; diff --git a/package/src/components/Channel/hooks/useCreateTypingContext.ts b/package/src/components/Channel/hooks/useCreateTypingContext.ts index 1205bf9e4d..960177b8de 100644 --- a/package/src/components/Channel/hooks/useCreateTypingContext.ts +++ b/package/src/components/Channel/hooks/useCreateTypingContext.ts @@ -1,16 +1,11 @@ import { useMemo } from 'react'; import type { TypingContextValue } from '../../../contexts/typingContext/TypingContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; -export const useCreateTypingContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - typing, -}: TypingContextValue) => { +export const useCreateTypingContext = ({ typing }: TypingContextValue) => { const typingValue = Object.keys(typing).join(); - const typingContext: TypingContextValue = useMemo( + const typingContext: TypingContextValue = useMemo( () => ({ typing, }), diff --git a/package/src/components/Channel/hooks/useMessageListPagination.tsx b/package/src/components/Channel/hooks/useMessageListPagination.tsx index 7f4e2a07f5..aea4184df8 100644 --- a/package/src/components/Channel/hooks/useMessageListPagination.tsx +++ b/package/src/components/Channel/hooks/useMessageListPagination.tsx @@ -6,7 +6,6 @@ import { Channel, ChannelState, MessageResponse } from 'stream-chat'; import { useChannelMessageDataState } from './useChannelDataState'; import { ChannelContextValue } from '../../../contexts/channelContext/ChannelContext'; -import { DefaultStreamChatGenerics } from '../../../types/types'; import { findInMessagesByDate, findInMessagesById } from '../../../utils/utils'; const defaultDebounceInterval = 500; @@ -21,13 +20,7 @@ const debounceOptions = { * * @param channel The channel object for which the message list pagination is being handled. */ -export const useMessageListPagination = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - channel, -}: { - channel: Channel; -}) => { +export const useMessageListPagination = ({ channel }: { channel: Channel }) => { const { copyMessagesStateFromChannel, jumpToLatestMessage, @@ -39,12 +32,12 @@ export const useMessageListPagination = < setLoadingMore, setLoadingMoreRecent, state, - } = useChannelMessageDataState(channel); + } = useChannelMessageDataState(channel); // hard limit to prevent you from scrolling faster than 1 page per 2 seconds const loadMoreFinished = useRef( debounce( - (hasMore: boolean, messages: ChannelState['messages']) => { + (hasMore: boolean, messages: ChannelState['messages']) => { loadMoreFinishedFn(hasMore, messages); }, defaultDebounceInterval, @@ -55,7 +48,7 @@ export const useMessageListPagination = < // hard limit to prevent you from scrolling faster than 1 page per 2 seconds const loadMoreRecentFinished = useRef( debounce( - (hasMore: boolean, newMessages: ChannelState['messages']) => { + (hasMore: boolean, newMessages: ChannelState['messages']) => { loadMoreRecentFinishedFn(hasMore, newMessages); }, defaultDebounceInterval, @@ -140,42 +133,43 @@ export const useMessageListPagination = < * * @param messageId If undefined, channel will be loaded at most recent message. */ - const loadChannelAroundMessage: ChannelContextValue['loadChannelAroundMessage'] = - async ({ limit = 25, messageId: messageIdToLoadAround, setTargetedMessage }) => { - if (!messageIdToLoadAround) { - return; - } - setLoadingMore(true); - setLoading(true); - try { - await channel.state.loadMessageIntoState(messageIdToLoadAround, undefined, limit); - loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages); - jumpToMessageFinished(channel.state.messagePagination.hasNext, messageIdToLoadAround); + const loadChannelAroundMessage: ChannelContextValue['loadChannelAroundMessage'] = async ({ + limit = 25, + messageId: messageIdToLoadAround, + setTargetedMessage, + }) => { + if (!messageIdToLoadAround) { + return; + } + setLoadingMore(true); + setLoading(true); + try { + await channel.state.loadMessageIntoState(messageIdToLoadAround, undefined, limit); + loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages); + jumpToMessageFinished(channel.state.messagePagination.hasNext, messageIdToLoadAround); - if (setTargetedMessage) { - setTargetedMessage(messageIdToLoadAround); - } - } catch (error) { - setLoadingMore(false); - setLoading(false); - console.warn( - 'Message pagination(fetching messages in the channel around a message id) request failed with error:', - error, - ); - return; + if (setTargetedMessage) { + setTargetedMessage(messageIdToLoadAround); } - }; + } catch (error) { + setLoadingMore(false); + setLoading(false); + console.warn( + 'Message pagination(fetching messages in the channel around a message id) request failed with error:', + error, + ); + return; + } + }; /** * Fetch messages around a specific timestamp. */ - const fetchMessagesAround = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, - >( - channel: Channel, + const fetchMessagesAround = async ( + channel: Channel, timestamp: string, limit: number, - ): Promise[]> => { + ): Promise => { try { const { messages } = await channel.query( { messages: { created_at_around: timestamp, limit } }, @@ -191,7 +185,7 @@ export const useMessageListPagination = < /** * Loads channel at first unread message. */ - const loadChannelAtFirstUnreadMessage: ChannelContextValue['loadChannelAtFirstUnreadMessage'] = + const loadChannelAtFirstUnreadMessage: ChannelContextValue['loadChannelAtFirstUnreadMessage'] = async ({ channelUnreadState, limit = 25, setChannelUnreadState, setTargetedMessage }) => { try { if (!channelUnreadState?.unread_messages) { diff --git a/package/src/components/ChannelList/ChannelList.tsx b/package/src/components/ChannelList/ChannelList.tsx index 833aebe111..0d9db694f4 100644 --- a/package/src/components/ChannelList/ChannelList.tsx +++ b/package/src/components/ChannelList/ChannelList.tsx @@ -21,16 +21,14 @@ import { } from '../../contexts/channelsContext/ChannelsContext'; import { useChatContext } from '../../contexts/chatContext/ChatContext'; import { upsertCidsForQuery } from '../../store/apis/upsertCidsForQuery'; -import type { ChannelListEventListenerOptions, DefaultStreamChatGenerics } from '../../types/types'; +import type { ChannelListEventListenerOptions } from '../../types/types'; import { ChannelPreviewMessenger } from '../ChannelPreview/ChannelPreviewMessenger'; import { EmptyStateIndicator as EmptyStateIndicatorDefault } from '../Indicators/EmptyStateIndicator'; import { LoadingErrorIndicator as LoadingErrorIndicatorDefault } from '../Indicators/LoadingErrorIndicator'; -export type ChannelListProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial< +export type ChannelListProps = Partial< Pick< - ChannelsContextValue, + ChannelsContextValue, | 'additionalFlatListProps' | 'EmptyStateIndicator' | 'FooterLoadingIndicator' @@ -55,9 +53,7 @@ export type ChannelListProps< > > & { /** Optional function to filter channels prior to rendering the list. Do not use any complex logic that would delay the loading of the ChannelList. We recommend using a pure function with array methods like filter/sort/reduce. */ - channelRenderFilterFn?: ( - channels: Array>, - ) => Array>; + channelRenderFilterFn?: (channels: Array) => Array; /** * Object containing channel query filters * @@ -65,13 +61,13 @@ export type ChannelListProps< * * @overrideType object * */ - filters?: ChannelFilters; + filters?: ChannelFilters; /** * Custom UI component to display the list of channels * * Default: [ChannelListMessenger](https://getstream.io/chat/docs/sdk/reactnative/ui-components/channel-list-messenger/) */ - List?: React.ComponentType>; + List?: React.ComponentType; /** * If set to true, channels won't dynamically sort by most recent message, defaults to false */ @@ -87,9 +83,9 @@ export type ChannelListProps< * @overrideType Function * */ onAddedToChannel?: ( - setChannels: React.Dispatch[]>>, - event: Event, - options?: ChannelListEventListenerOptions, + setChannels: React.Dispatch>, + event: Event, + options?: ChannelListEventListenerOptions, ) => void; /** * Function that overrides default behavior when a channel gets deleted. In absence of this prop, the channel will be removed from the list. @@ -100,8 +96,8 @@ export type ChannelListProps< * @overrideType Function * */ onChannelDeleted?: ( - setChannels: React.Dispatch[]>>, - event: Event, + setChannels: React.Dispatch>, + event: Event, ) => void; /** * Function that overrides default behavior when a channel gets hidden. In absence of this prop, the channel will be removed from the list. @@ -112,8 +108,8 @@ export type ChannelListProps< * @overrideType Function * */ onChannelHidden?: ( - setChannels: React.Dispatch[]>>, - event: Event, + setChannels: React.Dispatch>, + event: Event, ) => void; /** * Function that overrides default behavior when a channel member.updated event is triggered @@ -126,9 +122,9 @@ export type ChannelListProps< */ onChannelMemberUpdated?: ( lockChannelOrder: boolean, - setChannels: React.Dispatch[]>>, - event: Event, - options?: ChannelListEventListenerOptions, + setChannels: React.Dispatch>, + event: Event, + options?: ChannelListEventListenerOptions, ) => void; /** * Function to customize behavior when a channel gets truncated @@ -139,8 +135,8 @@ export type ChannelListProps< * @overrideType Function * */ onChannelTruncated?: ( - setChannels: React.Dispatch[]>>, - event: Event, + setChannels: React.Dispatch>, + event: Event, ) => void; /** * Function that overrides default behavior when a channel gets updated @@ -151,8 +147,8 @@ export type ChannelListProps< * @overrideType Function * */ onChannelUpdated?: ( - setChannels: React.Dispatch[]>>, - event: Event, + setChannels: React.Dispatch>, + event: Event, ) => void; /** * Function that overrides default behavior when a channel gets visible. In absence of this prop, the channel will be added to the list. @@ -163,8 +159,8 @@ export type ChannelListProps< * @overrideType Function * */ onChannelVisible?: ( - setChannels: React.Dispatch[]>>, - event: Event, + setChannels: React.Dispatch>, + event: Event, ) => void; /** * Override the default listener/handler for event `message.new` @@ -180,9 +176,9 @@ export type ChannelListProps< * */ onNewMessage?: ( lockChannelOrder: boolean, - setChannels: React.Dispatch[]>>, - event: Event, - options?: ChannelListEventListenerOptions, + setChannels: React.Dispatch>, + event: Event, + options?: ChannelListEventListenerOptions, ) => void; /** * Override the default listener/handler for event `notification.message_new` @@ -194,9 +190,9 @@ export type ChannelListProps< * @overrideType Function * */ onNewMessageNotification?: ( - setChannels: React.Dispatch[]>>, - event: Event, - options?: ChannelListEventListenerOptions, + setChannels: React.Dispatch>, + event: Event, + options?: ChannelListEventListenerOptions, ) => void; /** @@ -208,8 +204,8 @@ export type ChannelListProps< * @overrideType Function * */ onRemovedFromChannel?: ( - setChannels: React.Dispatch[]>>, - event: Event, + setChannels: React.Dispatch>, + event: Event, ) => void; /** * Object containing channel query options @@ -220,7 +216,7 @@ export type ChannelListProps< * Object containing channel sort parameters * @see See [Channel query documentation](https://getstream.io/chat/docs/query_channels) for a list of available sorting fields * */ - sort?: ChannelSort; + sort?: ChannelSort; }; const DEFAULT_FILTERS = {}; @@ -234,11 +230,7 @@ const DEFAULT_SORT = {}; * * @example ./ChannelList.md */ -export const ChannelList = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ChannelListProps, -) => { +export const ChannelList = (props: ChannelListProps) => { const { additionalFlatListProps = {}, channelRenderFilterFn, @@ -281,7 +273,7 @@ export const ChannelList = < } = props; const [forceUpdate, setForceUpdate] = useState(0); - const { client, enableOfflineSupport } = useChatContext(); + const { client, enableOfflineSupport } = useChatContext(); const channelManager = useMemo(() => client.createChannelManager({}), [client]); /** @@ -353,7 +345,7 @@ export const ChannelList = < refreshList, reloadList, staticChannelsActive, - } = usePaginatedChannels({ + } = usePaginatedChannels({ channelManager, enableOfflineSupport, filters, @@ -423,7 +415,7 @@ export const ChannelList = < refreshing, refreshList, reloadList, - setFlatListRef: (ref: FlatList> | null) => { + setFlatListRef: (ref: FlatList | null) => { if (setFlatListRef) { setFlatListRef(ref); } @@ -433,7 +425,7 @@ export const ChannelList = < return ( - /> + ); }; diff --git a/package/src/components/ChannelList/ChannelListMessenger.tsx b/package/src/components/ChannelList/ChannelListMessenger.tsx index 97d92ceedf..87d514e732 100644 --- a/package/src/components/ChannelList/ChannelListMessenger.tsx +++ b/package/src/components/ChannelList/ChannelListMessenger.tsx @@ -13,7 +13,6 @@ import { useChatContext } from '../../contexts/chatContext/ChatContext'; import { useDebugContext } from '../../contexts/debugContext/DebugContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { ChannelPreview } from '../ChannelPreview/ChannelPreview'; const styles = StyleSheet.create({ @@ -22,10 +21,8 @@ const styles = StyleSheet.create({ statusIndicator: { left: 0, position: 'absolute', right: 0, top: 0 }, }); -export type ChannelListMessengerPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Omit< - ChannelsContextValue, +export type ChannelListMessengerPropsWithContext = Omit< + ChannelsContextValue, | 'HeaderErrorIndicator' | 'HeaderNetworkDownIndicator' | 'maxUnreadCount' @@ -39,12 +36,10 @@ export type ChannelListMessengerPropsWithContext< | 'Skeleton' >; -const StatusIndicator = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const { isOnline } = useChatContext(); +const StatusIndicator = () => { + const { isOnline } = useChatContext(); const { error, HeaderErrorIndicator, HeaderNetworkDownIndicator, loadingChannels, refreshList } = - useChannelsContext(); + useChannelsContext(); if (loadingChannels) { return null; @@ -66,25 +61,11 @@ const StatusIndicator = < return null; }; -const renderItem = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - item, -}: { - item: Channel; -}) => channel={item} />; +const renderItem = ({ item }: { item: Channel }) => ; -const keyExtractor = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - item: Channel, -) => item.cid; +const keyExtractor = (item: Channel) => item.cid; -const ChannelListMessengerWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ChannelListMessengerPropsWithContext, -) => { +const ChannelListMessengerWithContext = (props: ChannelListMessengerPropsWithContext) => { const onEndReachedCalledDuringCurrentScrollRef = useRef(false); const { additionalFlatListProps, @@ -195,14 +176,12 @@ const ChannelListMessengerWithContext = < testID='channel-list-messenger' {...additionalFlatListProps} /> - /> + ); }; -export type ChannelListMessengerProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type ChannelListMessengerProps = Partial; /** * This UI component displays the preview list of channels and handles Channel navigation. It @@ -210,11 +189,7 @@ export type ChannelListMessengerProps< * * @example ./ChannelListMessenger.md */ -export const ChannelListMessenger = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ChannelListMessengerProps, -) => { +export const ChannelListMessenger = (props: ChannelListMessengerProps) => { const { additionalFlatListProps, channelListInitialized, @@ -235,7 +210,7 @@ export const ChannelListMessenger = < refreshList, reloadList, setFlatListRef, - } = useChannelsContext(); + } = useChannelsContext(); return ( = - { - setChannels: React.Dispatch[] | null>>; - onAddedToChannel?: ( - setChannels: React.Dispatch[] | null>>, - event: Event, - options?: ChannelListEventListenerOptions, - ) => void; - options?: ChannelListEventListenerOptions; - }; +type Parameters = { + setChannels: React.Dispatch>; + onAddedToChannel?: ( + setChannels: React.Dispatch>, + event: Event, + options?: ChannelListEventListenerOptions, + ) => void; + options?: ChannelListEventListenerOptions; +}; -export const useAddedToChannelNotification = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useAddedToChannelNotification = ({ onAddedToChannel, options, setChannels, -}: Parameters) => { - const { client } = useChatContext(); +}: Parameters) => { + const { client } = useChatContext(); useEffect(() => { - const handleEvent = async (event: Event) => { + const handleEvent = async (event: Event) => { if (typeof onAddedToChannel === 'function') { onAddedToChannel(setChannels, event, options); } else { @@ -43,7 +37,7 @@ export const useAddedToChannelNotification = < } const { sort } = options; if (event.channel?.id && event.channel?.type) { - const channel = await getChannel({ + const channel = await getChannel({ client, id: event.channel.id, type: event.channel.type, diff --git a/package/src/components/ChannelList/hooks/listeners/useChannelDeleted.ts b/package/src/components/ChannelList/hooks/listeners/useChannelDeleted.ts index 98cddfe56f..195f5780cb 100644 --- a/package/src/components/ChannelList/hooks/listeners/useChannelDeleted.ts +++ b/package/src/components/ChannelList/hooks/listeners/useChannelDeleted.ts @@ -4,27 +4,19 @@ import type { Channel, Event } from 'stream-chat'; import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; - -type Parameters = - { - setChannels: React.Dispatch[] | null>>; - onChannelDeleted?: ( - setChannels: React.Dispatch[] | null>>, - event: Event, - ) => void; - }; +type Parameters = { + setChannels: React.Dispatch>; + onChannelDeleted?: ( + setChannels: React.Dispatch>, + event: Event, + ) => void; +}; -export const useChannelDeleted = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - onChannelDeleted, - setChannels, -}: Parameters) => { - const { client } = useChatContext(); +export const useChannelDeleted = ({ onChannelDeleted, setChannels }: Parameters) => { + const { client } = useChatContext(); useEffect(() => { - const handleEvent = (event: Event) => { + const handleEvent = (event: Event) => { if (typeof onChannelDeleted === 'function') { onChannelDeleted(setChannels, event); } else { diff --git a/package/src/components/ChannelList/hooks/listeners/useChannelHidden.ts b/package/src/components/ChannelList/hooks/listeners/useChannelHidden.ts index a132cf3c57..74a75b3693 100644 --- a/package/src/components/ChannelList/hooks/listeners/useChannelHidden.ts +++ b/package/src/components/ChannelList/hooks/listeners/useChannelHidden.ts @@ -4,27 +4,19 @@ import type { Channel, Event } from 'stream-chat'; import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; - -type Parameters = - { - setChannels: React.Dispatch[] | null>>; - onChannelHidden?: ( - setChannels: React.Dispatch[] | null>>, - event: Event, - ) => void; - }; +type Parameters = { + setChannels: React.Dispatch>; + onChannelHidden?: ( + setChannels: React.Dispatch>, + event: Event, + ) => void; +}; -export const useChannelHidden = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - onChannelHidden, - setChannels, -}: Parameters) => { - const { client } = useChatContext(); +export const useChannelHidden = ({ onChannelHidden, setChannels }: Parameters) => { + const { client } = useChatContext(); useEffect(() => { - const handleEvent = (event: Event) => { + const handleEvent = (event: Event) => { if (typeof onChannelHidden === 'function') { onChannelHidden(setChannels, event); } else { diff --git a/package/src/components/ChannelList/hooks/listeners/useChannelMemberUpdated.ts b/package/src/components/ChannelList/hooks/listeners/useChannelMemberUpdated.ts index 183b49e21b..33a45e2b97 100644 --- a/package/src/components/ChannelList/hooks/listeners/useChannelMemberUpdated.ts +++ b/package/src/components/ChannelList/hooks/listeners/useChannelMemberUpdated.ts @@ -4,10 +4,7 @@ import type { Channel, Event } from 'stream-chat'; import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; -import type { - ChannelListEventListenerOptions, - DefaultStreamChatGenerics, -} from '../../../../types/types'; +import type { ChannelListEventListenerOptions } from '../../../../types/types'; import { findLastPinnedChannelIndex, findPinnedAtSortOrder, @@ -17,31 +14,28 @@ import { shouldConsiderPinnedChannels, } from '../utils'; -type Parameters = - { - lockChannelOrder: boolean; - setChannels: React.Dispatch[]>>; - onChannelMemberUpdated?: ( - lockChannelOrder: boolean, - setChannels: React.Dispatch[]>>, - event: Event, - options?: ChannelListEventListenerOptions, - ) => void; - options?: ChannelListEventListenerOptions; - }; - -export const useChannelMemberUpdated = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +type Parameters = { + lockChannelOrder: boolean; + setChannels: React.Dispatch>; + onChannelMemberUpdated?: ( + lockChannelOrder: boolean, + setChannels: React.Dispatch>, + event: Event, + options?: ChannelListEventListenerOptions, + ) => void; + options?: ChannelListEventListenerOptions; +}; + +export const useChannelMemberUpdated = ({ lockChannelOrder, onChannelMemberUpdated, options, setChannels, -}: Parameters) => { - const { client } = useChatContext(); +}: Parameters) => { + const { client } = useChatContext(); useEffect(() => { - const handleEvent = (event: Event) => { + const handleEvent = (event: Event) => { if (typeof onChannelMemberUpdated === 'function') { onChannelMemberUpdated(lockChannelOrder, setChannels, event, options); } else { diff --git a/package/src/components/ChannelList/hooks/listeners/useChannelTruncated.ts b/package/src/components/ChannelList/hooks/listeners/useChannelTruncated.ts index cbaa8b5ddd..e2fa7fb1f7 100644 --- a/package/src/components/ChannelList/hooks/listeners/useChannelTruncated.ts +++ b/package/src/components/ChannelList/hooks/listeners/useChannelTruncated.ts @@ -4,31 +4,26 @@ import type { Channel, Event } from 'stream-chat'; import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; - -type Parameters = - { - refreshList: () => void; - setChannels: React.Dispatch[] | null>>; - setForceUpdate: React.Dispatch>; - onChannelTruncated?: ( - setChannels: React.Dispatch[] | null>>, - event: Event, - ) => void; - }; +type Parameters = { + refreshList: () => void; + setChannels: React.Dispatch>; + setForceUpdate: React.Dispatch>; + onChannelTruncated?: ( + setChannels: React.Dispatch>, + event: Event, + ) => void; +}; -export const useChannelTruncated = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useChannelTruncated = ({ onChannelTruncated, refreshList, setChannels, setForceUpdate, -}: Parameters) => { - const { client } = useChatContext(); +}: Parameters) => { + const { client } = useChatContext(); useEffect(() => { - const handleEvent = (event: Event) => { + const handleEvent = (event: Event) => { if (typeof onChannelTruncated === 'function') { onChannelTruncated(setChannels, event); } diff --git a/package/src/components/ChannelList/hooks/listeners/useChannelUpdated.ts b/package/src/components/ChannelList/hooks/listeners/useChannelUpdated.ts index a1c7ba8fa8..db078b626f 100644 --- a/package/src/components/ChannelList/hooks/listeners/useChannelUpdated.ts +++ b/package/src/components/ChannelList/hooks/listeners/useChannelUpdated.ts @@ -4,27 +4,19 @@ import type { Channel, Event } from 'stream-chat'; import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; - -type Parameters = - { - setChannels: React.Dispatch[]>>; - onChannelUpdated?: ( - setChannels: React.Dispatch[]>>, - event: Event, - ) => void; - }; - -export const useChannelUpdated = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - onChannelUpdated, - setChannels, -}: Parameters) => { - const { client } = useChatContext(); +type Parameters = { + setChannels: React.Dispatch>; + onChannelUpdated?: ( + setChannels: React.Dispatch>, + event: Event, + ) => void; +}; + +export const useChannelUpdated = ({ onChannelUpdated, setChannels }: Parameters) => { + const { client } = useChatContext(); useEffect(() => { - const handleEvent = (event: Event) => { + const handleEvent = (event: Event) => { if (typeof onChannelUpdated === 'function') { onChannelUpdated(setChannels, event); } else { diff --git a/package/src/components/ChannelList/hooks/listeners/useChannelVisible.ts b/package/src/components/ChannelList/hooks/listeners/useChannelVisible.ts index 4b0a03b7f2..2e3b84496a 100644 --- a/package/src/components/ChannelList/hooks/listeners/useChannelVisible.ts +++ b/package/src/components/ChannelList/hooks/listeners/useChannelVisible.ts @@ -4,34 +4,24 @@ import type { Channel, Event } from 'stream-chat'; import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; -import type { - ChannelListEventListenerOptions, - DefaultStreamChatGenerics, -} from '../../../../types/types'; +import type { ChannelListEventListenerOptions } from '../../../../types/types'; import { getChannel, moveChannelUp } from '../../utils'; -type Parameters = - { - setChannels: React.Dispatch[] | null>>; - onChannelVisible?: ( - setChannels: React.Dispatch[] | null>>, - event: Event, - options?: ChannelListEventListenerOptions, - ) => void; - options?: ChannelListEventListenerOptions; - }; +type Parameters = { + setChannels: React.Dispatch>; + onChannelVisible?: ( + setChannels: React.Dispatch>, + event: Event, + options?: ChannelListEventListenerOptions, + ) => void; + options?: ChannelListEventListenerOptions; +}; -export const useChannelVisible = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - onChannelVisible, - options, - setChannels, -}: Parameters) => { - const { client } = useChatContext(); +export const useChannelVisible = ({ onChannelVisible, options, setChannels }: Parameters) => { + const { client } = useChatContext(); useEffect(() => { - const handleEvent = async (event: Event) => { + const handleEvent = async (event: Event) => { if (typeof onChannelVisible === 'function') { onChannelVisible(setChannels, event); } else { @@ -40,7 +30,7 @@ export const useChannelVisible = < } const { sort } = options; if (event.channel_id && event.channel_type) { - const channel = await getChannel({ + const channel = await getChannel({ client, id: event.channel_id, type: event.channel_type, diff --git a/package/src/components/ChannelList/hooks/listeners/useNewMessage.ts b/package/src/components/ChannelList/hooks/listeners/useNewMessage.ts index 0ee797f6df..915a10ebeb 100644 --- a/package/src/components/ChannelList/hooks/listeners/useNewMessage.ts +++ b/package/src/components/ChannelList/hooks/listeners/useNewMessage.ts @@ -4,10 +4,7 @@ import type { Channel, Event } from 'stream-chat'; import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; -import type { - ChannelListEventListenerOptions, - DefaultStreamChatGenerics, -} from '../../../../types/types'; +import type { ChannelListEventListenerOptions } from '../../../../types/types'; import { moveChannelUp } from '../../utils'; import { isChannelArchived, @@ -16,31 +13,28 @@ import { shouldConsiderPinnedChannels, } from '../utils'; -type Parameters = - { - lockChannelOrder: boolean; - setChannels: React.Dispatch[] | null>>; - onNewMessage?: ( - lockChannelOrder: boolean, - setChannels: React.Dispatch[] | null>>, - event: Event, - options?: ChannelListEventListenerOptions, - ) => void; - options?: ChannelListEventListenerOptions; - }; +type Parameters = { + lockChannelOrder: boolean; + setChannels: React.Dispatch>; + onNewMessage?: ( + lockChannelOrder: boolean, + setChannels: React.Dispatch>, + event: Event, + options?: ChannelListEventListenerOptions, + ) => void; + options?: ChannelListEventListenerOptions; +}; -export const useNewMessage = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useNewMessage = ({ lockChannelOrder, onNewMessage, options, setChannels, -}: Parameters) => { - const { client } = useChatContext(); +}: Parameters) => { + const { client } = useChatContext(); useEffect(() => { - const handleEvent = (event: Event) => { + const handleEvent = (event: Event) => { if (typeof onNewMessage === 'function') { onNewMessage(lockChannelOrder, setChannels, event, options); } else { @@ -80,7 +74,7 @@ export const useNewMessage = < return [...channels]; } - return moveChannelUp({ + return moveChannelUp({ channels, channelToMove: targetChannel, channelToMoveIndexWithinChannels: targetChannelIndex, diff --git a/package/src/components/ChannelList/hooks/listeners/useNewMessageNotification.ts b/package/src/components/ChannelList/hooks/listeners/useNewMessageNotification.ts index b3e4bf2ddf..0d00e9808e 100644 --- a/package/src/components/ChannelList/hooks/listeners/useNewMessageNotification.ts +++ b/package/src/components/ChannelList/hooks/listeners/useNewMessageNotification.ts @@ -4,35 +4,29 @@ import type { Channel, Event } from 'stream-chat'; import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; -import type { - ChannelListEventListenerOptions, - DefaultStreamChatGenerics, -} from '../../../../types/types'; +import type { ChannelListEventListenerOptions } from '../../../../types/types'; import { getChannel, moveChannelUp } from '../../utils'; import { isChannelArchived } from '../utils'; -type Parameters = - { - setChannels: React.Dispatch[] | null>>; - onNewMessageNotification?: ( - setChannels: React.Dispatch[] | null>>, - event: Event, - options?: ChannelListEventListenerOptions, - ) => void; - options?: ChannelListEventListenerOptions; - }; +type Parameters = { + setChannels: React.Dispatch>; + onNewMessageNotification?: ( + setChannels: React.Dispatch>, + event: Event, + options?: ChannelListEventListenerOptions, + ) => void; + options?: ChannelListEventListenerOptions; +}; -export const useNewMessageNotification = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useNewMessageNotification = ({ onNewMessageNotification, options, setChannels, -}: Parameters) => { - const { client } = useChatContext(); +}: Parameters) => { + const { client } = useChatContext(); useEffect(() => { - const handleEvent = async (event: Event) => { + const handleEvent = async (event: Event) => { if (typeof onNewMessageNotification === 'function') { onNewMessageNotification(setChannels, event, options); } else { diff --git a/package/src/components/ChannelList/hooks/listeners/useRemovedFromChannelNotification.ts b/package/src/components/ChannelList/hooks/listeners/useRemovedFromChannelNotification.ts index d7a8840d3b..e9a72e4754 100644 --- a/package/src/components/ChannelList/hooks/listeners/useRemovedFromChannelNotification.ts +++ b/package/src/components/ChannelList/hooks/listeners/useRemovedFromChannelNotification.ts @@ -4,27 +4,22 @@ import type { Channel, Event } from 'stream-chat'; import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; - -type Parameters = - { - setChannels: React.Dispatch[] | null>>; - onRemovedFromChannel?: ( - setChannels: React.Dispatch[] | null>>, - event: Event, - ) => void; - }; +type Parameters = { + setChannels: React.Dispatch>; + onRemovedFromChannel?: ( + setChannels: React.Dispatch>, + event: Event, + ) => void; +}; -export const useRemovedFromChannelNotification = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useRemovedFromChannelNotification = ({ onRemovedFromChannel, setChannels, -}: Parameters) => { - const { client } = useChatContext(); +}: Parameters) => { + const { client } = useChatContext(); useEffect(() => { - const handleEvent = (event: Event) => { + const handleEvent = (event: Event) => { if (typeof onRemovedFromChannel === 'function') { onRemovedFromChannel(setChannels, event); } else { diff --git a/package/src/components/ChannelList/hooks/listeners/useUserPresence.ts b/package/src/components/ChannelList/hooks/listeners/useUserPresence.ts index 4bf878b7b7..f470569297 100644 --- a/package/src/components/ChannelList/hooks/listeners/useUserPresence.ts +++ b/package/src/components/ChannelList/hooks/listeners/useUserPresence.ts @@ -4,24 +4,16 @@ import type { Channel, Event } from 'stream-chat'; import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; - -type Parameters = - { - setChannels: React.Dispatch[]>>; - setForceUpdate: React.Dispatch>; - }; - -export const useUserPresence = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - setChannels, - setForceUpdate, -}: Parameters) => { - const { client } = useChatContext(); +type Parameters = { + setChannels: React.Dispatch>; + setForceUpdate: React.Dispatch>; +}; + +export const useUserPresence = ({ setChannels, setForceUpdate }: Parameters) => { + const { client } = useChatContext(); useEffect(() => { - const handleEvent = (event: Event) => { + const handleEvent = (event: Event) => { setChannels((channels) => { if (!channels) { return channels; diff --git a/package/src/components/ChannelList/hooks/useChannelMembershipState.ts b/package/src/components/ChannelList/hooks/useChannelMembershipState.ts index 6e285862be..5ddf5761c3 100644 --- a/package/src/components/ChannelList/hooks/useChannelMembershipState.ts +++ b/package/src/components/ChannelList/hooks/useChannelMembershipState.ts @@ -2,21 +2,11 @@ import { Channel, ChannelMemberResponse, EventTypes } from 'stream-chat'; import { useSelectedChannelState } from './useSelectedChannelState'; -import { DefaultStreamChatGenerics } from '../../../types/types'; - -const selector = ( - channel: Channel, -) => channel.state.membership; +const selector = (channel: Channel) => channel.state.membership; const keys: EventTypes[] = ['member.updated']; -export function useChannelMembershipState( - channel: Channel, -): ChannelMemberResponse; -export function useChannelMembershipState( - channel?: Channel, -): ChannelMemberResponse | undefined; -export function useChannelMembershipState( - channel?: Channel, -) { +export function useChannelMembershipState(channel: Channel): ChannelMemberResponse; +export function useChannelMembershipState(channel?: Channel): ChannelMemberResponse | undefined; +export function useChannelMembershipState(channel?: Channel) { return useSelectedChannelState({ channel, selector, stateChangeEventKeys: keys }); } diff --git a/package/src/components/ChannelList/hooks/useCreateChannelsContext.ts b/package/src/components/ChannelList/hooks/useCreateChannelsContext.ts index 0e652fed3a..dbe7e8c554 100644 --- a/package/src/components/ChannelList/hooks/useCreateChannelsContext.ts +++ b/package/src/components/ChannelList/hooks/useCreateChannelsContext.ts @@ -1,11 +1,8 @@ import { useMemo } from 'react'; import type { ChannelsContextValue } from '../../../contexts/channelsContext/ChannelsContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; -export const useCreateChannelsContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useCreateChannelsContext = ({ additionalFlatListProps, channelListInitialized, channels, @@ -38,7 +35,7 @@ export const useCreateChannelsContext = < reloadList, setFlatListRef, Skeleton, -}: ChannelsContextValue) => { +}: ChannelsContextValue) => { const channelValueString = channels ?.map( (channel) => @@ -49,7 +46,7 @@ export const useCreateChannelsContext = < .join()}`, ) .join(); - const channelsContext: ChannelsContextValue = useMemo( + const channelsContext: ChannelsContextValue = useMemo( () => ({ additionalFlatListProps, channelListInitialized, diff --git a/package/src/components/ChannelList/hooks/usePaginatedChannels.ts b/package/src/components/ChannelList/hooks/usePaginatedChannels.ts index 4211e7b046..1e7b234c5e 100644 --- a/package/src/components/ChannelList/hooks/usePaginatedChannels.ts +++ b/package/src/components/ChannelList/hooks/usePaginatedChannels.ts @@ -14,7 +14,7 @@ import { useStateStore } from '../../../hooks'; import { useIsMountedRef } from '../../../hooks/useIsMountedRef'; import { getChannelsForFilterSort } from '../../../store/apis/getChannelsForFilterSort'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { ONE_SECOND_IN_MS } from '../../../utils/date'; import { DBSyncManager } from '../../../utils/DBSyncManager'; import { MAX_QUERY_CHANNELS_LIMIT } from '../utils'; @@ -24,15 +24,14 @@ const waitSeconds = (seconds: number) => setTimeout(resolve, seconds * ONE_SECOND_IN_MS); }); -type Parameters = - { - channelManager: ChannelManager; - enableOfflineSupport: boolean; - filters: ChannelFilters; - options: ChannelOptions; - setForceUpdate: React.Dispatch>; - sort: ChannelSort; - }; +type Parameters = { + channelManager: ChannelManager; + enableOfflineSupport: boolean; + filters: ChannelFilters; + options: ChannelOptions; + setForceUpdate: React.Dispatch>; + sort: ChannelSort; +}; const DEFAULT_OPTIONS = { message_limit: 10, @@ -45,31 +44,27 @@ type QueryType = 'queryLocalDB' | 'reload' | 'refresh' | 'loadChannels'; export type QueryChannels = (queryType?: QueryType, retryCount?: number) => Promise; -const selector = ( - nextValue: ChannelManagerState, -) => +const selector = (nextValue: ChannelManagerState) => ({ channelListInitialized: nextValue.initialized, channels: nextValue.channels, pagination: nextValue.pagination, }) as const; -export const usePaginatedChannels = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const usePaginatedChannels = ({ channelManager, enableOfflineSupport, filters = {}, options = DEFAULT_OPTIONS, setForceUpdate, sort = {}, -}: Parameters) => { +}: Parameters) => { const [error, setError] = useState(undefined); const [staticChannelsActive, setStaticChannelsActive] = useState(false); const activeQueryType = useRef('queryLocalDB'); const activeChannels = useActiveChannelsRefContext(); const isMountedRef = useIsMountedRef(); - const { client } = useChatContext(); + const { client } = useChatContext(); const { channelListInitialized, channels, pagination } = useStateStore(channelManager?.state, selector) ?? {}; const hasNextPage = pagination?.hasNext; diff --git a/package/src/components/ChannelList/hooks/useSelectedChannelState.ts b/package/src/components/ChannelList/hooks/useSelectedChannelState.ts index d4cbfa3aee..78b400c20a 100644 --- a/package/src/components/ChannelList/hooks/useSelectedChannelState.ts +++ b/package/src/components/ChannelList/hooks/useSelectedChannelState.ts @@ -3,33 +3,25 @@ import { useCallback } from 'react'; import type { Channel, EventTypes } from 'stream-chat'; import { useSyncExternalStore } from 'use-sync-external-store/shim'; -import { DefaultStreamChatGenerics } from '../../../types/types'; - const noop = () => {}; -export function useSelectedChannelState< - StreamChatGenerics extends DefaultStreamChatGenerics, - O, ->(_: { - channel: Channel; - selector: (channel: Channel) => O; +export function useSelectedChannelState(_: { + channel: Channel; + selector: (channel: Channel) => O; stateChangeEventKeys?: EventTypes[]; }): O; -export function useSelectedChannelState< - StreamChatGenerics extends DefaultStreamChatGenerics, - O, ->(_: { - selector: (channel: Channel) => O; - channel?: Channel | undefined; +export function useSelectedChannelState(_: { + selector: (channel: Channel) => O; + channel?: Channel | undefined; stateChangeEventKeys?: EventTypes[]; }): O | undefined; -export function useSelectedChannelState({ +export function useSelectedChannelState({ channel, selector, stateChangeEventKeys = ['all'], }: { - selector: (channel: Channel) => O; - channel?: Channel; + selector: (channel: Channel) => O; + channel?: Channel; stateChangeEventKeys?: EventTypes[]; }): O | undefined { const subscribe = useCallback( diff --git a/package/src/components/ChannelList/hooks/utils/index.ts b/package/src/components/ChannelList/hooks/utils/index.ts index 087b0f6fcd..8d6289b7f0 100644 --- a/package/src/components/ChannelList/hooks/utils/index.ts +++ b/package/src/components/ChannelList/hooks/utils/index.ts @@ -1,13 +1,8 @@ import { Channel, ChannelSortBase } from 'stream-chat'; -import { DefaultStreamChatGenerics } from '../../../../types/types'; import { ChannelListProps } from '../../ChannelList'; -export const isChannelPinned = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, -) => { +export const isChannelPinned = (channel: Channel) => { if (!channel) { return false; } @@ -17,11 +12,7 @@ export const isChannelPinned = < return !!member?.pinned_at; }; -export const isChannelArchived = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, -) => { +export const isChannelArchived = (channel: Channel) => { if (!channel) { return false; } @@ -31,11 +22,7 @@ export const isChannelArchived = < return !!member?.archived_at; }; -export const shouldConsiderArchivedChannels = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - filters: ChannelListProps['filters'], -) => { +export const shouldConsiderArchivedChannels = (filters: ChannelListProps['filters']) => { if (!filters) { return false; } @@ -43,21 +30,19 @@ export const shouldConsiderArchivedChannels = < return typeof filters.archived === 'boolean'; }; -export const extractSortValue = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const extractSortValue = ({ atIndex, sort, targetKey, }: { atIndex: number; - targetKey: keyof ChannelSortBase; - sort?: ChannelListProps['sort']; + targetKey: keyof ChannelSortBase; + sort?: ChannelListProps['sort']; }) => { if (!sort) { return null; } - let option: null | ChannelSortBase = null; + let option: null | ChannelSortBase = null; if (Array.isArray(sort)) { option = sort[atIndex] ?? null; @@ -85,11 +70,7 @@ export const extractSortValue = < /** * Returns true only if `{ pinned_at: -1 }` or `{ pinned_at: 1 }` option is first within the `sort` array. */ -export const shouldConsiderPinnedChannels = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - sort: ChannelListProps['sort'], -) => { +export const shouldConsiderPinnedChannels = (sort: ChannelListProps['sort']) => { const value = extractSortValue({ atIndex: 0, sort, @@ -103,9 +84,7 @@ export const shouldConsiderPinnedChannels = < return Math.abs(value) === 1; }; -export function findPinnedAtSortOrder< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ sort }: { sort: ChannelListProps['sort'] }) { +export function findPinnedAtSortOrder({ sort }: { sort: ChannelListProps['sort'] }) { if (!sort) { return null; } @@ -127,9 +106,7 @@ export function findPinnedAtSortOrder< } } -export function findLastPinnedChannelIndex< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ channels }: { channels: Channel[] }) { +export function findLastPinnedChannelIndex({ channels }: { channels: Channel[] }) { let lastPinnedChannelIndex: number | null = null; for (const channel of channels) { diff --git a/package/src/components/ChannelList/utils.ts b/package/src/components/ChannelList/utils.ts index 7abb355be5..706fd9d1a3 100644 --- a/package/src/components/ChannelList/utils.ts +++ b/package/src/components/ChannelList/utils.ts @@ -2,29 +2,23 @@ import type { Channel, ChannelSort, StreamChat } from 'stream-chat'; import { findLastPinnedChannelIndex, shouldConsiderPinnedChannels } from './hooks/utils'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - -type MoveParameters< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - channels: Array>; - channelToMove: Channel; +type MoveParameters = { + channels: Array; + channelToMove: Channel; /** * If the index of the channel within `channels` list which is being moved upwards * (`channelToMove`) is known, you can supply it to skip extra calculation. */ channelToMoveIndexWithinChannels?: number; - sort?: ChannelSort; + sort?: ChannelSort; }; -export const moveChannelUp = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const moveChannelUp = ({ channels, channelToMove, channelToMoveIndexWithinChannels, sort, -}: MoveParameters) => { +}: MoveParameters) => { // get index of channel to move up const targetChannelIndex = channelToMoveIndexWithinChannels ?? @@ -66,21 +60,13 @@ export const moveChannelUp = < return newChannels; }; -type GetParameters< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - client: StreamChat; +type GetParameters = { + client: StreamChat; id: string; type: string; }; -export const getChannel = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - client, - id, - type, -}: GetParameters) => { +export const getChannel = async ({ client, id, type }: GetParameters) => { const channel = client.channel(type, id); await channel.watch(); return channel; diff --git a/package/src/components/ChannelPreview/ChannelAvatar.tsx b/package/src/components/ChannelPreview/ChannelAvatar.tsx index 5216393e39..e38b3e428e 100644 --- a/package/src/components/ChannelPreview/ChannelAvatar.tsx +++ b/package/src/components/ChannelPreview/ChannelAvatar.tsx @@ -6,13 +6,11 @@ import { useChannelPreviewDisplayPresence } from './hooks/useChannelPreviewDispl import { ChatContextValue, useChatContext } from '../../contexts/chatContext/ChatContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { Avatar } from '../Avatar/Avatar'; import { GroupAvatar } from '../Avatar/GroupAvatar'; -export type ChannelAvatarProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'channel'> & { +export type ChannelAvatarProps = Pick & { /** * The size of the avatar. */ @@ -22,10 +20,8 @@ export type ChannelAvatarProps< /** * This UI component displays an avatar for a particular channel. */ -export const ChannelAvatarWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ChannelAvatarProps & Pick, +export const ChannelAvatarWithContext = ( + props: ChannelAvatarProps & Pick, ) => { const { channel, ImageComponent, size: propSize } = props; const { @@ -63,12 +59,8 @@ export const ChannelAvatarWithContext = < ); }; -export const ChannelAvatar = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ChannelAvatarProps, -) => { - const { ImageComponent } = useChatContext(); +export const ChannelAvatar = (props: ChannelAvatarProps) => { + const { ImageComponent } = useChatContext(); return ; }; diff --git a/package/src/components/ChannelPreview/ChannelPreview.tsx b/package/src/components/ChannelPreview/ChannelPreview.tsx index fb8edbbed9..003c9c6875 100644 --- a/package/src/components/ChannelPreview/ChannelPreview.tsx +++ b/package/src/components/ChannelPreview/ChannelPreview.tsx @@ -10,27 +10,19 @@ import { } from '../../contexts/channelsContext/ChannelsContext'; import { ChatContextValue, useChatContext } from '../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - -export type ChannelPreviewProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial, 'client'>> & - Partial, 'Preview' | 'forceUpdate'>> & { +export type ChannelPreviewProps = Partial> & + Partial> & { /** * Instance of Channel from stream-chat package. */ - channel: Channel; + channel: Channel; }; -export const ChannelPreview = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ChannelPreviewProps, -) => { +export const ChannelPreview = (props: ChannelPreviewProps) => { const { channel, client: propClient, forceUpdate: propForceUpdate, Preview: propPreview } = props; - const { client: contextClient } = useChatContext(); - const { Preview: contextPreview } = useChannelsContext(); + const { client: contextClient } = useChatContext(); + const { Preview: contextPreview } = useChannelsContext(); const client = propClient || contextClient; const Preview = propPreview || contextPreview; diff --git a/package/src/components/ChannelPreview/ChannelPreviewMessage.tsx b/package/src/components/ChannelPreview/ChannelPreviewMessage.tsx index ed623715a7..5b0346640a 100644 --- a/package/src/components/ChannelPreview/ChannelPreviewMessage.tsx +++ b/package/src/components/ChannelPreview/ChannelPreviewMessage.tsx @@ -5,8 +5,6 @@ import type { LatestMessagePreview } from './hooks/useLatestMessagePreview'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - const styles = StyleSheet.create({ bold: { fontWeight: '600' }, message: { @@ -15,20 +13,14 @@ const styles = StyleSheet.create({ }, }); -export type ChannelPreviewMessageProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type ChannelPreviewMessageProps = { /** * Latest message on a channel, formatted for preview. */ - latestMessagePreview: LatestMessagePreview; + latestMessagePreview: LatestMessagePreview; }; -export const ChannelPreviewMessage = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ChannelPreviewMessageProps, -) => { +export const ChannelPreviewMessage = (props: ChannelPreviewMessageProps) => { const { latestMessagePreview } = props; const { diff --git a/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx b/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx index 2805b61325..11bb5741d3 100644 --- a/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx +++ b/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx @@ -19,7 +19,6 @@ import { } from '../../contexts/channelsContext/ChannelsContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { useViewport } from '../../hooks/useViewport'; -import type { DefaultStreamChatGenerics } from '../../types/types'; const styles = StyleSheet.create({ container: { @@ -44,11 +43,9 @@ const styles = StyleSheet.create({ title: { fontSize: 14, fontWeight: '700' }, }); -export type ChannelPreviewMessengerPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'channel'> & +export type ChannelPreviewMessengerPropsWithContext = Pick & Pick< - ChannelsContextValue, + ChannelsContextValue, | 'maxUnreadCount' | 'onSelect' | 'PreviewAvatar' @@ -83,7 +80,7 @@ export type ChannelPreviewMessengerPropsWithContext< * * @overrideType object */ - latestMessagePreview: LatestMessagePreview; + latestMessagePreview: LatestMessagePreview; /** * Formatter function for date of latest message. * @param date Message date @@ -100,11 +97,7 @@ export type ChannelPreviewMessengerPropsWithContext< unread?: number; }; -const ChannelPreviewMessengerWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ChannelPreviewMessengerPropsWithContext, -) => { +const ChannelPreviewMessengerWithContext = (props: ChannelPreviewMessengerPropsWithContext) => { const { channel, formatLatestMessageDate, @@ -175,18 +168,10 @@ const ChannelPreviewMessengerWithContext = < ); }; -export type ChannelPreviewMessengerProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial< - Omit< - ChannelPreviewMessengerPropsWithContext, - 'channel' | 'latestMessagePreview' - > +export type ChannelPreviewMessengerProps = Partial< + Omit > & - Pick< - ChannelPreviewMessengerPropsWithContext, - 'channel' | 'latestMessagePreview' - >; + Pick; const MemoizedChannelPreviewMessengerWithContext = React.memo( ChannelPreviewMessengerWithContext, @@ -196,11 +181,7 @@ const MemoizedChannelPreviewMessengerWithContext = React.memo( * This UI component displays an individual preview item for each channel in a list. It also receives all props * from the ChannelPreview component. */ -export const ChannelPreviewMessenger = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ChannelPreviewMessengerProps, -) => { +export const ChannelPreviewMessenger = (props: ChannelPreviewMessengerProps) => { const { forceUpdate, maxUnreadCount, @@ -211,7 +192,7 @@ export const ChannelPreviewMessenger = < PreviewStatus, PreviewTitle, PreviewUnreadCount, - } = useChannelsContext(); + } = useChannelsContext(); return ( = Pick< - ChannelPreviewMessengerPropsWithContext, +export type ChannelPreviewStatusProps = Pick< + ChannelPreviewMessengerPropsWithContext, 'latestMessagePreview' | 'formatLatestMessageDate' > & - Pick, 'channel'>; + Pick; -export const ChannelPreviewStatus = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ChannelPreviewStatusProps, -) => { +export const ChannelPreviewStatus = (props: ChannelPreviewStatusProps) => { const { formatLatestMessageDate, latestMessagePreview } = props; const { t, tDateTimeParser } = useTranslationContext(); const { diff --git a/package/src/components/ChannelPreview/ChannelPreviewTitle.tsx b/package/src/components/ChannelPreview/ChannelPreviewTitle.tsx index 24ae659ff5..fd248f17c6 100644 --- a/package/src/components/ChannelPreview/ChannelPreviewTitle.tsx +++ b/package/src/components/ChannelPreview/ChannelPreviewTitle.tsx @@ -4,26 +4,19 @@ import { StyleSheet, Text } from 'react-native'; import type { ChannelPreviewProps } from './ChannelPreview'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; const styles = StyleSheet.create({ title: { fontSize: 14, fontWeight: '700' }, }); -export type ChannelPreviewTitleProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'channel'> & { +export type ChannelPreviewTitleProps = Pick & { /** * Formatted name for the previewed channel. */ displayName: string; }; -export const ChannelPreviewTitle = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ChannelPreviewTitleProps, -) => { +export const ChannelPreviewTitle = (props: ChannelPreviewTitleProps) => { const { displayName } = props; const { theme: { diff --git a/package/src/components/ChannelPreview/ChannelPreviewUnreadCount.tsx b/package/src/components/ChannelPreview/ChannelPreviewUnreadCount.tsx index 76ffd31e32..cd592ac958 100644 --- a/package/src/components/ChannelPreview/ChannelPreviewUnreadCount.tsx +++ b/package/src/components/ChannelPreview/ChannelPreviewUnreadCount.tsx @@ -6,23 +6,15 @@ import { ChannelPreviewProps } from './ChannelPreview'; import type { ChannelsContextValue } from '../../contexts/channelsContext/ChannelsContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - -export type ChannelPreviewUnreadCountProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'maxUnreadCount'> & - Pick, 'channel'> & { +export type ChannelPreviewUnreadCountProps = Pick & + Pick & { /** * Number of unread messages on the channel */ unread?: number; }; -export const ChannelPreviewUnreadCount = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ChannelPreviewUnreadCountProps, -) => { +export const ChannelPreviewUnreadCount = (props: ChannelPreviewUnreadCountProps) => { const { maxUnreadCount, unread } = props; const { theme: { diff --git a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx index 7865355361..b9eb81ff02 100644 --- a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx +++ b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx @@ -12,7 +12,7 @@ import { } from '../../../../mock-builders/api/queryMembers'; import { generateUser } from '../../../../mock-builders/generator/user'; import { getTestClientWithUser } from '../../../../mock-builders/mock'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; + import { getChannelPreviewDisplayName, useChannelPreviewDisplayName, diff --git a/package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx b/package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx index 9e51b11b00..1173f00216 100644 --- a/package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx +++ b/package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx @@ -18,7 +18,6 @@ import { import { generateUser } from '../../../../mock-builders/generator/user'; import { getTestClientWithUser } from '../../../../mock-builders/mock'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; import { useLatestMessagePreview } from '../useLatestMessagePreview'; diff --git a/package/src/components/ChannelPreview/hooks/useChannelPreviewData.ts b/package/src/components/ChannelPreview/hooks/useChannelPreviewData.ts index 5c3db61c68..9df1c86c80 100644 --- a/package/src/components/ChannelPreview/hooks/useChannelPreviewData.ts +++ b/package/src/components/ChannelPreview/hooks/useChannelPreviewData.ts @@ -8,23 +8,19 @@ import { useIsChannelMuted } from './useIsChannelMuted'; import { useLatestMessagePreview } from './useLatestMessagePreview'; import { useChannelsContext } from '../../../contexts'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; -export const useChannelPreviewData = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, - client: StreamChat, +export const useChannelPreviewData = ( + channel: Channel, + client: StreamChat, forceUpdateOverride?: number, ) => { const [forceUpdate, setForceUpdate] = useState(0); const [lastMessage, setLastMessage] = useState< - | ReturnType['formatMessage']> - | MessageResponse + ReturnType | MessageResponse >(channel.state.messages[channel.state.messages.length - 1]); const [unread, setUnread] = useState(channel.countUnread()); const { muted } = useIsChannelMuted(channel); - const { forceUpdate: contextForceUpdate } = useChannelsContext(); + const { forceUpdate: contextForceUpdate } = useChannelsContext(); const channelListForceUpdate = forceUpdateOverride ?? contextForceUpdate; const channelLastMessage = channel.lastMessage(); @@ -113,7 +109,7 @@ export const useChannelPreviewData = < refreshUnreadCount(); }; - const handleNewMessageEvent = (event: Event) => { + const handleNewMessageEvent = (event: Event) => { const message = event.message; if (message && (!message.parent_id || message.show_in_channel)) { setLastMessage(message); @@ -121,7 +117,7 @@ export const useChannelPreviewData = < } }; - const handleUpdatedOrDeletedMessage = (event: Event) => { + const handleUpdatedOrDeletedMessage = (event: Event) => { setLastMessage((prevLastMessage) => { if (prevLastMessage?.id === event.message?.id) { return event.message; diff --git a/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayAvatar.ts b/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayAvatar.ts index 54f6856784..0743017273 100644 --- a/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayAvatar.ts +++ b/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayAvatar.ts @@ -4,14 +4,7 @@ import type { Channel, StreamChat } from 'stream-chat'; import { useChatContext } from '../../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; - -export const getChannelPreviewDisplayAvatar = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, - client: StreamChat, -) => { +export const getChannelPreviewDisplayAvatar = (channel: Channel, client: StreamChat) => { const currentUserId = client?.user?.id; const channelId = channel?.id; const channelData = channel?.data; @@ -54,12 +47,8 @@ export const getChannelPreviewDisplayAvatar = < * * @returns {object} e.g., { image: 'http://dummyurl.com/test.png', name: 'Uhtred Bebbanburg' } */ -export const useChannelPreviewDisplayAvatar = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, -) => { - const { client } = useChatContext(); +export const useChannelPreviewDisplayAvatar = (channel: Channel) => { + const { client } = useChatContext(); const channelData = channel?.data; const image = channelData?.image; diff --git a/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayName.ts b/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayName.ts index 9a1d5e04c5..128b54be60 100644 --- a/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayName.ts +++ b/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayName.ts @@ -5,16 +5,12 @@ import type { Channel, ChannelMemberResponse } from 'stream-chat'; import { useChatContext } from '../../../contexts/chatContext/ChatContext'; import { useViewport } from '../../../hooks/useViewport'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; - const ELLIPSIS = '...'; const getMemberName = (member: ChannelMemberResponse) => member.user?.name || member.user?.id || 'Unknown User'; -export const getChannelPreviewDisplayName = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const getChannelPreviewDisplayName = ({ channelName, characterLimit, currentUserId, @@ -23,7 +19,7 @@ export const getChannelPreviewDisplayName = < characterLimit: number; channelName?: string; currentUserId?: string; - members?: Channel['state']['members']; + members?: Channel['state']['members']; }): string => { if (channelName) { return channelName; @@ -74,13 +70,8 @@ export const getChannelPreviewDisplayName = < return name; }; -export const useChannelPreviewDisplayName = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel?: Channel, - characterLength?: number, -) => { - const { client } = useChatContext(); +export const useChannelPreviewDisplayName = (channel?: Channel, characterLength?: number) => { + const { client } = useChatContext(); const { vw } = useViewport(); const DEFAULT_MAX_CHARACTER_LENGTH = (vw(100) - 16) / 6; diff --git a/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts b/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts index f76a82f191..1eee2279cd 100644 --- a/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts +++ b/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts @@ -4,14 +4,7 @@ import type { Channel, StreamChat } from 'stream-chat'; import { useChatContext } from '../../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; - -const getChannelPreviewDisplayPresence = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, - client: StreamChat, -) => { +const getChannelPreviewDisplayPresence = (channel: Channel, client: StreamChat) => { const currentUserId = client.userID; if (currentUserId) { @@ -31,12 +24,8 @@ const getChannelPreviewDisplayPresence = < * * @returns {boolean} e.g., true */ -export const useChannelPreviewDisplayPresence = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, -) => { - const { client } = useChatContext(); +export const useChannelPreviewDisplayPresence = (channel: Channel) => { + const { client } = useChatContext(); const currentUserId = client.userID; const members = Object.values(channel.state.members).filter( diff --git a/package/src/components/ChannelPreview/hooks/useIsChannelMuted.ts b/package/src/components/ChannelPreview/hooks/useIsChannelMuted.ts index 02d83f79d7..5d4a45218b 100644 --- a/package/src/components/ChannelPreview/hooks/useIsChannelMuted.ts +++ b/package/src/components/ChannelPreview/hooks/useIsChannelMuted.ts @@ -4,14 +4,8 @@ import type { Channel } from 'stream-chat'; import { useChatContext } from '../../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; - -export const useIsChannelMuted = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, -) => { - const { client } = useChatContext(); +export const useIsChannelMuted = (channel: Channel) => { + const { client } = useChatContext(); const [muted, setMuted] = useState(() => channel.muteStatus()); diff --git a/package/src/components/ChannelPreview/hooks/useLatestMessagePreview.ts b/package/src/components/ChannelPreview/hooks/useLatestMessagePreview.ts index 5886fccab1..950e85b738 100644 --- a/package/src/components/ChannelPreview/hooks/useLatestMessagePreview.ts +++ b/package/src/components/ChannelPreview/hooks/useLatestMessagePreview.ts @@ -16,19 +16,13 @@ import { useTranslationContext } from '../../../contexts/translationContext/Tran import { useStateStore } from '../../../hooks'; import { useTranslatedMessage } from '../../../hooks/useTranslatedMessage'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { stringifyMessage } from '../../../utils/utils'; -type LatestMessage< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = - | ReturnType['formatMessage']> - | MessageResponse; +type LatestMessage = ReturnType | MessageResponse; -export type LatestMessagePreview< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - messageObject: LatestMessage | undefined; +export type LatestMessagePreview = { + messageObject: LatestMessage | undefined; previews: { bold: boolean; text: string; @@ -43,18 +37,14 @@ export type LatestMessagePreviewSelectorReturnType = { name?: string; }; -const selector = ( - nextValue: PollState, -): LatestMessagePreviewSelectorReturnType => ({ +const selector = (nextValue: PollState): LatestMessagePreviewSelectorReturnType => ({ createdBy: nextValue.created_by, latestVotesByOption: nextValue.latest_votes_by_option, name: nextValue.name, }); -const getMessageSenderName = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - message: LatestMessage | undefined, +const getMessageSenderName = ( + message: LatestMessage | undefined, currentUserId: string | undefined, t: (key: string) => string, membersLength: number, @@ -70,11 +60,7 @@ const getMessageSenderName = < return ''; }; -const getMentionUsers = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - mentionedUser: UserResponse[] | undefined, -) => { +const getMentionUsers = (mentionedUser: UserResponse[] | undefined) => { if (Array.isArray(mentionedUser)) { const mentionUserString = mentionedUser.reduce((acc, cur) => { const userName = cur.name || cur.id || ''; @@ -93,12 +79,10 @@ const getMentionUsers = < return ''; }; -const getLatestMessageDisplayText = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, - client: StreamChat, - message: LatestMessage | undefined, +const getLatestMessageDisplayText = ( + channel: Channel, + client: StreamChat, + message: LatestMessage | undefined, t: (key: string) => string, pollState: LatestMessagePreviewSelectorReturnType | undefined, ) => { @@ -185,12 +169,10 @@ export enum MessageReadStatus { READ = 2, } -const getLatestMessageReadStatus = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, - client: StreamChat, - message: LatestMessage | undefined, +const getLatestMessageReadStatus = ( + channel: Channel, + client: StreamChat, + message: LatestMessage | undefined, readEvents: boolean, ): MessageReadStatus => { const currentUserId = client.userID; @@ -216,17 +198,13 @@ const getLatestMessageReadStatus = < : MessageReadStatus.UNREAD; }; -const getLatestMessagePreview = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->(params: { - channel: Channel; - client: StreamChat; +const getLatestMessagePreview = (params: { + channel: Channel; + client: StreamChat; pollState: LatestMessagePreviewSelectorReturnType | undefined; readEvents: boolean; t: TFunction; - lastMessage?: - | ReturnType['formatMessage']> - | MessageResponse; + lastMessage?: ReturnType | MessageResponse; }) => { const { channel, client, lastMessage, pollState, readEvents, t } = params; @@ -265,30 +243,24 @@ const getLatestMessagePreview = < * * @returns {object} latest message preview e.g.. { text: 'this was last message ...', created_at: '11/12/2020', messageObject: { originalMessageObject } } */ -export const useLatestMessagePreview = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, +export const useLatestMessagePreview = ( + channel: Channel, forceUpdate: number, - lastMessage?: - | ReturnType['formatMessage']> - | MessageResponse, + lastMessage?: ReturnType | MessageResponse, ) => { - const { client } = useChatContext(); + const { client } = useChatContext(); const { t } = useTranslationContext(); const channelConfigExists = typeof channel?.getConfig === 'function'; - const translatedLastMessage = useTranslatedMessage(lastMessage); + const translatedLastMessage = useTranslatedMessage(lastMessage); const channelLastMessageString = translatedLastMessage ? stringifyMessage(translatedLastMessage) : ''; const [readEvents, setReadEvents] = useState(true); - const [latestMessagePreview, setLatestMessagePreview] = useState< - LatestMessagePreview - >({ + const [latestMessagePreview, setLatestMessagePreview] = useState({ created_at: '', messageObject: undefined, previews: [ diff --git a/package/src/components/Chat/Chat.tsx b/package/src/components/Chat/Chat.tsx index 1039e0d6d2..35f7796064 100644 --- a/package/src/components/Chat/Chat.tsx +++ b/package/src/components/Chat/Chat.tsx @@ -25,17 +25,15 @@ import init from '../../init'; import { SDK } from '../../native'; import { SqliteClient } from '../../store/SqliteClient'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { DBSyncManager } from '../../utils/DBSyncManager'; import type { Streami18n } from '../../utils/i18n/Streami18n'; import { version } from '../../version.json'; init(); -export type ChatProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'client'> & - Partial, 'ImageComponent' | 'isMessageAIGenerated'>> & { +export type ChatProps = Pick & + Partial> & { /** * When false, ws connection won't be disconnection upon backgrounding the app. * To receive push notifications, its necessary that user doesn't have active @@ -136,11 +134,7 @@ export type ChatProps< style?: DeepPartial; }; -const ChatWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: PropsWithChildren>, -) => { +const ChatWithContext = (props: PropsWithChildren) => { const { children, client, @@ -153,7 +147,7 @@ const ChatWithContext = < style, } = props; - const [channel, setChannel] = useState>(); + const [channel, setChannel] = useState(); // Setup translators const translators = useStreami18n(i18nInstance); @@ -161,10 +155,7 @@ const ChatWithContext = < /** * Setup connection event listeners */ - const { connectionRecovering, isOnline } = useIsOnline( - client, - closeConnectionOnBackground, - ); + const { connectionRecovering, isOnline } = useIsOnline(client, closeConnectionOnBackground); const [initialisedDatabaseConfig, setInitialisedDatabaseConfig] = useState<{ initialised: boolean; @@ -178,7 +169,7 @@ const ChatWithContext = < * Setup muted user listener * TODO: reimplement */ - const mutedUsers = useMutedUsers(client); + const mutedUsers = useMutedUsers(client); const debugRef = useDebugContext(); const isDebugModeEnabled = __DEV__ && debugRef && debugRef.current; @@ -214,7 +205,7 @@ const ChatWithContext = < // eslint-disable-next-line react-hooks/exhaustive-deps }, [client, enableOfflineSupport]); - const setActiveChannel = (newChannel?: Channel) => setChannel(newChannel); + const setActiveChannel = (newChannel?: Channel) => setChannel(newChannel); useEffect(() => { if (!(userID && enableOfflineSupport)) { @@ -294,12 +285,12 @@ const ChatWithContext = < } return ( - value={chatContext}> + - >{children} + {children} @@ -327,11 +318,7 @@ const ChatWithContext = < * - Re (ReactionType) - custom Reaction object extension * - Us (UserType) - custom User object extension */ -export const Chat = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: PropsWithChildren>, -) => { +export const Chat = (props: PropsWithChildren) => { const { style } = useOverlayContext(); return ; diff --git a/package/src/components/Chat/hooks/handleEventToSyncDB.ts b/package/src/components/Chat/hooks/handleEventToSyncDB.ts index e3ea1d7c2b..8f90918a46 100644 --- a/package/src/components/Chat/hooks/handleEventToSyncDB.ts +++ b/package/src/components/Chat/hooks/handleEventToSyncDB.ts @@ -14,15 +14,8 @@ import { upsertReads } from '../../../store/apis/upsertReads'; import { createSelectQuery } from '../../../store/sqlite-utils/createSelectQuery'; import { SqliteClient } from '../../../store/SqliteClient'; import { PreparedQueries } from '../../../store/types'; -import { DefaultStreamChatGenerics } from '../../../types/types'; -export const handleEventToSyncDB = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - event: Event, - client: StreamChat, - flush?: boolean, -) => { +export const handleEventToSyncDB = async (event: Event, client: StreamChat, flush?: boolean) => { const { type } = event; // This function is used to guard the queries that require channel to be present in the db first diff --git a/package/src/components/Chat/hooks/useAppSettings.ts b/package/src/components/Chat/hooks/useAppSettings.ts index 6ea63488ea..f51a34931e 100644 --- a/package/src/components/Chat/hooks/useAppSettings.ts +++ b/package/src/components/Chat/hooks/useAppSettings.ts @@ -4,12 +4,9 @@ import type { AppSettingsAPIResponse, StreamChat } from 'stream-chat'; import { useIsMountedRef } from '../../../hooks/useIsMountedRef'; import * as dbApi from '../../../store/apis'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; -export const useAppSettings = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - client: StreamChat, +export const useAppSettings = ( + client: StreamChat, isOnline: boolean | null, enableOfflineSupport: boolean, initialisedDatabase: boolean, diff --git a/package/src/components/Chat/hooks/useCreateChatClient.ts b/package/src/components/Chat/hooks/useCreateChatClient.ts index eb5625001a..eab9a51f0f 100644 --- a/package/src/components/Chat/hooks/useCreateChatClient.ts +++ b/package/src/components/Chat/hooks/useCreateChatClient.ts @@ -3,8 +3,6 @@ import { useEffect, useState } from 'react'; import { StreamChat } from 'stream-chat'; import type { - DefaultGenerics, - ExtendableGenerics, OwnUserResponse, StreamChatOptions, TokenOrProvider, @@ -14,7 +12,7 @@ import type { /** * React hook to create, connect and return `StreamChat` client. */ -export const useCreateChatClient = ({ +export const useCreateChatClient = ({ apiKey, options, tokenOrProvider, @@ -22,10 +20,10 @@ export const useCreateChatClient = | UserResponse; + userData: OwnUserResponse | UserResponse; options?: StreamChatOptions; }) => { - const [chatClient, setChatClient] = useState | null>(null); + const [chatClient, setChatClient] = useState(null); const [cachedUserData, setCachedUserData] = useState(userData); if (userData.id !== cachedUserData.id) { @@ -35,7 +33,7 @@ export const useCreateChatClient = { - const client = new StreamChat(apiKey, undefined, cachedOptions); + const client = new StreamChat(apiKey, undefined, cachedOptions); let didUserConnectInterrupt = false; const connectionPromise = client.connectUser(cachedUserData, tokenOrProvider).then(() => { diff --git a/package/src/components/Chat/hooks/useCreateChatContext.ts b/package/src/components/Chat/hooks/useCreateChatContext.ts index e39728c142..2992dbc961 100644 --- a/package/src/components/Chat/hooks/useCreateChatContext.ts +++ b/package/src/components/Chat/hooks/useCreateChatContext.ts @@ -1,11 +1,8 @@ import { useMemo } from 'react'; import type { ChatContextValue } from '../../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; -export const useCreateChatContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useCreateChatContext = ({ appSettings, channel, client, @@ -16,7 +13,7 @@ export const useCreateChatContext = < isOnline, mutedUsers, setActiveChannel, -}: ChatContextValue) => { +}: ChatContextValue) => { const channelId = channel?.id; const clientValues = client ? `${client.clientID}${Object.keys(client.activeChannels).length}${ @@ -25,7 +22,7 @@ export const useCreateChatContext = < : 'Offline'; const mutedUsersLength = mutedUsers.length; - const chatContext: ChatContextValue = useMemo( + const chatContext: ChatContextValue = useMemo( () => ({ appSettings, channel, diff --git a/package/src/components/Chat/hooks/useIsOnline.ts b/package/src/components/Chat/hooks/useIsOnline.ts index d9fd3c0fa2..15b12fd913 100644 --- a/package/src/components/Chat/hooks/useIsOnline.ts +++ b/package/src/components/Chat/hooks/useIsOnline.ts @@ -7,20 +7,13 @@ import type { StreamChat, Event as StreamEvent } from 'stream-chat'; import { useAppStateListener } from '../../../hooks/useAppStateListener'; import { useIsMountedRef } from '../../../hooks/useIsMountedRef'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; - /** * Disconnect the websocket connection when app goes to background, * and reconnect when app comes to foreground. * We do this to make sure the user receives push notifications when app is in the background. * You can't receive push notification until you have active websocket connection. */ -export const useIsOnline = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - client: StreamChat, - closeConnectionOnBackground = true, -) => { +export const useIsOnline = (client: StreamChat, closeConnectionOnBackground = true) => { const [isOnline, setIsOnline] = useState(null); const [connectionRecovering, setConnectionRecovering] = useState(false); const isMounted = useIsMountedRef(); @@ -47,7 +40,7 @@ export const useIsOnline = < useAppStateListener(onForeground, onBackground); useEffect(() => { - const handleChangedEvent = (event: StreamEvent) => { + const handleChangedEvent = (event: StreamEvent) => { setConnectionRecovering(!event.online); setIsOnline(event.online || false); }; diff --git a/package/src/components/Chat/hooks/useMutedUsers.ts b/package/src/components/Chat/hooks/useMutedUsers.ts index 8aa77163a0..07f88ce028 100644 --- a/package/src/components/Chat/hooks/useMutedUsers.ts +++ b/package/src/components/Chat/hooks/useMutedUsers.ts @@ -2,19 +2,11 @@ import { useEffect, useState } from 'react'; import type { Event, Mute, StreamChat } from 'stream-chat'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; - -export const useMutedUsers = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - client: StreamChat, -) => { - const [mutedUsers, setMutedUsers] = useState[]>( - client?.mutedUsers || [], - ); +export const useMutedUsers = (client: StreamChat) => { + const [mutedUsers, setMutedUsers] = useState(client?.mutedUsers || []); useEffect(() => { - const handleEvent = (event: Event) => { + const handleEvent = (event: Event) => { setMutedUsers((mutes) => event.me?.mutes || mutes || []); }; diff --git a/package/src/components/Chat/hooks/useSyncDatabase.ts b/package/src/components/Chat/hooks/useSyncDatabase.ts index 2aa4e8b01d..10401a2f07 100644 --- a/package/src/components/Chat/hooks/useSyncDatabase.ts +++ b/package/src/components/Chat/hooks/useSyncDatabase.ts @@ -4,20 +4,12 @@ import type { StreamChat } from 'stream-chat'; import { handleEventToSyncDB } from './handleEventToSyncDB'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; - -type Params = { - client: StreamChat; +type Params = { + client: StreamChat; enableOfflineSupport: boolean; initialisedDatabase: boolean; }; -export const useSyncDatabase = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - client, - enableOfflineSupport, - initialisedDatabase, -}: Params) => { +export const useSyncDatabase = ({ client, enableOfflineSupport, initialisedDatabase }: Params) => { useEffect(() => { let listener: ReturnType | undefined; diff --git a/package/src/components/ImageGallery/ImageGallery.tsx b/package/src/components/ImageGallery/ImageGallery.tsx index 40776564bc..f9242e1b6f 100644 --- a/package/src/components/ImageGallery/ImageGallery.tsx +++ b/package/src/components/ImageGallery/ImageGallery.tsx @@ -42,7 +42,7 @@ import { OverlayProviderProps } from '../../contexts/overlayContext/OverlayConte import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { useViewport } from '../../hooks/useViewport'; import { isVideoPlayerAvailable, VideoType } from '../../native'; -import { DefaultStreamChatGenerics, FileTypes } from '../../types/types'; +import { FileTypes } from '../../types/types'; import { getResizedImageUrl } from '../../utils/getResizedImageUrl'; import { getUrlOfImageAttachment } from '../../utils/getUrlOfImageAttachment'; import { getGiphyMimeType } from '../Attachment/utils/getGiphyMimeType'; @@ -64,9 +64,7 @@ export enum IsSwiping { FALSE, } -export type ImageGalleryCustomComponents< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type ImageGalleryCustomComponents = { /** * Override props for following UI components, which are part of [image gallery](https://github.com/GetStream/stream-chat-react-native/wiki/Cookbook-v3.0#gallery-components). * @@ -99,30 +97,25 @@ export type ImageGalleryCustomComponents< * @overrideType object */ imageGalleryCustomComponents?: { - footer?: ImageGalleryFooterCustomComponentProps; - grid?: ImageGalleryGridImageComponents; + footer?: ImageGalleryFooterCustomComponentProps; + grid?: ImageGalleryGridImageComponents; gridHandle?: ImageGalleryGridHandleCustomComponentProps; - header?: ImageGalleryHeaderCustomComponentProps; + header?: ImageGalleryHeaderCustomComponentProps; }; }; -type Props = - ImageGalleryCustomComponents & { - overlayOpacity: SharedValue; - } & Pick< - OverlayProviderProps, - | 'giphyVersion' - | 'imageGalleryGridSnapPoints' - | 'imageGalleryGridHandleHeight' - | 'numberOfImageGalleryGridColumns' - | 'autoPlayVideo' - >; - -export const ImageGallery = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: Props, -) => { +type Props = ImageGalleryCustomComponents & { + overlayOpacity: SharedValue; +} & Pick< + OverlayProviderProps, + | 'giphyVersion' + | 'imageGalleryGridSnapPoints' + | 'imageGalleryGridHandleHeight' + | 'numberOfImageGalleryGridColumns' + | 'autoPlayVideo' + >; + +export const ImageGallery = (props: Props) => { const { autoPlayVideo = false, giphyVersion = 'fixed_height', @@ -132,9 +125,7 @@ export const ImageGallery = < numberOfImageGalleryGridColumns, overlayOpacity, } = props; - const [imageGalleryAttachments, setImageGalleryAttachments] = useState< - Photo[] - >([]); + const [imageGalleryAttachments, setImageGalleryAttachments] = useState([]); const { resizableCDNHosts } = useChatConfigContext(); const { theme: { @@ -142,9 +133,8 @@ export const ImageGallery = < imageGallery: { backgroundColor, pager, slide }, }, } = useTheme(); - const [gridPhotos, setGridPhotos] = useState[]>([]); - const { messages, selectedMessage, setSelectedMessage } = - useImageGalleryContext(); + const [gridPhotos, setGridPhotos] = useState([]); + const { messages, selectedMessage, setSelectedMessage } = useImageGalleryContext(); const { vh, vw } = useViewport(); @@ -224,7 +214,7 @@ export const ImageGallery = < * photo attachments */ - const photos = messages.reduce((acc: Photo[], cur) => { + const photos = messages.reduce((acc: Photo[], cur) => { const attachmentImages = cur.attachments ?.filter( @@ -273,7 +263,7 @@ export const ImageGallery = < }; }); - return [...attachmentPhotos, ...acc] as Photo[]; + return [...attachmentPhotos, ...acc] as Photo[]; }, []); /** @@ -583,7 +573,7 @@ export const ImageGallery = < - + {imageGalleryAttachments[selectedIndex] && ( - + = { +export type Photo = { id: string; uri: string; channelId?: string; @@ -669,7 +657,7 @@ export type Photo< progress?: number; thumb_url?: string; type?: string; - user?: UserResponse | null; + user?: UserResponse | null; user_id?: string; }; diff --git a/package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx b/package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx index 85d862db1a..402de210b0 100644 --- a/package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +++ b/package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx @@ -17,7 +17,7 @@ import { generateVideoAttachment, } from '../../../mock-builders/generator/attachment'; import { generateMessage } from '../../../mock-builders/generator/message'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import type { MessageType } from '../../MessageList/hooks/useMessageList'; import { ImageGallery } from '../ImageGallery'; diff --git a/package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx b/package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx index ad041353f8..ca168a1471 100644 --- a/package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx +++ b/package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx @@ -20,7 +20,7 @@ import { import { generateMessage } from '../../../mock-builders/generator/message'; import { getTestClientWithUser } from '../../../mock-builders/mock'; import * as NativeUtils from '../../../native'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import type { MessageType } from '../../MessageList/hooks/useMessageList'; import { ImageGallery, ImageGalleryCustomComponents } from '../ImageGallery'; diff --git a/package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx b/package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx index c89109c237..a31d617d97 100644 --- a/package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx +++ b/package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx @@ -23,7 +23,7 @@ import { } from '../../../mock-builders/generator/attachment'; import { generateMessage } from '../../../mock-builders/generator/message'; import { getTestClientWithUser } from '../../../mock-builders/mock'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import type { MessageType } from '../../MessageList/hooks/useMessageList'; import { ImageGallery, ImageGalleryCustomComponents } from '../ImageGallery'; diff --git a/package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx b/package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx index b008904e67..557ded66cb 100644 --- a/package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx +++ b/package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx @@ -19,7 +19,7 @@ import { import { generateImageAttachment } from '../../../mock-builders/generator/attachment'; import { generateMessage } from '../../../mock-builders/generator/message'; import { getTestClientWithUser } from '../../../mock-builders/mock'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import type { MessageType } from '../../MessageList/hooks/useMessageList'; import { ImageGalleryOverlay } from '../components/ImageGalleryOverlay'; diff --git a/package/src/components/ImageGallery/components/ImageGalleryFooter.tsx b/package/src/components/ImageGallery/components/ImageGalleryFooter.tsx index 95cec819ab..2ce89cddce 100644 --- a/package/src/components/ImageGallery/components/ImageGalleryFooter.tsx +++ b/package/src/components/ImageGallery/components/ImageGalleryFooter.tsx @@ -25,12 +25,10 @@ const ReanimatedSafeAreaView = Animated.createAnimatedComponent ? Animated.createAnimatedComponent(SafeAreaView) : SafeAreaView; -import { DefaultStreamChatGenerics, FileTypes } from '../../../types/types'; +import { FileTypes } from '../../../types/types'; import type { Photo } from '../ImageGallery'; -export type ImageGalleryFooterCustomComponent< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = ({ +export type ImageGalleryFooterCustomComponent = ({ openGridView, photo, share, @@ -39,7 +37,7 @@ export type ImageGalleryFooterCustomComponent< openGridView: () => void; share: () => Promise; shareMenuOpen: boolean; - photo?: Photo; + photo?: Photo; }) => React.ReactElement | null; export type ImageGalleryFooterVideoControlProps = { @@ -57,27 +55,23 @@ export type ImageGalleryFooterVideoControlComponent = ({ progress, }: ImageGalleryFooterVideoControlProps) => React.ReactElement | null; -export type ImageGalleryFooterCustomComponentProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - centerElement?: ImageGalleryFooterCustomComponent; +export type ImageGalleryFooterCustomComponentProps = { + centerElement?: ImageGalleryFooterCustomComponent; GridIcon?: React.ReactElement; - leftElement?: ImageGalleryFooterCustomComponent; - rightElement?: ImageGalleryFooterCustomComponent; + leftElement?: ImageGalleryFooterCustomComponent; + rightElement?: ImageGalleryFooterCustomComponent; ShareIcon?: React.ReactElement; videoControlElement?: ImageGalleryFooterVideoControlComponent; }; -type ImageGalleryFooterPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = ImageGalleryFooterCustomComponentProps & { +type ImageGalleryFooterPropsWithContext = ImageGalleryFooterCustomComponentProps & { accessibilityLabel: string; duration: number; onPlayPause: () => void; opacity: SharedValue; openGridView: () => void; paused: boolean; - photo: Photo; + photo: Photo; photoLength: number; progress: number; selectedIndex: number; @@ -85,11 +79,7 @@ type ImageGalleryFooterPropsWithContext< visible: SharedValue; }; -export const ImageGalleryFooterWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ImageGalleryFooterPropsWithContext, -) => { +export const ImageGalleryFooterWithContext = (props: ImageGalleryFooterPropsWithContext) => { const { accessibilityLabel, centerElement, @@ -241,9 +231,9 @@ const ShareButton = ({ share, ShareIcon, shareMenuOpen }: ShareButtonProps) => { ); }; -const areEqual = ( - prevProps: ImageGalleryFooterPropsWithContext, - nextProps: ImageGalleryFooterPropsWithContext, +const areEqual = ( + prevProps: ImageGalleryFooterPropsWithContext, + nextProps: ImageGalleryFooterPropsWithContext, ) => { const { duration: prevDuration, @@ -286,15 +276,11 @@ const MemoizedImageGalleryFooter = React.memo( areEqual, ) as typeof ImageGalleryFooterWithContext; -export type ImageGalleryFooterProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = ImageGalleryFooterPropsWithContext; +export type ImageGalleryFooterProps = ImageGalleryFooterPropsWithContext; -export const ImageGalleryFooter = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ImageGalleryFooterProps, -) => ; +export const ImageGalleryFooter = (props: ImageGalleryFooterProps) => ( + +); ImageGalleryFooter.displayName = 'ImageGalleryFooter{imageGallery{footer}}'; diff --git a/package/src/components/ImageGallery/components/ImageGalleryHeader.tsx b/package/src/components/ImageGallery/components/ImageGalleryHeader.tsx index a2afec24d4..1c831681ff 100644 --- a/package/src/components/ImageGallery/components/ImageGalleryHeader.tsx +++ b/package/src/components/ImageGallery/components/ImageGalleryHeader.tsx @@ -12,7 +12,6 @@ import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext'; import { Close } from '../../../icons'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; import { getDateString } from '../../../utils/i18n/getDateString'; import type { Photo } from '../ImageGallery'; @@ -20,38 +19,29 @@ const ReanimatedSafeAreaView = Animated.createAnimatedComponent ? Animated.createAnimatedComponent(SafeAreaView) : SafeAreaView; -export type ImageGalleryHeaderCustomComponent< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = ({ +export type ImageGalleryHeaderCustomComponent = ({ hideOverlay, photo, }: { hideOverlay: () => void; - photo?: Photo; + photo?: Photo; }) => React.ReactElement | null; -export type ImageGalleryHeaderCustomComponentProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - centerElement?: ImageGalleryHeaderCustomComponent; +export type ImageGalleryHeaderCustomComponentProps = { + centerElement?: ImageGalleryHeaderCustomComponent; CloseIcon?: React.ReactElement; - leftElement?: ImageGalleryHeaderCustomComponent; - rightElement?: ImageGalleryHeaderCustomComponent; + leftElement?: ImageGalleryHeaderCustomComponent; + rightElement?: ImageGalleryHeaderCustomComponent; }; -type Props = - ImageGalleryHeaderCustomComponentProps & { - opacity: SharedValue; - visible: SharedValue; - photo?: Photo; - /* Lookup key in the language corresponding translations sheet to perform date formatting */ - }; +type Props = ImageGalleryHeaderCustomComponentProps & { + opacity: SharedValue; + visible: SharedValue; + photo?: Photo; + /* Lookup key in the language corresponding translations sheet to perform date formatting */ +}; -export const ImageGalleryHeader = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: Props, -) => { +export const ImageGalleryHeader = (props: Props) => { const { centerElement, CloseIcon, leftElement, opacity, photo, rightElement, visible } = props; const [height, setHeight] = useState(200); const { diff --git a/package/src/components/ImageGallery/components/ImageGrid.tsx b/package/src/components/ImageGallery/components/ImageGrid.tsx index ca03d49302..0cf5a70172 100644 --- a/package/src/components/ImageGallery/components/ImageGrid.tsx +++ b/package/src/components/ImageGallery/components/ImageGrid.tsx @@ -4,7 +4,7 @@ import { Image, StyleSheet, View } from 'react-native'; import { VideoThumbnail } from '../../../components/Attachment/VideoThumbnail'; import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { useViewport } from '../../../hooks/useViewport'; -import { DefaultStreamChatGenerics, FileTypes } from '../../../types/types'; +import { FileTypes } from '../../../types/types'; import { BottomSheetFlatList } from '../../BottomSheetCompatibility/BottomSheetFlatList'; import { BottomSheetTouchableOpacity } from '../../BottomSheetCompatibility/BottomSheetTouchableOpacity'; @@ -31,39 +31,27 @@ const styles = StyleSheet.create({ }, }); -export type ImageGalleryGridImageComponent< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = ({ +export type ImageGalleryGridImageComponent = ({ item, }: { - item: Photo & { + item: Photo & { selectAndClose: () => void; numberOfImageGalleryGridColumns?: number; }; }) => React.ReactElement | null; -export type ImageGalleryGridImageComponents< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - avatarComponent?: ImageGalleryGridImageComponent; - imageComponent?: ImageGalleryGridImageComponent; +export type ImageGalleryGridImageComponents = { + avatarComponent?: ImageGalleryGridImageComponent; + imageComponent?: ImageGalleryGridImageComponent; }; -export type GridImageItem< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Photo & - ImageGalleryGridImageComponents & { +export type GridImageItem = Photo & + ImageGalleryGridImageComponents & { selectAndClose: () => void; numberOfImageGalleryGridColumns?: number; }; -const GridImage = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - item, -}: { - item: GridImageItem; -}) => { +const GridImage = ({ item }: { item: GridImageItem }) => { const { theme: { imageGallery: { @@ -95,19 +83,11 @@ const GridImage = < ); }; -const renderItem = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - item, -}: { - item: GridImageItem; -}) => ; +const renderItem = ({ item }: { item: GridImageItem }) => ; -export type ImageGridType< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = ImageGalleryGridImageComponents & { +export type ImageGridType = ImageGalleryGridImageComponents & { closeGridView: () => void; - photos: Photo[]; + photos: Photo[]; setSelectedMessage: React.Dispatch< React.SetStateAction< | { @@ -120,11 +100,7 @@ export type ImageGridType< numberOfImageGalleryGridColumns?: number; }; -export const ImageGrid = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ImageGridType, -) => { +export const ImageGrid = (props: ImageGridType) => { const { avatarComponent, closeGridView, @@ -155,14 +131,14 @@ export const ImageGrid = < })); return ( - > + accessibilityLabel='Image Grid' contentContainerStyle={[ styles.contentContainer, { backgroundColor: white }, contentContainer, ]} - data={imageGridItems as GridImageItem[]} + data={imageGridItems as GridImageItem[]} keyExtractor={(item, index) => `${item.uri}-${index}`} numColumns={numberOfImageGalleryGridColumns || 3} renderItem={renderItem} diff --git a/package/src/components/Message/Message.tsx b/package/src/components/Message/Message.tsx index 47232641eb..211a519f55 100644 --- a/package/src/components/Message/Message.tsx +++ b/package/src/components/Message/Message.tsx @@ -32,7 +32,7 @@ import { } from '../../contexts/translationContext/TranslationContext'; import { isVideoPlayerAvailable, triggerHaptic } from '../../native'; -import { DefaultStreamChatGenerics, FileTypes } from '../../types/types'; +import { FileTypes } from '../../types/types'; import { hasOnlyEmojis, isBlockedMessage, @@ -56,15 +56,11 @@ export type TouchableEmitter = | 'messageReplies' | 'reactionList'; -export type TextMentionTouchableHandlerAdditionalInfo< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { user?: UserResponse }; +export type TextMentionTouchableHandlerAdditionalInfo = { user?: UserResponse }; -export type TextMentionTouchableHandlerPayload< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type TextMentionTouchableHandlerPayload = { emitter: 'textMention'; - additionalInfo?: TextMentionTouchableHandlerAdditionalInfo; + additionalInfo?: TextMentionTouchableHandlerAdditionalInfo; }; export type UrlTouchableHandlerAdditionalInfo = { url?: string }; @@ -74,15 +70,13 @@ export type UrlTouchableHandlerPayload = { additionalInfo?: UrlTouchableHandlerAdditionalInfo; }; -export type FileAttachmentTouchableHandlerAdditionalInfo< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { attachment?: Attachment }; +export type FileAttachmentTouchableHandlerAdditionalInfo = { + attachment?: Attachment; +}; -export type FileAttachmentTouchableHandlerPayload< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type FileAttachmentTouchableHandlerPayload = { emitter: 'fileAttachment'; - additionalInfo?: FileAttachmentTouchableHandlerAdditionalInfo; + additionalInfo?: FileAttachmentTouchableHandlerAdditionalInfo; }; export type GalleryThumbnailTouchableHandlerAdditionalInfo = { thumbnail?: Thumbnail }; @@ -108,13 +102,11 @@ export type PressableHandlerPayload = { | GalleryThumbnailTouchableHandlerPayload ); -export type MessagePressableHandlerPayload< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = PressableHandlerPayload & { +export type MessagePressableHandlerPayload = PressableHandlerPayload & { /** * Set of action handler functions for various message actions. You can use these functions to perform any action when give interaction occurs. */ - actionHandlers?: MessageActionHandlers; + actionHandlers?: MessageActionHandlers; /** * Additional message touchable handler info. */ @@ -122,12 +114,10 @@ export type MessagePressableHandlerPayload< /** * Message object, on which interaction occurred. */ - message?: MessageType; + message?: MessageType; }; -export type MessageActionHandlers< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type MessageActionHandlers = { copyMessage: () => void; deleteMessage: () => void; editMessage: () => void; @@ -140,25 +130,20 @@ export type MessageActionHandlers< toggleMuteUser: () => Promise; toggleReaction: (reactionType: string) => Promise; unpinMessage: () => Promise; - threadReply?: (message: MessageType) => Promise; + threadReply?: (message: MessageType) => Promise; }; -export type MessagePropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'channel' | 'enforceUniqueReaction' | 'members'> & +export type MessagePropsWithContext = Pick< + ChannelContextValue, + 'channel' | 'enforceUniqueReaction' | 'members' +> & Pick & Partial< - Omit< - MessageContextValue, - 'groupStyles' | 'handleReaction' | 'message' | 'isMessageAIGenerated' - > - > & - Pick< - MessageContextValue, - 'groupStyles' | 'message' | 'isMessageAIGenerated' + Omit > & + Pick & Pick< - MessagesContextValue, + MessagesContextValue, | 'sendReaction' | 'deleteMessage' | 'dismissKeyboardOnMessageTouch' @@ -194,10 +179,10 @@ export type MessagePropsWithContext< | 'updateMessage' | 'PollContent' > & - Pick, 'openThread'> & + Pick & Pick & { - chatContext: ChatContextValue; - messagesContext: MessagesContextValue; + chatContext: ChatContextValue; + messagesContext: MessagesContextValue; /** * Whether or not users are able to long press messages. */ @@ -209,7 +194,7 @@ export type MessagePropsWithContext< * * @param message A message object to open the thread upon. */ - onThreadSelect?: (message: MessageType) => void; + onThreadSelect?: (message: MessageType) => void; showUnreadUnderlay?: boolean; style?: StyleProp; }; @@ -219,11 +204,7 @@ export type MessagePropsWithContext< * we memoized and broke it up to prevent new messages from re-rendering * each individual Message component. */ -const MessageWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessagePropsWithContext, -) => { +const MessageWithContext = (props: MessagePropsWithContext) => { const [messageOverlayVisible, setMessageOverlayVisible] = useState(false); const [isErrorInMessage, setIsErrorInMessage] = useState(false); const [showMessageReactions, setShowMessageReactions] = useState(true); @@ -331,7 +312,7 @@ const MessageWithContext = < } }; - const onPressQuotedMessage = (quotedMessage: MessageType) => { + const onPressQuotedMessage = (quotedMessage: MessageType) => { if (!goToMessage) { return; } @@ -348,7 +329,7 @@ const MessageWithContext = < if (isEditedMessage(message)) { setIsEditedMessageOpen((prevState) => !prevState); } - const quotedMessage = message.quoted_message as MessageType; + const quotedMessage = message.quoted_message as MessageType; if (error) { setIsErrorInMessage(true); /** @@ -424,17 +405,17 @@ const MessageWithContext = < return acc; }, { - files: [] as Attachment[], - images: [] as Attachment[], - other: [] as Attachment[], - videos: [] as Attachment[], + files: [] as Attachment[], + images: [] as Attachment[], + other: [] as Attachment[], + videos: [] as Attachment[], }, ) : { - files: [] as Attachment[], - images: [] as Attachment[], - other: [] as Attachment[], - videos: [] as Attachment[], + files: [] as Attachment[], + images: [] as Attachment[], + other: [] as Attachment[], + videos: [] as Attachment[], }; /** * Check if any actions to prevent long press @@ -598,7 +579,7 @@ const MessageWithContext = < unpinMessage, }); - const actionHandlers: MessageActionHandlers = { + const actionHandlers: MessageActionHandlers = { copyMessage: handleCopyMessage, deleteMessage: handleDeleteMessage, editMessage: handleEditMessage, @@ -763,10 +744,7 @@ const MessageWithContext = < ); }; -const areEqual = ( - prevProps: MessagePropsWithContext, - nextProps: MessagePropsWithContext, -) => { +const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWithContext) => { const { chatContext: { mutedUsers: prevMutedUsers }, goToMessage: prevGoToMessage, @@ -934,12 +912,10 @@ const areEqual = = Partial< - Omit, 'groupStyles' | 'handleReaction' | 'message'> +export type MessageProps = Partial< + Omit > & - Pick, 'groupStyles' | 'message'>; + Pick; /** * Message - A high level component which implements all the logic required for a message. @@ -947,20 +923,16 @@ export type MessageProps< * * @example ./Message.md */ -export const Message = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageProps, -) => { - const { channel, enforceUniqueReaction, members } = useChannelContext(); - const chatContext = useChatContext(); +export const Message = (props: MessageProps) => { + const { channel, enforceUniqueReaction, members } = useChannelContext(); + const chatContext = useChatContext(); const { dismissKeyboard } = useKeyboardContext(); - const messagesContext = useMessagesContext(); - const { openThread } = useThreadContext(); + const messagesContext = useMessagesContext(); + const { openThread } = useThreadContext(); const { t } = useTranslationContext(); return ( - + = Pick< - MessageContextValue, +export type MessageAvatarPropsWithContext = Pick< + MessageContextValue, 'alignment' | 'lastGroupMessage' | 'message' | 'showAvatar' > & - Pick, 'ImageComponent'> & + Pick & Partial>; -const MessageAvatarWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageAvatarPropsWithContext, -) => { +const MessageAvatarWithContext = (props: MessageAvatarPropsWithContext) => { const { alignment, ImageComponent, lastGroupMessage, message, showAvatar, size } = props; const { theme: { @@ -56,9 +49,9 @@ const MessageAvatarWithContext = < ); }; -const areEqual = ( - prevProps: MessageAvatarPropsWithContext, - nextProps: MessageAvatarPropsWithContext, +const areEqual = ( + prevProps: MessageAvatarPropsWithContext, + nextProps: MessageAvatarPropsWithContext, ) => { const { lastGroupMessage: prevLastGroupMessage, message: prevMessage } = prevProps; const { lastGroupMessage: nextLastGroupMessage, message: nextMessage } = nextProps; @@ -84,18 +77,11 @@ const MemoizedMessageAvatar = React.memo( areEqual, ) as typeof MessageAvatarWithContext; -export type MessageAvatarProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type MessageAvatarProps = Partial; -export const MessageAvatar = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageAvatarProps, -) => { - const { alignment, lastGroupMessage, message, showAvatar } = - useMessageContext(); - const { ImageComponent } = useChatContext(); +export const MessageAvatar = (props: MessageAvatarProps) => { + const { alignment, lastGroupMessage, message, showAvatar } = useMessageContext(); + const { ImageComponent } = useChatContext(); return ( = Pick< - MessagesContextValue, +export type MessageBouncePropsWithContext = Pick< + MessagesContextValue, 'setEditingState' | 'removeMessage' | 'retrySendMessage' > & - Pick, 'message'> & { + Pick & { setIsBounceDialogOpen: React.Dispatch>; }; -export const MessageBounceWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageBouncePropsWithContext, -) => { +export const MessageBounceWithContext = (props: MessageBouncePropsWithContext) => { const { t } = useTranslationContext(); const { message, removeMessage, retrySendMessage, setEditingState, setIsBounceDialogOpen } = props; @@ -71,9 +63,9 @@ export const MessageBounceWithContext = < ); }; -const areEqual = ( - prevProps: MessageBouncePropsWithContext, - nextProps: MessageBouncePropsWithContext, +const areEqual = ( + prevProps: MessageBouncePropsWithContext, + nextProps: MessageBouncePropsWithContext, ) => { const { message: prevMessage } = prevProps; const { message: nextMessage } = nextProps; @@ -93,22 +85,15 @@ const MemoizedMessageBounce = React.memo( areEqual, ) as typeof MessageBounceWithContext; -export type MessageBounceProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial> & { +export type MessageBounceProps = Partial & { setIsBounceDialogOpen: React.Dispatch>; }; -export const MessageBounce = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageBounceProps, -) => { - const { message } = useMessageContext(); - const { removeMessage, retrySendMessage, setEditingState } = - useMessagesContext(); +export const MessageBounce = (props: MessageBounceProps) => { + const { message } = useMessageContext(); + const { removeMessage, retrySendMessage, setEditingState } = useMessagesContext(); return ( - + = Pick< - MessageContextValue, +export type MessageContentPropsWithContext = Pick< + MessageContextValue, | 'alignment' | 'goToMessage' | 'groupStyles' @@ -85,7 +83,7 @@ export type MessageContentPropsWithContext< | 'isMessageAIGenerated' > & Pick< - MessagesContextValue, + MessagesContextValue, | 'additionalPressableProps' | 'Attachment' | 'FileAttachmentGroup' @@ -111,11 +109,7 @@ export type MessageContentPropsWithContext< /** * Child of MessageSimple that displays a message's content */ -const MessageContentWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageContentPropsWithContext, -) => { +const MessageContentWithContext = (props: MessageContentPropsWithContext) => { const { additionalPressableProps, alignment, @@ -334,7 +328,7 @@ const MessageContentWithContext = < default: return (otherAttachments.length && otherAttachments[0].actions) || isAIGenerated ? null : ( - + ); @@ -347,9 +341,9 @@ const MessageContentWithContext = < ); }; -const areEqual = ( - prevProps: MessageContentPropsWithContext, - nextProps: MessageContentPropsWithContext, +const areEqual = ( + prevProps: MessageContentPropsWithContext, + nextProps: MessageContentPropsWithContext, ) => { const { goToMessage: prevGoToMessage, @@ -487,19 +481,15 @@ const MemoizedMessageContent = React.memo( areEqual, ) as typeof MessageContentWithContext; -export type MessageContentProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial, 'setMessageContentWidth'>> & - Pick, 'setMessageContentWidth'>; +export type MessageContentProps = Partial< + Omit +> & + Pick; /** * Child of MessageSimple that displays a message's content */ -export const MessageContent = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageContentProps, -) => { +export const MessageContent = (props: MessageContentProps) => { const { alignment, goToMessage, @@ -516,7 +506,7 @@ export const MessageContent = < otherAttachments, preventPress, threadList, - } = useMessageContext(); + } = useMessageContext(); const { additionalPressableProps, Attachment, @@ -527,11 +517,11 @@ export const MessageContent = < myMessageTheme, Reply, StreamingMessageView, - } = useMessagesContext(); + } = useMessagesContext(); const { t } = useTranslationContext(); return ( - + = Pick, 'alignment' | 'message'> & - Pick, 'MessageFooter'> & +type MessageDeletedPropsWithContext = Pick & + Pick & MessageDeletedComponentProps; -const MessageDeletedWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageDeletedPropsWithContext, -) => { +const MessageDeletedWithContext = (props: MessageDeletedPropsWithContext) => { const { alignment, date, groupStyle, message, MessageFooter, noBorder, onLayout } = props; const { @@ -96,7 +88,7 @@ const MessageDeletedWithContext = < deletedContainerInner, ]} > - + @@ -106,9 +98,9 @@ const MessageDeletedWithContext = < ); }; -const areEqual = ( - prevProps: MessageDeletedPropsWithContext, - nextProps: MessageDeletedPropsWithContext, +const areEqual = ( + prevProps: MessageDeletedPropsWithContext, + nextProps: MessageDeletedPropsWithContext, ) => { const { alignment: prevAlignment, date: prevDate, message: prevMessage } = prevProps; const { alignment: nextAlignment, date: nextDate, message: nextMessage } = nextProps; @@ -144,22 +136,16 @@ const MemoizedMessageDeleted = React.memo( areEqual, ) as typeof MessageDeletedWithContext; -export type MessageDeletedProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial> & { +export type MessageDeletedProps = Partial & { groupStyle: string; noBorder: boolean; onLayout: (event: LayoutChangeEvent) => void; }; -export const MessageDeleted = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageDeletedProps, -) => { - const { alignment, message } = useMessageContext(); +export const MessageDeleted = (props: MessageDeletedProps) => { + const { alignment, message } = useMessageContext(); - const { MessageFooter } = useMessagesContext(); + const { MessageFooter } = useMessagesContext(); return ( = Partial, 'message'>> & - Partial, 'MessageTimestamp'>>; +export type MessageEditedTimestampProps = Partial> & + Partial>; -export const MessageEditedTimestamp = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageEditedTimestampProps, -) => { +export const MessageEditedTimestamp = (props: MessageEditedTimestampProps) => { const { message: propMessage, MessageTimestamp } = props; const { theme: { @@ -31,7 +24,7 @@ export const MessageEditedTimestamp = < }, } = useTheme(); const { t } = useTranslationContext(); - const { message: contextMessage } = useMessageContext(); + const { message: contextMessage } = useMessageContext(); const message = propMessage || contextMessage; if (!isEditedMessage(message)) { diff --git a/package/src/components/Message/MessageSimple/MessageFooter.tsx b/package/src/components/Message/MessageSimple/MessageFooter.tsx index b2a03f622f..6c5fb99c74 100644 --- a/package/src/components/Message/MessageSimple/MessageFooter.tsx +++ b/package/src/components/Message/MessageSimple/MessageFooter.tsx @@ -20,7 +20,6 @@ import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext'; import { Eye } from '../../../icons'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; import { isEditedMessage, MessageStatusTypes } from '../../../utils/utils'; import type { MessageType } from '../../MessageList/hooks/useMessageList'; @@ -30,10 +29,8 @@ type MessageFooterComponentProps = { isDeleted?: boolean; }; -type MessageFooterPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick< - MessageContextValue, +type MessageFooterPropsWithContext = Pick< + MessageContextValue, | 'alignment' | 'isEditedMessageOpen' | 'members' @@ -44,7 +41,7 @@ type MessageFooterPropsWithContext< | 'isMessageAIGenerated' > & Pick< - MessagesContextValue, + MessagesContextValue, | 'deletedMessagesVisibilityType' | 'MessageEditedTimestamp' | 'MessageStatus' @@ -83,11 +80,7 @@ const OnlyVisibleToYouComponent = ({ alignment }: { alignment: Alignment }) => { ); }; -const MessageFooterWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageFooterPropsWithContext, -) => { +const MessageFooterWithContext = (props: MessageFooterPropsWithContext) => { const { alignment, date, @@ -177,9 +170,9 @@ const MessageFooterWithContext = < ); }; -const areEqual = ( - prevProps: MessageFooterPropsWithContext, - nextProps: MessageFooterPropsWithContext, +const areEqual = ( + prevProps: MessageFooterPropsWithContext, + nextProps: MessageFooterPropsWithContext, ) => { const { alignment: prevAlignment, @@ -274,23 +267,17 @@ const MemoizedMessageFooter = React.memo( areEqual, ) as typeof MessageFooterWithContext; -export type MessageFooterProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial, 'members'>> & +export type MessageFooterProps = Partial> & MessageFooterComponentProps & { alignment?: Alignment; lastGroupMessage?: boolean; - message?: MessageType; - MessageStatus?: React.ComponentType>; - otherAttachments?: Attachment[]; + message?: MessageType; + MessageStatus?: React.ComponentType; + otherAttachments?: Attachment[]; showMessageStatus?: boolean; }; -export const MessageFooter = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageFooterProps, -) => { +export const MessageFooter = (props: MessageFooterProps) => { const { alignment, isEditedMessageOpen, @@ -300,10 +287,10 @@ export const MessageFooter = < message, otherAttachments, showMessageStatus, - } = useMessageContext(); + } = useMessageContext(); const { deletedMessagesVisibilityType, MessageEditedTimestamp, MessageStatus, MessageTimestamp } = - useMessagesContext(); + useMessagesContext(); return ( >; -export type MessagePinnedHeaderProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial, 'message'>>; - -export const MessagePinnedHeader = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessagePinnedHeaderProps, -) => { +export const MessagePinnedHeader = (props: MessagePinnedHeaderProps) => { const { message: propMessage } = props; - const { message: contextMessage } = useMessageContext(); + const { message: contextMessage } = useMessageContext(); const message = propMessage || contextMessage; const { theme: { diff --git a/package/src/components/Message/MessageSimple/MessageReplies.tsx b/package/src/components/Message/MessageSimple/MessageReplies.tsx index 5b0f7bccf9..d4e15bff5f 100644 --- a/package/src/components/Message/MessageSimple/MessageReplies.tsx +++ b/package/src/components/Message/MessageSimple/MessageReplies.tsx @@ -15,8 +15,6 @@ import { useTranslationContext, } from '../../../contexts/translationContext/TranslationContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; - const styles = StyleSheet.create({ container: { alignItems: 'center', @@ -48,10 +46,8 @@ const styles = StyleSheet.create({ }, }); -export type MessageRepliesPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick< - MessageContextValue, +export type MessageRepliesPropsWithContext = Pick< + MessageContextValue, | 'alignment' | 'message' | 'onLongPress' @@ -61,17 +57,13 @@ export type MessageRepliesPropsWithContext< | 'preventPress' | 'threadList' > & - Pick, 'MessageRepliesAvatars'> & + Pick & Pick & { noBorder?: boolean; repliesCurveColor?: ColorValue; }; -const MessageRepliesWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageRepliesPropsWithContext, -) => { +const MessageRepliesWithContext = (props: MessageRepliesPropsWithContext) => { const { alignment, message, @@ -175,9 +167,9 @@ const MessageRepliesWithContext = < ); }; -const areEqual = ( - prevProps: MessageRepliesPropsWithContext, - nextProps: MessageRepliesPropsWithContext, +const areEqual = ( + prevProps: MessageRepliesPropsWithContext, + nextProps: MessageRepliesPropsWithContext, ) => { const { message: prevMessage, @@ -234,15 +226,9 @@ const MemoizedMessageReplies = React.memo( areEqual, ) as typeof MessageRepliesWithContext; -export type MessageRepliesProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type MessageRepliesProps = Partial; -export const MessageReplies = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageRepliesProps, -) => { +export const MessageReplies = (props: MessageRepliesProps) => { const { alignment, message, @@ -252,8 +238,8 @@ export const MessageReplies = < onPressIn, preventPress, threadList, - } = useMessageContext(); - const { MessageRepliesAvatars } = useMessagesContext(); + } = useMessageContext(); + const { MessageRepliesAvatars } = useMessagesContext(); const { t } = useTranslationContext(); return ( diff --git a/package/src/components/Message/MessageSimple/MessageRepliesAvatars.tsx b/package/src/components/Message/MessageSimple/MessageRepliesAvatars.tsx index 5485d9a428..715ad80b72 100644 --- a/package/src/components/Message/MessageSimple/MessageRepliesAvatars.tsx +++ b/package/src/components/Message/MessageSimple/MessageRepliesAvatars.tsx @@ -5,7 +5,6 @@ import { ChatContextValue, useChatContext } from '../../../contexts/chatContext/ import type { MessageContextValue } from '../../../contexts/messageContext/MessageContext'; import { useTheme } from '../../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; import { Avatar } from '../../Avatar/Avatar'; const styles = StyleSheet.create({ @@ -20,14 +19,10 @@ const styles = StyleSheet.create({ }, }); -export type MessageRepliesAvatarsProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'alignment' | 'message'>; +export type MessageRepliesAvatarsProps = Pick; -export const MessageRepliesAvatarsWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageRepliesAvatarsProps & Pick, +export const MessageRepliesAvatarsWithContext = ( + props: MessageRepliesAvatarsProps & Pick, ) => { const { alignment, ImageComponent, message } = props; @@ -88,11 +83,7 @@ export const MessageRepliesAvatarsWithContext = < ); }; -export const MessageRepliesAvatars = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageRepliesAvatarsProps, -) => { +export const MessageRepliesAvatars = (props: MessageRepliesAvatarsProps) => { const { ImageComponent } = useChatContext(); return ; diff --git a/package/src/components/Message/MessageSimple/MessageSimple.tsx b/package/src/components/Message/MessageSimple/MessageSimple.tsx index 0c883c77fe..3dea5c3d97 100644 --- a/package/src/components/Message/MessageSimple/MessageSimple.tsx +++ b/package/src/components/Message/MessageSimple/MessageSimple.tsx @@ -23,7 +23,7 @@ import { import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { triggerHaptic } from '../../../native'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { useMessageData } from '../hooks/useMessageData'; const styles = StyleSheet.create({ @@ -54,10 +54,8 @@ const styles = StyleSheet.create({ }, }); -export type MessageSimplePropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick< - MessageContextValue, +export type MessageSimplePropsWithContext = Pick< + MessageContextValue, | 'alignment' | 'channel' | 'groupStyles' @@ -71,7 +69,7 @@ export type MessageSimplePropsWithContext< | 'showMessageStatus' > & Pick< - MessagesContextValue, + MessagesContextValue, | 'clearQuotedMessageState' | 'enableMessageGroupingByUser' | 'enableSwipeToReply' @@ -92,11 +90,7 @@ export type MessageSimplePropsWithContext< | 'setQuotedMessageState' >; -const MessageSimpleWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageSimplePropsWithContext, -) => { +const MessageSimpleWithContext = (props: MessageSimplePropsWithContext) => { const [messageContentWidth, setMessageContentWidth] = useState(0); const { width } = Dimensions.get('screen'); const { @@ -390,9 +384,9 @@ const MessageSimpleWithContext = < ); }; -const areEqual = ( - prevProps: MessageSimplePropsWithContext, - nextProps: MessageSimplePropsWithContext, +const areEqual = ( + prevProps: MessageSimplePropsWithContext, + nextProps: MessageSimplePropsWithContext, ) => { const { channel: prevChannel, @@ -529,19 +523,13 @@ const MemoizedMessageSimple = React.memo( areEqual, ) as typeof MessageSimpleWithContext; -export type MessageSimpleProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type MessageSimpleProps = Partial; /** * * Message UI component */ -export const MessageSimple = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageSimpleProps, -) => { +export const MessageSimple = (props: MessageSimpleProps) => { const { alignment, channel, @@ -554,7 +542,7 @@ export const MessageSimple = < onlyEmojis, otherAttachments, showMessageStatus, - } = useMessageContext(); + } = useMessageContext(); const { clearQuotedMessageState, enableMessageGroupingByUser, @@ -574,10 +562,10 @@ export const MessageSimple = < reactionListPosition, ReactionListTop, setQuotedMessageState, - } = useMessagesContext(); + } = useMessagesContext(); return ( - + = Pick, 'message' | 'threadList'>; +export type MessageStatusPropsWithContext = Pick; -const MessageStatusWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageStatusPropsWithContext, -) => { +const MessageStatusWithContext = (props: MessageStatusPropsWithContext) => { const { message, threadList } = props; const { @@ -79,9 +73,9 @@ const MessageStatusWithContext = < return null; }; -const areEqual = ( - prevProps: MessageStatusPropsWithContext, - nextProps: MessageStatusPropsWithContext, +const areEqual = ( + prevProps: MessageStatusPropsWithContext, + nextProps: MessageStatusPropsWithContext, ) => { const { message: prevMessage, threadList: prevThreadList } = prevProps; const { message: nextMessage, threadList: nextThreadList } = nextProps; @@ -108,16 +102,10 @@ const MemoizedMessageStatus = React.memo( areEqual, ) as typeof MessageStatusWithContext; -export type MessageStatusProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type MessageStatusProps = Partial; -export const MessageStatus = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageStatusProps, -) => { - const { message, threadList } = useMessageContext(); +export const MessageStatus = (props: MessageStatusProps) => { + const { message, threadList } = useMessageContext(); return ; }; diff --git a/package/src/components/Message/MessageSimple/MessageTextContainer.tsx b/package/src/components/Message/MessageSimple/MessageTextContainer.tsx index e5a2f55988..30a4edb701 100644 --- a/package/src/components/Message/MessageSimple/MessageTextContainer.tsx +++ b/package/src/components/Message/MessageSimple/MessageTextContainer.tsx @@ -15,28 +15,24 @@ import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import type { MarkdownStyle, Theme } from '../../../contexts/themeContext/utils/theme'; import { useTranslatedMessage } from '../../../hooks/useTranslatedMessage'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import type { MessageType } from '../../MessageList/hooks/useMessageList'; const styles = StyleSheet.create({ textContainer: { maxWidth: 250, paddingHorizontal: 16 }, }); -export type MessageTextProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = MessageTextContainerProps & { - renderText: (params: RenderTextParams) => React.ReactNode | null; +export type MessageTextProps = MessageTextContainerProps & { + renderText: (params: RenderTextParams) => React.ReactNode | null; theme: { theme: Theme }; }; -export type MessageTextContainerPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick< - MessageContextValue, +export type MessageTextContainerPropsWithContext = Pick< + MessageContextValue, 'message' | 'onLongPress' | 'onlyEmojis' | 'onPress' | 'preventPress' > & Pick< - MessagesContextValue, + MessagesContextValue, 'markdownRules' | 'MessageText' | 'myMessageTheme' | 'messageTextNumberOfLines' > & { markdownStyles?: MarkdownStyle; @@ -46,11 +42,7 @@ export type MessageTextContainerPropsWithContext< }>; }; -const MessageTextContainerWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageTextContainerPropsWithContext, -) => { +const MessageTextContainerWithContext = (props: MessageTextContainerPropsWithContext) => { const theme = useTheme(); const { @@ -79,9 +71,7 @@ const MessageTextContainerWithContext = < }, } = theme; - const translatedMessage = useTranslatedMessage( - message, - ) as MessageType; + const translatedMessage = useTranslatedMessage(message) as MessageType; if (!message.text) { return null; @@ -97,7 +87,7 @@ const MessageTextContainerWithContext = < {MessageText ? ( ) : ( - renderText({ + renderText({ colors, markdownRules, markdownStyles: { @@ -117,9 +107,9 @@ const MessageTextContainerWithContext = < ); }; -const areEqual = ( - prevProps: MessageTextContainerPropsWithContext, - nextProps: MessageTextContainerPropsWithContext, +const areEqual = ( + prevProps: MessageTextContainerPropsWithContext, + nextProps: MessageTextContainerPropsWithContext, ) => { const { markdownStyles: prevMarkdownStyles, @@ -188,19 +178,12 @@ const MemoizedMessageTextContainer = React.memo( areEqual, ) as typeof MessageTextContainerWithContext; -export type MessageTextContainerProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type MessageTextContainerProps = Partial; -export const MessageTextContainer = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageTextContainerProps, -) => { - const { message, onLongPress, onlyEmojis, onPress, preventPress } = - useMessageContext(); +export const MessageTextContainer = (props: MessageTextContainerProps) => { + const { message, onLongPress, onlyEmojis, onPress, preventPress } = useMessageContext(); const { markdownRules, MessageText, messageTextNumberOfLines, myMessageTheme } = - useMessagesContext(); + useMessagesContext(); return ( { return ; }; -export type ReactionListBottomItemProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial< +export type ReactionListBottomItemProps = Partial< Pick< - MessageContextValue, + MessageContextValue, | 'handleReaction' | 'onLongPress' | 'onPress' @@ -44,15 +42,11 @@ export type ReactionListBottomItemProps< | 'showMessageOverlay' > > & - Partial, 'supportedReactions'>> & { + Partial> & { reaction: ReactionSummary; }; -export const ReactionListBottomItem = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ReactionListBottomItemProps, -) => { +export const ReactionListBottomItem = (props: ReactionListBottomItemProps) => { const { handleReaction, onLongPress, @@ -174,11 +168,9 @@ const renderItem = ({ index, item }: { index: number; item: ReactionListBottomIt /> ); -export type ReactionListBottomProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial< +export type ReactionListBottomProps = Partial< Pick< - MessageContextValue, + MessageContextValue, | 'handleReaction' | 'hasReactions' | 'onLongPress' @@ -189,13 +181,9 @@ export type ReactionListBottomProps< | 'showMessageOverlay' > > & - Partial, 'supportedReactions'>>; + Partial>; -export const ReactionListBottom = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ReactionListBottomProps, -) => { +export const ReactionListBottom = (props: ReactionListBottomProps) => { const { handleReaction: propHandlerReaction, hasReactions: propHasReactions, @@ -217,10 +205,9 @@ export const ReactionListBottom = < preventPress: contextPreventPress, reactions: contextReactions, showMessageOverlay: contextShowMessageOverlay, - } = useMessageContext(); + } = useMessageContext(); - const { supportedReactions: contextSupportedReactions } = - useMessagesContext(); + const { supportedReactions: contextSupportedReactions } = useMessagesContext(); const handleReaction = propHandlerReaction || contextHandleReaction; const hasReactions = propHasReactions || contextHasReactions; diff --git a/package/src/components/Message/MessageSimple/ReactionList/ReactionListTop.tsx b/package/src/components/Message/MessageSimple/ReactionList/ReactionListTop.tsx index 9344c726cf..51b3b6b795 100644 --- a/package/src/components/Message/MessageSimple/ReactionList/ReactionListTop.tsx +++ b/package/src/components/Message/MessageSimple/ReactionList/ReactionListTop.tsx @@ -14,7 +14,7 @@ import { useTheme } from '../../../../contexts/themeContext/ThemeContext'; import { Unknown } from '../../../../icons/Unknown'; import type { IconProps } from '../../../../icons/utils/base'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; + import type { ReactionData } from '../../../../utils/utils'; import { ReactionSummary } from '../../hooks/useProcessReactions'; @@ -35,19 +35,13 @@ const Icon = ({ pathFill, size, style, supportedReactions, type }: Props) => { ); }; -export type ReactionListTopItemProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial, 'reactions'>> & - Partial, 'supportedReactions'>> & { +export type ReactionListTopItemProps = Partial> & + Partial> & { index: number; reaction: ReactionSummary; }; -export const ReactionListTopItem = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ReactionListTopItemProps, -) => { +export const ReactionListTopItem = (props: ReactionListTopItemProps) => { const { index, reaction, reactions, supportedReactions } = props; const { theme: { @@ -84,11 +78,9 @@ export const ReactionListTopItem = < ); }; -export type ReactionListTopProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial< +export type ReactionListTopProps = Partial< Pick< - MessageContextValue, + MessageContextValue, | 'alignment' | 'hasReactions' | 'onLongPress' @@ -99,7 +91,7 @@ export type ReactionListTopProps< | 'showMessageOverlay' > > & - Pick, 'supportedReactions'> & { + Pick & { messageContentWidth: number; fill?: string; reactionSize?: number; @@ -108,11 +100,7 @@ export type ReactionListTopProps< /** * ReactionListTop - A high level component which implements all the logic required for a message reaction list */ -export const ReactionListTop = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ReactionListTopProps, -) => { +export const ReactionListTop = (props: ReactionListTopProps) => { const { alignment: propAlignment, fill: propFill, @@ -137,10 +125,9 @@ export const ReactionListTop = < preventPress: contextPreventPress, reactions: contextReactions, showMessageOverlay: contextShowMessageOverlay, - } = useMessageContext(); + } = useMessageContext(); - const { supportedReactions: contextSupportedReactions } = - useMessagesContext(); + const { supportedReactions: contextSupportedReactions } = useMessagesContext(); const alignment = propAlignment || contextAlignment; const hasReactions = propHasReactions || contextHasReactions; diff --git a/package/src/components/Message/MessageSimple/StreamingMessageView.tsx b/package/src/components/Message/MessageSimple/StreamingMessageView.tsx index 88dd0d1b64..c9566c21b6 100644 --- a/package/src/components/Message/MessageSimple/StreamingMessageView.tsx +++ b/package/src/components/Message/MessageSimple/StreamingMessageView.tsx @@ -3,23 +3,17 @@ import React from 'react'; import { MessageTextContainer, MessageTextContainerProps } from './MessageTextContainer'; import { useMessageContext } from '../../../contexts'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { useStreamingMessage } from '../hooks/useStreamingMessage'; -export type StreamingMessageViewProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'message'> & { +export type StreamingMessageViewProps = Pick & { letterInterval?: number; renderingLetterCount?: number; }; -export const StreamingMessageView = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: StreamingMessageViewProps, -) => { +export const StreamingMessageView = (props: StreamingMessageViewProps) => { const { letterInterval, message: messageFromProps, renderingLetterCount } = props; - const { message: messageFromContext } = useMessageContext(); + const { message: messageFromContext } = useMessageContext(); const message = messageFromProps || messageFromContext; const { text = '' } = message; const { streamedMessageText } = useStreamingMessage({ diff --git a/package/src/components/Message/MessageSimple/utils/renderText.tsx b/package/src/components/Message/MessageSimple/utils/renderText.tsx index 0df0ff4802..1c894900b0 100644 --- a/package/src/components/Message/MessageSimple/utils/renderText.tsx +++ b/package/src/components/Message/MessageSimple/utils/renderText.tsx @@ -32,7 +32,7 @@ import { generateMarkdownText } from './generateMarkdownText'; import type { MessageContextValue } from '../../../../contexts/messageContext/MessageContext'; import type { Colors, MarkdownStyle } from '../../../../contexts/themeContext/utils/theme'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; + import { escapeRegExp } from '../../../../utils/utils'; import type { MessageType } from '../../../MessageList/hooks/useMessageList'; @@ -158,13 +158,11 @@ const mentionsParseFunction: ParseFunction = (capture, parse, state) => ({ export type MarkdownRules = Partial; -export type RenderTextParams< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial< - Pick, 'onLongPress' | 'onPress' | 'preventPress'> +export type RenderTextParams = Partial< + Pick > & { colors: typeof Colors; - message: MessageType; + message: MessageType; markdownRules?: MarkdownRules; markdownStyles?: MarkdownStyle; messageOverlay?: boolean; @@ -173,11 +171,7 @@ export type RenderTextParams< onlyEmojis?: boolean; }; -export const renderText = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - params: RenderTextParams, -) => { +export const renderText = (params: RenderTextParams) => { const { colors, markdownRules, @@ -368,9 +362,7 @@ export const renderText = < if (!preventPress && onPressParam) { onPressParam({ additionalInfo: { - user: mentioned_users?.find( - (user: UserResponse) => userName === user.name, - ), + user: mentioned_users?.find((user: UserResponse) => userName === user.name), }, emitter: 'textMention', event, diff --git a/package/src/components/Message/hooks/useCreateMessageContext.ts b/package/src/components/Message/hooks/useCreateMessageContext.ts index 5984eb8faa..942907c329 100644 --- a/package/src/components/Message/hooks/useCreateMessageContext.ts +++ b/package/src/components/Message/hooks/useCreateMessageContext.ts @@ -1,12 +1,10 @@ import { useMemo } from 'react'; import type { MessageContextValue } from '../../../contexts/messageContext/MessageContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { stringifyMessage } from '../../../utils/utils'; -export const useCreateMessageContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useCreateMessageContext = ({ actionsEnabled, alignment, channel, @@ -42,7 +40,7 @@ export const useCreateMessageContext = < showMessageStatus, threadList, videos, -}: MessageContextValue) => { +}: MessageContextValue) => { const groupStylesLength = groupStyles.length; const reactionsValue = reactions.map(({ count, own, type }) => `${own}${type}${count}`).join(); const stringifiedMessage = stringifyMessage(message); @@ -52,7 +50,7 @@ export const useCreateMessageContext = < const quotedMessageDeletedValue = message.quoted_message?.deleted_at; - const messageContext: MessageContextValue = useMemo( + const messageContext: MessageContextValue = useMemo( () => ({ actionsEnabled, alignment, diff --git a/package/src/components/Message/hooks/useMessageActionHandlers.ts b/package/src/components/Message/hooks/useMessageActionHandlers.ts index 567eee779a..c737f3dc95 100644 --- a/package/src/components/Message/hooks/useMessageActionHandlers.ts +++ b/package/src/components/Message/hooks/useMessageActionHandlers.ts @@ -9,11 +9,8 @@ import type { MessagesContextValue } from '../../../contexts/messagesContext/Mes import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext'; import { setClipboardString } from '../../../native'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; -export const useMessageActionHandlers = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useMessageActionHandlers = ({ channel, client, deleteMessage, @@ -24,7 +21,7 @@ export const useMessageActionHandlers = < setEditingState, setQuotedMessageState, }: Pick< - MessagesContextValue, + MessagesContextValue, | 'sendReaction' | 'deleteMessage' | 'deleteReaction' @@ -33,9 +30,9 @@ export const useMessageActionHandlers = < | 'setQuotedMessageState' | 'supportedReactions' > & - Pick, 'channel' | 'enforceUniqueReaction'> & - Pick, 'client'> & - Pick, 'message'>) => { + Pick & + Pick & + Pick) => { const { t } = useTranslationContext(); const handleResendMessage = () => retrySendMessage(message); @@ -65,7 +62,7 @@ export const useMessageActionHandlers = < { style: 'cancel', text: t('Cancel') }, { onPress: async () => { - await deleteMessage(message as MessageResponse); + await deleteMessage(message as MessageResponse); }, style: 'destructive', text: t('Delete'), diff --git a/package/src/components/Message/hooks/useMessageActions.tsx b/package/src/components/Message/hooks/useMessageActions.tsx index a70b0c6030..95b0114c6c 100644 --- a/package/src/components/Message/hooks/useMessageActions.tsx +++ b/package/src/components/Message/hooks/useMessageActions.tsx @@ -23,17 +23,15 @@ import { UnreadIndicator, UserDelete, } from '../../../icons'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { removeReservedFields } from '../../../utils/removeReservedFields'; import { MessageStatusTypes } from '../../../utils/utils'; import type { MessageType } from '../../MessageList/hooks/useMessageList'; import type { MessageActionType } from '../../MessageMenu/MessageActionListItem'; -export type MessageActionsHookProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick< - MessagesContextValue, +export type MessageActionsHookProps = Pick< + MessagesContextValue, | 'deleteMessage' | 'sendReaction' | 'handleBan' @@ -57,17 +55,15 @@ export type MessageActionsHookProps< | 'supportedReactions' | 'updateMessage' > & - Pick, 'channel' | 'enforceUniqueReaction'> & - Pick, 'client'> & - Pick, 'openThread'> & - Pick, 'dismissOverlay' | 'message'> & + Pick & + Pick & + Pick & + Pick & Pick & { - onThreadSelect?: (message: MessageType) => void; + onThreadSelect?: (message: MessageType) => void; }; -export const useMessageActions = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useMessageActions = ({ channel, client, deleteMessage: deleteMessageFromContext, @@ -96,7 +92,7 @@ export const useMessageActions = < setQuotedMessageState, supportedReactions, t, -}: MessageActionsHookProps) => { +}: MessageActionsHookProps) => { const { theme: { colors: { accent_red, grey }, @@ -297,7 +293,7 @@ export const useMessageActions = < dismissOverlay(); const messageWithoutReservedFields = removeReservedFields(message); if (handleRetry) { - handleRetry(messageWithoutReservedFields as MessageType); + handleRetry(messageWithoutReservedFields as MessageType); } await handleResendMessage(); diff --git a/package/src/components/Message/hooks/useMessageData.ts b/package/src/components/Message/hooks/useMessageData.ts index 20cd17d923..7853d51198 100644 --- a/package/src/components/Message/hooks/useMessageData.ts +++ b/package/src/components/Message/hooks/useMessageData.ts @@ -3,26 +3,18 @@ import { useMessageContext, } from '../../../contexts/messageContext/MessageContext'; -import { DefaultStreamChatGenerics } from '../../../types/types'; import { MessageStatusTypes } from '../../../utils/utils'; -export type UseMessageDataProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial< - Pick< - MessageContextValue, - 'channel' | 'groupStyles' | 'isMyMessage' | 'message' - > +export type UseMessageDataProps = Partial< + Pick >; -export const useMessageData = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useMessageData = ({ channel: propChannel, groupStyles: propGroupStyles, isMyMessage: propIsMyMessage, message: propMessage, -}: UseMessageDataProps) => { +}: UseMessageDataProps) => { const { channel: contextChannel, groupStyles: contextGroupStyles, diff --git a/package/src/components/Message/hooks/useProcessReactions.ts b/package/src/components/Message/hooks/useProcessReactions.ts index 22e0e11f9b..7ea35c4bdd 100644 --- a/package/src/components/Message/hooks/useProcessReactions.ts +++ b/package/src/components/Message/hooks/useProcessReactions.ts @@ -7,7 +7,6 @@ import { MessagesContextValue, useMessagesContext, } from '../../../contexts/messagesContext/MessagesContext'; -import { DefaultStreamChatGenerics } from '../../../types/types'; import { ReactionData } from '../../../utils/utils'; export type ReactionSummary = { @@ -23,21 +22,17 @@ export type ReactionSummary = { export type ReactionsComparator = (a: ReactionSummary, b: ReactionSummary) => number; -export type MessageReactionsData< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type MessageReactionsData = { /** An array of the reaction objects to display in the list */ - latest_reactions?: ReactionResponse[]; + latest_reactions?: ReactionResponse[]; /** An array of the own reaction objects to distinguish own reactions visually */ - own_reactions?: ReactionResponse[] | null; + own_reactions?: ReactionResponse[] | null; /** An object containing summary for each reaction type on a message */ reaction_groups?: Record | null; }; -type UseProcessReactionsParams< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = MessageReactionsData & - Partial, 'supportedReactions'>> & { +type UseProcessReactionsParams = MessageReactionsData & + Partial> & { sortReactions?: ReactionsComparator; }; @@ -49,12 +44,10 @@ export const defaultReactionsSort: ReactionsComparator = (a, b) => { return a.type.localeCompare(b.type, 'en'); }; -const isOwnReaction = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( +const isOwnReaction = ( reactionType: string, - ownReactions?: MessageReactionsData['own_reactions'], - latestReactions?: ReactionResponse[] | null, + ownReactions?: MessageReactionsData['own_reactions'], + latestReactions?: ReactionResponse[] | null, userID?: string, ) => (ownReactions ? ownReactions.some((reaction) => reaction.type === reactionType) : false) || @@ -86,13 +79,9 @@ const getLatestReactedUserNames = (reactionType: string, latestReactions?: React /** * Custom hook to process reactions data from message and return a list of reactions with additional info. */ -export const useProcessReactions = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: UseProcessReactionsParams, -) => { +export const useProcessReactions = (props: UseProcessReactionsParams) => { const { supportedReactions: contextSupportedReactions } = useMessagesContext(); - const { client } = useChatContext(); + const { client } = useChatContext(); const { latest_reactions, @@ -120,12 +109,7 @@ export const useProcessReactions = < Icon: getEmojiByReactionType(reactionType, supportedReactions), lastReactionAt: last_reaction_at ? new Date(last_reaction_at) : null, latestReactedUserNames, - own: isOwnReaction( - reactionType, - own_reactions, - latest_reactions, - client.userID, - ), + own: isOwnReaction(reactionType, own_reactions, latest_reactions, client.userID), type: reactionType, unlistedReactedUserCount: count - latestReactedUserNames.length, }; diff --git a/package/src/components/Message/hooks/useStreamingMessage.ts b/package/src/components/Message/hooks/useStreamingMessage.ts index 793c632c6f..506ba99fe0 100644 --- a/package/src/components/Message/hooks/useStreamingMessage.ts +++ b/package/src/components/Message/hooks/useStreamingMessage.ts @@ -1,12 +1,9 @@ import { useEffect, useRef, useState } from 'react'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; import { StreamingMessageViewProps } from '../MessageSimple/StreamingMessageView'; -export type UseStreamingMessageProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick< - StreamingMessageViewProps, +export type UseStreamingMessageProps = Pick< + StreamingMessageViewProps, 'letterInterval' | 'renderingLetterCount' > & { text: string }; @@ -21,13 +18,11 @@ const DEFAULT_RENDERING_LETTER_COUNT = 2; * @param {string} text - The text that we want to render in a typewriter fashion. * @returns {{ streamedMessageText: string }} - A substring of the text property, up until we've finished rendering the typewriter animation. */ -export const useStreamingMessage = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useStreamingMessage = ({ letterInterval = DEFAULT_LETTER_INTERVAL, renderingLetterCount = DEFAULT_RENDERING_LETTER_COUNT, text, -}: UseStreamingMessageProps): { streamedMessageText: string } => { +}: UseStreamingMessageProps): { streamedMessageText: string } => { const [streamedMessageText, setStreamedMessageText] = useState(text); const textCursor = useRef(text.length); diff --git a/package/src/components/Message/utils/messageActions.ts b/package/src/components/Message/utils/messageActions.ts index dc4696e4b4..8d019238b9 100644 --- a/package/src/components/Message/utils/messageActions.ts +++ b/package/src/components/Message/utils/messageActions.ts @@ -1,12 +1,10 @@ import type { MessageContextValue } from '../../../contexts/messageContext/MessageContext'; import type { OwnCapabilitiesContextValue } from '../../../contexts/ownCapabilitiesContext/OwnCapabilitiesContext'; import { isClipboardAvailable } from '../../../native'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import type { MessageActionType } from '../../MessageMenu/MessageActionListItem'; -export type MessageActionsParams< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type MessageActionsParams = { banUser: MessageActionType; copyMessage: MessageActionType; deleteMessage: MessageActionType; @@ -27,15 +25,11 @@ export type MessageActionsParams< showMessageReactions: boolean; threadReply: MessageActionType; unpinMessage: MessageActionType; -} & Pick, 'message' | 'isMyMessage'>; +} & Pick; -export type MessageActionsProp< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = (param: MessageActionsParams) => MessageActionType[]; +export type MessageActionsProp = (param: MessageActionsParams) => MessageActionType[]; -export const messageActions = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const messageActions = ({ banUser, copyMessage, deleteMessage, @@ -53,7 +47,7 @@ export const messageActions = < showMessageReactions, threadReply, unpinMessage, -}: MessageActionsParams) => { +}: MessageActionsParams) => { if (showMessageReactions) { return []; } diff --git a/package/src/components/MessageInput/AttachButton.tsx b/package/src/components/MessageInput/AttachButton.tsx index ae53ccbc9e..281387c4b4 100644 --- a/package/src/components/MessageInput/AttachButton.tsx +++ b/package/src/components/MessageInput/AttachButton.tsx @@ -11,21 +11,14 @@ import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { Attach } from '../../icons/Attach'; import { isImageMediaLibraryAvailable } from '../../native'; -import type { DefaultStreamChatGenerics } from '../../types/types'; -type AttachButtonPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'disabled'> & { +type AttachButtonPropsWithContext = Pick & { /** Function that opens attachment options bottom sheet */ handleOnPress?: ((event: GestureResponderEvent) => void) & (() => void); selectedPicker?: 'images'; }; -const AttachButtonWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AttachButtonPropsWithContext, -) => { +const AttachButtonWithContext = (props: AttachButtonPropsWithContext) => { const [showAttachButtonPicker, setShowAttachButtonPicker] = useState(false); const [attachButtonLayoutRectangle, setAttachButtonLayoutRectangle] = useState(); const { disabled, handleOnPress, selectedPicker } = props; diff --git a/package/src/components/MessageInput/CommandsButton.tsx b/package/src/components/MessageInput/CommandsButton.tsx index bd049b8185..8cba55d77c 100644 --- a/package/src/components/MessageInput/CommandsButton.tsx +++ b/package/src/components/MessageInput/CommandsButton.tsx @@ -10,20 +10,12 @@ import { import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { Lightning } from '../../icons/Lightning'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - -type CommandsButtonPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'suggestions'> & { +type CommandsButtonPropsWithContext = Pick & { /** Function that opens commands selector */ handleOnPress?: ((event: GestureResponderEvent) => void) & (() => void); }; -const CommandsButtonWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: CommandsButtonPropsWithContext, -) => { +const CommandsButtonWithContext = (props: CommandsButtonPropsWithContext) => { const { handleOnPress, suggestions } = props; const { @@ -47,9 +39,9 @@ const CommandsButtonWithContext = < ); }; -const areEqual = ( - prevProps: CommandsButtonPropsWithContext, - nextProps: CommandsButtonPropsWithContext, +const areEqual = ( + prevProps: CommandsButtonPropsWithContext, + nextProps: CommandsButtonPropsWithContext, ) => { const { suggestions: prevSuggestions } = prevProps; const { suggestions: nextSuggestions } = nextProps; @@ -67,19 +59,13 @@ const MemoizedCommandsButton = React.memo( areEqual, ) as typeof CommandsButtonWithContext; -export type CommandsButtonProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type CommandsButtonProps = Partial; /** * UI Component for attach button in MessageInput component. */ -export const CommandsButton = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: CommandsButtonProps, -) => { - const { suggestions } = useSuggestionsContext(); +export const CommandsButton = (props: CommandsButtonProps) => { + const { suggestions } = useSuggestionsContext(); return ; }; diff --git a/package/src/components/MessageInput/FileUploadPreview.tsx b/package/src/components/MessageInput/FileUploadPreview.tsx index fd06ec3d91..0ec0fa78f9 100644 --- a/package/src/components/MessageInput/FileUploadPreview.tsx +++ b/package/src/components/MessageInput/FileUploadPreview.tsx @@ -17,7 +17,7 @@ import { useTranslationContext } from '../../contexts/translationContext/Transla import { Close } from '../../icons/Close'; import { Warning } from '../../icons/Warning'; import { isSoundPackageAvailable } from '../../native'; -import type { DefaultStreamChatGenerics, FileUpload } from '../../types/types'; +import type { FileUpload } from '../../types/types'; import { getTrimmedAttachmentTitle } from '../../utils/getTrimmedAttachmentTitle'; import { getDurationLabelFromDuration, @@ -123,20 +123,14 @@ const UnsupportedFileTypeOrFileSizeIndicator = ({ ); }; -type FileUploadPreviewPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick< - MessageInputContextValue, +type FileUploadPreviewPropsWithContext = Pick< + MessageInputContextValue, 'fileUploads' | 'removeFile' | 'uploadFile' | 'setFileUploads' | 'AudioAttachmentUploadPreview' > & - Pick, 'FileAttachmentIcon'> & - Pick, 'enableOfflineSupport'>; + Pick & + Pick; -const FileUploadPreviewWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: FileUploadPreviewPropsWithContext, -) => { +const FileUploadPreviewWithContext = (props: FileUploadPreviewPropsWithContext) => { const { AudioAttachmentUploadPreview, enableOfflineSupport, @@ -323,9 +317,9 @@ const FileUploadPreviewWithContext = < ) : null; }; -const areEqual = ( - prevProps: FileUploadPreviewPropsWithContext, - nextProps: FileUploadPreviewPropsWithContext, +const areEqual = ( + prevProps: FileUploadPreviewPropsWithContext, + nextProps: FileUploadPreviewPropsWithContext, ) => { const { fileUploads: prevFileUploads } = prevProps; const { fileUploads: nextFileUploads } = nextProps; @@ -347,23 +341,17 @@ const MemoizedFileUploadPreview = React.memo( areEqual, ) as typeof FileUploadPreviewWithContext; -export type FileUploadPreviewProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type FileUploadPreviewProps = Partial; /** * FileUploadPreview * UI Component to preview the files set for upload */ -export const FileUploadPreview = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: FileUploadPreviewProps, -) => { - const { enableOfflineSupport } = useChatContext(); +export const FileUploadPreview = (props: FileUploadPreviewProps) => { + const { enableOfflineSupport } = useChatContext(); const { AudioAttachmentUploadPreview, fileUploads, removeFile, setFileUploads, uploadFile } = - useMessageInputContext(); - const { FileAttachmentIcon } = useMessagesContext(); + useMessageInputContext(); + const { FileAttachmentIcon } = useMessagesContext(); return ( = Pick< - MessageInputContextValue, +type ImageUploadPreviewPropsWithContext = Pick< + MessageInputContextValue, 'imageUploads' | 'removeImage' | 'uploadImage' > & - Pick, 'enableOfflineSupport'>; + Pick; -export type ImageUploadPreviewProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type ImageUploadPreviewProps = Partial; type ImageUploadPreviewItem = { index: number; item: ImageUpload }; @@ -114,11 +110,7 @@ export const UnsupportedImageTypeIndicator = ({ ) : null; }; -const ImageUploadPreviewWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ImageUploadPreviewPropsWithContext, -) => { +const ImageUploadPreviewWithContext = (props: ImageUploadPreviewPropsWithContext) => { const { enableOfflineSupport, imageUploads, removeImage, uploadImage } = props; const { @@ -197,9 +189,9 @@ const DismissUpload = ({ onPress }: DismissUploadProps) => { ); }; -const areEqual = ( - prevProps: ImageUploadPreviewPropsWithContext, - nextProps: ImageUploadPreviewPropsWithContext, +const areEqual = ( + prevProps: ImageUploadPreviewPropsWithContext, + nextProps: ImageUploadPreviewPropsWithContext, ) => { const { imageUploads: prevImageUploads } = prevProps; const { imageUploads: nextImageUploads } = nextProps; @@ -220,13 +212,9 @@ const MemoizedImageUploadPreviewWithContext = React.memo( /** * UI Component to preview the images set for upload */ -export const ImageUploadPreview = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ImageUploadPreviewProps, -) => { - const { enableOfflineSupport } = useChatContext(); - const { imageUploads, removeImage, uploadImage } = useMessageInputContext(); +export const ImageUploadPreview = (props: ImageUploadPreviewProps) => { + const { enableOfflineSupport } = useChatContext(); + const { imageUploads, removeImage, uploadImage } = useMessageInputContext(); return ( = Partial>; +export type InputButtonsProps = Partial; -export type InputButtonsWithContextProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick< - MessageInputContextValue, +export type InputButtonsWithContextProps = Pick< + MessageInputContextValue, | 'AttachButton' | 'CommandsButton' | 'giphyActive' @@ -38,11 +32,7 @@ export type InputButtonsWithContextProps< | 'toggleAttachmentPicker' >; -export const InputButtonsWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: InputButtonsWithContextProps, -) => { +export const InputButtonsWithContext = (props: InputButtonsWithContextProps) => { const { AttachButton, CommandsButton, @@ -90,9 +80,9 @@ export const InputButtonsWithContext = < ); }; -const areEqual = ( - prevProps: InputButtonsWithContextProps, - nextProps: InputButtonsWithContextProps, +const areEqual = ( + prevProps: InputButtonsWithContextProps, + nextProps: InputButtonsWithContextProps, ) => { const { giphyActive: prevGiphyActive, @@ -156,11 +146,7 @@ const MemoizedInputButtonsWithContext = React.memo( areEqual, ) as typeof InputButtonsWithContext; -export const InputButtons = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: InputButtonsProps, -) => { +export const InputButtons = (props: InputButtonsProps) => { const { AttachButton, CommandsButton, @@ -176,7 +162,7 @@ export const InputButtons = < showMoreOptions, text, toggleAttachmentPicker, - } = useMessageInputContext(); + } = useMessageInputContext(); return ( = Pick & - Pick, 'isOnline'> & - Pick, 'members' | 'threadList' | 'watchers'> & +type MessageInputPropsWithContext = Pick< + AttachmentPickerContextValue, + 'AttachmentPickerSelectionBar' +> & + Pick & + Pick & Pick< - MessageInputContextValue, + MessageInputContextValue, | 'additionalTextInputProps' | 'asyncIds' | 'audioRecordingEnabled' @@ -166,23 +167,19 @@ type MessageInputPropsWithContext< | 'CreatePollContent' | 'StopMessageStreamingButton' > & - Pick, 'Reply'> & + Pick & Pick< - SuggestionsContextValue, + SuggestionsContextValue, | 'AutoCompleteSuggestionHeader' | 'AutoCompleteSuggestionItem' | 'AutoCompleteSuggestionList' | 'suggestions' | 'triggerType' > & - Pick, 'thread'> & + Pick & Pick; -const MessageInputWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageInputPropsWithContext, -) => { +const MessageInputWithContext = (props: MessageInputPropsWithContext) => { const { additionalTextInputProps, asyncIds, @@ -554,7 +551,7 @@ const MessageInputWithContext = < }, [asyncIdsString, asyncUploadsString, sendMessageAsync]); const getMembers = () => { - const result: UserResponse[] = []; + const result: UserResponse[] = []; if (members && Object.values(members).length) { Object.values(members).forEach((member) => { if (member.user) { @@ -570,7 +567,7 @@ const MessageInputWithContext = < const users = [...getMembers(), ...getWatchers()]; // make sure we don't list users twice - const uniqueUsers: { [key: string]: UserResponse } = {}; + const uniqueUsers: { [key: string]: UserResponse } = {}; for (const user of users) { if (user && !uniqueUsers[user.id]) { uniqueUsers[user.id] = user; @@ -582,7 +579,7 @@ const MessageInputWithContext = < }; const getWatchers = () => { - const result: UserResponse[] = []; + const result: UserResponse[] = []; if (watchers && Object.values(watchers).length) { result.push(...Object.values(watchers)); } @@ -746,7 +743,7 @@ const MessageInputWithContext = < })), }; - const { channel } = useChannelContext(); + const { channel } = useChannelContext(); const { aiState } = useAIState(channel); const stopGenerating = useCallback(() => channel?.stopAIResponse(), [channel]); @@ -848,7 +845,7 @@ const MessageInputWithContext = < ) : ( - + @@ -946,9 +943,9 @@ const MessageInputWithContext = < ); }; -const areEqual = ( - prevProps: MessageInputPropsWithContext, - nextProps: MessageInputPropsWithContext, +const areEqual = ( + prevProps: MessageInputPropsWithContext, + nextProps: MessageInputPropsWithContext, ) => { const { additionalTextInputProps: prevAdditionalTextInputProps, @@ -1138,9 +1135,7 @@ const MemoizedMessageInput = React.memo( areEqual, ) as typeof MessageInputWithContext; -export type MessageInputProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type MessageInputProps = Partial; /** * UI Component for message input @@ -1151,16 +1146,12 @@ export type MessageInputProps< * [Suggestions Context](https://getstream.io/chat/docs/sdk/reactnative/contexts/suggestions-context/), and * [Translation Context](https://getstream.io/chat/docs/sdk/reactnative/contexts/translation-context/) */ -export const MessageInput = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageInputProps, -) => { +export const MessageInput = (props: MessageInputProps) => { const { AttachmentPickerSelectionBar } = useAttachmentPickerContext(); const { isOnline } = useChatContext(); const ownCapabilities = useOwnCapabilitiesContext(); - const { members, threadList, watchers } = useChannelContext(); + const { members, threadList, watchers } = useChannelContext(); const { additionalTextInputProps, @@ -1219,9 +1210,9 @@ export const MessageInput = < text, uploadNewFile, uploadNewImage, - } = useMessageInputContext(); + } = useMessageInputContext(); - const { Reply } = useMessagesContext(); + const { Reply } = useMessagesContext(); const { AutoCompleteSuggestionHeader, @@ -1229,9 +1220,9 @@ export const MessageInput = < AutoCompleteSuggestionList, suggestions, triggerType, - } = useSuggestionsContext(); + } = useSuggestionsContext(); - const { thread } = useThreadContext(); + const { thread } = useThreadContext(); const { t } = useTranslationContext(); diff --git a/package/src/components/MessageInput/SendButton.tsx b/package/src/components/MessageInput/SendButton.tsx index 42d4ff5e39..f2bcec8afd 100644 --- a/package/src/components/MessageInput/SendButton.tsx +++ b/package/src/components/MessageInput/SendButton.tsx @@ -11,19 +11,11 @@ import { Search } from '../../icons/Search'; import { SendRight } from '../../icons/SendRight'; import { SendUp } from '../../icons/SendUp'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - -type SendButtonPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'giphyActive' | 'sendMessage'> & { +type SendButtonPropsWithContext = Pick & { /** Disables the button */ disabled: boolean; }; -const SendButtonWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: SendButtonPropsWithContext, -) => { +const SendButtonWithContext = (props: SendButtonPropsWithContext) => { const { disabled = false, giphyActive, sendMessage } = props; const { theme: { @@ -50,10 +42,7 @@ const SendButtonWithContext = < ); }; -const areEqual = ( - prevProps: SendButtonPropsWithContext, - nextProps: SendButtonPropsWithContext, -) => { +const areEqual = (prevProps: SendButtonPropsWithContext, nextProps: SendButtonPropsWithContext) => { const { disabled: prevDisabled, giphyActive: prevGiphyActive, @@ -88,19 +77,13 @@ const MemoizedSendButton = React.memo( areEqual, ) as typeof SendButtonWithContext; -export type SendButtonProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type SendButtonProps = Partial; /** * UI Component for send button in MessageInput component. */ -export const SendButton = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: SendButtonProps, -) => { - const { giphyActive, sendMessage } = useMessageInputContext(); +export const SendButton = (props: SendButtonProps) => { + const { giphyActive, sendMessage } = useMessageInputContext(); return ( ; -export const ShowThreadMessageInChannelButton = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ShowThreadMessageInChannelButtonProps, -) => { +export const ShowThreadMessageInChannelButton = (props: ShowThreadMessageInChannelButtonProps) => { const { t } = useTranslationContext(); - const { allowThreadMessagesInChannel } = useThreadContext(); - const { sendThreadMessageInChannel, setSendThreadMessageInChannel } = - useMessageInputContext(); + const { allowThreadMessagesInChannel } = useThreadContext(); + const { sendThreadMessageInChannel, setSendThreadMessageInChannel } = useMessageInputContext(); return ( = Pick, 'asyncMessagesMultiSendEnabled'> & { +type AudioRecorderPropsWithContext = Pick< + MessageInputContextValue, + 'asyncMessagesMultiSendEnabled' +> & { /** * Function to stop and delete the voice recording. */ @@ -128,11 +128,7 @@ const DeleteRecording = ({ ); }; -const AudioRecorderWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AudioRecorderPropsWithContext, -) => { +const AudioRecorderWithContext = (props: AudioRecorderPropsWithContext) => { const { asyncMessagesMultiSendEnabled, deleteVoiceRecording, @@ -201,9 +197,9 @@ const AudioRecorderWithContext = < } }; -const areEqual = ( - prevProps: AudioRecorderPropsWithContext, - nextProps: AudioRecorderPropsWithContext, +const areEqual = ( + prevProps: AudioRecorderPropsWithContext, + nextProps: AudioRecorderPropsWithContext, ) => { const { asyncMessagesMultiSendEnabled: prevAsyncMessagesMultiSendEnabled, @@ -254,11 +250,9 @@ const MemoizedAudioRecorder = React.memo( areEqual, ) as typeof AudioRecorderWithContext; -export type AudioRecorderProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial> & +export type AudioRecorderProps = Partial & Pick< - AudioRecorderPropsWithContext, + AudioRecorderPropsWithContext, | 'deleteVoiceRecording' | 'micLocked' | 'recording' @@ -270,12 +264,8 @@ export type AudioRecorderProps< /** * Component to display the Recording UI in the Message Input. */ -export const AudioRecorder = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AudioRecorderProps, -) => { - const { asyncMessagesMultiSendEnabled } = useMessageInputContext(); +export const AudioRecorder = (props: AudioRecorderProps) => { + const { asyncMessagesMultiSendEnabled } = useMessageInputContext(); return ( = Pick, 'asyncMessagesMinimumPressDuration'> & { +type AudioRecordingButtonPropsWithContext = Pick< + MessageInputContextValue, + 'asyncMessagesMinimumPressDuration' +> & { /** * The current voice recording that is in progress. */ @@ -41,11 +40,7 @@ type AudioRecordingButtonPropsWithContext< startVoiceRecording?: () => Promise; }; -const AudioRecordingButtonWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AudioRecordingButtonPropsWithContext, -) => { +const AudioRecordingButtonWithContext = (props: AudioRecordingButtonPropsWithContext) => { const { asyncMessagesMinimumPressDuration, buttonSize, @@ -121,9 +116,9 @@ const AudioRecordingButtonWithContext = < ); }; -const areEqual = ( - prevProps: AudioRecordingButtonPropsWithContext, - nextProps: AudioRecordingButtonPropsWithContext, +const areEqual = ( + prevProps: AudioRecordingButtonPropsWithContext, + nextProps: AudioRecordingButtonPropsWithContext, ) => { const { asyncMessagesMinimumPressDuration: prevAsyncMessagesMinimumPressDuration, @@ -153,21 +148,15 @@ const MemoizedAudioRecordingButton = React.memo( areEqual, ) as typeof AudioRecordingButtonWithContext; -export type AudioRecordingButtonProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial> & { +export type AudioRecordingButtonProps = Partial & { recording: AudioRecordingReturnType; }; /** * Component to display the mic button on the Message Input. */ -export const AudioRecordingButton = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AudioRecordingButtonProps, -) => { - const { asyncMessagesMinimumPressDuration } = useMessageInputContext(); +export const AudioRecordingButton = (props: AudioRecordingButtonProps) => { + const { asyncMessagesMinimumPressDuration } = useMessageInputContext(); return ; }; diff --git a/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingInProgress.tsx b/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingInProgress.tsx index bcf55d177b..d83d4f022d 100644 --- a/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingInProgress.tsx +++ b/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingInProgress.tsx @@ -9,11 +9,10 @@ import { } from '../../../../contexts/messageInputContext/MessageInputContext'; import { useTheme } from '../../../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; - -type AudioRecordingInProgressPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'AudioRecordingWaveform'> & { +type AudioRecordingInProgressPropsWithContext = Pick< + MessageInputContextValue, + 'AudioRecordingWaveform' +> & { /** * The waveform data to be presented to show the audio levels. */ @@ -28,11 +27,7 @@ type AudioRecordingInProgressPropsWithContext< recordingDuration?: number; }; -const AudioRecordingInProgressWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AudioRecordingInProgressPropsWithContext, -) => { +const AudioRecordingInProgressWithContext = (props: AudioRecordingInProgressPropsWithContext) => { const { AudioRecordingWaveform, maxDataPointsDrawn = 80, @@ -60,9 +55,9 @@ const AudioRecordingInProgressWithContext = < ); }; -const areEqual = ( - prevProps: AudioRecordingInProgressPropsWithContext, - nextProps: AudioRecordingInProgressPropsWithContext, +const areEqual = ( + prevProps: AudioRecordingInProgressPropsWithContext, + nextProps: AudioRecordingInProgressPropsWithContext, ) => { const { recordingDuration: prevRecordingDuration } = prevProps; const { recordingDuration: nextRecordingDuration } = nextProps; @@ -81,21 +76,15 @@ const MemoizedAudioRecordingInProgress = React.memo( areEqual, ) as typeof AudioRecordingInProgressWithContext; -export type AudioRecordingInProgressProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial> & { +export type AudioRecordingInProgressProps = Partial & { waveformData: number[]; }; /** * Component displayed when the audio is in the recording state. */ -export const AudioRecordingInProgress = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: AudioRecordingInProgressProps, -) => { - const { AudioRecordingWaveform } = useMessageInputContext(); +export const AudioRecordingInProgress = (props: AudioRecordingInProgressProps) => { + const { AudioRecordingWaveform } = useMessageInputContext(); return ; }; diff --git a/package/src/components/MessageInput/components/InputEditingStateHeader.tsx b/package/src/components/MessageInput/components/InputEditingStateHeader.tsx index 1faab83718..5164971278 100644 --- a/package/src/components/MessageInput/components/InputEditingStateHeader.tsx +++ b/package/src/components/MessageInput/components/InputEditingStateHeader.tsx @@ -9,7 +9,6 @@ import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext'; import { CircleClose, Edit } from '../../../icons'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; const styles = StyleSheet.create({ editingBoxHeader: { @@ -24,19 +23,17 @@ const styles = StyleSheet.create({ }, }); -export type InputEditingStateHeaderProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial, 'clearEditingState' | 'resetInput'>>; +export type InputEditingStateHeaderProps = Partial< + Pick +>; -export const InputEditingStateHeader = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const InputEditingStateHeader = ({ clearEditingState: propClearEditingState, resetInput: propResetInput, -}: InputEditingStateHeaderProps) => { +}: InputEditingStateHeaderProps) => { const { t } = useTranslationContext(); const { clearEditingState: contextClearEditingState, resetInput: contextResetInput } = - useMessageInputContext(); + useMessageInputContext(); const clearEditingState = propClearEditingState || contextClearEditingState; const resetInput = propResetInput || contextResetInput; diff --git a/package/src/components/MessageInput/components/InputGiphySearch.tsx b/package/src/components/MessageInput/components/InputGiphySearch.tsx index f9c0638ae7..fc01b85650 100644 --- a/package/src/components/MessageInput/components/InputGiphySearch.tsx +++ b/package/src/components/MessageInput/components/InputGiphySearch.tsx @@ -8,7 +8,7 @@ import { import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { CircleClose, GiphyLightning } from '../../../icons'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { AutoCompleteInput } from '../../AutoCompleteInput/AutoCompleteInput'; import { useCountdown } from '../hooks/useCountdown'; @@ -33,32 +33,28 @@ const styles = StyleSheet.create({ }, }); -export type InputGiphySearchProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial< +export type InputGiphySearchProps = Partial< Pick< - MessageInputContextValue, + MessageInputContextValue, 'additionalTextInputProps' | 'cooldownEndsAt' | 'setGiphyActive' | 'setShowMoreOptions' > > & { disabled: boolean; }; -export const InputGiphySearch = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const InputGiphySearch = ({ additionalTextInputProps: propAdditionalTextInputProps, cooldownEndsAt: propCooldownEndsAt, disabled, setGiphyActive: propSetGiphyActive, setShowMoreOptions: propSetShowMoreOptions, -}: InputGiphySearchProps) => { +}: InputGiphySearchProps) => { const { additionalTextInputProps: contextAdditionalTextInputProps, cooldownEndsAt: contextCooldownEndsAt, setGiphyActive: contextSetGiphyActive, setShowMoreOptions: contextSetShowMoreOptions, - } = useMessageInputContext(); + } = useMessageInputContext(); const additionalTextInputProps = propAdditionalTextInputProps || contextAdditionalTextInputProps; const cooldownEndsAt = propCooldownEndsAt || contextCooldownEndsAt; @@ -84,7 +80,7 @@ export const InputGiphySearch = < GIPHY - + diff --git a/package/src/components/MessageInput/components/InputReplyStateHeader.tsx b/package/src/components/MessageInput/components/InputReplyStateHeader.tsx index 7e45f3145e..8860217967 100644 --- a/package/src/components/MessageInput/components/InputReplyStateHeader.tsx +++ b/package/src/components/MessageInput/components/InputReplyStateHeader.tsx @@ -9,7 +9,6 @@ import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext'; import { CircleClose, CurveLineLeftUp } from '../../../icons'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; const styles = StyleSheet.create({ replyBoxHeader: { @@ -24,18 +23,14 @@ const styles = StyleSheet.create({ }, }); -export type InputReplyStateHeaderProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial< - Pick, 'clearQuotedMessageState' | 'resetInput'> +export type InputReplyStateHeaderProps = Partial< + Pick >; -export const InputReplyStateHeader = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const InputReplyStateHeader = ({ clearQuotedMessageState: propClearQuotedMessageState, resetInput: propResetInput, -}: InputReplyStateHeaderProps) => { +}: InputReplyStateHeaderProps) => { const { t } = useTranslationContext(); const { clearQuotedMessageState: contextClearQuotedMessageState, resetInput: contextResetInput } = useMessageInputContext(); diff --git a/package/src/components/MessageInput/hooks/useCooldown.ts b/package/src/components/MessageInput/hooks/useCooldown.ts index 12484776f7..7e77d4cfbe 100644 --- a/package/src/components/MessageInput/hooks/useCooldown.ts +++ b/package/src/components/MessageInput/hooks/useCooldown.ts @@ -4,7 +4,7 @@ import { BuiltinRoles, ChannelResponse, Role } from 'stream-chat'; import { useChannelContext } from '../../../contexts/channelContext/ChannelContext'; import { useChatContext } from '../../../contexts/chatContext/ChatContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { ONE_SECOND_IN_MS } from '../../../utils/date'; type Roles = Array; @@ -13,14 +13,12 @@ type Roles = Array; * useCooldown can be used to start a cooldown defined * for a Channel by setting an end time for **/ -export const useCooldown = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { +export const useCooldown = () => { const [endsAt, setEndsAt] = useState(new Date()); - const { client } = useChatContext(); - const { channel } = useChannelContext(); - const { cooldown } = (channel?.data || {}) as ChannelResponse; + const { client } = useChatContext(); + const { channel } = useChannelContext(); + const { cooldown } = (channel?.data || {}) as ChannelResponse; const interval: number = cooldown ?? 0; /** diff --git a/package/src/components/MessageList/InlineLoadingMoreIndicator.tsx b/package/src/components/MessageList/InlineLoadingMoreIndicator.tsx index 334536d7d6..f369cb3eb1 100644 --- a/package/src/components/MessageList/InlineLoadingMoreIndicator.tsx +++ b/package/src/components/MessageList/InlineLoadingMoreIndicator.tsx @@ -4,8 +4,6 @@ import { ActivityIndicator, StyleSheet, View } from 'react-native'; import { usePaginatedMessageListContext } from '../../contexts/paginatedMessageListContext/PaginatedMessageListContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - const styles = StyleSheet.create({ activityIndicatorContainer: { padding: 10, @@ -57,10 +55,8 @@ const MemoizedInlineLoadingMoreIndicator = React.memo( areEqual, ) as typeof InlineLoadingMoreIndicatorWithContext; -export const InlineLoadingMoreIndicator = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const { loadingMore } = usePaginatedMessageListContext(); +export const InlineLoadingMoreIndicator = () => { + const { loadingMore } = usePaginatedMessageListContext(); return ; }; diff --git a/package/src/components/MessageList/InlineLoadingMoreRecentIndicator.tsx b/package/src/components/MessageList/InlineLoadingMoreRecentIndicator.tsx index 7027c26818..11fccfcea9 100644 --- a/package/src/components/MessageList/InlineLoadingMoreRecentIndicator.tsx +++ b/package/src/components/MessageList/InlineLoadingMoreRecentIndicator.tsx @@ -4,8 +4,6 @@ import { ActivityIndicator, StyleSheet, View } from 'react-native'; import { usePaginatedMessageListContext } from '../../contexts/paginatedMessageListContext/PaginatedMessageListContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - const styles = StyleSheet.create({ activityIndicatorContainer: { padding: 10, @@ -57,10 +55,8 @@ const MemoizedInlineLoadingMoreRecentIndicator = React.memo( areEqual, ) as typeof InlineLoadingMoreRecentIndicatorWithContext; -export const InlineLoadingMoreRecentIndicator = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const { loadingMoreRecent } = usePaginatedMessageListContext(); +export const InlineLoadingMoreRecentIndicator = () => { + const { loadingMoreRecent } = usePaginatedMessageListContext(); return ; }; diff --git a/package/src/components/MessageList/InlineLoadingMoreRecentThreadIndicator.tsx b/package/src/components/MessageList/InlineLoadingMoreRecentThreadIndicator.tsx index b68b393401..fd2e23c946 100644 --- a/package/src/components/MessageList/InlineLoadingMoreRecentThreadIndicator.tsx +++ b/package/src/components/MessageList/InlineLoadingMoreRecentThreadIndicator.tsx @@ -4,8 +4,6 @@ import { ActivityIndicator, StyleSheet, View } from 'react-native'; import { useThreadContext } from '../../contexts'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - const styles = StyleSheet.create({ activityIndicatorContainer: { padding: 10, @@ -57,10 +55,8 @@ const MemoizedInlineLoadingMoreRecentIndicator = React.memo( areEqual, ) as typeof InlineLoadingMoreRecentIndicatorWithContext; -export const InlineLoadingMoreRecentThreadIndicator = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const { threadLoadingMoreRecent } = useThreadContext(); +export const InlineLoadingMoreRecentThreadIndicator = () => { + const { threadLoadingMoreRecent } = useThreadContext(); return ; }; diff --git a/package/src/components/MessageList/MessageList.tsx b/package/src/components/MessageList/MessageList.tsx index 43e40ed2df..e4c3e0d4b8 100644 --- a/package/src/components/MessageList/MessageList.tsx +++ b/package/src/components/MessageList/MessageList.tsx @@ -53,7 +53,7 @@ import { import { mergeThemes, ThemeProvider, useTheme } from '../../contexts/themeContext/ThemeContext'; import { ThreadContextValue, useThreadContext } from '../../contexts/threadContext/ThreadContext'; -import { DefaultStreamChatGenerics, FileTypes } from '../../types/types'; +import { FileTypes } from '../../types/types'; // This is just to make sure that the scrolling happens in a different task queue. // TODO: Think if we really need this and strive to remove it if we can. @@ -90,11 +90,7 @@ const styles = StyleSheet.create({ }, }); -const keyExtractor = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - item: MessageType, -) => { +const keyExtractor = (item: MessageType) => { if (item.id) { return item.id; } @@ -108,11 +104,12 @@ const flatListViewabilityConfig: ViewabilityConfig = { viewAreaCoveragePercentThreshold: 1, }; -type MessageListPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick & +type MessageListPropsWithContext = Pick< + AttachmentPickerContextValue, + 'closePicker' | 'selectedPicker' | 'setSelectedPicker' +> & Pick< - ChannelContextValue, + ChannelContextValue, | 'channel' | 'channelUnreadState' | 'disabled' @@ -131,12 +128,12 @@ type MessageListPropsWithContext< | 'targetedMessage' | 'threadList' > & - Pick, 'client'> & - Pick, 'setMessages'> & - Pick, 'loadMore' | 'loadMoreRecent'> & + Pick & + Pick & + Pick & Pick & Pick< - MessagesContextValue, + MessagesContextValue, | 'DateHeader' | 'disableTypingIndicator' | 'FlatList' @@ -153,7 +150,7 @@ type MessageListPropsWithContext< | 'UnreadMessagesNotification' > & Pick< - ThreadContextValue, + ThreadContextValue, 'loadMoreRecentThread' | 'loadMoreThread' | 'thread' | 'threadInstance' > & { /** @@ -170,7 +167,7 @@ type MessageListPropsWithContext< * additionalFlatListProps={{ bounces: true, keyboardDismissMode: true }} /> * ``` */ - additionalFlatListProps?: Partial>>; + additionalFlatListProps?: Partial>; /** * UI component for footer of message list. By default message list will use `InlineLoadingMoreIndicator` * as FooterComponent. If you want to implement your own inline loading indicator, you can access `loadingMore` @@ -200,7 +197,7 @@ type MessageListPropsWithContext< * * @param message A message object to open the thread upon. */ - onThreadSelect?: (message: ThreadContextValue['thread']) => void; + onThreadSelect?: (message: ThreadContextValue['thread']) => void; /** * Use `setFlatListRef` to get access to ref to inner FlatList. * @@ -212,7 +209,7 @@ type MessageListPropsWithContext< * }} * ``` */ - setFlatListRef?: (ref: FlatListType> | null) => void; + setFlatListRef?: (ref: FlatListType | null) => void; }; /** @@ -224,11 +221,7 @@ type MessageListPropsWithContext< * [ThreadContext](https://getstream.io/chat/docs/sdk/reactnative/contexts/thread-context/) * [TranslationContext](https://getstream.io/chat/docs/sdk/reactnative/contexts/translation-context/) */ -const MessageListWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageListPropsWithContext, -) => { +const MessageListWithContext = (props: MessageListPropsWithContext) => { const LoadingMoreRecentIndicator = props.threadList ? InlineLoadingMoreRecentThreadIndicator : InlineLoadingMoreRecentIndicator; @@ -306,7 +299,7 @@ const MessageListWithContext = < * NOTE: rawMessageList changes only when messages array state changes * processedMessageList changes on any state change */ - const { processedMessageList, rawMessageList } = useMessageList({ + const { processedMessageList, rawMessageList } = useMessageList({ noGroupByUser, threadList, }); @@ -317,11 +310,9 @@ const MessageListWithContext = < * We need topMessage and channelLastRead values to set the initial scroll position. * So these values only get used if `initialScrollToFirstUnreadMessage` prop is true. */ - const topMessageBeforeUpdate = useRef>(undefined); - const latestNonCurrentMessageBeforeUpdateRef = - useRef>(undefined); - const topMessageAfterUpdate: FormatMessageResponse | undefined = - rawMessageList[0]; + const topMessageBeforeUpdate = useRef(undefined); + const latestNonCurrentMessageBeforeUpdateRef = useRef(undefined); + const topMessageAfterUpdate: FormatMessageResponse | undefined = rawMessageList[0]; const shouldScrollToRecentOnNewOwnMessageRef = useShouldScrollToRecentOnNewOwnMessage( rawMessageList, @@ -340,7 +331,7 @@ const MessageListWithContext = < const onStartReachedInPromise = useRef | null>(null); const onEndReachedInPromise = useRef | null>(null); - const flatListRef = useRef> | null>(null); + const flatListRef = useRef | null>(null); const channelResyncScrollSet = useRef(true); @@ -669,13 +660,7 @@ const MessageListWithContext = < // TODO: do not apply on RN 0.73 and above const shouldApplyAndroidWorkaround = inverted && Platform.OS === 'android'; - const renderItem = ({ - index, - item: message, - }: { - index: number; - item: MessageType; - }) => { + const renderItem = ({ index, item: message }: { index: number; item: MessageType }) => { if (!channel || channel.disconnected || (!channel.initialized && !channel.offlineMode)) { return null; } @@ -905,49 +890,49 @@ const MessageListWithContext = < const scrollToIndexFailedRetryCountRef = useRef(0); const failScrollTimeoutId = useRef>(undefined); - const onScrollToIndexFailedRef = useRef< - FlatListProps>['onScrollToIndexFailed'] - >((info) => { - // We got a failure as we tried to scroll to an item that was outside the render length - if (!flatListRef.current) { - return; - } - // we don't know the actual size of all items but we can see the average, so scroll to the closest offset - // since we used only an average offset... we won't go to the center of the item yet - // with a little delay to wait for scroll to offset to complete, we can then scroll to the index - failScrollTimeoutId.current = setTimeout(() => { - try { - flatListRef.current?.scrollToIndex({ - animated: true, - index: info.index, - viewPosition: 0.5, // try to place message in the center of the screen - }); - if (messageIdLastScrolledToRef.current) { - // in case the target message was cleared out - // the state being set again will trigger the highlight again - setTargetedMessage(messageIdLastScrolledToRef.current); - } - scrollToIndexFailedRetryCountRef.current = 0; - } catch (e) { - if ( - !onScrollToIndexFailedRef.current || - scrollToIndexFailedRetryCountRef.current > MAX_RETRIES_AFTER_SCROLL_FAILURE - ) { + const onScrollToIndexFailedRef = useRef['onScrollToIndexFailed']>( + (info) => { + // We got a failure as we tried to scroll to an item that was outside the render length + if (!flatListRef.current) { + return; + } + // we don't know the actual size of all items but we can see the average, so scroll to the closest offset + // since we used only an average offset... we won't go to the center of the item yet + // with a little delay to wait for scroll to offset to complete, we can then scroll to the index + failScrollTimeoutId.current = setTimeout(() => { + try { + flatListRef.current?.scrollToIndex({ + animated: true, + index: info.index, + viewPosition: 0.5, // try to place message in the center of the screen + }); + if (messageIdLastScrolledToRef.current) { + // in case the target message was cleared out + // the state being set again will trigger the highlight again + setTargetedMessage(messageIdLastScrolledToRef.current); + } scrollToIndexFailedRetryCountRef.current = 0; - return; + } catch (e) { + if ( + !onScrollToIndexFailedRef.current || + scrollToIndexFailedRetryCountRef.current > MAX_RETRIES_AFTER_SCROLL_FAILURE + ) { + scrollToIndexFailedRetryCountRef.current = 0; + return; + } + // At some cases the index we're trying to scroll to, doesn't exist yet in the messageList + // Scrolling to an index not in range of the Flatlist's data will result in a crash that + // won't call onScrollToIndexFailed. + // By catching this error we retry scrolling by calling onScrollToIndexFailedRef + scrollToIndexFailedRetryCountRef.current += 1; + onScrollToIndexFailedRef.current(info); } - // At some cases the index we're trying to scroll to, doesn't exist yet in the messageList - // Scrolling to an index not in range of the Flatlist's data will result in a crash that - // won't call onScrollToIndexFailed. - // By catching this error we retry scrolling by calling onScrollToIndexFailedRef - scrollToIndexFailedRetryCountRef.current += 1; - onScrollToIndexFailedRef.current(info); - } - }, WAIT_FOR_SCROLL_TIMEOUT); + }, WAIT_FOR_SCROLL_TIMEOUT); - // Only when index is greater than 0 and in range of items in FlatList - // this onScrollToIndexFailed will be called again - }); + // Only when index is greater than 0 and in range of items in FlatList + // this onScrollToIndexFailed will be called again + }, + ); const messagesWithImages = legacyImageViewerSwipeBehaviour && @@ -990,7 +975,7 @@ const MessageListWithContext = < isListActive && ((threadList && thread) || (!threadList && !thread)) ) { - setMessages(messagesWithImages as MessageType[]); + setMessages(messagesWithImages as MessageType[]); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [ @@ -1019,7 +1004,7 @@ const MessageListWithContext = < onUserScrollEvent(event); }; - const refCallback = (ref: FlatListType>) => { + const refCallback = (ref: FlatListType) => { flatListRef.current = ref; if (setFlatListRef) { @@ -1185,15 +1170,9 @@ const MessageListWithContext = < ); }; -export type MessageListProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial>; +export type MessageListProps = Partial; -export const MessageList = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageListProps, -) => { +export const MessageList = (props: MessageListProps) => { const { closePicker, selectedPicker, setSelectedPicker } = useAttachmentPickerContext(); const { channel, @@ -1216,9 +1195,9 @@ export const MessageList = < StickyHeader, targetedMessage, threadList, - } = useChannelContext(); - const { client } = useChatContext(); - const { setMessages } = useImageGalleryContext(); + } = useChannelContext(); + const { client } = useChatContext(); + const { setMessages } = useImageGalleryContext(); const { DateHeader, disableTypingIndicator, @@ -1234,11 +1213,10 @@ export const MessageList = < TypingIndicator, TypingIndicatorContainer, UnreadMessagesNotification, - } = useMessagesContext(); - const { loadMore, loadMoreRecent } = usePaginatedMessageListContext(); + } = useMessagesContext(); + const { loadMore, loadMoreRecent } = usePaginatedMessageListContext(); const { overlay } = useOverlayContext(); - const { loadMoreRecentThread, loadMoreThread, thread, threadInstance } = - useThreadContext(); + const { loadMoreRecentThread, loadMoreThread, thread, threadInstance } = useThreadContext(); return ( = { +export type MessageSystemProps = { /** Current [message object](https://getstream.io/chat/docs/#message_format) */ - message: MessageType; + message: MessageType; /** * Additional styles for the system message container. */ @@ -28,11 +25,7 @@ export type MessageSystemProps< * they can attach a message with that update. That message will be available * in message list as (type) system message. */ -export const MessageSystem = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageSystemProps, -) => { +export const MessageSystem = (props: MessageSystemProps) => { const { message, style } = props; const { diff --git a/package/src/components/MessageList/StickyHeader.tsx b/package/src/components/MessageList/StickyHeader.tsx index e48c9463e0..9ecaefac70 100644 --- a/package/src/components/MessageList/StickyHeader.tsx +++ b/package/src/components/MessageList/StickyHeader.tsx @@ -3,15 +3,12 @@ import React, { useMemo } from 'react'; import { MessagesContextValue } from '../../contexts/messagesContext/MessagesContext'; import { useTranslationContext } from '../../contexts/translationContext/TranslationContext'; -import { DefaultStreamChatGenerics } from '../../types/types'; import { getDateString } from '../../utils/i18n/getDateString'; /** * Props for the StickyHeader component. */ -export type StickyHeaderProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'DateHeader'> & { +export type StickyHeaderProps = Pick & { /** * Date to be displayed in the sticky header. */ diff --git a/package/src/components/MessageList/TypingIndicator.tsx b/package/src/components/MessageList/TypingIndicator.tsx index a1e96646d6..9d457b13f6 100644 --- a/package/src/components/MessageList/TypingIndicator.tsx +++ b/package/src/components/MessageList/TypingIndicator.tsx @@ -5,7 +5,6 @@ import { useTypingString } from './hooks/useTypingString'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { LoadingDots } from '../Indicators/LoadingDots'; const styles = StyleSheet.create({ @@ -23,16 +22,14 @@ const styles = StyleSheet.create({ }, }); -export const TypingIndicator = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { +export const TypingIndicator = () => { const { theme: { colors: { grey, white_snow }, typingIndicator: { container, text }, }, } = useTheme(); - const typingString = useTypingString(); + const typingString = useTypingString(); return ( = Pick, 'typing'> & - Pick, 'client'> & - Pick, 'thread'>; +type TypingIndicatorContainerPropsWithContext = Pick & + Pick & + Pick; -const TypingIndicatorContainerWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: PropsWithChildren>, +const TypingIndicatorContainerWithContext = ( + props: PropsWithChildren, ) => { const { children, client, thread, typing } = props; @@ -49,18 +43,14 @@ const TypingIndicatorContainerWithContext = < ); }; -export type TypingIndicatorContainerProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = PropsWithChildren>>; +export type TypingIndicatorContainerProps = PropsWithChildren< + Partial +>; -export const TypingIndicatorContainer = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: TypingIndicatorContainerProps, -) => { - const { typing } = useTypingContext(); - const { client } = useChatContext(); - const { thread } = useThreadContext(); +export const TypingIndicatorContainer = (props: TypingIndicatorContainerProps) => { + const { typing } = useTypingContext(); + const { client } = useChatContext(); + const { thread } = useThreadContext(); return ; }; diff --git a/package/src/components/MessageList/__tests__/useMessageList.test.tsx b/package/src/components/MessageList/__tests__/useMessageList.test.tsx index 30e6b8cafd..4a29dba041 100644 --- a/package/src/components/MessageList/__tests__/useMessageList.test.tsx +++ b/package/src/components/MessageList/__tests__/useMessageList.test.tsx @@ -15,7 +15,7 @@ import { import { generateMessage } from '../../../mock-builders/generator/message'; import { generateUser } from '../../../mock-builders/generator/user'; import { getTestClientWithUser } from '../../../mock-builders/mock'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { useMessageList } from '../hooks/useMessageList'; const clientUser = generateUser(); diff --git a/package/src/components/MessageList/hooks/useLastReadData.ts b/package/src/components/MessageList/hooks/useLastReadData.ts index f0922a08f8..771a4b56cd 100644 --- a/package/src/components/MessageList/hooks/useLastReadData.ts +++ b/package/src/components/MessageList/hooks/useLastReadData.ts @@ -4,25 +4,17 @@ import type { ChannelState } from 'stream-chat'; import { PaginatedMessageListContextValue } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext'; import { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { getReadStates } from '../utils/getReadStates'; -type UseLastReadDataParams< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - messages: - | PaginatedMessageListContextValue['messages'] - | ThreadContextValue['threadMessages']; +type UseLastReadDataParams = { + messages: PaginatedMessageListContextValue['messages'] | ThreadContextValue['threadMessages']; userID: string | undefined; - read?: ChannelState['read']; + read?: ChannelState['read']; returnAllReadData?: boolean; }; -export const useLastReadData = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: UseLastReadDataParams, -) => { +export const useLastReadData = (props: UseLastReadDataParams) => { const { messages, read, returnAllReadData = true, userID } = props; return useMemo( diff --git a/package/src/components/MessageList/hooks/useMessageList.ts b/package/src/components/MessageList/hooks/useMessageList.ts index 790256dfbc..5c129ceb72 100644 --- a/package/src/components/MessageList/hooks/useMessageList.ts +++ b/package/src/components/MessageList/hooks/useMessageList.ts @@ -10,7 +10,7 @@ import { } from '../../../contexts/messagesContext/MessagesContext'; import { usePaginatedMessageListContext } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext'; import { useThreadContext } from '../../../contexts/threadContext/ThreadContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { getDateSeparators } from '../utils/getDateSeparators'; import { getGroupStyles } from '../utils/getGroupStyles'; @@ -22,55 +22,42 @@ export type UseMessageListParams = { export type GroupType = string; -export type MessagesWithStylesReadByAndDateSeparator< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = MessageResponse & { +export type MessagesWithStylesReadByAndDateSeparator = MessageResponse & { groupStyles: GroupType[]; readBy: boolean | number; dateSeparator?: Date; }; -export type MessageType< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = - | ReturnType['formatMessage']> - | MessagesWithStylesReadByAndDateSeparator; +export type MessageType = + | ReturnType + | MessagesWithStylesReadByAndDateSeparator; // Type guards to check MessageType -export const isMessageWithStylesReadByAndDateSeparator = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - message: MessageType, -): message is MessagesWithStylesReadByAndDateSeparator => - (message as MessagesWithStylesReadByAndDateSeparator).readBy !== undefined; - -export const useMessageList = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - params: UseMessageListParams, -) => { +export const isMessageWithStylesReadByAndDateSeparator = ( + message: MessageType, +): message is MessagesWithStylesReadByAndDateSeparator => + (message as MessagesWithStylesReadByAndDateSeparator).readBy !== undefined; + +export const useMessageList = (params: UseMessageListParams) => { const { noGroupByUser, threadList } = params; - const { client } = useChatContext(); - const { hideDateSeparators, maxTimeBetweenGroupedMessages, read } = - useChannelContext(); + const { client } = useChatContext(); + const { hideDateSeparators, maxTimeBetweenGroupedMessages, read } = useChannelContext(); const { deletedMessagesVisibilityType, getMessagesGroupStyles = getGroupStyles } = - useMessagesContext(); - const { messages } = usePaginatedMessageListContext(); - const { threadMessages } = useThreadContext(); + useMessagesContext(); + const { messages } = usePaginatedMessageListContext(); + const { threadMessages } = useThreadContext(); const messageList = threadList ? threadMessages : messages; - const readList: ChannelState['read'] | undefined = threadList - ? undefined - : read; + const readList: ChannelState['read'] | undefined = threadList ? undefined : read; - const dateSeparators = getDateSeparators({ + const dateSeparators = getDateSeparators({ deletedMessagesVisibilityType, hideDateSeparators, messages: messageList, userId: client.userID, }); - const messageGroupStyles = getMessagesGroupStyles({ + const messageGroupStyles = getMessagesGroupStyles({ dateSeparators, hideDateSeparators, maxTimeBetweenGroupedMessages, @@ -107,7 +94,7 @@ export const useMessageList = < const processedMessageList = [ ...messagesWithStylesReadByAndDateSeparator, - ].reverse() as MessageType[]; + ].reverse() as MessageType[]; return { /** Messages enriched with dates/readby/groups and also reversed in order */ diff --git a/package/src/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.ts b/package/src/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.ts index 9f7c0f6855..76cdb4fe13 100644 --- a/package/src/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.ts +++ b/package/src/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.ts @@ -2,11 +2,10 @@ import { useEffect, useRef } from 'react'; import type { FormatMessageResponse } from 'stream-chat'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; - -export function useShouldScrollToRecentOnNewOwnMessage< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->(rawMessageList: FormatMessageResponse[], currentUserId?: string) { +export function useShouldScrollToRecentOnNewOwnMessage( + rawMessageList: FormatMessageResponse[], + currentUserId?: string, +) { const lastFocusedOwnMessageId = useRef(''); const initialFocusRegistered = useRef(false); const messagesRef = useRef(rawMessageList); diff --git a/package/src/components/MessageList/hooks/useTypingString.ts b/package/src/components/MessageList/hooks/useTypingString.ts index d4a4b302e7..1efd15efe9 100644 --- a/package/src/components/MessageList/hooks/useTypingString.ts +++ b/package/src/components/MessageList/hooks/useTypingString.ts @@ -3,16 +3,13 @@ import { useThreadContext } from '../../../contexts/threadContext/ThreadContext' import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext'; import { useTypingContext } from '../../../contexts/typingContext/TypingContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; import { filterTypingUsers } from '../utils/filterTypingUsers'; -export const useTypingString = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const { client } = useChatContext(); - const { thread } = useThreadContext(); +export const useTypingString = () => { + const { client } = useChatContext(); + const { thread } = useThreadContext(); const { t } = useTranslationContext(); - const { typing } = useTypingContext(); + const { typing } = useTypingContext(); const filteredTypingUsers = filterTypingUsers({ client, thread, typing }); diff --git a/package/src/components/MessageList/utils/filterTypingUsers.ts b/package/src/components/MessageList/utils/filterTypingUsers.ts index 7cee43ab56..47a50f7e80 100644 --- a/package/src/components/MessageList/utils/filterTypingUsers.ts +++ b/package/src/components/MessageList/utils/filterTypingUsers.ts @@ -1,21 +1,12 @@ import type { ChatContextValue } from '../../../contexts/chatContext/ChatContext'; import type { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext'; import type { TypingContextValue } from '../../../contexts/typingContext/TypingContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; - -type FilterTypingUsersParams< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'typing'> & - Pick, 'client'> & - Pick, 'thread'>; - -export const filterTypingUsers = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - client, - thread, - typing, -}: FilterTypingUsersParams) => { + +type FilterTypingUsersParams = Pick & + Pick & + Pick; + +export const filterTypingUsers = ({ client, thread, typing }: FilterTypingUsersParams) => { const nonSelfUsers: string[] = []; if (!client || !client.user || !typing) { diff --git a/package/src/components/MessageList/utils/getDateSeparators.ts b/package/src/components/MessageList/utils/getDateSeparators.ts index 3dd8bc7cc8..90f35d5c32 100644 --- a/package/src/components/MessageList/utils/getDateSeparators.ts +++ b/package/src/components/MessageList/utils/getDateSeparators.ts @@ -1,14 +1,9 @@ import type { DeletedMessagesVisibilityType } from '../../../contexts/messagesContext/MessagesContext'; import type { PaginatedMessageListContextValue } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext'; import type { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; -export type GetDateSeparatorsParams< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - messages: - | PaginatedMessageListContextValue['messages'] - | ThreadContextValue['threadMessages']; +export type GetDateSeparatorsParams = { + messages: PaginatedMessageListContextValue['messages'] | ThreadContextValue['threadMessages']; deletedMessagesVisibilityType?: DeletedMessagesVisibilityType; hideDateSeparators?: boolean; userId?: string; @@ -18,11 +13,7 @@ export type DateSeparators = { [key: string]: Date; }; -export const getDateSeparators = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - params: GetDateSeparatorsParams, -) => { +export const getDateSeparators = (params: GetDateSeparatorsParams) => { const { deletedMessagesVisibilityType, hideDateSeparators, messages, userId } = params; const dateSeparators: DateSeparators = {}; diff --git a/package/src/components/MessageList/utils/getGroupStyles.ts b/package/src/components/MessageList/utils/getGroupStyles.ts index 07af64b9cb..4ee09a1cec 100644 --- a/package/src/components/MessageList/utils/getGroupStyles.ts +++ b/package/src/components/MessageList/utils/getGroupStyles.ts @@ -2,17 +2,13 @@ import type { DateSeparators } from './getDateSeparators'; import type { PaginatedMessageListContextValue } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext'; import type { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { isEditedMessage } from '../../../utils/utils'; import type { GroupType, MessageType } from '../hooks/useMessageList'; -export type GetGroupStylesParams< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type GetGroupStylesParams = { dateSeparators: DateSeparators; - messages: - | PaginatedMessageListContextValue['messages'] - | ThreadContextValue['threadMessages']; + messages: PaginatedMessageListContextValue['messages'] | ThreadContextValue['threadMessages']; hideDateSeparators?: boolean; maxTimeBetweenGroupedMessages?: number; noGroupByUser?: boolean; @@ -21,13 +17,11 @@ export type GetGroupStylesParams< export type GroupStyle = '' | 'middle' | 'top' | 'bottom' | 'single'; -const getGroupStyle = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( +const getGroupStyle = ( dateSeparators: DateSeparators, - message: MessageType, - previousMessage: MessageType, - nextMessage: MessageType, + message: MessageType, + previousMessage: MessageType, + nextMessage: MessageType, hideDateSeparators?: boolean, maxTimeBetweenGroupedMessages?: number, ): GroupStyle[] => { @@ -101,11 +95,7 @@ const getGroupStyle = < return groupStyles; }; -export const getGroupStyles = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - params: GetGroupStylesParams, -) => { +export const getGroupStyles = (params: GetGroupStylesParams) => { const { dateSeparators, hideDateSeparators, diff --git a/package/src/components/MessageList/utils/getLastReceivedMessage.ts b/package/src/components/MessageList/utils/getLastReceivedMessage.ts index d3f7d76543..0f65de9ac7 100644 --- a/package/src/components/MessageList/utils/getLastReceivedMessage.ts +++ b/package/src/components/MessageList/utils/getLastReceivedMessage.ts @@ -1,13 +1,8 @@ -import type { DefaultStreamChatGenerics } from '../../../types/types'; import { MessageStatusTypes } from '../../../utils/utils'; import type { MessageType } from '../hooks/useMessageList'; -export const getLastReceivedMessage = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - messages: MessageType[], -) => { +export const getLastReceivedMessage = (messages: MessageType[]) => { /** * There are no status on dates so they will be skipped */ diff --git a/package/src/components/MessageList/utils/getReadStates.ts b/package/src/components/MessageList/utils/getReadStates.ts index b581eb18d2..f8418b67ee 100644 --- a/package/src/components/MessageList/utils/getReadStates.ts +++ b/package/src/components/MessageList/utils/getReadStates.ts @@ -2,15 +2,10 @@ import { ChannelState } from 'stream-chat'; import type { PaginatedMessageListContextValue } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext'; import type { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; - -export const getReadStates = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - messages: - | PaginatedMessageListContextValue['messages'] - | ThreadContextValue['threadMessages'], - read?: ChannelState['read'], + +export const getReadStates = ( + messages: PaginatedMessageListContextValue['messages'] | ThreadContextValue['threadMessages'], + read?: ChannelState['read'], returnAllReadData?: boolean, ) => { const readData: Record = {}; diff --git a/package/src/components/MessageMenu/MessageMenu.tsx b/package/src/components/MessageMenu/MessageMenu.tsx index 2c6c5b34e0..f8201ac560 100644 --- a/package/src/components/MessageMenu/MessageMenu.tsx +++ b/package/src/components/MessageMenu/MessageMenu.tsx @@ -13,14 +13,11 @@ import { useMessagesContext, } from '../../contexts/messagesContext/MessagesContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; -import { DefaultStreamChatGenerics } from '../../types/types'; import { BottomSheetModal } from '../UIComponents/BottomSheetModal'; -export type MessageMenuProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial< +export type MessageMenuProps = Partial< Pick< - MessagesContextValue, + MessagesContextValue, | 'MessageActionList' | 'MessageActionListItem' | 'MessageReactionPicker' @@ -29,7 +26,7 @@ export type MessageMenuProps< | 'MessageUserReactionsItem' > > & - Partial, 'message'>> & { + Partial> & { /** * Function to close the message actions bottom sheet * @returns void @@ -59,11 +56,7 @@ export type MessageMenuProps< selectedReaction?: string; }; -export const MessageMenu = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageMenuProps, -) => { +export const MessageMenu = (props: MessageMenuProps) => { const { dismissOverlay, handleReaction, @@ -87,8 +80,8 @@ export const MessageMenu = < MessageUserReactions: contextMessageUserReactions, MessageUserReactionsAvatar: contextMessageUserReactionsAvatar, MessageUserReactionsItem: contextMessageUserReactionsItem, - } = useMessagesContext(); - const { message: contextMessage } = useMessageContext(); + } = useMessagesContext(); + const { message: contextMessage } = useMessageContext(); const MessageActionList = propMessageActionList ?? contextMessageActionList; const MessageActionListItem = propMessageActionListItem ?? contextMessageActionListItem; const MessageReactionPicker = propMessageReactionPicker ?? contextMessageReactionPicker; diff --git a/package/src/components/MessageMenu/MessageReactionPicker.tsx b/package/src/components/MessageMenu/MessageReactionPicker.tsx index 0c5f97a62a..21677b58b1 100644 --- a/package/src/components/MessageMenu/MessageReactionPicker.tsx +++ b/package/src/components/MessageMenu/MessageReactionPicker.tsx @@ -12,13 +12,11 @@ import { import { useOwnCapabilitiesContext } from '../../contexts/ownCapabilitiesContext/OwnCapabilitiesContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { triggerHaptic } from '../../native'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { ReactionData } from '../../utils/utils'; -export type MessageReactionPickerProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'supportedReactions'> & - Pick, 'handleReaction' | 'dismissOverlay'> & { +export type MessageReactionPickerProps = Pick & + Pick & { /** * An array of reaction types that the current user has reacted with */ @@ -43,11 +41,7 @@ const renderItem = ({ index, item }: { index: number; item: ReactionPickerItemTy /** * MessageReactionPicker - A high level component which implements all the logic required for a message overlay reaction list */ -export const MessageReactionPicker = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: MessageReactionPickerProps, -) => { +export const MessageReactionPicker = (props: MessageReactionPickerProps) => { const { dismissOverlay, handleReaction, diff --git a/package/src/components/MessageMenu/MessageUserReactions.tsx b/package/src/components/MessageMenu/MessageUserReactions.tsx index f2836350ae..8f53b5c6c8 100644 --- a/package/src/components/MessageMenu/MessageUserReactions.tsx +++ b/package/src/components/MessageMenu/MessageUserReactions.tsx @@ -14,18 +14,16 @@ import { } from '../../contexts/messagesContext/MessagesContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { useTranslationContext } from '../../contexts/translationContext/TranslationContext'; -import { DefaultStreamChatGenerics, Reaction } from '../../types/types'; +import { Reaction } from '../../types/types'; import { ReactionData } from '../../utils/utils'; -export type MessageUserReactionsProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial< +export type MessageUserReactionsProps = Partial< Pick< - MessagesContextValue, + MessagesContextValue, 'MessageUserReactionsAvatar' | 'MessageUserReactionsItem' | 'supportedReactions' > > & - Partial, 'message'>> & { + Partial> & { /** * An array of reactions */ diff --git a/package/src/components/MessageMenu/MessageUserReactionsItem.tsx b/package/src/components/MessageMenu/MessageUserReactionsItem.tsx index 7372ab4da9..7dff4e45e0 100644 --- a/package/src/components/MessageMenu/MessageUserReactionsItem.tsx +++ b/package/src/components/MessageMenu/MessageUserReactionsItem.tsx @@ -7,12 +7,13 @@ import { MessagesContextValue } from '../../contexts/messagesContext/MessagesCon import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { Unknown } from '../../icons'; -import type { DefaultStreamChatGenerics, Reaction } from '../../types/types'; +import type { Reaction } from '../../types/types'; import { ReactionData } from '../../utils/utils'; -export type MessageUserReactionsItemProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'MessageUserReactionsAvatar'> & { +export type MessageUserReactionsItemProps = Pick< + MessagesContextValue, + 'MessageUserReactionsAvatar' +> & { /** * The reaction object */ @@ -23,13 +24,11 @@ export type MessageUserReactionsItemProps< supportedReactions: ReactionData[]; }; -export const MessageUserReactionsItem = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const MessageUserReactionsItem = ({ MessageUserReactionsAvatar, reaction, supportedReactions, -}: MessageUserReactionsItemProps) => { +}: MessageUserReactionsItemProps) => { const { id, name, type } = reaction; const { theme: { diff --git a/package/src/components/MessageMenu/hooks/useFetchReactions.ts b/package/src/components/MessageMenu/hooks/useFetchReactions.ts index 689c00b3a6..f6c886dbdf 100644 --- a/package/src/components/MessageMenu/hooks/useFetchReactions.ts +++ b/package/src/components/MessageMenu/hooks/useFetchReactions.ts @@ -5,26 +5,21 @@ import { ReactionResponse, ReactionSort } from 'stream-chat'; import { MessageType } from '../../../components/MessageList/hooks/useMessageList'; import { useChatContext } from '../../../contexts/chatContext/ChatContext'; import { getReactionsForFilterSort } from '../../../store/apis/getReactionsforFilterSort'; -import { DefaultStreamChatGenerics } from '../../../types/types'; -export type UseFetchReactionParams< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type UseFetchReactionParams = { limit?: number; - message?: MessageType; + message?: MessageType; reactionType?: string; - sort?: ReactionSort; + sort?: ReactionSort; }; -export const useFetchReactions = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useFetchReactions = ({ limit = 25, message, reactionType, sort, }: UseFetchReactionParams) => { - const [reactions, setReactions] = useState[]>([]); + const [reactions, setReactions] = useState([]); const [loading, setLoading] = useState(true); const [next, setNext] = useState(undefined); const messageId = message?.id; diff --git a/package/src/components/Poll/Poll.tsx b/package/src/components/Poll/Poll.tsx index dc27cb895c..dc64810994 100644 --- a/package/src/components/Poll/Poll.tsx +++ b/package/src/components/Poll/Poll.tsx @@ -14,12 +14,9 @@ import { useTheme, useTranslationContext, } from '../../contexts'; -import type { DefaultStreamChatGenerics } from '../../types/types'; -export type PollProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'poll' | 'message'> & - Pick, 'PollContent'>; +export type PollProps = Pick & + Pick; export type PollContentProps = { PollButtons?: React.ComponentType; @@ -90,13 +87,7 @@ export const PollContent = ({ ); }; -export const Poll = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - message, - poll, - PollContent: PollContentOverride, -}: PollProps) => ( +export const Poll = ({ message, poll, PollContent: PollContentOverride }: PollProps) => ( = { - onPress?: ({ - message, - poll, - }: { - message: MessageType; - poll: Poll; - }) => void; +export type PollButtonProps = { + onPress?: ({ message, poll }: { message: MessageType; poll: Poll }) => void; }; export type PollVoteButtonProps = { diff --git a/package/src/components/Poll/components/PollAnswersList.tsx b/package/src/components/Poll/components/PollAnswersList.tsx index 541ec27c27..a4949602a9 100644 --- a/package/src/components/Poll/components/PollAnswersList.tsx +++ b/package/src/components/Poll/components/PollAnswersList.tsx @@ -13,7 +13,6 @@ import { useTheme, useTranslationContext, } from '../../../contexts'; -import { DefaultStreamChatGenerics } from '../../../types/types'; import { getDateString } from '../../../utils/i18n/getDateString'; import { Avatar } from '../../Avatar/Avatar'; import { usePollAnswersPagination } from '../hooks/usePollAnswersPagination'; @@ -73,10 +72,8 @@ export const AnswerListAddCommentButton = (props: PollButtonProps) => { ); }; -export type PollAnswersListProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = PollContextValue & { - additionalFlatListProps?: Partial>>; +export type PollAnswersListProps = PollContextValue & { + additionalFlatListProps?: Partial>; PollAnswersListContent?: React.ComponentType; }; diff --git a/package/src/components/Poll/components/PollResults/PollOptionFullResults.tsx b/package/src/components/Poll/components/PollResults/PollOptionFullResults.tsx index 362fce31e4..03a8f4ec82 100644 --- a/package/src/components/Poll/components/PollResults/PollOptionFullResults.tsx +++ b/package/src/components/Poll/components/PollResults/PollOptionFullResults.tsx @@ -11,16 +11,14 @@ import { useTheme, useTranslationContext, } from '../../../../contexts'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; + import { usePollOptionVotesPagination } from '../../hooks/usePollOptionVotesPagination'; import { usePollState } from '../../hooks/usePollState'; -export type PollOptionFullResultsProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = PollContextValue & { - option: PollOption; - additionalFlatListProps?: Partial>>; - PollOptionFullResultsContent?: React.ComponentType<{ option: PollOption }>; +export type PollOptionFullResultsProps = PollContextValue & { + option: PollOption; + additionalFlatListProps?: Partial>; + PollOptionFullResultsContent?: React.ComponentType<{ option: PollOption }>; }; export const PollOptionFullResultsItem = ({ item }: { item: PollVoteClass }) => ( diff --git a/package/src/components/Poll/components/PollResults/PollResultItem.tsx b/package/src/components/Poll/components/PollResults/PollResultItem.tsx index 38fdcb1c3d..3a7a6421d9 100644 --- a/package/src/components/Poll/components/PollResults/PollResultItem.tsx +++ b/package/src/components/Poll/components/PollResults/PollResultItem.tsx @@ -12,24 +12,22 @@ import { useTheme, useTranslationContext, } from '../../../../contexts'; -import type { DefaultStreamChatGenerics } from '../../../../types/types'; + import { MessageType } from '../../../MessageList/hooks/useMessageList'; import { usePollState } from '../../hooks/usePollState'; import { GenericPollButton } from '../Button'; import { PollModalHeader } from '../PollModalHeader'; -export type ShowAllVotesButtonProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - option: PollOption; +export type ShowAllVotesButtonProps = { + option: PollOption; onPress?: ({ message, option, poll, }: { - message: MessageType; - option: PollOption; - poll: Poll; + message: MessageType; + option: PollOption; + poll: Poll; }) => void; }; @@ -79,10 +77,8 @@ export const ShowAllVotesButton = (props: ShowAllVotesButtonProps) => { ); }; -export type PollResultItemProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - option: PollOption; +export type PollResultItemProps = { + option: PollOption; }; const PollResultsVoteItem = (vote: PollVoteClass) => ( diff --git a/package/src/components/Poll/hooks/usePollState.ts b/package/src/components/Poll/hooks/usePollState.ts index 0c64c67c38..9100724b5e 100644 --- a/package/src/components/Poll/hooks/usePollState.ts +++ b/package/src/components/Poll/hooks/usePollState.ts @@ -16,8 +16,6 @@ import { usePollStateStore } from './usePollStateStore'; import { usePollContext } from '../../../contexts'; -import { DefaultStreamChatGenerics } from '../../../types/types'; - export type UsePollStateSelectorReturnType = { allowAnswers: boolean | undefined; allowUserSuggestedOptions: boolean | undefined; @@ -36,19 +34,13 @@ export type UsePollStateSelectorReturnType = { votingVisibility: VotingVisibility | undefined; }; -export type UsePollStateReturnType< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = UsePollStateSelectorReturnType & { - addComment: ( - answerText: string, - ) => Promise>; +export type UsePollStateReturnType = UsePollStateSelectorReturnType & { + addComment: (answerText: string) => Promise; addOption: (optionText: string) => Promise; - endVote: () => Promise>; + endVote: () => Promise; }; -const selector = ( - nextValue: PollState, -): UsePollStateSelectorReturnType => ({ +const selector = (nextValue: PollState): UsePollStateSelectorReturnType => ({ allowAnswers: nextValue.allow_answers, allowUserSuggestedOptions: nextValue.allow_user_suggested_options, answersCount: nextValue.answers_count, diff --git a/package/src/components/Reply/Reply.tsx b/package/src/components/Reply/Reply.tsx index 6f3d9f069d..48299579ba 100644 --- a/package/src/components/Reply/Reply.tsx +++ b/package/src/components/Reply/Reply.tsx @@ -25,7 +25,7 @@ import { useTranslationContext, } from '../../contexts/translationContext/TranslationContext'; import { useStateStore } from '../../hooks'; -import { DefaultStreamChatGenerics, FileTypes } from '../../types/types'; +import { FileTypes } from '../../types/types'; import { getResizedImageUrl } from '../../utils/getResizedImageUrl'; import { getTrimmedAttachmentTitle } from '../../utils/getTrimmedAttachmentTitle'; import { hasOnlyEmojis } from '../../utils/utils'; @@ -80,16 +80,12 @@ export type ReplySelectorReturnType = { name?: string; }; -const selector = ( - nextValue: PollState, -): ReplySelectorReturnType => ({ +const selector = (nextValue: PollState): ReplySelectorReturnType => ({ name: nextValue.name, }); -type ReplyPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'quotedMessage'> & - Pick, 'FileAttachmentIcon' | 'MessageAvatar'> & +type ReplyPropsWithContext = Pick & + Pick & Pick & { attachmentSize?: number; styles?: Partial<{ @@ -101,11 +97,7 @@ type ReplyPropsWithContext< }>; }; -const getMessageType = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - lastAttachment: Attachment, -) => { +const getMessageType = (lastAttachment: Attachment) => { let messageType; const isLastAttachmentFile = lastAttachment.type === FileTypes.File; @@ -149,11 +141,7 @@ const getMessageType = < return messageType; }; -const ReplyWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ReplyPropsWithContext, -) => { +const ReplyWithContext = (props: ReplyPropsWithContext) => { const { client } = useChatContext(); const { attachmentSize = 40, @@ -205,7 +193,7 @@ const ReplyWithContext = < return null; } - const lastAttachment = quotedMessage.attachments?.slice(-1)[0] as Attachment; + const lastAttachment = quotedMessage.attachments?.slice(-1)[0] as Attachment; const messageType = lastAttachment && getMessageType(lastAttachment); const trimmedLastAttachmentTitle = getTrimmedAttachmentTitle(lastAttachment?.title); @@ -281,7 +269,7 @@ const ReplyWithContext = < /> ) : null} - + () => { - const contextValue = useContext( - MessageInputContext, - ) as unknown as MessageInputContextValue; +const useMessageInputContextIfAvailable = () => { + const contextValue = useContext(MessageInputContext) as unknown as MessageInputContextValue; return contextValue; }; -const areEqual = ( - prevProps: ReplyPropsWithContext, - nextProps: ReplyPropsWithContext, -) => { +const areEqual = (prevProps: ReplyPropsWithContext, nextProps: ReplyPropsWithContext) => { const { quotedMessage: prevQuotedMessage } = prevProps; const { quotedMessage: nextQuotedMessage } = nextProps; @@ -396,28 +377,22 @@ const areEqual = = Partial>; +export type ReplyProps = Partial; /** * UI Component for reply */ -export const Reply = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ReplyProps, -) => { - const { message } = useMessageContext(); +export const Reply = (props: ReplyProps) => { + const { message } = useMessageContext(); const { FileAttachmentIcon = FileIconDefault, MessageAvatar = MessageAvatarDefault } = - useMessagesContext(); + useMessagesContext(); - const { editing, quotedMessage } = useMessageInputContextIfAvailable(); + const { editing, quotedMessage } = useMessageInputContextIfAvailable(); const quotedEditingMessage = ( typeof editing !== 'boolean' ? editing?.quoted_message || false : false - ) as MessageInputContextValue['quotedMessage']; + ) as MessageInputContextValue['quotedMessage']; const { t } = useTranslationContext(); @@ -427,7 +402,7 @@ export const Reply = < FileAttachmentIcon, MessageAvatar, quotedMessage: message - ? (message.quoted_message as MessageInputContextValue['quotedMessage']) + ? (message.quoted_message as MessageInputContextValue['quotedMessage']) : quotedMessage || quotedEditingMessage, t, }} diff --git a/package/src/components/Thread/Thread.tsx b/package/src/components/Thread/Thread.tsx index 465fc67158..791b2d6000 100644 --- a/package/src/components/Thread/Thread.tsx +++ b/package/src/components/Thread/Thread.tsx @@ -10,19 +10,16 @@ import { } from '../../contexts/messagesContext/MessagesContext'; import { ThreadContextValue, useThreadContext } from '../../contexts/threadContext/ThreadContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { MessageInput as DefaultMessageInput, MessageInputProps, } from '../MessageInput/MessageInput'; import type { MessageListProps } from '../MessageList/MessageList'; -type ThreadPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'client'> & - Pick, 'MessageList'> & +type ThreadPropsWithContext = Pick & + Pick & Pick< - ThreadContextValue, + ThreadContextValue, | 'closeThread' | 'loadMoreThread' | 'parentMessagePreventPress' @@ -34,12 +31,12 @@ type ThreadPropsWithContext< * Additional props for underlying MessageInput component. * Available props - https://getstream.io/chat/docs/sdk/reactnative/ui-components/message-input/#props * */ - additionalMessageInputProps?: Partial>; + additionalMessageInputProps?: Partial; /** * Additional props for underlying MessageList component. * Available props - https://getstream.io/chat/docs/sdk/reactnative/ui-components/message-list/#props * */ - additionalMessageListProps?: Partial>; + additionalMessageListProps?: Partial; /** Make input focus on mounting thread */ autoFocus?: boolean; /** Closes thread on dismount, defaults to true */ @@ -50,18 +47,14 @@ type ThreadPropsWithContext< * **Customized MessageInput component to used within Thread instead of default MessageInput * **Available from [MessageInput](https://getstream.io/chat/docs/sdk/reactnative/ui-components/message-input)** */ - MessageInput?: React.ComponentType>; + MessageInput?: React.ComponentType; /** * Call custom function on closing thread if handling thread state elsewhere */ onThreadDismount?: () => void; }; -const ThreadWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ThreadPropsWithContext, -) => { +const ThreadWithContext = (props: ThreadPropsWithContext) => { const { additionalMessageInputProps, additionalMessageListProps, @@ -120,7 +113,7 @@ const ThreadWithContext = < threadList {...additionalMessageListProps} /> - + = Partial>; +export type ThreadProps = Partial; /** * Thread - The Thread renders a parent message with a list of replies. Use the standard message list of the main channel's messages. @@ -142,16 +133,11 @@ export type ThreadProps< * - additionalMessageListProps * - additionalMessageInputProps */ -export const Thread = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ThreadProps, -) => { - const { client } = useChatContext(); - const { threadList } = useChannelContext(); - const { MessageList } = useMessagesContext(); - const { closeThread, loadMoreThread, reloadThread, thread, threadInstance } = - useThreadContext(); +export const Thread = (props: ThreadProps) => { + const { client } = useChatContext(); + const { threadList } = useChannelContext(); + const { MessageList } = useMessagesContext(); + const { closeThread, loadMoreThread, reloadThread, thread, threadInstance } = useThreadContext(); if (thread?.id && !threadList) { throw new Error( @@ -160,7 +146,7 @@ export const Thread = < } return ( - + regular

", "attachments": [], "created_at": 2020-05-05T14:50:00.000Z, "dateSeparator": undefined, @@ -80,7 +79,6 @@ exports[`Thread should match thread snapshot 1`] = ` }, }, { - "__html": "

regular

", "attachments": [], "created_at": 2020-05-05T14:50:00.000Z, "dateSeparator": undefined, @@ -111,7 +109,6 @@ exports[`Thread should match thread snapshot 1`] = ` }, }, { - "__html": "

regular

", "attachments": [], "created_at": 2020-05-05T14:50:00.000Z, "dateSeparator": 2020-05-05T14:50:00.000Z, diff --git a/package/src/components/Thread/components/ThreadFooterComponent.tsx b/package/src/components/Thread/components/ThreadFooterComponent.tsx index 609558a751..3232feed0f 100644 --- a/package/src/components/Thread/components/ThreadFooterComponent.tsx +++ b/package/src/components/Thread/components/ThreadFooterComponent.tsx @@ -13,7 +13,6 @@ import { } from '../../../contexts/threadContext/ThreadContext'; import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext'; import { useViewport } from '../../../hooks/useViewport'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; const styles = StyleSheet.create({ absolute: { position: 'absolute' }, @@ -39,10 +38,8 @@ const styles = StyleSheet.create({ }, }); -type ThreadFooterComponentPropsWithContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'Message'> & - Pick, 'parentMessagePreventPress' | 'thread'>; +type ThreadFooterComponentPropsWithContext = Pick & + Pick; export const InlineLoadingMoreThreadIndicator = () => { const { threadLoadingMore } = useThreadContext(); @@ -63,11 +60,7 @@ export const InlineLoadingMoreThreadIndicator = () => { ); }; -const ThreadFooterComponentWithContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ThreadFooterComponentPropsWithContext, -) => { +const ThreadFooterComponentWithContext = (props: ThreadFooterComponentPropsWithContext) => { const { Message, parentMessagePreventPress, thread } = props; const { t } = useTranslationContext(); const { vw } = useViewport(); @@ -141,9 +134,9 @@ const ThreadFooterComponentWithContext = < ); }; -const areEqual = ( - prevProps: ThreadFooterComponentPropsWithContext, - nextProps: ThreadFooterComponentPropsWithContext, +const areEqual = ( + prevProps: ThreadFooterComponentPropsWithContext, + nextProps: ThreadFooterComponentPropsWithContext, ) => { const { parentMessagePreventPress: prevParentMessagePreventPress, thread: prevThread } = prevProps; @@ -184,19 +177,12 @@ const MemoizedThreadFooter = React.memo( areEqual, ) as typeof ThreadFooterComponentWithContext; -export type ThreadFooterComponentProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial, 'Message'>> & - Partial, 'parentMessagePreventPress' | 'thread'>>; +export type ThreadFooterComponentProps = Partial> & + Partial>; -export const ThreadFooterComponent = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: ThreadFooterComponentProps, -) => { - const { Message } = useMessagesContext(); - const { parentMessagePreventPress, thread, threadLoadingMore } = - useThreadContext(); +export const ThreadFooterComponent = (props: ThreadFooterComponentProps) => { + const { Message } = useMessagesContext(); + const { parentMessagePreventPress, thread, threadLoadingMore } = useThreadContext(); return ( threads: nextValue.threads, }) as const; -export type ThreadListProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick< - ThreadsContextValue, +export type ThreadListProps = Pick< + ThreadsContextValue, | 'additionalFlatListProps' | 'isFocused' | 'onThreadSelect' diff --git a/package/src/contexts/channelContext/ChannelContext.tsx b/package/src/contexts/channelContext/ChannelContext.tsx index eea9c855dd..c7a7f59894 100644 --- a/package/src/contexts/channelContext/ChannelContext.tsx +++ b/package/src/contexts/channelContext/ChannelContext.tsx @@ -6,14 +6,12 @@ import { MarkReadFunctionOptions } from '../../components/Channel/Channel'; import type { EmptyStateProps } from '../../components/Indicators/EmptyStateIndicator'; import type { LoadingProps } from '../../components/Indicators/LoadingIndicator'; import { StickyHeaderProps } from '../../components/MessageList/StickyHeader'; -import type { ChannelUnreadState, DefaultStreamChatGenerics } from '../../types/types'; +import type { ChannelUnreadState } from '../../types/types'; import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; -export type ChannelContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type ChannelContextValue = { /** * Instance of channel object from stream-chat package. * @@ -36,7 +34,7 @@ export type ChannelContextValue< * * @overrideType Channel */ - channel: Channel; + channel: Channel; /** * Custom UI component to display empty state when channel has no messages. * @@ -87,11 +85,9 @@ export type ChannelContextValue< limit, setTargetedMessage, }: { - channelUnreadState?: ChannelUnreadState; + channelUnreadState?: ChannelUnreadState; limit?: number; - setChannelUnreadState?: React.Dispatch< - React.SetStateAction | undefined> - >; + setChannelUnreadState?: React.Dispatch>; setTargetedMessage?: (messageId: string) => void; }) => Promise; @@ -123,17 +119,15 @@ export type ChannelContextValue< * } * ``` */ - members: ChannelState['members']; + members: ChannelState['members']; /** * Custom network down indicator to override the Stream default */ NetworkDownIndicator: React.ComponentType; - read: ChannelState['read']; + read: ChannelState['read']; reloadChannel: () => Promise; scrollToFirstUnreadThreshold: number; - setChannelUnreadState: React.Dispatch< - React.SetStateAction | undefined> - >; + setChannelUnreadState: React.Dispatch>; setLastRead: React.Dispatch>; setTargetedMessage: (messageId?: string) => void; /** @@ -141,7 +135,7 @@ export type ChannelContextValue< * Its a map of filename and AbortController */ uploadAbortControllerRef: React.MutableRefObject>; - channelUnreadState?: ChannelUnreadState; + channelUnreadState?: ChannelUnreadState; disabled?: boolean; enableMessageGroupingByUser?: boolean; /** @@ -170,7 +164,7 @@ export type ChannelContextValue< */ targetedMessage?: string; threadList?: boolean; - watcherCount?: ChannelState['watcher_count']; + watcherCount?: ChannelState['watcher_count']; /** * * ```json @@ -194,32 +188,26 @@ export type ChannelContextValue< * } * ``` */ - watchers?: ChannelState['watchers']; + watchers?: ChannelState['watchers']; }; export const ChannelContext = React.createContext( DEFAULT_BASE_CONTEXT_VALUE as ChannelContextValue, ); -export const ChannelProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const ChannelProvider = ({ children, value, }: PropsWithChildren<{ - value: ChannelContextValue; + value: ChannelContextValue; }>) => ( {children} ); -export const useChannelContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const contextValue = useContext( - ChannelContext, - ) as unknown as ChannelContextValue; +export const useChannelContext = () => { + const contextValue = useContext(ChannelContext) as unknown as ChannelContextValue; if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) { throw new Error( diff --git a/package/src/contexts/channelsContext/ChannelsContext.tsx b/package/src/contexts/channelsContext/ChannelsContext.tsx index 0202c58354..64bbc4f500 100644 --- a/package/src/contexts/channelsContext/ChannelsContext.tsx +++ b/package/src/contexts/channelsContext/ChannelsContext.tsx @@ -16,14 +16,12 @@ import type { ChannelPreviewUnreadCountProps } from '../../components/ChannelPre import type { EmptyStateProps } from '../../components/Indicators/EmptyStateIndicator'; import type { LoadingErrorProps } from '../../components/Indicators/LoadingErrorIndicator'; import type { LoadingProps } from '../../components/Indicators/LoadingIndicator'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; -export type ChannelsContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type ChannelsContextValue = { /** * Besides the existing default behavior of the ChannelListMessenger component, you can attach * additional props to the underlying React Native FlatList. @@ -41,7 +39,7 @@ export type ChannelsContextValue< * * **Note:** Don't use `additionalFlatListProps` to access the FlatList ref, use `setFlatListRef` */ - additionalFlatListProps: Partial>>; + additionalFlatListProps: Partial>; /** * A control prop used to determine whether the first query of the channel list has succeeded. */ @@ -49,7 +47,7 @@ export type ChannelsContextValue< /** * Channels can be either an array of channels or a promise which resolves to an array of channels */ - channels: Channel[] | null; + channels: Channel[] | null; /** * Custom indicator to use when channel list is empty * @@ -123,7 +121,7 @@ export type ChannelsContextValue< * * Default: [ChannelPreviewMessenger](https://getstream.io/chat/docs/sdk/reactnative/ui-components/channel-preview-messenger/) */ - Preview: React.ComponentType>; + Preview: React.ComponentType; /** * Triggered when the channel list is refreshing, displays a loading spinner at the top of the list */ @@ -142,7 +140,7 @@ export type ChannelsContextValue< // * // * @param channel A channel object // */ - // setActiveChannel?: (channel: Channel) => void; + // setActiveChannel?: (channel: Channel) => void; /** * Function to gain access to the inner FlatList ref * @@ -155,7 +153,7 @@ export type ChannelsContextValue< * }} * ``` */ - setFlatListRef: (ref: FlatList> | null) => void; + setFlatListRef: (ref: FlatList | null) => void; /** * Custom UI component to display loading channel skeletons * @@ -172,19 +170,19 @@ export type ChannelsContextValue< * * @param channel A channel object */ - onSelect?: (channel: Channel) => void; + onSelect?: (channel: Channel) => void; /** * Custom UI component to render preview avatar. * * **Default** [ChannelAvatar](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelAvatar.tsx) */ - PreviewAvatar?: React.ComponentType>; + PreviewAvatar?: React.ComponentType; /** * Custom UI component to render preview of latest message on channel. * * **Default** [ChannelPreviewMessage](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewMessage.tsx) */ - PreviewMessage?: React.ComponentType>; + PreviewMessage?: React.ComponentType; /** * Custom UI component to render muted status. * @@ -196,44 +194,38 @@ export type ChannelsContextValue< * * **Default** [ChannelPreviewStatus](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewStatus.tsx) */ - PreviewStatus?: React.ComponentType>; + PreviewStatus?: React.ComponentType; /** * Custom UI component to render preview avatar. * * **Default** [ChannelPreviewTitle](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewTitle.tsx) */ - PreviewTitle?: React.ComponentType>; + PreviewTitle?: React.ComponentType; /** * Custom UI component to render preview avatar. * * **Default** [ChannelPreviewUnreadCount](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewUnreadCount.tsx) */ - PreviewUnreadCount?: React.ComponentType>; + PreviewUnreadCount?: React.ComponentType; }; export const ChannelsContext = React.createContext( DEFAULT_BASE_CONTEXT_VALUE as ChannelsContextValue, ); -export const ChannelsProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const ChannelsProvider = ({ children, value, }: PropsWithChildren<{ - value: ChannelsContextValue; + value: ChannelsContextValue; }>) => ( {children} ); -export const useChannelsContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const contextValue = useContext( - ChannelsContext, - ) as unknown as ChannelsContextValue; +export const useChannelsContext = () => { + const contextValue = useContext(ChannelsContext) as unknown as ChannelsContextValue; if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) { throw new Error( diff --git a/package/src/contexts/channelsStateContext/ChannelsStateContext.tsx b/package/src/contexts/channelsStateContext/ChannelsStateContext.tsx index 4d2ed02692..ac9d493f10 100644 --- a/package/src/contexts/channelsStateContext/ChannelsStateContext.tsx +++ b/package/src/contexts/channelsStateContext/ChannelsStateContext.tsx @@ -8,7 +8,6 @@ import React, { useRef, } from 'react'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { ActiveChannelsProvider } from '../activeChannelsRefContext/ActiveChannelsRefContext'; import type { ThreadContextValue } from '../threadContext/ThreadContext'; @@ -16,50 +15,35 @@ import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; -export type ChannelState< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - threadMessages: ThreadContextValue['threadMessages']; +export type ChannelState = { + threadMessages: ThreadContextValue['threadMessages']; }; -type ChannelsState< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - [cid: string]: ChannelState; +type ChannelsState = { + [cid: string]: ChannelState; }; export type Keys = keyof ChannelState; -export type Payload< - Key extends Keys = Keys, - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type Payload = { cid: string; key: Key; - value: ChannelState[Key]; + value: ChannelState[Key]; }; -type SetStateAction< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - payload: Payload; +type SetStateAction = { + payload: Payload; type: 'SET_STATE'; }; -type Action = - SetStateAction; +type Action = SetStateAction; -export type ChannelsStateContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - setState: (value: Payload) => void; - state: ChannelsState; +export type ChannelsStateContextValue = { + setState: (value: Payload) => void; + state: ChannelsState; }; -type Reducer = ( - state: ChannelsState, - action: Action, -) => ChannelsState; +type Reducer = (state: ChannelsState, action: Action) => ChannelsState; function reducer(state: ChannelsState, action: Action) { switch (action.type) { @@ -81,16 +65,10 @@ const ChannelsStateContext = React.createContext( DEFAULT_BASE_CONTEXT_VALUE as ChannelsStateContextValue, ); -export const ChannelsStateProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - children, -}: { - children: ReactNode; -}) => { - const [state, dispatch] = useReducer(reducer as unknown as Reducer, {}); +export const ChannelsStateProvider = ({ children }: { children: ReactNode }) => { + const [state, dispatch] = useReducer(reducer as unknown as Reducer, {}); - const setState = useCallback((payload: Payload) => { + const setState = useCallback((payload: Payload) => { dispatch({ payload, type: 'SET_STATE' }); }, []); @@ -116,12 +94,8 @@ export const ChannelsStateProvider = < ); }; -export const useChannelsStateContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const contextValue = useContext( - ChannelsStateContext, - ) as unknown as ChannelsStateContextValue; +export const useChannelsStateContext = () => { + const contextValue = useContext(ChannelsStateContext) as unknown as ChannelsStateContextValue; if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) { throw new Error( diff --git a/package/src/contexts/channelsStateContext/useChannelState.ts b/package/src/contexts/channelsStateContext/useChannelState.ts index f0683afcfa..ae29f4d14f 100644 --- a/package/src/contexts/channelsStateContext/useChannelState.ts +++ b/package/src/contexts/channelsStateContext/useChannelState.ts @@ -6,12 +6,7 @@ import { useChannelsStateContext } from './ChannelsStateContext'; import type { ChannelsStateContextValue, ChannelState, Keys } from './ChannelsStateContext'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - -type StateManagerParams< - Key extends Keys, - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = ChannelsStateContextValue & { +type StateManagerParams = ChannelsStateContextValue & { cid: string; key: Key; }; @@ -21,20 +16,16 @@ type StateManagerParams< updates to the ChannelsStateContext reducer. It receives the cid and key which it wants to update and perform the state updates. Also supports a initialState. */ -export function useStateManager< - Key extends Keys, - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - { cid, key, setState, state }: StateManagerParams, - initialValue?: ChannelState[Key], +export function useStateManager( + { cid, key, setState, state }: StateManagerParams, + initialValue?: ChannelState[Key], ) { // eslint-disable-next-line react-hooks/exhaustive-deps const memoizedInitialValue = useMemo(() => initialValue, []); - const value = - state[cid]?.[key] || (memoizedInitialValue as ChannelState[Key]); + const value = state[cid]?.[key] || (memoizedInitialValue as ChannelState[Key]); const setValue = useCallback( - (value: ChannelState[Key]) => setState({ cid, key, value }), + (value: ChannelState[Key]) => setState({ cid, key, value }), // eslint-disable-next-line react-hooks/exhaustive-deps [cid, key], ); @@ -42,21 +33,17 @@ export function useStateManager< return [value, setValue] as const; } -export type UseChannelStateValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - setThreadMessages: (value: ChannelState['threadMessages']) => void; - threadMessages: ChannelState['threadMessages']; +export type UseChannelStateValue = { + setThreadMessages: (value: ChannelState['threadMessages']) => void; + threadMessages: ChannelState['threadMessages']; }; -export function useChannelState< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: ChannelType | undefined, +export function useChannelState( + channel: ChannelType | undefined, threadId?: string, -): UseChannelStateValue { +): UseChannelStateValue { const cid = channel?.id || 'id'; // in case channel is not initialized, use generic id string for indexing - const { setState, state } = useChannelsStateContext(); + const { setState, state } = useChannelsStateContext(); const [threadMessages, setThreadMessages] = useStateManager( { diff --git a/package/src/contexts/chatContext/ChatContext.tsx b/package/src/contexts/chatContext/ChatContext.tsx index 9c19d705f7..9c26b0cc83 100644 --- a/package/src/contexts/chatContext/ChatContext.tsx +++ b/package/src/contexts/chatContext/ChatContext.tsx @@ -3,19 +3,16 @@ import type { ImageProps } from 'react-native'; import type { AppSettingsAPIResponse, Channel, Mute, StreamChat } from 'stream-chat'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { MessageContextValue } from '../messageContext/MessageContext'; import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; -export type ChatContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type ChatContextValue = { /** * Object of application settings returned from Stream. * */ - appSettings: AppSettingsAPIResponse | null; + appSettings: AppSettingsAPIResponse | null; /** * The StreamChat client object * @@ -32,7 +29,7 @@ export type ChatContextValue< * * @overrideType StreamChat * */ - client: StreamChat; + client: StreamChat; connectionRecovering: boolean; enableOfflineSupport: boolean; /** @@ -40,13 +37,13 @@ export type ChatContextValue< */ ImageComponent: React.ComponentType; isOnline: boolean | null; - mutedUsers: Mute[]; + mutedUsers: Mute[]; /** * @param newChannel Channel to set as active. * * @overrideType Function */ - setActiveChannel: (newChannel?: Channel) => void; + setActiveChannel: (newChannel?: Channel) => void; /** * Instance of channel object from stream-chat package. * @@ -64,28 +61,24 @@ export type ChatContextValue< * * @overrideType Channel */ - channel?: Channel; -} & Partial, 'isMessageAIGenerated'>>; + channel?: Channel; +} & Partial>; export const ChatContext = React.createContext(DEFAULT_BASE_CONTEXT_VALUE as ChatContextValue); -export const ChatProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const ChatProvider = ({ children, value, }: PropsWithChildren<{ - value?: ChatContextValue; + value?: ChatContextValue; }>) => ( {children} ); -export const useChatContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const contextValue = useContext(ChatContext) as unknown as ChatContextValue; +export const useChatContext = () => { + const contextValue = useContext(ChatContext) as unknown as ChatContextValue; if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) { throw new Error( diff --git a/package/src/contexts/debugContext/DebugContext.tsx b/package/src/contexts/debugContext/DebugContext.tsx index 03b82339a2..02291f3dda 100644 --- a/package/src/contexts/debugContext/DebugContext.tsx +++ b/package/src/contexts/debugContext/DebugContext.tsx @@ -3,59 +3,52 @@ import React, { PropsWithChildren, useContext, useRef } from 'react'; import type { Channel, ChannelState, StreamChat } from 'stream-chat'; import type { MessageType } from '../../components/MessageList/hooks/useMessageList'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; -export type DebugDataType< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = - | StreamChat['user'] +export type DebugDataType = + | StreamChat['user'] | { - data: Channel['data']; - members: ChannelState['members']; + data: Channel['data']; + members: ChannelState['members']; }[] - | MessageType[]; + | MessageType[]; -export type DebugContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type DebugContextValue = { eventType?: string; sendEventParams?: { action: string; - data: DebugDataType; + data: DebugDataType; }; setEventType?: (data: string) => void; - setSendEventParams?: (data: { action: string; data: DebugDataType }) => void; + setSendEventParams?: (data: { action: string; data: DebugDataType }) => void; }; export const DebugContext = React.createContext( DEFAULT_BASE_CONTEXT_VALUE as React.MutableRefObject, ); -export const DebugContextProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const DebugContextProvider = ({ children, useFlipper, }: PropsWithChildren<{ useFlipper: () => { - updateData: (ref: React.RefObject>) => void; + updateData: (ref: React.RefObject) => void; }; }>) => { - const debugRef = useRef>({ + const debugRef = useRef({ eventType: undefined, sendEventParams: undefined, }); const { updateData } = useFlipper(); - const ref = useRef>({ + const ref = useRef({ setEventType: (data: string) => { debugRef.current.eventType = data; updateData(debugRef); }, - setSendEventParams: (data: { action: string; data: DebugDataType }) => { + setSendEventParams: (data: { action: string; data: DebugDataType }) => { debugRef.current.sendEventParams = data; updateData(debugRef); }, diff --git a/package/src/contexts/imageGalleryContext/ImageGalleryContext.tsx b/package/src/contexts/imageGalleryContext/ImageGalleryContext.tsx index dc9efcd1db..eb68b53501 100644 --- a/package/src/contexts/imageGalleryContext/ImageGalleryContext.tsx +++ b/package/src/contexts/imageGalleryContext/ImageGalleryContext.tsx @@ -1,7 +1,7 @@ import React, { PropsWithChildren, useContext, useState } from 'react'; import type { MessageType } from '../../components/MessageList/hooks/useMessageList'; -import type { DefaultStreamChatGenerics, UnknownType } from '../../types/types'; +import type { UnknownType } from '../../types/types'; import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; @@ -11,11 +11,9 @@ type SelectedMessage = { url?: string; }; -export type ImageGalleryContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - messages: MessageType[]; - setMessages: React.Dispatch[]>>; +export type ImageGalleryContextValue = { + messages: MessageType[]; + setMessages: React.Dispatch>; setSelectedMessage: React.Dispatch>; selectedMessage?: SelectedMessage; }; @@ -24,12 +22,8 @@ export const ImageGalleryContext = React.createContext( DEFAULT_BASE_CONTEXT_VALUE as ImageGalleryContextValue, ); -export const ImageGalleryProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - children, -}: PropsWithChildren) => { - const [messages, setMessages] = useState[]>([]); +export const ImageGalleryProvider = ({ children }: PropsWithChildren) => { + const [messages, setMessages] = useState([]); const [selectedMessage, setSelectedMessage] = useState(); return ( @@ -48,12 +42,8 @@ export const ImageGalleryProvider = < ); }; -export const useImageGalleryContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const contextValue = useContext( - ImageGalleryContext, - ) as unknown as ImageGalleryContextValue; +export const useImageGalleryContext = () => { + const contextValue = useContext(ImageGalleryContext) as unknown as ImageGalleryContextValue; if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) { throw new Error( @@ -61,5 +51,5 @@ export const useImageGalleryContext = < ); } - return contextValue as ImageGalleryContextValue; + return contextValue as ImageGalleryContextValue; }; diff --git a/package/src/contexts/messageContext/MessageContext.tsx b/package/src/contexts/messageContext/MessageContext.tsx index a6422c2957..4b12d60f5c 100644 --- a/package/src/contexts/messageContext/MessageContext.tsx +++ b/package/src/contexts/messageContext/MessageContext.tsx @@ -13,14 +13,12 @@ import type { ChannelContextValue } from '../../contexts/channelContext/ChannelC import type { MessageContentType } from '../../contexts/messagesContext/MessagesContext'; import type { DeepPartial } from '../../contexts/themeContext/ThemeContext'; import type { Theme } from '../../contexts/themeContext/utils/theme'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; export type Alignment = 'right' | 'left'; -export type MessageContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type MessageContextValue = { /** Whether or not actions can be performed on message */ actionsEnabled: boolean; /** Position of the message, either 'right' or 'left' */ @@ -30,7 +28,7 @@ export type MessageContextValue< */ dismissOverlay: () => void; /** The files attached to a message */ - files: Attachment[]; + files: Attachment[]; /** * Position of message in group - top, bottom, middle, single. * @@ -44,19 +42,19 @@ export type MessageContextValue< /** Whether or not message has reactions */ hasReactions: boolean; /** The images attached to a message */ - images: Attachment[]; + images: Attachment[]; /** Boolean that determines if the edited message is pressed. */ isEditedMessageOpen: boolean; /** * A factory function that determines whether a message is AI generated or not. */ - isMessageAIGenerated: (message: MessageType) => boolean; + isMessageAIGenerated: (message: MessageType) => boolean; /** Whether or not this is the active user's message */ isMyMessage: boolean; /** Whether or not this is the last message in a group of messages */ lastGroupMessage: boolean; /** Current [message object](https://getstream.io/chat/docs/#message_format) */ - message: MessageType; + message: MessageType; /** Order to render the message content */ messageContentOrder: MessageContentType[]; /** @@ -87,7 +85,7 @@ export type MessageContextValue< onPress: (payload: MessagePressableHandlerPayload) => void; onPressIn: ((payload: PressableHandlerPayload) => void) | null; /** The images attached to a message */ - otherAttachments: Attachment[]; + otherAttachments: Attachment[]; reactions: ReactionSummary[]; /** React set state function to set the state of `isEditedMessageOpen` */ setIsEditedMessageOpen: React.Dispatch>; @@ -101,7 +99,7 @@ export type MessageContextValue< /** Whether or not the Message is part of a Thread */ threadList: boolean; /** The videos attached to a message */ - videos: Attachment[]; + videos: Attachment[]; goToMessage?: (messageId: string) => void; /** * Function to handle reaction on message @@ -119,31 +117,25 @@ export type MessageContextValue< preventPress?: boolean; /** Whether or not the avatar show show next to Message */ showAvatar?: boolean; -} & Pick, 'channel' | 'members'>; +} & Pick; export const MessageContext = React.createContext( DEFAULT_BASE_CONTEXT_VALUE as MessageContextValue, ); -export const MessageProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const MessageProvider = ({ children, value, }: PropsWithChildren<{ - value?: MessageContextValue; + value?: MessageContextValue; }>) => ( {children} ); -export const useMessageContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const contextValue = useContext( - MessageContext, - ) as unknown as MessageContextValue; +export const useMessageContext = () => { + const contextValue = useContext(MessageContext) as unknown as MessageContextValue; return contextValue; }; diff --git a/package/src/contexts/messageInputContext/MessageInputContext.tsx b/package/src/contexts/messageInputContext/MessageInputContext.tsx index 214a32745c..2070569ef8 100644 --- a/package/src/contexts/messageInputContext/MessageInputContext.tsx +++ b/package/src/contexts/messageInputContext/MessageInputContext.tsx @@ -62,14 +62,7 @@ import { pickImage, takePhoto, } from '../../native'; -import { - Asset, - DefaultStreamChatGenerics, - File, - FileTypes, - FileUpload, - ImageUpload, -} from '../../types/types'; +import { Asset, File, FileTypes, FileUpload, ImageUpload } from '../../types/types'; import { ACITriggerSettings, ACITriggerSettingsParams, @@ -108,17 +101,13 @@ export type EmojiSearchIndex = { search: (query: string) => PromiseLike> | Array | null; }; -export type MentionAllAppUsersQuery< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - filters?: UserFilters; +export type MentionAllAppUsersQuery = { + filters?: UserFilters; options?: UserOptions; - sort?: UserSort; + sort?: UserSort; }; -export type LocalMessageInputContext< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type LocalMessageInputContext = { appendText: (newText: string) => void; asyncIds: string[]; asyncUploads: { @@ -178,7 +167,7 @@ export type LocalMessageInputContext< mentionedUsers: string[]; numberOfUploads: number; onChange: (newText: string) => void; - onSelectItem: (item: UserResponse) => void; + onSelectItem: (item: UserResponse) => void; openAttachmentPicker: () => void; openCommandsPicker: () => void; openFilePicker: () => void; @@ -200,12 +189,10 @@ export type LocalMessageInputContext< * @param id string ID of image in `imageUploads` object in state of MessageInput */ removeImage: (id: string) => void; - resetInput: (pendingAttachments?: Attachment[]) => void; + resetInput: (pendingAttachments?: Attachment[]) => void; selectedPicker: string | undefined; sending: React.MutableRefObject; - sendMessage: (params?: { - customMessageData?: Partial>; - }) => Promise; + sendMessage: (params?: { customMessageData?: Partial }) => Promise; sendMessageAsync: (id: string) => void; sendThreadMessageInChannel: boolean; setAsyncIds: React.Dispatch>; @@ -239,7 +226,7 @@ export type LocalMessageInputContext< /** * Mapping of input triggers to the outputs to be displayed by the AutoCompleteInput */ - triggerSettings: TriggerSettings; + triggerSettings: TriggerSettings; updateMessage: () => Promise; /** Function for attempting to upload a file */ uploadFile: ({ newFile }: { newFile: FileUpload }) => Promise; @@ -249,9 +236,7 @@ export type LocalMessageInputContext< uploadNewImage: (image: Partial) => Promise; }; -export type InputMessageInputContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type InputMessageInputContextValue = { /** * Controls how many pixels to the top side the user has to scroll in order to lock the recording view and allow the user to lift their finger from the screen without stopping the recording. */ @@ -285,7 +270,7 @@ export type InputMessageInputContextValue< * * Defaults to and accepts same props as: [AudioRecorder](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/MessageInput/AudioRecorder.tsx) */ - AudioRecorder: React.ComponentType>; + AudioRecorder: React.ComponentType; /** * Controls whether the async audio feature is enabled. */ @@ -322,7 +307,7 @@ export type InputMessageInputContextValue< * * Defaults to and accepts same props as: [CommandsButton](https://getstream.io/chat/docs/sdk/reactnative/ui-components/commands-button/) */ - CommandsButton: React.ComponentType>; + CommandsButton: React.ComponentType; /** * Custom UI component to display the remaining cooldown a user will have to wait before * being allowed to send another message. This component is displayed in place of the @@ -331,12 +316,12 @@ export type InputMessageInputContextValue< * **default** [CooldownTimer](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/MessageInput/CooldownTimer.tsx) */ CooldownTimer: React.ComponentType; - editMessage: StreamChat['updateMessage']; + editMessage: StreamChat['updateMessage']; /** * Custom UI component for FileUploadPreview. * Defaults to and accepts same props as: https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/MessageInput/FileUploadPreview.tsx */ - FileUploadPreview: React.ComponentType>; + FileUploadPreview: React.ComponentType; /** When false, CameraSelectorIcon will be hidden */ hasCameraPicker: boolean; @@ -351,10 +336,10 @@ export type InputMessageInputContextValue< * Custom UI component for ImageUploadPreview. * Defaults to and accepts same props as: https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/MessageInput/ImageUploadPreview.tsx */ - ImageUploadPreview: React.ComponentType>; - InputEditingStateHeader: React.ComponentType>; - InputGiphySearch: React.ComponentType>; - InputReplyStateHeader: React.ComponentType>; + ImageUploadPreview: React.ComponentType; + InputEditingStateHeader: React.ComponentType; + InputGiphySearch: React.ComponentType; + InputReplyStateHeader: React.ComponentType; /** Limit on allowed number of files to attach at a time. */ maxNumberOfFiles: number; /** @@ -371,10 +356,10 @@ export type InputMessageInputContextValue< * * Defaults to and accepts same props as: [SendButton](https://getstream.io/chat/docs/sdk/reactnative/ui-components/send-button/) */ - SendButton: React.ComponentType>; + SendButton: React.ComponentType; sendImageAsync: boolean; - sendMessage: (message: Partial>) => Promise; - setQuotedMessageState: (message: MessageType) => void; + sendMessage: (message: Partial) => Promise; + setQuotedMessageState: (message: MessageType) => void; /** * Custom UI component to render checkbox with text ("Also send to channel") in Thread's input box. * When ticked, message will also be sent in parent channel. @@ -388,7 +373,7 @@ export type InputMessageInputContextValue< * * Defaults to and accepts same props as: [AudioRecordingButton](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingButton.tsx) */ - StartAudioRecordingButton: React.ComponentType>; + StartAudioRecordingButton: React.ComponentType; StopMessageStreamingButton: React.ComponentType | null; /** * Custom UI component to render upload progress indicator on attachment preview. @@ -407,9 +392,7 @@ export type InputMessageInputContextValue< /** * Mapping of input triggers to the outputs to be displayed by the AutoCompleteInput */ - autoCompleteTriggerSettings?: ( - settings: ACITriggerSettingsParams, - ) => TriggerSettings; + autoCompleteTriggerSettings?: (settings: ACITriggerSettingsParams) => TriggerSettings; closePollCreationDialog?: () => void; /** * Compress image with quality (from 0 to 1, where 1 is best quality). @@ -435,7 +418,7 @@ export type InputMessageInputContextValue< */ doDocUploadRequest?: ( file: File, - channel: ChannelContextValue['channel'], + channel: ChannelContextValue['channel'], ) => Promise; /** @@ -451,14 +434,14 @@ export type InputMessageInputContextValue< name?: string; uri?: string; }, - channel: ChannelContextValue['channel'], + channel: ChannelContextValue['channel'], ) => Promise; /** * Variable that tracks the editing state. * It is defined with message type if the editing state is true, else its undefined. */ - editing?: MessageType; + editing?: MessageType; /** * Prop to override the default emoji search index in auto complete suggestion list. */ @@ -474,9 +457,9 @@ export type InputMessageInputContextValue< * Has access to all of [MessageInputContext](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/contexts/messageInputContext/MessageInputContext.tsx) */ Input?: React.ComponentType< - Omit, 'Input'> & - InputButtonsProps & { - getUsers: () => UserResponse[]; + Omit & + InputButtonsProps & { + getUsers: () => UserResponse[]; } >; /** @@ -494,17 +477,17 @@ export type InputMessageInputContextValue< * - openCommandsPicker * - toggleAttachmentPicker */ - InputButtons?: React.ComponentType>; + InputButtons?: React.ComponentType; maxMessageLength?: number; /** Object containing filters/sort/options overrides for an @mention user query */ mentionAllAppUsersEnabled?: boolean; - mentionAllAppUsersQuery?: MentionAllAppUsersQuery; + mentionAllAppUsersQuery?: MentionAllAppUsersQuery; /** * Callback that is called when the text input's text changes. Changed text is passed as a single string argument to the callback handler. */ onChangeText?: (newText: string) => void; openPollCreationDialog?: ({ sendMessage }: Pick) => void; - quotedMessage?: MessageType; + quotedMessage?: MessageType; SendMessageDisallowedIndicator?: React.ComponentType; /** * ref for input setter function @@ -517,22 +500,18 @@ export type InputMessageInputContextValue< showPollCreationDialog?: boolean; }; -export type MessageInputContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = LocalMessageInputContext & - Omit, 'sendMessage'>; +export type MessageInputContextValue = LocalMessageInputContext & + Omit; export const MessageInputContext = React.createContext( DEFAULT_BASE_CONTEXT_VALUE as MessageInputContextValue, ); -export const MessageInputProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const MessageInputProvider = ({ children, value, }: PropsWithChildren<{ - value: InputMessageInputContextValue; + value: InputMessageInputContextValue; }>) => { const { closePicker, @@ -544,8 +523,7 @@ export const MessageInputProvider = < setSelectedImages, setSelectedPicker, } = useAttachmentPickerContext(); - const { appSettings, client, enableOfflineSupport, isOnline } = - useChatContext(); + const { appSettings, client, enableOfflineSupport, isOnline } = useChatContext(); const { removeMessage } = useMessagesContext(); const getFileUploadConfig = () => { @@ -567,9 +545,8 @@ export const MessageInputProvider = < const channelCapabities = useOwnCapabilitiesContext(); - const { channel, giphyEnabled, uploadAbortControllerRef } = - useChannelContext(); - const { thread } = useThreadContext(); + const { channel, giphyEnabled, uploadAbortControllerRef } = useChannelContext(); + const { thread } = useThreadContext(); const { t } = useTranslationContext(); const inputBoxRef = useRef(null); const sending = useRef(false); @@ -608,8 +585,8 @@ export const MessageInputProvider = < setText, showMoreOptions, text, - } = useMessageDetailsForState(editing, initialValue); - const { endsAt: cooldownEndsAt, start: startCooldown } = useCooldown(); + } = useMessageDetailsForState(editing, initialValue); + const { endsAt: cooldownEndsAt, start: startCooldown } = useCooldown(); const threadId = thread?.id; useEffect(() => { @@ -778,7 +755,7 @@ export const MessageInputProvider = < } }, [closeAttachmentPicker, openAttachmentPicker, selectedPicker]); - const onSelectItem = (item: UserResponse) => { + const onSelectItem = (item: UserResponse) => { setMentionedUsers((prevMentionedUsers) => [...prevMentionedUsers, item.id]); }; @@ -833,7 +810,7 @@ export const MessageInputProvider = < [imageUploads, setImageUploads, setNumberOfUploads], ); - const resetInput = (pendingAttachments: Attachment[] = []) => { + const resetInput = (pendingAttachments: Attachment[] = []) => { /** * If the MediaLibrary is available, reset the selected files and images */ @@ -856,7 +833,7 @@ export const MessageInputProvider = < } }; - const mapImageUploadToAttachment = (image: ImageUpload): Attachment => { + const mapImageUploadToAttachment = (image: ImageUpload): Attachment => { const mime_type: string | boolean = lookup(image.file.name as string); const name = image.file.name as string; return { @@ -870,7 +847,7 @@ export const MessageInputProvider = < }; }; - const mapFileUploadToAttachment = (file: FileUpload): Attachment => { + const mapFileUploadToAttachment = (file: FileUpload): Attachment => { if (file.type === FileTypes.Image) { return { fallback: file.file.name, @@ -927,7 +904,7 @@ export const MessageInputProvider = < const sendMessage = async ({ customMessageData, }: { - customMessageData?: Partial>; + customMessageData?: Partial; } = {}) => { if (sending.current) { return; @@ -951,7 +928,7 @@ export const MessageInputProvider = < inputBoxRef.current.clear(); } - const attachments = [] as Attachment[]; + const attachments = [] as Attachment[]; for (const image of imageUploads) { if (enableOfflineSupport) { if (image.state === FileState.NOT_SUPPORTED) { @@ -1024,7 +1001,7 @@ export const MessageInputProvider = < quoted_message: undefined, text: prevText, ...customMessageData, - } as Parameters['updateMessage']>[0]; + } as Parameters[0]; // TODO: Remove this line and show an error when submit fails value.clearEditingState(); @@ -1044,7 +1021,7 @@ export const MessageInputProvider = < /** * If the message is bounced by moderation, we firstly remove the message from message list and then send a new message. */ - if (message && isBouncedMessage(message as MessageType)) { + if (message && isBouncedMessage(message as MessageType)) { await removeMessage(message); } value.sendMessage({ @@ -1056,7 +1033,7 @@ export const MessageInputProvider = < show_in_channel: sendThreadMessageInChannel || undefined, text: prevText, ...customMessageData, - } as unknown as StreamMessage); + } as unknown as StreamMessage); value.clearQuotedMessageState(); sending.current = false; @@ -1084,7 +1061,7 @@ export const MessageInputProvider = < image_url: image.url, type: FileTypes.Image, }, - ] as StreamMessage['attachments']; + ] as StreamMessage['attachments']; startCooldown(); try { @@ -1095,7 +1072,7 @@ export const MessageInputProvider = < quoted_message_id: value.quotedMessage ? value.quotedMessage.id : undefined, show_in_channel: sendThreadMessageInChannel || undefined, text: '', - } as unknown as Partial>); + } as unknown as Partial); setAsyncIds((prevAsyncIds) => prevAsyncIds.splice(prevAsyncIds.indexOf(id), 1)); setAsyncUploads((prevAsyncUploads) => { @@ -1119,7 +1096,7 @@ export const MessageInputProvider = < const getTriggerSettings = () => { try { - let triggerSettings: TriggerSettings = {}; + let triggerSettings: TriggerSettings = {}; if (channel) { if (value.autoCompleteTriggerSettings) { triggerSettings = value.autoCompleteTriggerSettings({ @@ -1129,7 +1106,7 @@ export const MessageInputProvider = < onMentionSelectItem: onSelectItem, }); } else { - triggerSettings = ACITriggerSettings({ + triggerSettings = ACITriggerSettings({ channel, client, emojiSearchIndex: value.emojiSearchIndex, @@ -1153,7 +1130,7 @@ export const MessageInputProvider = < ...value.editing, quoted_message: undefined, text: giphyEnabled && giphyActive ? `/giphy ${text}` : text, - } as Parameters['updateMessage']>[0]); + } as Parameters[0]); } value.clearEditingState(); @@ -1503,12 +1480,8 @@ export const MessageInputProvider = < ); }; -export const useMessageInputContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const contextValue = useContext( - MessageInputContext, - ) as unknown as MessageInputContextValue; +export const useMessageInputContext = () => { + const contextValue = useContext(MessageInputContext) as unknown as MessageInputContextValue; if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) { throw new Error( diff --git a/package/src/contexts/messageInputContext/__tests__/MessageInputContext.test.tsx b/package/src/contexts/messageInputContext/__tests__/MessageInputContext.test.tsx index 3670fce03d..c3aac6c485 100644 --- a/package/src/contexts/messageInputContext/__tests__/MessageInputContext.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/MessageInputContext.test.tsx @@ -12,7 +12,6 @@ import { generateImageAttachment } from '../../../mock-builders/generator/attach import { generateMessage } from '../../../mock-builders/generator/message'; import { generateUser } from '../../../mock-builders/generator/user'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; import { FileState } from '../../../utils/utils'; import { InputMessageInputContextValue, @@ -21,20 +20,14 @@ import { useMessageInputContext, } from '../MessageInputContext'; -type WrapperType = - Partial>; +type WrapperType = Partial; afterEach(jest.clearAllMocks); const user1 = generateUser(); const message = generateMessage({ user: user1 }); describe('MessageInputContext', () => { - const Wrapper = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, - >({ - children, - ...rest - }: PropsWithChildren>) => ( + const Wrapper = ({ children, ...rest }: PropsWithChildren) => ( { blocked_mime_types: ['image/png'], }, }, - } as unknown as AppSettingsAPIResponse, + } as unknown as AppSettingsAPIResponse, client: { updateMessage: jest.fn().mockResolvedValue({ message }), - } as unknown as StreamChat, - } as ChatContextValue + } as unknown as StreamChat, + } as ChatContextValue } > + } as MessageInputContextValue } > {children} diff --git a/package/src/contexts/messageInputContext/__tests__/isValidMessage.test.tsx b/package/src/contexts/messageInputContext/__tests__/isValidMessage.test.tsx index 2e9a04c1cc..9ad3fbda9f 100644 --- a/package/src/contexts/messageInputContext/__tests__/isValidMessage.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/isValidMessage.test.tsx @@ -9,7 +9,7 @@ import { } from '../../../mock-builders/generator/attachment'; import { generateMessage } from '../../../mock-builders/generator/message'; import { generateUser } from '../../../mock-builders/generator/user'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { FileState } from '../../../utils/utils'; import { InputMessageInputContextValue, @@ -20,18 +20,14 @@ import { const user1 = generateUser(); const message = generateMessage({ user: user1 }); -type WrapperType = - Partial>; +type WrapperType = Partial; -const Wrapper = ({ - children, - ...rest -}: PropsWithChildren>) => ( +const Wrapper = ({ children, ...rest }: PropsWithChildren) => ( + } as InputMessageInputContextValue } > {children} diff --git a/package/src/contexts/messageInputContext/__tests__/pickFile.test.tsx b/package/src/contexts/messageInputContext/__tests__/pickFile.test.tsx index 8a125d408d..92b70fb554 100644 --- a/package/src/contexts/messageInputContext/__tests__/pickFile.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/pickFile.test.tsx @@ -9,7 +9,7 @@ import { generateFileAttachment } from '../../../mock-builders/generator/attachm import { generateMessage } from '../../../mock-builders/generator/message'; import { generateUser } from '../../../mock-builders/generator/user'; import * as NativeUtils from '../../../native'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import * as AttachmentPickerContext from '../../attachmentPickerContext/AttachmentPickerContext'; import { @@ -21,18 +21,14 @@ import { const user1 = generateUser(); const message = generateMessage({ user: user1 }); -type WrapperType = - Partial>; +type WrapperType = Partial; -const Wrapper = ({ - children, - ...rest -}: PropsWithChildren>) => ( +const Wrapper = ({ children, ...rest }: PropsWithChildren) => ( + } as MessageInputContextValue } > {children} diff --git a/package/src/contexts/messageInputContext/__tests__/removeFile.test.tsx b/package/src/contexts/messageInputContext/__tests__/removeFile.test.tsx index d45b1c6656..b07c10e402 100644 --- a/package/src/contexts/messageInputContext/__tests__/removeFile.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/removeFile.test.tsx @@ -6,7 +6,7 @@ import { renderHook, waitFor } from '@testing-library/react-native'; import { generateFileUploadPreview } from '../../../mock-builders/generator/attachment'; import { generateMessage } from '../../../mock-builders/generator/message'; import { generateUser } from '../../../mock-builders/generator/user'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { InputMessageInputContextValue, MessageInputContextValue, @@ -14,18 +14,14 @@ import { useMessageInputContext, } from '../MessageInputContext'; -type WrapperType = - Partial>; +type WrapperType = Partial; -const Wrapper = ({ - children, - ...rest -}: PropsWithChildren>) => ( +const Wrapper = ({ children, ...rest }: PropsWithChildren) => ( + } as MessageInputContextValue } > {children} diff --git a/package/src/contexts/messageInputContext/__tests__/removeImage.test.tsx b/package/src/contexts/messageInputContext/__tests__/removeImage.test.tsx index 4351d3cd37..a1a0cb6c34 100644 --- a/package/src/contexts/messageInputContext/__tests__/removeImage.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/removeImage.test.tsx @@ -6,7 +6,7 @@ import { renderHook, waitFor } from '@testing-library/react-native'; import { generateImageUploadPreview } from '../../../mock-builders/generator/attachment'; import { generateMessage } from '../../../mock-builders/generator/message'; import { generateUser } from '../../../mock-builders/generator/user'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { InputMessageInputContextValue, MessageInputContextValue, @@ -14,18 +14,14 @@ import { useMessageInputContext, } from '../MessageInputContext'; -type WrapperType = - Partial>; +type WrapperType = Partial; -const Wrapper = ({ - children, - ...rest -}: PropsWithChildren>) => ( +const Wrapper = ({ children, ...rest }: PropsWithChildren) => ( + } as MessageInputContextValue } > {children} diff --git a/package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx b/package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx index b091ab12da..290f74f5b4 100644 --- a/package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx @@ -10,7 +10,7 @@ import { } from '../../../mock-builders/generator/attachment'; import { generateMessage } from '../../../mock-builders/generator/message'; import { generateUser } from '../../../mock-builders/generator/user'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { FileState } from '../../../utils/utils'; import * as AttachmentPickerContext from '../../attachmentPickerContext/AttachmentPickerContext'; import { @@ -20,18 +20,14 @@ import { useMessageInputContext, } from '../MessageInputContext'; -type WrapperType = - Partial>; +type WrapperType = Partial; -const Wrapper = ({ - children, - ...rest -}: PropsWithChildren>) => ( +const Wrapper = ({ children, ...rest }: PropsWithChildren) => ( + } as MessageInputContextValue } > {children} diff --git a/package/src/contexts/messageInputContext/__tests__/sendMessageAsync.test.tsx b/package/src/contexts/messageInputContext/__tests__/sendMessageAsync.test.tsx index 3b802c6c2e..b552eff3f2 100644 --- a/package/src/contexts/messageInputContext/__tests__/sendMessageAsync.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/sendMessageAsync.test.tsx @@ -6,7 +6,6 @@ import { renderHook, waitFor } from '@testing-library/react-native'; import { generateMessage } from '../../../mock-builders/generator/message'; import { generateUser } from '../../../mock-builders/generator/user'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; import { FileState } from '../../../utils/utils'; import { InputMessageInputContextValue, @@ -15,18 +14,14 @@ import { useMessageInputContext, } from '../MessageInputContext'; -type WrapperType = - Partial>; +type WrapperType = Partial; -const Wrapper = ({ - children, - ...rest -}: PropsWithChildren>) => ( +const Wrapper = ({ children, ...rest }: PropsWithChildren) => ( + } as MessageInputContextValue } > {children} diff --git a/package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx b/package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx index 39f5e131ff..3817268015 100644 --- a/package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx @@ -10,7 +10,7 @@ import type { MessageType } from '../../../components/MessageList/hooks/useMessa import { ChatContextValue, ChatProvider } from '../../../contexts/chatContext/ChatContext'; import { generateMessage } from '../../../mock-builders/generator/message'; import { generateUser } from '../../../mock-builders/generator/user'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import * as AttachmentPickerContext from '../../attachmentPickerContext/AttachmentPickerContext'; import { InputMessageInputContextValue, @@ -21,27 +21,23 @@ import { const message = generateMessage({}); -type WrapperType = - Partial>; +type WrapperType = Partial; -const Wrapper = ({ - children, - ...rest -}: PropsWithChildren>) => ( +const Wrapper = ({ children, ...rest }: PropsWithChildren) => ( , - } as ChatContextValue + } as unknown as StreamChat, + } as ChatContextValue } > + } as MessageInputContextValue } > {children} diff --git a/package/src/contexts/messageInputContext/__tests__/uploadFile.test.tsx b/package/src/contexts/messageInputContext/__tests__/uploadFile.test.tsx index 7d7b3c5049..2af2fdde78 100644 --- a/package/src/contexts/messageInputContext/__tests__/uploadFile.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/uploadFile.test.tsx @@ -6,28 +6,24 @@ import { renderHook, waitFor } from '@testing-library/react-native'; import { generateFileUploadPreview } from '../../../mock-builders/generator/attachment'; import { generateMessage } from '../../../mock-builders/generator/message'; import { generateUser } from '../../../mock-builders/generator/user'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { InputMessageInputContextValue, MessageInputProvider, useMessageInputContext, } from '../MessageInputContext'; -type WrapperType = - Partial>; +type WrapperType = Partial; const user1 = generateUser(); const message = generateMessage({ user: user1 }); -const Wrapper = ({ - children, - ...rest -}: PropsWithChildren>) => ( +const Wrapper = ({ children, ...rest }: PropsWithChildren) => ( + } as InputMessageInputContextValue } > {children} diff --git a/package/src/contexts/messageInputContext/__tests__/uploadImage.test.tsx b/package/src/contexts/messageInputContext/__tests__/uploadImage.test.tsx index 7bd2a571fc..97d34b05bd 100644 --- a/package/src/contexts/messageInputContext/__tests__/uploadImage.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/uploadImage.test.tsx @@ -5,25 +5,21 @@ import { renderHook, waitFor } from '@testing-library/react-native'; import { generateImageUploadPreview } from '../../../mock-builders/generator/attachment'; import { generateMessage } from '../../../mock-builders/generator/message'; import { generateUser } from '../../../mock-builders/generator/user'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { InputMessageInputContextValue, MessageInputProvider, useMessageInputContext, } from '../MessageInputContext'; -type WrapperType = - Partial>; +type WrapperType = Partial; -const Wrapper = ({ - children, - ...rest -}: PropsWithChildren>) => ( +const Wrapper = ({ children, ...rest }: PropsWithChildren) => ( + } as InputMessageInputContextValue } > {children} diff --git a/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx b/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx index fa10fba349..eef52d4844 100644 --- a/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx @@ -9,7 +9,7 @@ import { import { generateMessage } from '../../../mock-builders/generator/message'; import { generateUser } from '../../../mock-builders/generator/user'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; + import { useMessageDetailsForState } from '../hooks/useMessageDetailsForState'; describe('useMessageDetailsForState', () => { diff --git a/package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts b/package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts index ea42939ca3..2f643289b5 100644 --- a/package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts +++ b/package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts @@ -1,12 +1,9 @@ import { useMemo } from 'react'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; import type { ThreadContextValue } from '../../threadContext/ThreadContext'; import type { MessageInputContextValue } from '../MessageInputContext'; -export const useCreateMessageInputContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const useCreateMessageInputContext = ({ additionalTextInputProps, appendText, asyncIds, @@ -115,8 +112,7 @@ export const useCreateMessageInputContext = < uploadNewFile, uploadNewImage, UploadProgressIndicator, -}: MessageInputContextValue & - Pick, 'thread'>) => { +}: MessageInputContextValue & Pick) => { const editingdep = editing?.id; const fileUploadsValue = fileUploads .map(({ duration, paused, progress, state }) => `${state},${paused},${progress},${duration}`) @@ -128,7 +124,7 @@ export const useCreateMessageInputContext = < const threadId = thread?.id; const asyncIdsLength = asyncIds.length; - const messageInputContext: MessageInputContextValue = useMemo( + const messageInputContext: MessageInputContextValue = useMemo( () => ({ additionalTextInputProps, appendText, diff --git a/package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts b/package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts index 8708b6e4e1..ac1e433376 100644 --- a/package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts +++ b/package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts @@ -2,20 +2,13 @@ import { useEffect, useState } from 'react'; import { Attachment } from 'stream-chat'; -import { - DefaultStreamChatGenerics, - FileTypes, - FileUpload, - ImageUpload, -} from '../../../types/types'; +import { FileTypes, FileUpload, ImageUpload } from '../../../types/types'; import { generateRandomId, stringifyMessage } from '../../../utils/utils'; import type { MessageInputContextValue } from '../MessageInputContext'; -export const useMessageDetailsForState = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - message: MessageInputContextValue['editing'], +export const useMessageDetailsForState = ( + message: MessageInputContextValue['editing'], initialValue?: string, ) => { const [fileUploads, setFileUploads] = useState([]); @@ -47,7 +40,7 @@ export const useMessageDetailsForState = < // eslint-disable-next-line react-hooks/exhaustive-deps }, [messageValue]); - const mapAttachmentToFileUpload = (attachment: Attachment): FileUpload => { + const mapAttachmentToFileUpload = (attachment: Attachment): FileUpload => { const id = generateRandomId(); if (attachment.type === FileTypes.Audio) { diff --git a/package/src/contexts/messagesContext/MessagesContext.tsx b/package/src/contexts/messagesContext/MessagesContext.tsx index 430b4326df..e56c9734bb 100644 --- a/package/src/contexts/messagesContext/MessagesContext.tsx +++ b/package/src/contexts/messagesContext/MessagesContext.tsx @@ -60,7 +60,7 @@ import { MessageUserReactionsAvatarProps } from '../../components/MessageMenu/Me import { MessageUserReactionsItemProps } from '../../components/MessageMenu/MessageUserReactionsItem'; import type { ReplyProps } from '../../components/Reply/Reply'; import { FlatList } from '../../native'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import type { ReactionData } from '../../utils/utils'; import type { Alignment, MessageContextValue } from '../messageContext/MessageContext'; import type { SuggestionCommand } from '../suggestionsContext/SuggestionsContext'; @@ -80,26 +80,24 @@ export type MessageContentType = | 'text'; export type DeletedMessagesVisibilityType = 'always' | 'never' | 'receiver' | 'sender'; -export type MessagesContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Pick, 'isMessageAIGenerated'> & { +export type MessagesContextValue = Pick & { /** * UI component for Attachment. * Defaults to: [Attachment](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Attachment/Attachment.tsx) */ - Attachment: React.ComponentType>; + Attachment: React.ComponentType; /** * UI component to display AttachmentActions. e.g., send, shuffle, cancel in case of giphy * Defaults to: [AttachmentActions](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Attachment/AttachmentActions.tsx) */ - AttachmentActions: React.ComponentType>; + AttachmentActions: React.ComponentType; /** Custom UI component for AudioAttachment. */ AudioAttachment: React.ComponentType; /** * UI component to display generic media type e.g. giphy, url preview etc * Defaults to: [Card](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Attachment/Card.tsx) */ - Card: React.ComponentType>; + Card: React.ComponentType; /** * Handler to clear the quoted state of the message. */ @@ -109,7 +107,7 @@ export type MessagesContextValue< * Defaults to: [DateHeader](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/MessageList/DateHeader.tsx) **/ DateHeader: React.ComponentType; - deleteMessage: (message: MessageResponse) => Promise; + deleteMessage: (message: MessageResponse) => Promise; deleteReaction: (type: string, messageId: string) => Promise; /** Should keyboard be dismissed when messaged is touched */ @@ -121,12 +119,12 @@ export type MessagesContextValue< * UI component to display File type attachment. * Defaults to: [FileAttachment](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Attachment/FileAttachment.tsx) */ - FileAttachment: React.ComponentType>; + FileAttachment: React.ComponentType; /** * UI component to display group of File type attachments or multiple file attachments (in single message). * Defaults to: [FileAttachmentGroup](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Attachment/FileAttachmentGroup.tsx) */ - FileAttachmentGroup: React.ComponentType>; + FileAttachmentGroup: React.ComponentType; /** * UI component for attachment icon for type 'file' attachment. * Defaults to: https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Attachment/FileIcon.tsx @@ -137,12 +135,12 @@ export type MessagesContextValue< * UI component to display image attachments * Defaults to: [Gallery](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Attachment/Gallery.tsx) */ - Gallery: React.ComponentType>; + Gallery: React.ComponentType; /** * UI component for Giphy * Defaults to: [Giphy](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Attachment/Giphy.tsx) */ - Giphy: React.ComponentType>; + Giphy: React.ComponentType; /** * The giphy version to render - check the keys of the [Image Object](https://developers.giphy.com/docs/api/schema#image-object) for possible values. Uses 'fixed_height' by default * */ @@ -173,7 +171,7 @@ export type MessagesContextValue< **/ InlineUnreadIndicator: React.ComponentType; - Message: React.ComponentType>; + Message: React.ComponentType; /** * Custom UI component for rendering Message actions in message menu. * @@ -190,23 +188,23 @@ export type MessagesContextValue< * UI component for MessageAvatar * Defaults to: [MessageAvatar](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Message/MessageSimple/MessageAvatar.tsx) **/ - MessageAvatar: React.ComponentType>; + MessageAvatar: React.ComponentType; /** * UI Component for MessageBounce */ - MessageBounce: React.ComponentType>; + MessageBounce: React.ComponentType; /** * UI component for MessageContent * Defaults to: [MessageContent](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Message/MessageSimple/MessageContent.tsx) */ - MessageContent: React.ComponentType>; + MessageContent: React.ComponentType; /** Order to render the message content */ messageContentOrder: MessageContentType[]; /** * UI component for MessageDeleted * Defaults to: [MessageDeleted](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/MessageSimple/MessageDeleted.tsx) */ - MessageDeleted: React.ComponentType>; + MessageDeleted: React.ComponentType; /** * UI component for MessageEditedTimestamp * Defaults to: [MessageEditedTimestamp](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/MessageSimple/MessageEditedTimestamp.tsx) @@ -219,45 +217,45 @@ export type MessagesContextValue< /** * Custom message footer component */ - MessageFooter: React.ComponentType>; - MessageList: React.ComponentType>; + MessageFooter: React.ComponentType; + MessageList: React.ComponentType; /** * UI component for MessageMenu */ - MessageMenu: React.ComponentType>; + MessageMenu: React.ComponentType; /** * Custom message pinned component */ - MessagePinnedHeader: React.ComponentType>; + MessagePinnedHeader: React.ComponentType; /** * UI component for MessageReactionPicker */ - MessageReactionPicker: React.ComponentType>; + MessageReactionPicker: React.ComponentType; /** * UI component for MessageReplies * Defaults to: [MessageReplies](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/MessageSimple/MessageReplies.tsx) */ - MessageReplies: React.ComponentType>; + MessageReplies: React.ComponentType; /** * UI Component for MessageRepliesAvatars * Defaults to: [MessageRepliesAvatars](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/MessageSimple/MessageRepliesAvatars.tsx) */ - MessageRepliesAvatars: React.ComponentType>; + MessageRepliesAvatars: React.ComponentType; /** * UI component for MessageSimple * Defaults to: [MessageSimple](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Message/MessageSimple/MessageSimple.tsx) */ - MessageSimple: React.ComponentType>; + MessageSimple: React.ComponentType; /** * UI component for MessageStatus (delivered/read) * Defaults to: [MessageStatus](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Message/MessageSimple/MessageStatus.tsx) */ - MessageStatus: React.ComponentType>; + MessageStatus: React.ComponentType; /** * UI component for MessageSystem * Defaults to: [MessageSystem](https://getstream.io/chat/docs/sdk/reactnative/ui-components/message-system/) */ - MessageSystem: React.ComponentType>; + MessageSystem: React.ComponentType; /** * UI component for MessageTimestamp * Defaults to: [MessageTimestamp](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/Message/MessageSimple/MessageTimestamp.tsx) @@ -268,7 +266,7 @@ export type MessagesContextValue< * * **Default** [MessageUserReactions](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/MessageMenu/MessageUserReactions.tsx) */ - MessageUserReactions: React.ComponentType>; + MessageUserReactions: React.ComponentType; /** * Custom UI component for rendering user reactions avatar under `MessageUserReactionsItem`, in message menu. * @@ -287,23 +285,23 @@ export type MessagesContextValue< * UI component for Reply * Defaults to: [Reply](https://getstream.io/chat/docs/sdk/reactnative/ui-components/reply/) */ - Reply: React.ComponentType>; + Reply: React.ComponentType; /** * Override the api request for retry message functionality. */ - retrySendMessage: (message: MessageType) => Promise; + retrySendMessage: (message: MessageType) => Promise; /** * UI component for ScrollToBottomButton * Defaults to: [ScrollToBottomButton](https://getstream.io/chat/docs/sdk/reactnative/ui-components/scroll-to-bottom-button/) */ ScrollToBottomButton: React.ComponentType; sendReaction: (type: string, messageId: string) => Promise; - setEditingState: (message?: MessageType) => void; - setQuotedMessageState: (message?: MessageType) => void; + setEditingState: (message?: MessageType) => void; + setQuotedMessageState: (message?: MessageType) => void; /** * UI component for StreamingMessageView. Displays the text of a message with a typewriter animation. */ - StreamingMessageView: React.ComponentType>; + StreamingMessageView: React.ComponentType; /** * UI component for TypingIndicator * Defaults to: [TypingIndicator](https://getstream.io/chat/docs/sdk/reactnative/ui-components/typing-indicator/) @@ -316,18 +314,18 @@ export type MessagesContextValue< TypingIndicatorContainer: React.ComponentType; UnreadMessagesNotification: React.ComponentType; updateMessage: ( - updatedMessage: MessageResponse, + updatedMessage: MessageResponse, extraState?: { - commands?: SuggestionCommand[]; + commands?: SuggestionCommand[]; messageInput?: string; - threadMessages?: ChannelState['threads'][string]; + threadMessages?: ChannelState['threads'][string]; }, ) => void; /** * Custom UI component to display enriched url preview. * Defaults to https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Attachment/Card.tsx */ - UrlPreview: React.ComponentType>; + UrlPreview: React.ComponentType; VideoThumbnail: React.ComponentType; /** * Provide any additional props for `Pressable` which wraps inner MessageContent component here. @@ -340,18 +338,18 @@ export type MessagesContextValue< * Custom UI component to override default cover (between Header and Footer) of Card component. * Accepts the same props as Card component. */ - CardCover?: React.ComponentType>; + CardCover?: React.ComponentType; /** * Custom UI component to override default Footer of Card component. * Accepts the same props as Card component. */ - CardFooter?: React.ComponentType>; + CardFooter?: React.ComponentType; /** * Custom UI component to override default header of Card component. * Accepts the same props as Card component. */ - CardHeader?: React.ComponentType>; + CardHeader?: React.ComponentType; /** * Full override of the delete message button in the Message Actions @@ -378,39 +376,33 @@ export type MessagesContextValue< * Handler to access when a ban user action is invoked. * @param message */ - handleBan?: (message: MessageType) => Promise; + handleBan?: (message: MessageType) => Promise; /** Handler to access when a copy message action is invoked */ - handleCopy?: (message: MessageType) => Promise; + handleCopy?: (message: MessageType) => Promise; /** Handler to access when a delete message action is invoked */ - handleDelete?: (message: MessageType) => Promise; + handleDelete?: (message: MessageType) => Promise; /** Handler to access when an edit message action is invoked */ - handleEdit?: (message: MessageType) => void; + handleEdit?: (message: MessageType) => void; /** Handler to access when a flag message action is invoked */ - handleFlag?: (message: MessageType) => Promise; + handleFlag?: (message: MessageType) => Promise; /** Handler to access when a mark unread action is invoked */ - handleMarkUnread?: (message: MessageType) => Promise; + handleMarkUnread?: (message: MessageType) => Promise; /** Handler to access when a mute user action is invoked */ - handleMute?: (message: MessageType) => Promise; + handleMute?: (message: MessageType) => Promise; /** Handler to access when a pin/unpin user action is invoked*/ - handlePinMessage?: ((message: MessageType) => MessageActionType) | null; + handlePinMessage?: ((message: MessageType) => MessageActionType) | null; /** Handler to access when a quoted reply action is invoked */ - handleQuotedReply?: (message: MessageType) => Promise; + handleQuotedReply?: (message: MessageType) => Promise; /** Handler to process a reaction */ - handleReaction?: ( - message: MessageType, - reactionType: string, - ) => Promise; + handleReaction?: (message: MessageType, reactionType: string) => Promise; /** Handler to access when a retry action is invoked */ - handleRetry?: (message: MessageType) => Promise; + handleRetry?: (message: MessageType) => Promise; /** Handler to access when a thread reply action is invoked */ - handleThreadReply?: (message: MessageType) => Promise; + handleThreadReply?: (message: MessageType) => Promise; /** A flag specifying whether the poll creation button is available or not. */ hasCreatePoll?: boolean; /** Handler to deal with custom memoization logic of Attachment */ - isAttachmentEqual?: ( - prevAttachment: Attachment, - nextAttachment: Attachment, - ) => boolean; + isAttachmentEqual?: (prevAttachment: Attachment, nextAttachment: Attachment) => boolean; legacyImageViewerSwipeBehaviour?: boolean; /** Object specifying rules defined within simple-markdown https://github.com/Khan/simple-markdown#adding-a-simple-extension */ markdownRules?: MarkdownRules; @@ -466,19 +458,19 @@ export type MessagesContextValue< * * @overrideType Function | Array */ - messageActions?: (param: MessageActionsParams) => MessageActionType[]; + messageActions?: (param: MessageActionsParams) => MessageActionType[]; /** * Custom message header component */ - MessageHeader?: React.ComponentType>; + MessageHeader?: React.ComponentType; MessageSwipeContent?: React.ComponentType; /** * HitSlop for the message swipe to reply gesture */ messageSwipeToReplyHitSlop?: ViewProps['hitSlop']; /** Custom UI component for message text */ - MessageText?: React.ComponentType>; + MessageText?: React.ComponentType; /** * The number of lines of the message text to be displayed */ @@ -513,7 +505,7 @@ export type MessagesContextValue< * /> * ``` */ - onLongPressMessage?: (payload: MessagePressableHandlerPayload) => void; + onLongPressMessage?: (payload: MessagePressableHandlerPayload) => void; /** * Add onPressIn handler for attachments. You have access to payload of that handler as param: * @@ -540,7 +532,7 @@ export type MessagesContextValue< * /> * ``` */ - onPressInMessage?: (payload: MessagePressableHandlerPayload) => void; + onPressInMessage?: (payload: MessagePressableHandlerPayload) => void; /** * Override onPress handler for message. You have access to payload of that handler as param: * @@ -567,7 +559,7 @@ export type MessagesContextValue< * /> * ``` */ - onPressMessage?: (payload: MessagePressableHandlerPayload) => void; + onPressMessage?: (payload: MessagePressableHandlerPayload) => void; /** * Override the entire content of the Poll component. The component has full access to the * usePollState() and usePollContext() hooks. @@ -577,7 +569,7 @@ export type MessagesContextValue< * UI component for ReactionListTop * Defaults to: [ReactionList](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Reaction/ReactionList.tsx) */ - ReactionListBottom?: React.ComponentType>; + ReactionListBottom?: React.ComponentType; /** * The position of the reaction list in the message */ @@ -587,16 +579,14 @@ export type MessagesContextValue< * UI component for ReactionListTop * Defaults to: [ReactionList](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Reaction/ReactionList.tsx) */ - ReactionListTop?: React.ComponentType>; + ReactionListTop?: React.ComponentType; /** * Full override of the reaction function on Message and Message Overlay * * Please check [cookbook](https://github.com/GetStream/stream-chat-react-native/wiki/Cookbook-v3.0#override-or-intercept-message-actions-edit-delete-reaction-reply-etc) for details. * */ - selectReaction?: ( - message: MessageType, - ) => (reactionType: string) => Promise; + selectReaction?: (message: MessageType) => (reactionType: string) => Promise; /** * Boolean to enable/disable the message underlay background when there are unread messages in the Message List. @@ -614,25 +604,19 @@ export const MessagesContext = React.createContext( DEFAULT_BASE_CONTEXT_VALUE as MessagesContextValue, ); -export const MessagesProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const MessagesProvider = ({ children, value, }: PropsWithChildren<{ - value?: MessagesContextValue; + value?: MessagesContextValue; }>) => ( {children} ); -export const useMessagesContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const contextValue = useContext( - MessagesContext, - ) as unknown as MessagesContextValue; +export const useMessagesContext = () => { + const contextValue = useContext(MessagesContext) as unknown as MessagesContextValue; if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) { throw new Error( diff --git a/package/src/contexts/overlayContext/OverlayContext.tsx b/package/src/contexts/overlayContext/OverlayContext.tsx index 7f1b25213b..6cc559388d 100644 --- a/package/src/contexts/overlayContext/OverlayContext.tsx +++ b/package/src/contexts/overlayContext/OverlayContext.tsx @@ -6,7 +6,6 @@ import type { Attachment } from 'stream-chat'; import type { AttachmentPickerProps } from '../../components/AttachmentPicker/AttachmentPicker'; import type { ImageGalleryCustomComponents } from '../../components/ImageGallery/ImageGallery'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import type { Streami18n } from '../../utils/i18n/Streami18n'; import type { AttachmentPickerContextValue } from '../attachmentPickerContext/AttachmentPickerContext'; import type { DeepPartial } from '../themeContext/ThemeContext'; @@ -27,9 +26,7 @@ export const OverlayContext = React.createContext( DEFAULT_BASE_CONTEXT_VALUE as OverlayContextValue, ); -export type OverlayProviderProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Partial & +export type OverlayProviderProps = Partial & Partial< Pick< AttachmentPickerContextValue, @@ -47,7 +44,7 @@ export type OverlayProviderProps< | 'VideoRecorderSelectorIcon' > > & - ImageGalleryCustomComponents & { + ImageGalleryCustomComponents & { autoPlayVideo?: boolean; /** * The giphy version to render - check the keys of the [Image Object](https://developers.giphy.com/docs/api/schema#image-object) for possible values. Uses 'fixed_height' by default diff --git a/package/src/contexts/overlayContext/OverlayProvider.tsx b/package/src/contexts/overlayContext/OverlayProvider.tsx index 34c9788d74..cf64e2edbf 100644 --- a/package/src/contexts/overlayContext/OverlayProvider.tsx +++ b/package/src/contexts/overlayContext/OverlayProvider.tsx @@ -26,7 +26,7 @@ import { useStreami18n } from '../../hooks/useStreami18n'; import { useViewport } from '../../hooks/useViewport'; import { isImageMediaLibraryAvailable } from '../../native'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { AttachmentPickerProvider } from '../attachmentPickerContext/AttachmentPickerContext'; import { ImageGalleryProvider } from '../imageGalleryContext/ImageGalleryContext'; import { ThemeProvider } from '../themeContext/ThemeContext'; @@ -55,11 +55,7 @@ import { * * @example ./OverlayProvider.md */ -export const OverlayProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - props: PropsWithChildren>, -) => { +export const OverlayProvider = (props: PropsWithChildren) => { const { vh } = useViewport(); const bottomSheetCloseTimeoutRef = useRef>(undefined); const { @@ -211,7 +207,7 @@ export const OverlayProvider = < {children} {overlay === 'gallery' && ( - + = { +export type PaginatedMessageListContextValue = { /** * Load latest messages * @returns Promise @@ -26,7 +23,7 @@ export type PaginatedMessageListContextValue< /** * Messages from client state */ - messages: ChannelState['messages']; + messages: ChannelState['messages']; /** * Has more messages to load */ @@ -53,13 +50,11 @@ export const PaginatedMessageListContext = React.createContext( DEFAULT_BASE_CONTEXT_VALUE as PaginatedMessageListContextValue, ); -export const PaginatedMessageListProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const PaginatedMessageListProvider = ({ children, value, }: PropsWithChildren<{ - value?: PaginatedMessageListContextValue; + value?: PaginatedMessageListContextValue; }>) => ( ); -export const usePaginatedMessageListContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { +export const usePaginatedMessageListContext = () => { const contextValue = useContext( PaginatedMessageListContext, - ) as unknown as PaginatedMessageListContextValue; + ) as unknown as PaginatedMessageListContextValue; if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) { throw new Error( diff --git a/package/src/contexts/pollContext/pollContext.tsx b/package/src/contexts/pollContext/pollContext.tsx index c891ed54b1..a6969ed48b 100644 --- a/package/src/contexts/pollContext/pollContext.tsx +++ b/package/src/contexts/pollContext/pollContext.tsx @@ -3,27 +3,23 @@ import React, { PropsWithChildren, useContext } from 'react'; import { Poll } from 'stream-chat'; import { MessageType } from '../../components'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; -export type PollContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - message: MessageType; - poll: Poll; +export type PollContextValue = { + message: MessageType; + poll: Poll; }; export const PollContext = React.createContext(DEFAULT_BASE_CONTEXT_VALUE as PollContextValue); -export const PollContextProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const PollContextProvider = ({ children, value, }: PropsWithChildren<{ - value: PollContextValue; + value: PollContextValue; }>) => ( {children} diff --git a/package/src/contexts/suggestionsContext/SuggestionsContext.tsx b/package/src/contexts/suggestionsContext/SuggestionsContext.tsx index 16fbb2c137..30ca5fc9d2 100644 --- a/package/src/contexts/suggestionsContext/SuggestionsContext.tsx +++ b/package/src/contexts/suggestionsContext/SuggestionsContext.tsx @@ -6,60 +6,37 @@ import type { AutoCompleteSuggestionHeaderProps } from '../../components/AutoCom import type { AutoCompleteSuggestionItemProps } from '../../components/AutoCompleteInput/AutoCompleteSuggestionItem'; import type { AutoCompleteSuggestionListProps } from '../../components/AutoCompleteInput/AutoCompleteSuggestionList'; import type { Emoji } from '../../emoji-data'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; export type SuggestionComponentType = 'command' | 'emoji' | 'mention'; -export const isSuggestionCommand = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - suggestion: Suggestion, -): suggestion is SuggestionCommand => 'args' in suggestion; - -export const isSuggestionEmoji = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - suggestion: Suggestion, -): suggestion is Emoji => 'unicode' in suggestion; - -export const isSuggestionUser = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - suggestion: Suggestion, -): suggestion is SuggestionUser => 'id' in suggestion; - -export type Suggestion< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Emoji | SuggestionCommand | SuggestionUser; - -export type SuggestionCommand< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = CommandResponse; -export type SuggestionUser< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = UserResponse; - -export type Suggestions< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - data: Suggestion[]; - onSelect: (item: Suggestion) => void; +export const isSuggestionCommand = (suggestion: Suggestion): suggestion is SuggestionCommand => + 'args' in suggestion; + +export const isSuggestionEmoji = (suggestion: Suggestion): suggestion is Emoji => + 'unicode' in suggestion; + +export const isSuggestionUser = (suggestion: Suggestion): suggestion is SuggestionUser => + 'id' in suggestion; + +export type Suggestion = Emoji | SuggestionCommand | SuggestionUser; + +export type SuggestionCommand = CommandResponse; +export type SuggestionUser = UserResponse; + +export type Suggestions = { + data: Suggestion[]; + onSelect: (item: Suggestion) => void; queryText?: string; }; -export type SuggestionsContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type SuggestionsContextValue = { AutoCompleteSuggestionHeader: React.ComponentType; - AutoCompleteSuggestionItem: React.ComponentType< - AutoCompleteSuggestionItemProps - >; - AutoCompleteSuggestionList: React.ComponentType< - AutoCompleteSuggestionListProps - >; + AutoCompleteSuggestionItem: React.ComponentType; + AutoCompleteSuggestionList: React.ComponentType; /** Override handler for closing suggestions (mentions, command autocomplete etc) */ closeSuggestions: () => void; /** @@ -69,7 +46,7 @@ export type SuggestionsContextValue< * @overrideType Function */ openSuggestions: (component: SuggestionComponentType) => Promise; - suggestions: Suggestions; + suggestions: Suggestions; triggerType: SuggestionComponentType; /** * Override handler for updating suggestions (mentions, command autocomplete etc) @@ -77,7 +54,7 @@ export type SuggestionsContextValue< * @param newSuggestions {Component|element} UI Component for suggestion item. * @overrideType Function */ - updateSuggestions: (newSuggestions: Suggestions) => void; + updateSuggestions: (newSuggestions: Suggestions) => void; queryText?: string; suggestionsViewActive?: boolean; }; @@ -89,14 +66,12 @@ export const SuggestionsContext = React.createContext( /** * This provider component exposes the properties stored within the SuggestionsContext. */ -export const SuggestionsProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const SuggestionsProvider = ({ children, value, -}: PropsWithChildren<{ value?: Partial> }>) => { +}: PropsWithChildren<{ value?: Partial }>) => { const [triggerType, setTriggerType] = useState(null); - const [suggestions, setSuggestions] = useState>(); + const [suggestions, setSuggestions] = useState(); const [suggestionsViewActive, setSuggestionsViewActive] = useState(false); const openSuggestions = (component: SuggestionComponentType) => { @@ -104,7 +79,7 @@ export const SuggestionsProvider = < setSuggestionsViewActive(true); }; - const updateSuggestions = (newSuggestions: Suggestions) => { + const updateSuggestions = (newSuggestions: Suggestions) => { setSuggestions(newSuggestions); setSuggestionsViewActive(!!triggerType); }; @@ -132,12 +107,8 @@ export const SuggestionsProvider = < ); }; -export const useSuggestionsContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const contextValue = useContext( - SuggestionsContext, - ) as unknown as SuggestionsContextValue; +export const useSuggestionsContext = () => { + const contextValue = useContext(SuggestionsContext) as unknown as SuggestionsContextValue; if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) { throw new Error( diff --git a/package/src/contexts/threadContext/ThreadContext.tsx b/package/src/contexts/threadContext/ThreadContext.tsx index 5ae41f4d89..35ec53a7d2 100644 --- a/package/src/contexts/threadContext/ThreadContext.tsx +++ b/package/src/contexts/threadContext/ThreadContext.tsx @@ -3,27 +3,23 @@ import React, { PropsWithChildren, useContext } from 'react'; import { ChannelState, Thread } from 'stream-chat'; import type { MessageType } from '../../components/MessageList/hooks/useMessageList'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; -export type ThreadType< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { thread: MessageType; threadInstance: Thread }; +export type ThreadType = { thread: MessageType; threadInstance: Thread }; -export type ThreadContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type ThreadContextValue = { allowThreadMessagesInChannel: boolean; closeThread: () => void; loadMoreThread: () => Promise; - openThread: (message: MessageType) => void; + openThread: (message: MessageType) => void; reloadThread: () => void; setThreadLoadingMore: React.Dispatch>; - thread: MessageType | null; + thread: MessageType | null; threadHasMore: boolean; - threadMessages: ChannelState['threads'][string]; + threadMessages: ChannelState['threads'][string]; loadMoreRecentThread?: (opts: { limit?: number }) => Promise; /** * Boolean to enable/disable parent message press @@ -36,25 +32,19 @@ export type ThreadContextValue< export const ThreadContext = React.createContext(DEFAULT_BASE_CONTEXT_VALUE as ThreadContextValue); -export const ThreadProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const ThreadProvider = ({ children, value, }: PropsWithChildren<{ - value: ThreadContextValue; + value: ThreadContextValue; }>) => ( {children} ); -export const useThreadContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const contextValue = useContext( - ThreadContext, - ) as unknown as ThreadContextValue; +export const useThreadContext = () => { + const contextValue = useContext(ThreadContext) as unknown as ThreadContextValue; if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) { throw new Error( diff --git a/package/src/contexts/threadsContext/ThreadListItemContext.tsx b/package/src/contexts/threadsContext/ThreadListItemContext.tsx index a25bd6fbf0..8602fb86e1 100644 --- a/package/src/contexts/threadsContext/ThreadListItemContext.tsx +++ b/package/src/contexts/threadsContext/ThreadListItemContext.tsx @@ -3,39 +3,33 @@ import React, { PropsWithChildren, useContext } from 'react'; import { Channel, Thread } from 'stream-chat'; import { MessageType } from '../../components'; -import type { DefaultStreamChatGenerics } from '../../types/types'; + import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; -export type ThreadListItemContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - channel: Channel; +export type ThreadListItemContextValue = { + channel: Channel; dateString: string | number | undefined; deletedAtDateString: string | number | undefined; - lastReply: MessageType | undefined; + lastReply: MessageType | undefined; ownUnreadMessageCount: number; - parentMessage: MessageType | undefined; - thread: Thread; + parentMessage: MessageType | undefined; + thread: Thread; }; export const ThreadListItemContext = React.createContext( DEFAULT_BASE_CONTEXT_VALUE as ThreadListItemContextValue, ); -export const ThreadListItemProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const ThreadListItemProvider = ({ children, value, }: PropsWithChildren<{ - value: ThreadListItemContextValue; + value: ThreadListItemContextValue; }>) => ( {children} ); -export const useThreadListItemContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => - useContext(ThreadListItemContext) as unknown as ThreadListItemContextValue; +export const useThreadListItemContext = () => + useContext(ThreadListItemContext) as unknown as ThreadListItemContextValue; diff --git a/package/src/contexts/threadsContext/ThreadsContext.tsx b/package/src/contexts/threadsContext/ThreadsContext.tsx index 16dc2dc5ee..e93c8f30c7 100644 --- a/package/src/contexts/threadsContext/ThreadsContext.tsx +++ b/package/src/contexts/threadsContext/ThreadsContext.tsx @@ -4,19 +4,16 @@ import { FlatListProps } from 'react-native'; import { Channel, Thread } from 'stream-chat'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { ThreadType } from '../threadContext/ThreadContext'; import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; -export type ThreadsContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type ThreadsContextValue = { isFocused: boolean; isLoading: boolean; isLoadingNext: boolean; - threads: Thread[]; + threads: Thread[]; additionalFlatListProps?: Partial>; loadMore?: () => Promise; onThreadSelect?: (thread: ThreadType, channel: Channel) => void; @@ -31,30 +28,23 @@ export const ThreadsContext = React.createContext( DEFAULT_BASE_CONTEXT_VALUE as ThreadsContextValue, ); -export const ThreadsProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const ThreadsProvider = ({ children, value, }: PropsWithChildren<{ - value: ThreadsContextValue; + value: ThreadsContextValue; }>) => ( {children} ); -export const useThreadsContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const contextValue = useContext( - ThreadsContext, - ) as unknown as ThreadsContextValue; +export const useThreadsContext = () => { + const contextValue = useContext(ThreadsContext) as unknown as ThreadsContextValue; if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) { throw new Error( - // TODO: Set correct link to docs page, should be the new ThreadList instead of Channel - 'The useThreadsContext hook was called outside of the ThreadsContext provider. Make sure you have configured the ThreadList component correctly - https://getstream.io/chat/docs/sdk/reactnative/basics/hello_stream_chat/#channel', + 'The useThreadsContext hook was called outside of the ThreadsContext provider. Make sure you have configured the ThreadList component correctly - https://getstream.io/chat/docs/sdk/react-native/ui-components/thread-list/', ); } diff --git a/package/src/contexts/typingContext/TypingContext.tsx b/package/src/contexts/typingContext/TypingContext.tsx index 62ca993063..86f70c5560 100644 --- a/package/src/contexts/typingContext/TypingContext.tsx +++ b/package/src/contexts/typingContext/TypingContext.tsx @@ -2,38 +2,29 @@ import React, { PropsWithChildren, useContext } from 'react'; import type { ChannelState } from 'stream-chat'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; -export type TypingContextValue< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - typing: ChannelState['typing']; +export type TypingContextValue = { + typing: ChannelState['typing']; }; export const TypingContext = React.createContext(DEFAULT_BASE_CONTEXT_VALUE as TypingContextValue); -export const TypingProvider = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const TypingProvider = ({ children, value, }: PropsWithChildren<{ - value: TypingContextValue; + value: TypingContextValue; }>) => ( {children} ); -export const useTypingContext = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->() => { - const contextValue = useContext( - TypingContext, - ) as unknown as TypingContextValue; +export const useTypingContext = () => { + const contextValue = useContext(TypingContext) as unknown as TypingContextValue; if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) { throw new Error( diff --git a/package/src/hooks/useTranslatedMessage.ts b/package/src/hooks/useTranslatedMessage.ts index f8b2c814e6..5f47f9cda4 100644 --- a/package/src/hooks/useTranslatedMessage.ts +++ b/package/src/hooks/useTranslatedMessage.ts @@ -1,15 +1,10 @@ import type { FormatMessageResponse, MessageResponse, TranslationLanguages } from 'stream-chat'; import { useTranslationContext } from '../contexts/translationContext/TranslationContext'; -import type { DefaultStreamChatGenerics } from '../types/types'; type TranslationKey = `${TranslationLanguages}_text`; -export const useTranslatedMessage = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - message?: MessageResponse | FormatMessageResponse, -) => { +export const useTranslatedMessage = (message?: MessageResponse | FormatMessageResponse) => { const { userLanguage: translationContextUserLanguage } = useTranslationContext(); const userLanguage = translationContextUserLanguage; diff --git a/package/src/mock-builders/api/channelMocks.tsx b/package/src/mock-builders/api/channelMocks.tsx index 50b31bacd9..787f862537 100644 --- a/package/src/mock-builders/api/channelMocks.tsx +++ b/package/src/mock-builders/api/channelMocks.tsx @@ -11,8 +11,6 @@ import { ONE_MEMBER_WITH_EMPTY_USER_MOCK, } from '../../mock-builders/api/queryMembers'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - const channelName = 'okechukwu'; const CHANNEL = { data: { name: channelName }, diff --git a/package/src/store/apis/getChannelMessages.ts b/package/src/store/apis/getChannelMessages.ts index 6b7707bc70..d7d34b3614 100644 --- a/package/src/store/apis/getChannelMessages.ts +++ b/package/src/store/apis/getChannelMessages.ts @@ -4,16 +4,13 @@ import { selectMessagesForChannels } from './queries/selectMessagesForChannels'; import { selectReactionsForMessages } from './queries/selectReactionsForMessages'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { isBlockedMessage } from '../../utils/utils'; import { mapStorableToMessage } from '../mappers/mapStorableToMessage'; import { createSelectQuery } from '../sqlite-utils/createSelectQuery'; import { SqliteClient } from '../SqliteClient'; import type { TableRow, TableRowJoinedUser } from '../types'; -export const getChannelMessages = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const getChannelMessages = async ({ channelIds, currentUserId, }: { @@ -53,7 +50,7 @@ export const getChannelMessages = async < }); // Populate the messages. - const cidVsMessages: Record[]> = {}; + const cidVsMessages: Record = {}; messageRows.forEach((m) => { if (!cidVsMessages[m.cid]) { cidVsMessages[m.cid] = []; @@ -61,7 +58,7 @@ export const getChannelMessages = async < if (!isBlockedMessage(m)) { cidVsMessages[m.cid].push( - mapStorableToMessage({ + mapStorableToMessage({ currentUserId, messageRow: m, pollRow: messageIdsVsPolls[m.poll_id], diff --git a/package/src/store/apis/getChannels.ts b/package/src/store/apis/getChannels.ts index 5e6fb48503..1c06f3c453 100644 --- a/package/src/store/apis/getChannels.ts +++ b/package/src/store/apis/getChannels.ts @@ -5,7 +5,6 @@ import { getMembers } from './getMembers'; import { getReads } from './getReads'; import { selectChannels } from './queries/selectChannels'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { mapStorableToChannel } from '../mappers/mapStorableToChannel'; import { SqliteClient } from '../SqliteClient'; @@ -18,28 +17,26 @@ import { SqliteClient } from '../SqliteClient'; * * @returns {Array} Channels with enriched state. */ -export const getChannels = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const getChannels = async ({ channelIds, currentUserId, }: { channelIds: string[]; currentUserId: string; -}): Promise, 'duration'>[]> => { +}): Promise[]> => { SqliteClient.logger?.('info', 'getChannels', { channelIds, currentUserId }); const channels = await selectChannels({ channelIds }); - const cidVsMembers = await getMembers({ channelIds }); - const cidVsReads = await getReads({ channelIds }); - const cidVsMessages = await getChannelMessages({ + const cidVsMembers = await getMembers({ channelIds }); + const cidVsReads = await getReads({ channelIds }); + const cidVsMessages = await getChannelMessages({ channelIds, currentUserId, }); // Enrich the channels with state return channels.map((c) => ({ - ...mapStorableToChannel(c), + ...mapStorableToChannel(c), members: cidVsMembers[c.cid] || [], messages: cidVsMessages[c.cid] || [], pinned_messages: [], diff --git a/package/src/store/apis/getChannelsForFilterSort.ts b/package/src/store/apis/getChannelsForFilterSort.ts index 92123d62ed..aef2f692a6 100644 --- a/package/src/store/apis/getChannelsForFilterSort.ts +++ b/package/src/store/apis/getChannelsForFilterSort.ts @@ -3,8 +3,6 @@ import type { ChannelAPIResponse, ChannelFilters, ChannelSort } from 'stream-cha import { getChannels } from './getChannels'; import { selectChannelIdsForFilterSort } from './queries/selectChannelIdsForFilterSort'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - import { SqliteClient } from '../SqliteClient'; /** @@ -17,17 +15,15 @@ import { SqliteClient } from '../SqliteClient'; * * @returns Array of channels corresponding to filters & sort. Returns null if filters + sort query doesn't exist in "channelQueries" table. */ -export const getChannelsForFilterSort = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const getChannelsForFilterSort = async ({ currentUserId, filters, sort, }: { currentUserId: string; - filters?: ChannelFilters; - sort?: ChannelSort; -}): Promise, 'duration'>[] | null> => { + filters?: ChannelFilters; + sort?: ChannelSort; +}): Promise[] | null> => { if (!filters && !sort) { console.warn('Please provide the query (filters/sort) to fetch channels from DB'); return null; diff --git a/package/src/store/apis/getMembers.ts b/package/src/store/apis/getMembers.ts index b6090bb7f6..cdaf4e85d1 100644 --- a/package/src/store/apis/getMembers.ts +++ b/package/src/store/apis/getMembers.ts @@ -2,26 +2,19 @@ import type { ChannelMemberResponse } from 'stream-chat'; import { selectMembersForChannels } from './queries/selectMembersForChannels'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { mapStorableToMember } from '../mappers/mapStorableToMember'; import { SqliteClient } from '../SqliteClient'; -export const getMembers = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - channelIds, -}: { - channelIds: string[]; -}) => { +export const getMembers = async ({ channelIds }: { channelIds: string[] }) => { SqliteClient.logger?.('info', 'getMembers', { channelIds }); const memberRows = await selectMembersForChannels(channelIds); - const cidVsMembers: Record[]> = {}; + const cidVsMembers: Record = {}; memberRows.forEach((member) => { if (!cidVsMembers[member.cid]) { cidVsMembers[member.cid] = []; } - cidVsMembers[member.cid].push(mapStorableToMember(member)); + cidVsMembers[member.cid].push(mapStorableToMember(member)); }); return cidVsMembers; diff --git a/package/src/store/apis/getReactions.ts b/package/src/store/apis/getReactions.ts index 3565eedc54..e43562646e 100644 --- a/package/src/store/apis/getReactions.ts +++ b/package/src/store/apis/getReactions.ts @@ -1,21 +1,18 @@ import type { ReactionResponse } from 'stream-chat'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { mapStorableToReaction } from '../mappers/mapStorableToReaction'; import { SqliteClient } from '../SqliteClient'; import { TableRowJoinedUser } from '../types'; -export const getReactions = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const getReactions = ({ reactions, }: { reactions: TableRowJoinedUser<'reactions'>[]; -}): ReactionResponse[] => { +}): ReactionResponse[] => { SqliteClient.logger?.('info', 'getReactions', { reactions }); // Enrich the channels with state return reactions.map((reaction) => ({ - ...mapStorableToReaction(reaction), + ...mapStorableToReaction(reaction), })); }; diff --git a/package/src/store/apis/getReactionsforFilterSort.ts b/package/src/store/apis/getReactionsforFilterSort.ts index 4c9d42bab8..ef7592ce0c 100644 --- a/package/src/store/apis/getReactionsforFilterSort.ts +++ b/package/src/store/apis/getReactionsforFilterSort.ts @@ -3,8 +3,6 @@ import type { ReactionFilters, ReactionResponse, ReactionSort } from 'stream-cha import { getReactions } from './getReactions'; import { selectReactionsForMessages } from './queries/selectReactionsForMessages'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - import { SqliteClient } from '../SqliteClient'; /** @@ -13,17 +11,15 @@ import { SqliteClient } from '../SqliteClient'; * @param filters The filters to be applied while fetching reactions. * @param sort The sort to be applied while fetching reactions. */ -export const getReactionsForFilterSort = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const getReactionsForFilterSort = async ({ currentMessageId, filters, sort, }: { currentMessageId: string; - filters?: ReactionFilters; - sort?: ReactionSort; -}): Promise[] | null> => { + filters?: ReactionFilters; + sort?: ReactionSort; +}): Promise => { if (!filters && !sort) { console.warn('Please provide the query (filters/sort) to fetch channels from DB'); return null; diff --git a/package/src/store/apis/getReads.ts b/package/src/store/apis/getReads.ts index e3025e18a1..d6c8301b90 100644 --- a/package/src/store/apis/getReads.ts +++ b/package/src/store/apis/getReads.ts @@ -2,26 +2,19 @@ import type { ReadResponse } from 'stream-chat'; import { selectReadsForChannels } from './queries/selectReadsForChannels'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import { mapStorableToRead } from '../mappers/mapStorableToRead'; import { SqliteClient } from '../SqliteClient'; -export const getReads = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - channelIds, -}: { - channelIds: string[]; -}) => { +export const getReads = async ({ channelIds }: { channelIds: string[] }) => { SqliteClient.logger?.('info', 'getReads', { channelIds }); const reads = await selectReadsForChannels(channelIds); - const cidVsReads: Record[]> = {}; + const cidVsReads: Record = {}; reads.forEach((read) => { if (!cidVsReads[read.cid]) { cidVsReads[read.cid] = []; } - cidVsReads[read.cid].push(mapStorableToRead(read)); + cidVsReads[read.cid].push(mapStorableToRead(read)); }); return cidVsReads; diff --git a/package/src/store/apis/queries/selectChannelIdsForFilterSort.ts b/package/src/store/apis/queries/selectChannelIdsForFilterSort.ts index 73cebfb4bc..4a18284d73 100644 --- a/package/src/store/apis/queries/selectChannelIdsForFilterSort.ts +++ b/package/src/store/apis/queries/selectChannelIdsForFilterSort.ts @@ -1,6 +1,5 @@ import type { ChannelFilters, ChannelSort } from 'stream-chat'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; import { createSelectQuery } from '../../sqlite-utils/createSelectQuery'; import { SqliteClient } from '../../SqliteClient'; @@ -16,14 +15,12 @@ import { convertFilterSortToQuery } from '../utils/convertFilterSortToQuery'; * @returns Array of channel ids corresponding to filters & sort. Returns null if filters + sort query doesn't exist in "channelQueries" table. */ -export const selectChannelIdsForFilterSort = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const selectChannelIdsForFilterSort = async ({ filters, sort, }: { - filters?: ChannelFilters; - sort?: ChannelSort; + filters?: ChannelFilters; + sort?: ChannelSort; }): Promise => { const query = convertFilterSortToQuery({ filters, sort }); diff --git a/package/src/store/apis/updatePollMessage.ts b/package/src/store/apis/updatePollMessage.ts index 7fe342b257..1263a4f9bb 100644 --- a/package/src/store/apis/updatePollMessage.ts +++ b/package/src/store/apis/updatePollMessage.ts @@ -1,6 +1,5 @@ import { isVoteAnswer, PollAnswer, PollResponse, PollVote } from 'stream-chat'; -import { DefaultStreamChatGenerics } from '../../types/types'; import { mapPollToStorable } from '../mappers/mapPollToStorable'; import { mapStorableToPoll } from '../mappers/mapStorableToPoll'; import { createSelectQuery } from '../sqlite-utils/createSelectQuery'; @@ -8,9 +7,7 @@ import { createUpdateQuery } from '../sqlite-utils/createUpdateQuery'; import { SqliteClient } from '../SqliteClient'; import type { PreparedQueries, TableRow } from '../types'; -export const updatePollMessage = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const updatePollMessage = async ({ eventType, flush = true, poll, @@ -18,10 +15,10 @@ export const updatePollMessage = async < userID, }: { eventType: string; - poll: PollResponse; + poll: PollResponse; userID: string; flush?: boolean; - poll_vote?: PollVote | PollAnswer; + poll_vote?: PollVote | PollAnswer; }) => { const queries: PreparedQueries[] = []; diff --git a/package/src/store/apis/upsertChannelDataFromChannel.ts b/package/src/store/apis/upsertChannelDataFromChannel.ts index b22b9ccaad..c65d1ca126 100644 --- a/package/src/store/apis/upsertChannelDataFromChannel.ts +++ b/package/src/store/apis/upsertChannelDataFromChannel.ts @@ -1,17 +1,14 @@ import type { Channel } from 'stream-chat'; -import { DefaultStreamChatGenerics } from '../../types/types'; import { mapChannelToStorable } from '../mappers/mapChannelToStorable'; import { createUpsertQuery } from '../sqlite-utils/createUpsertQuery'; import { SqliteClient } from '../SqliteClient'; -export const upsertChannelDataFromChannel = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const upsertChannelDataFromChannel = async ({ channel, flush = true, }: { - channel: Channel; + channel: Channel; flush?: boolean; }) => { const storableChannel = mapChannelToStorable(channel); diff --git a/package/src/store/apis/utils/convertFilterSortToQuery.ts b/package/src/store/apis/utils/convertFilterSortToQuery.ts index a6a944853f..0190f1bd1a 100644 --- a/package/src/store/apis/utils/convertFilterSortToQuery.ts +++ b/package/src/store/apis/utils/convertFilterSortToQuery.ts @@ -1,14 +1,10 @@ import type { ChannelFilters, ChannelSort } from 'stream-chat'; -import type { DefaultStreamChatGenerics } from '../../../types/types'; - -export const convertFilterSortToQuery = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const convertFilterSortToQuery = ({ filters, sort, }: { - filters?: ChannelFilters; - sort?: ChannelSort; + filters?: ChannelFilters; + sort?: ChannelSort; }) => JSON.stringify(`${filters ? JSON.stringify(filters) : ''}-${sort ? JSON.stringify(sort) : ''}`); diff --git a/package/src/store/mappers/mapChannelDataToStorable.ts b/package/src/store/mappers/mapChannelDataToStorable.ts index 6981917a6d..f254cc1a84 100644 --- a/package/src/store/mappers/mapChannelDataToStorable.ts +++ b/package/src/store/mappers/mapChannelDataToStorable.ts @@ -2,15 +2,9 @@ import type { ChannelResponse } from 'stream-chat'; import { mapDateTimeToStorable } from './mapDateTimeToStorable'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - import type { TableRow } from '../types'; -export const mapChannelDataToStorable = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: ChannelResponse, -): TableRow<'channels'> => { +export const mapChannelDataToStorable = (channel: ChannelResponse): TableRow<'channels'> => { const { auto_translation_enabled, auto_translation_language, diff --git a/package/src/store/mappers/mapChannelToStorable.ts b/package/src/store/mappers/mapChannelToStorable.ts index 9518149a4b..739f2ff4b0 100644 --- a/package/src/store/mappers/mapChannelToStorable.ts +++ b/package/src/store/mappers/mapChannelToStorable.ts @@ -2,15 +2,9 @@ import type { Channel, ChannelResponse } from 'stream-chat'; import { mapDateTimeToStorable } from './mapDateTimeToStorable'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - import type { TableRow } from '../types'; -export const mapChannelToStorable = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, -): TableRow<'channels'> | undefined => { +export const mapChannelToStorable = (channel: Channel): TableRow<'channels'> | undefined => { if (!channel.data) { return; } @@ -40,7 +34,7 @@ export const mapChannelToStorable = < type, updated_at, ...extraData - } = channel.data as unknown as ChannelResponse; + } = channel.data as unknown as ChannelResponse; return { autoTranslationEnabled: auto_translation_enabled, diff --git a/package/src/store/mappers/mapMemberToStorable.ts b/package/src/store/mappers/mapMemberToStorable.ts index eb3e64da76..ed1b492daf 100644 --- a/package/src/store/mappers/mapMemberToStorable.ts +++ b/package/src/store/mappers/mapMemberToStorable.ts @@ -2,17 +2,14 @@ import type { ChannelMemberResponse } from 'stream-chat'; import { mapDateTimeToStorable } from './mapDateTimeToStorable'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import type { TableRow } from '../types'; -export const mapMemberToStorable = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const mapMemberToStorable = ({ cid, member, }: { cid: string; - member: ChannelMemberResponse; + member: ChannelMemberResponse; }): TableRow<'members'> => { const { banned, diff --git a/package/src/store/mappers/mapReadToStorable.ts b/package/src/store/mappers/mapReadToStorable.ts index 4b989ee611..0e261be04d 100644 --- a/package/src/store/mappers/mapReadToStorable.ts +++ b/package/src/store/mappers/mapReadToStorable.ts @@ -2,17 +2,14 @@ import type { ReadResponse } from 'stream-chat'; import { mapDateTimeToStorable } from './mapDateTimeToStorable'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import type { TableRow } from '../types'; -export const mapReadToStorable = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const mapReadToStorable = ({ cid, read, }: { cid: string; - read: ReadResponse; + read: ReadResponse; }): TableRow<'reads'> => { const { last_read, unread_messages, user } = read; diff --git a/package/src/store/mappers/mapStorableToChannel.ts b/package/src/store/mappers/mapStorableToChannel.ts index 9911d23f3a..b60078fea0 100644 --- a/package/src/store/mappers/mapStorableToChannel.ts +++ b/package/src/store/mappers/mapStorableToChannel.ts @@ -1,16 +1,10 @@ import type { ChannelAPIResponse } from 'stream-chat'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import type { TableRow } from '../types'; -export const mapStorableToChannel = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( +export const mapStorableToChannel = ( channelRow: TableRow<'channels'>, -): Omit< - ChannelAPIResponse, - 'duration' | 'messages' | 'members' | 'pinned_messages' -> => { +): Omit => { const { autoTranslationEnabled, autoTranslationLanguage, diff --git a/package/src/store/mappers/mapStorableToMember.ts b/package/src/store/mappers/mapStorableToMember.ts index a093f6a3a0..ee5233547f 100644 --- a/package/src/store/mappers/mapStorableToMember.ts +++ b/package/src/store/mappers/mapStorableToMember.ts @@ -2,14 +2,11 @@ import type { ChannelMemberResponse } from 'stream-chat'; import { mapStorableToUser } from './mapStorableToUser'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import type { TableRowJoinedUser } from '../types'; -export const mapStorableToMember = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( +export const mapStorableToMember = ( memberRow: TableRowJoinedUser<'members'>, -): ChannelMemberResponse => { +): ChannelMemberResponse => { const { banned, channelRole, diff --git a/package/src/store/mappers/mapStorableToMessage.ts b/package/src/store/mappers/mapStorableToMessage.ts index 45d34d1734..f94cae17f2 100644 --- a/package/src/store/mappers/mapStorableToMessage.ts +++ b/package/src/store/mappers/mapStorableToMessage.ts @@ -5,13 +5,9 @@ import { mapStorableToReaction } from './mapStorableToReaction'; import { mapStorableToUser } from './mapStorableToUser'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - import type { TableRow, TableRowJoinedUser } from '../types'; -export const mapStorableToMessage = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const mapStorableToMessage = ({ currentUserId, messageRow, pollRow, @@ -21,7 +17,7 @@ export const mapStorableToMessage = < messageRow: TableRowJoinedUser<'messages'>; pollRow: TableRow<'poll'>; reactionRows: TableRowJoinedUser<'reactions'>[]; -}): MessageResponse => { +}): MessageResponse => { const { createdAt, deletedAt, @@ -33,8 +29,7 @@ export const mapStorableToMessage = < user, ...rest } = messageRow; - const latestReactions = - reactionRows?.map((reaction) => mapStorableToReaction(reaction)) || []; + const latestReactions = reactionRows?.map((reaction) => mapStorableToReaction(reaction)) || []; const ownReactions = latestReactions.filter((reaction) => reaction.user?.id === currentUserId); diff --git a/package/src/store/mappers/mapStorableToPoll.ts b/package/src/store/mappers/mapStorableToPoll.ts index ffeb1ad2de..b279350c8a 100644 --- a/package/src/store/mappers/mapStorableToPoll.ts +++ b/package/src/store/mappers/mapStorableToPoll.ts @@ -1,13 +1,8 @@ import { PollResponse, VotingVisibility } from 'stream-chat'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import type { TableRow } from '../types'; -export const mapStorableToPoll = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - pollRow: TableRow<'poll'>, -): PollResponse => { +export const mapStorableToPoll = (pollRow: TableRow<'poll'>): PollResponse => { const { allow_answers, allow_user_suggested_options, @@ -35,6 +30,8 @@ export const mapStorableToPoll = < allow_answers, allow_user_suggested_options, answers_count, + // TODO: Investigate why this is now here, this is just a quickfix for now as we do not use it. + cid: '', created_at, created_by: JSON.parse(created_by), created_by_id, diff --git a/package/src/store/mappers/mapStorableToReaction.ts b/package/src/store/mappers/mapStorableToReaction.ts index d0bf113176..6e3166c41a 100644 --- a/package/src/store/mappers/mapStorableToReaction.ts +++ b/package/src/store/mappers/mapStorableToReaction.ts @@ -2,15 +2,11 @@ import type { ReactionResponse } from 'stream-chat'; import { mapStorableToUser } from './mapStorableToUser'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - import type { TableRowJoinedUser } from '../types'; -export const mapStorableToReaction = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( +export const mapStorableToReaction = ( reactionRow: TableRowJoinedUser<'reactions'>, -): ReactionResponse => { +): ReactionResponse => { const { createdAt, extraData, messageId, score, type, updatedAt, user } = reactionRow; return { diff --git a/package/src/store/mappers/mapStorableToRead.ts b/package/src/store/mappers/mapStorableToRead.ts index cd336e468d..448aecea5b 100644 --- a/package/src/store/mappers/mapStorableToRead.ts +++ b/package/src/store/mappers/mapStorableToRead.ts @@ -2,15 +2,9 @@ import type { ReadResponse } from 'stream-chat'; import { mapStorableToUser } from './mapStorableToUser'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - import type { TableRowJoinedUser } from '../types'; -export const mapStorableToRead = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - row: TableRowJoinedUser<'reads'>, -): ReadResponse => { +export const mapStorableToRead = (row: TableRowJoinedUser<'reads'>): ReadResponse => { const { lastRead, unreadMessages, user } = row; return { diff --git a/package/src/store/mappers/mapStorableToUser.ts b/package/src/store/mappers/mapStorableToUser.ts index f740ce4ffc..1d09732606 100644 --- a/package/src/store/mappers/mapStorableToUser.ts +++ b/package/src/store/mappers/mapStorableToUser.ts @@ -1,13 +1,8 @@ import type { UserResponse } from 'stream-chat'; -import type { DefaultStreamChatGenerics } from '../../types/types'; import type { TableRow } from '../types'; -export const mapStorableToUser = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - userRow: TableRow<'users'>, -): UserResponse => { +export const mapStorableToUser = (userRow: TableRow<'users'>): UserResponse => { const { banned, createdAt, extraData, id, lastActive, online, role, updatedAt } = userRow; return { diff --git a/package/src/types/stream-chat-common-custom-data.d.ts b/package/src/types/stream-chat-common-custom-data.d.ts new file mode 100644 index 0000000000..78a5b46f1f --- /dev/null +++ b/package/src/types/stream-chat-common-custom-data.d.ts @@ -0,0 +1,42 @@ +import 'stream-chat'; +import { + DefaultAttachmentType, + DefaultChannelType, + DefaultCommandType, + DefaultEventType, + DefaultMemberType, + DefaultMessageType, + DefaultPollOptionType, + DefaultPollType, + DefaultReactionType, + DefaultThreadType, + DefaultUserType, +} from './types'; + +declare module 'stream-chat' { + /* eslint-disable @typescript-eslint/no-empty-object-type */ + + interface CustomAttachmentData extends DefaultAttachmentType {} + + interface CustomChannelData extends DefaultChannelType {} + + interface CustomCommandData extends DefaultCommandType {} + + interface CustomEventData extends DefaultEventType {} + + interface CustomMemberData extends DefaultMemberType {} + + interface CustomUserData extends DefaultUserType {} + + interface CustomMessageData extends DefaultMessageType {} + + interface CustomPollOptionData extends DefaultPollOptionType {} + + interface CustomPollData extends DefaultPollType {} + + interface CustomReactionData extends DefaultReactionType {} + + interface CustomThreadData extends DefaultThreadType {} + + /* eslint-enable @typescript-eslint/no-empty-object-type */ +} diff --git a/package/src/types/types.ts b/package/src/types/types.ts index 6d59e3f8c4..22606a3206 100644 --- a/package/src/types/types.ts +++ b/package/src/types/types.ts @@ -1,10 +1,4 @@ -import type { - ChannelFilters, - ChannelSort, - ChannelState, - ExtendableGenerics, - LiteralStringForUnion, -} from 'stream-chat'; +import type { ChannelFilters, ChannelSort, ChannelState } from 'stream-chat'; import type { FileStateValue } from '../utils/utils'; @@ -57,67 +51,73 @@ export type FileUpload = { url?: string; waveform_data?: number[]; }; - -export type ImageUpload = { - file: Partial; - id: string; - state: FileStateValue; - height?: number; - url?: string; - width?: number; -}; - -export type DefaultAttachmentType = UnknownType & { +export interface DefaultAttachmentType { duration?: number; file_size?: number; mime_type?: string; originalFile?: File; originalImage?: Partial; waveform_data?: number[]; -}; - -export type Reaction = { - id: string; - name: string; - type: string; - image?: string; -}; +} -interface DefaultUserType extends UnknownType { +export interface DefaultUserType { image?: string; } -interface DefaultChannelType extends UnknownType { +export interface DefaultChannelType { [key: string]: unknown; image?: string; } -export interface DefaultStreamChatGenerics extends ExtendableGenerics { - attachmentType: DefaultAttachmentType; - channelType: DefaultChannelType; - commandType: LiteralStringForUnion; - eventType: UnknownType; - memberType: UnknownType; - messageType: UnknownType; - reactionType: UnknownType; - userType: DefaultUserType; +export interface DefaultCommandType { + flag: unknown; + imgur: unknown; } -export type ChannelListEventListenerOptions< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - filters?: ChannelFilters; - sort?: ChannelSort; +/* eslint-disable @typescript-eslint/no-empty-object-type */ + +export interface DefaultEventType {} + +export interface DefaultMemberType {} + +export interface DefaultMessageType {} + +export interface DefaultPollOptionType {} + +export interface DefaultPollType {} + +export interface DefaultReactionType {} + +export interface DefaultThreadType {} + +/* eslint-enable @typescript-eslint/no-empty-object-type */ +export type ImageUpload = { + file: Partial; + id: string; + state: FileStateValue; + height?: number; + url?: string; + width?: number; +}; + +export type Reaction = { + id: string; + name: string; + type: string; + image?: string; +}; + +export type ChannelListEventListenerOptions = { + filters?: ChannelFilters; + sort?: ChannelSort; }; export type UnknownType = Record; export type ValueOf = T[keyof T]; -export type ChannelUnreadState< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = Omit['read']>, 'user'>; +export type ChannelUnreadState = Omit, 'user'>; // ASYNC AUDIO EXPO: export enum AndroidOutputFormat { diff --git a/package/src/utils/ACITriggerSettings.ts b/package/src/utils/ACITriggerSettings.ts index 14ace35e3e..610a7af945 100644 --- a/package/src/utils/ACITriggerSettings.ts +++ b/package/src/utils/ACITriggerSettings.ts @@ -15,13 +15,8 @@ import type { SuggestionUser, } from '../contexts/suggestionsContext/SuggestionsContext'; import { Emoji } from '../emoji-data'; -import type { DefaultStreamChatGenerics } from '../types/types'; -const getCommands = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, -) => channel.getConfig()?.commands || []; +const getCommands = (channel: Channel) => channel.getConfig()?.commands || []; export type TriggerSettingsOutputType = { caretPosition: string; @@ -29,22 +24,17 @@ export type TriggerSettingsOutputType = { text: string; }; -export type TriggerSettings< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { +export type TriggerSettings = { '/'?: { dataProvider: ( - query: CommandResponse['name'], + query: CommandResponse['name'], text: string, - onReady?: ( - data: CommandResponse[], - q: CommandResponse['name'], - ) => void, + onReady?: (data: CommandResponse[], q: CommandResponse['name']) => void, options?: { limit?: number; }, - ) => SuggestionCommand[]; - output: (entity: CommandResponse) => TriggerSettingsOutputType; + ) => SuggestionCommand[]; + output: (entity: CommandResponse) => TriggerSettingsOutputType; type: SuggestionComponentType; }; ':'?: { @@ -57,31 +47,26 @@ export type TriggerSettings< type: SuggestionComponentType; }; '@'?: { - callback: (item: SuggestionUser) => void; + callback: (item: SuggestionUser) => void; dataProvider: ( - query: SuggestionUser['name'], + query: SuggestionUser['name'], _: string, - onReady?: ( - data: SuggestionUser[], - q: SuggestionUser['name'], - ) => void, + onReady?: (data: SuggestionUser[], q: SuggestionUser['name']) => void, options?: { limit?: number; mentionAllAppUsersEnabled?: boolean; - mentionAllAppUsersQuery?: MentionAllAppUsersQuery; + mentionAllAppUsersQuery?: MentionAllAppUsersQuery; }, - ) => SuggestionUser[] | Promise | void; - output: (entity: SuggestionUser) => TriggerSettingsOutputType; + ) => SuggestionUser[] | Promise | void; + output: (entity: SuggestionUser) => TriggerSettingsOutputType; type: SuggestionComponentType; }; }; -export type ACITriggerSettingsParams< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = { - channel: Channel; - client: StreamChat; - onMentionSelectItem: (item: SuggestionUser) => void; +export type ACITriggerSettingsParams = { + channel: Channel; + client: StreamChat; + onMentionSelectItem: (item: SuggestionUser) => void; emojiSearchIndex?: EmojiSearchIndex; }; @@ -104,14 +89,12 @@ export type Trigger = '/' | '@' | ':'; * previous call without waiting for a1. So in this case, we want to execute onReady, when trailing * end of debounce executes. */ -export const ACITriggerSettings = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const ACITriggerSettings = ({ channel, client, emojiSearchIndex, onMentionSelectItem, -}: ACITriggerSettingsParams): TriggerSettings => ({ +}: ACITriggerSettingsParams): TriggerSettings => ({ '/': { dataProvider: (query, text, onReady, options = {}) => { try { @@ -208,7 +191,7 @@ export const ACITriggerSettings = < return []; } if (options?.mentionAllAppUsersEnabled) { - return (queryUsersDebounced as DebouncedFunc>)( + return (queryUsersDebounced as DebouncedFunc)( client, query, (data) => { @@ -257,7 +240,7 @@ export const ACITriggerSettings = < return data; } - return (queryMembersDebounced as DebouncedFunc>)( + return (queryMembersDebounced as DebouncedFunc)( client, channel, query, diff --git a/package/src/utils/DBSyncManager.ts b/package/src/utils/DBSyncManager.ts index b159e88855..d4daffe65b 100644 --- a/package/src/utils/DBSyncManager.ts +++ b/package/src/utils/DBSyncManager.ts @@ -11,7 +11,6 @@ import { deletePendingTask } from '../store/apis/deletePendingTask'; import { getPendingTasks } from '../store/apis/getPendingTasks'; import { SqliteClient } from '../store/SqliteClient'; import type { PendingTask } from '../store/types'; -import type { DefaultStreamChatGenerics } from '../types/types'; /** * DBSyncManager has the responsibility to sync the channel states @@ -104,11 +103,7 @@ export class DBSyncManager { }; }; - static sync = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, - >( - client: StreamChat, - ) => { + static sync = async (client: StreamChat) => { if (!this.client?.user) { return; } @@ -165,20 +160,12 @@ export class DBSyncManager { await this.sync(this.client); }; - static queueTask = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, - >({ - client, - task, - }: { - client: StreamChat; - task: PendingTask; - }) => { + static queueTask = async ({ client, task }: { client: StreamChat; task: PendingTask }) => { const removeFromApi = await addPendingTask(task); let response; try { - response = await this.executeTask({ client, task }); + response = await this.executeTask({ client, task }); } catch (e) { if ((e as AxiosError)?.response?.data?.code === 4) { // Error code 16 - message already exists @@ -193,15 +180,7 @@ export class DBSyncManager { return response; }; - static executeTask = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, - >({ - client, - task, - }: { - client: StreamChat; - task: PendingTask; - }) => { + static executeTask = async ({ client, task }: { client: StreamChat; task: PendingTask }) => { const channel = client.channel(task.channelType, task.channelId); if (task.type === 'send-reaction') { @@ -219,11 +198,7 @@ export class DBSyncManager { throw new Error('Invalid task type'); }; - static executePendingTasks = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, - >( - client: StreamChat, - ) => { + static executePendingTasks = async (client: StreamChat) => { const queue = await getPendingTasks(); for (const task of queue) { if (!task.id) { @@ -231,7 +206,7 @@ export class DBSyncManager { } try { - await this.executeTask({ + await this.executeTask({ client, task, }); diff --git a/package/src/utils/addReactionToLocalState.ts b/package/src/utils/addReactionToLocalState.ts index ae4739ae53..694dc42b21 100644 --- a/package/src/utils/addReactionToLocalState.ts +++ b/package/src/utils/addReactionToLocalState.ts @@ -3,22 +3,18 @@ import type { Channel, ReactionResponse, UserResponse } from 'stream-chat'; import { updateReaction } from '../store/apis'; import { insertReaction } from '../store/apis/insertReaction'; -import type { DefaultStreamChatGenerics } from '../types/types'; - -export const addReactionToLocalState = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const addReactionToLocalState = ({ channel, enforceUniqueReaction, messageId, reactionType, user, }: { - channel: Channel; + channel: Channel; enforceUniqueReaction: boolean; messageId: string; reactionType: string; - user: UserResponse; + user: UserResponse; }) => { const message = channel.state.messages.find(({ id }) => id === messageId); diff --git a/package/src/utils/i18n/Streami18n.ts b/package/src/utils/i18n/Streami18n.ts index a9215541ca..bd43691c28 100644 --- a/package/src/utils/i18n/Streami18n.ts +++ b/package/src/utils/i18n/Streami18n.ts @@ -49,8 +49,6 @@ import 'dayjs/locale/tr'; */ import 'dayjs/locale/en'; -import type { DefaultStreamChatGenerics } from '../../types/types'; - const defaultNS = 'translation'; const defaultLng = 'en'; @@ -383,7 +381,7 @@ export class Streami18n { translations: { [key: string]: { - [key: string]: Partial | DefaultStreamChatGenerics; + [key: string]: Partial; }; } = { en: { [defaultNS]: enTranslations }, @@ -643,7 +641,7 @@ export class Streami18n { */ registerTranslation( language: string, - translation: Partial | DefaultStreamChatGenerics, + translation: Partial, customDayjsLocale?: Partial, ) { if (!translation) { diff --git a/package/src/utils/queryMembers.ts b/package/src/utils/queryMembers.ts index 7ed2418ab2..19c5723c61 100644 --- a/package/src/utils/queryMembers.ts +++ b/package/src/utils/queryMembers.ts @@ -4,31 +4,18 @@ import type { Channel, ChannelMemberAPIResponse, StreamChat, User } from 'stream import { defaultAutoCompleteSuggestionsLimit } from './constants'; import type { SuggestionUser } from '../contexts/suggestionsContext/SuggestionsContext'; -import type { DefaultStreamChatGenerics } from '../types/types'; -const getMembers = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, -) => { +const getMembers = (channel: Channel) => { const members = channel.state.members; return members ? Object.values(members).map(({ user }) => user) : []; }; -const getWatchers = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, -) => { +const getWatchers = (channel: Channel) => { const watchers = channel.state.watchers; return watchers ? Object.values(watchers) : []; }; -export const getMembersAndWatchers = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - channel: Channel, -) => { +export const getMembersAndWatchers = (channel: Channel) => { const members = getMembers(channel); const watchers = getWatchers(channel); const users = [...members, ...watchers]; @@ -47,32 +34,24 @@ export const getMembersAndWatchers = < return uniqueUsers; }; -const isUserResponse = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - user: SuggestionUser | undefined, -): user is SuggestionUser => - (user as SuggestionUser) !== undefined; +const isUserResponse = (user: SuggestionUser | undefined): user is SuggestionUser => + (user as SuggestionUser) !== undefined; -export type QueryMembersFunction< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = ( - client: StreamChat, - channel: Channel, - query: SuggestionUser['name'], - onReady?: (users: SuggestionUser[]) => void, +export type QueryMembersFunction = ( + client: StreamChat, + channel: Channel, + query: SuggestionUser['name'], + onReady?: (users: SuggestionUser[]) => void, options?: { limit?: number; }, ) => Promise; -const queryMembers = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - client: StreamChat, - channel: Channel, - query: SuggestionUser['name'], - onReady?: (users: SuggestionUser[]) => void, +const queryMembers = async ( + client: StreamChat, + channel: Channel, + query: SuggestionUser['name'], + onReady?: (users: SuggestionUser[]) => void, options: { limit?: number; } = {}, @@ -89,9 +68,9 @@ const queryMembers = async < }, {}, { limit }, - )) as ChannelMemberAPIResponse; + )) as ChannelMemberAPIResponse; - const users: SuggestionUser[] = []; + const users: SuggestionUser[] = []; members .filter((member) => member.user?.id !== client.userID) .forEach((member) => isUserResponse(member.user) && users.push(member.user)); diff --git a/package/src/utils/queryUsers.ts b/package/src/utils/queryUsers.ts index 0bab70b890..0a1048db10 100644 --- a/package/src/utils/queryUsers.ts +++ b/package/src/utils/queryUsers.ts @@ -5,29 +5,24 @@ import { defaultAutoCompleteSuggestionsLimit, defaultMentionAllAppUsersQuery } f import type { MentionAllAppUsersQuery } from '../contexts/messageInputContext/MessageInputContext'; import type { SuggestionUser } from '../contexts/suggestionsContext/SuggestionsContext'; -import type { DefaultStreamChatGenerics } from '../types/types'; -export type QueryUsersFunction< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, -> = ( - client: StreamChat, - query: SuggestionUser['name'], - onReady?: (users: SuggestionUser[]) => void, +export type QueryUsersFunction = ( + client: StreamChat, + query: SuggestionUser['name'], + onReady?: (users: SuggestionUser[]) => void, options?: { limit?: number; - mentionAllAppUsersQuery?: MentionAllAppUsersQuery; + mentionAllAppUsersQuery?: MentionAllAppUsersQuery; }, ) => Promise; -const queryUsers = async < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - client: StreamChat, - query: SuggestionUser['name'], - onReady?: (users: SuggestionUser[]) => void, +const queryUsers = async ( + client: StreamChat, + query: SuggestionUser['name'], + onReady?: (users: SuggestionUser[]) => void, options: { limit?: number; - mentionAllAppUsersQuery?: MentionAllAppUsersQuery; + mentionAllAppUsersQuery?: MentionAllAppUsersQuery; } = {}, ): Promise => { if (!query) { diff --git a/package/src/utils/removeReactionFromLocalState.ts b/package/src/utils/removeReactionFromLocalState.ts index e7ffa754f3..b5cdba3913 100644 --- a/package/src/utils/removeReactionFromLocalState.ts +++ b/package/src/utils/removeReactionFromLocalState.ts @@ -2,20 +2,16 @@ import type { Channel, UserResponse } from 'stream-chat'; import { deleteReaction } from '../store/apis/deleteReaction'; -import type { DefaultStreamChatGenerics } from '../types/types'; - -export const removeReactionFromLocalState = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ +export const removeReactionFromLocalState = ({ channel, messageId, reactionType, user, }: { - channel: Channel; + channel: Channel; messageId: string; reactionType: string; - user: UserResponse; + user: UserResponse; }) => { const message = channel.state.messages.find(({ id }) => id === messageId); if (!message || !channel?.id || !user?.id) { diff --git a/package/src/utils/removeReservedFields.ts b/package/src/utils/removeReservedFields.ts index 1e8d580fbe..c2be8c6d2e 100644 --- a/package/src/utils/removeReservedFields.ts +++ b/package/src/utils/removeReservedFields.ts @@ -1,13 +1,10 @@ import type { MessageResponse } from 'stream-chat'; import type { MessageType } from '../components/MessageList/hooks/useMessageList'; -import type { DefaultStreamChatGenerics } from '../types/types'; -export const removeReservedFields = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - message: MessageType | MessageResponse, -): MessageType | MessageResponse => { +export const removeReservedFields = ( + message: MessageType | MessageResponse, +): MessageType | MessageResponse => { const retryMessage = { ...message }; const reserved = [ 'cid', @@ -26,7 +23,8 @@ export const removeReservedFields = < 'type', 'updated_at', 'reply_count', - ]; + ] as (keyof typeof message)[]; + reserved.forEach((key) => { delete retryMessage[key]; }); diff --git a/package/src/utils/utils.ts b/package/src/utils/utils.ts index 2da02867d3..684bdae3f4 100644 --- a/package/src/utils/utils.ts +++ b/package/src/utils/utils.ts @@ -5,11 +5,14 @@ import EmojiRegex from 'emoji-regex'; import type { ChannelState, FormatMessageResponse, MessageResponse } from 'stream-chat'; import { IconProps } from '../../src/icons/utils/base'; -import { MessageType } from '../components/MessageList/hooks/useMessageList'; +import { + MessagesWithStylesReadByAndDateSeparator, + MessageType, +} from '../components/MessageList/hooks/useMessageList'; import type { EmojiSearchIndex } from '../contexts/messageInputContext/MessageInputContext'; import { compiledEmojis } from '../emoji-data'; import type { TableRowJoinedUser } from '../store/types'; -import type { DefaultStreamChatGenerics, ValueOf } from '../types/types'; +import type { ValueOf } from '../types/types'; export type ReactionData = { Icon: React.ComponentType; @@ -75,11 +78,7 @@ export const getIndicatorTypeForFileState = ( * @param message * @returns boolean */ -export const isBlockedMessage = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - message: MessageType | TableRowJoinedUser<'messages'>, -) => { +export const isBlockedMessage = (message: MessageType | TableRowJoinedUser<'messages'>) => { // The only indicator for the blocked message is its message type is error and that the message text contains "Message was blocked by moderation policies". const pattern = /\bMessage was blocked by moderation policies\b/; return message.type === 'error' && message.text && pattern.test(message.text); @@ -90,11 +89,7 @@ export const isBlockedMessage = < * @param message * @returns boolean */ -export const isBouncedMessage = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - message: MessageType, -) => +export const isBouncedMessage = (message: MessageType) => (message.type === 'error' && message?.moderation_details?.action === 'MESSAGE_RESPONSE_ACTION_BOUNCE') || message?.moderation?.action === 'bounce'; @@ -104,11 +99,7 @@ export const isBouncedMessage = < * @param message * @returns boolean */ -export const isEditedMessage = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - message: MessageType, -) => !!message.message_text_updated_at && !message.ai_generated; +export const isEditedMessage = (message: MessageType) => !!message.message_text_updated_at; /** * Default emoji search index for auto complete text input @@ -196,27 +187,25 @@ export const hasOnlyEmojis = (text: string) => { /** * Stringifies a message object - * @param {FormatMessageResponse} message - the message object to be stringified + * @param {FormatMessageResponse} message - the message object to be stringified * @returns {string} The stringified message */ -export const stringifyMessage = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->({ - deleted_at, - i18n, - latest_reactions, - reaction_groups, - readBy, - reply_count, - status, - text, - type, - updated_at, -}: - | MessageResponse - | FormatMessageResponse - | MessageType): string => - `${ +export const stringifyMessage = ( + message: MessageResponse | FormatMessageResponse | MessageType, +): string => { + const { + deleted_at, + i18n, + latest_reactions, + reaction_groups, + reply_count, + status, + text, + type, + updated_at, + } = message; + const readBy = (message as MessagesWithStylesReadByAndDateSeparator)?.readBy ?? ''; + return `${ latest_reactions ? latest_reactions.map(({ type, user }) => `${type}${user?.id}`).join() : '' }${ reaction_groups @@ -228,17 +217,15 @@ export const stringifyMessage = < .join() : '' }${type}${deleted_at}${text}${readBy}${reply_count}${status}${updated_at}${JSON.stringify(i18n)}`; +}; /** * Reduces a list of messages to strings that are used in useEffect & useMemo * @param {messages} messages - the array of messages to be compared * @returns {string} The mapped message string */ -export const reduceMessagesToString = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - messages: FormatMessageResponse[], -): string => messages.map(stringifyMessage).join(); +export const reduceMessagesToString = (messages: FormatMessageResponse[]): string => + messages.map(stringifyMessage).join(); /** * Utility to get the file name from the path using regex. @@ -288,12 +275,7 @@ export function escapeRegExp(text: string) { * @param targetId * @returns number */ -export const findInMessagesById = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - messages: ChannelState['messages'], - targetId: string, -) => { +export const findInMessagesById = (messages: ChannelState['messages'], targetId: string) => { const idx = messages.findIndex((message) => message.id === targetId); return idx; }; @@ -304,10 +286,8 @@ export const findInMessagesById = < * @param targetDate * @returns an object with the index and the message object */ -export const findInMessagesByDate = < - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, ->( - messages: MessageResponse[] | ChannelState['messages'], +export const findInMessagesByDate = ( + messages: MessageResponse[] | ChannelState['messages'], targetDate: Date, ) => { // Binary search diff --git a/package/yarn.lock b/package/yarn.lock index ea60d8a08a..6b976cd60a 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -1056,7 +1056,7 @@ pirates "^4.0.6" source-map-support "^0.5.16" -"@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.23.2", "@babel/runtime@^7.25.0", "@babel/runtime@^7.26.9", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.17.2", "@babel/runtime@^7.23.2", "@babel/runtime@^7.25.0", "@babel/runtime@^7.26.9", "@babel/runtime@^7.8.4": version "7.26.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.9.tgz#aa4c6facc65b9cb3f87d75125ffd47781b475433" integrity sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg== @@ -1983,7 +1983,7 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/jsonwebtoken@~9.0.0": +"@types/jsonwebtoken@^9.0.8": version "9.0.9" resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3" integrity sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ== @@ -2081,10 +2081,10 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-10.0.0.tgz#e9c07fe50da0f53dc24970cca94d619ff03f6f6d" integrity sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ== -"@types/ws@^7.4.0": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== +"@types/ws@^8.5.14": + version "8.18.0" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" + integrity sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw== dependencies: "@types/node" "*" @@ -5027,10 +5027,10 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== +isomorphic-ws@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" @@ -5567,7 +5567,7 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonwebtoken@~9.0.0: +jsonwebtoken@^9.0.2: version "9.0.2" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== @@ -7680,20 +7680,19 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat@^8.57.6: - version "8.57.6" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.57.6.tgz#dd3a4a0a024ee44bfa6ae7ca15648e6c9f2e498f" - integrity sha512-+zkC5DtxvdkEBAv7dCzzO4WWosjaM15EjsH3q4xD1nX/yf2qT6BMhPJguM+CUWxwlFh32X0KR+ARtD0ChPqtnA== +stream-chat@9.0.0-rc.4: + version "9.0.0-rc.4" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.4.tgz#30ffd324069cd012372014efe3a6d94bf264963a" + integrity sha512-kVlDls6TXEWAlAQf6WLwNv3wDwVo0y9J536+NS8PFmkJKkBNfD9RGAbb4SuZNxeEpd+kAy3861vxspB1mpFEmQ== dependencies: - "@babel/runtime" "^7.16.3" - "@types/jsonwebtoken" "~9.0.0" - "@types/ws" "^7.4.0" + "@types/jsonwebtoken" "^9.0.8" + "@types/ws" "^8.5.14" axios "^1.6.0" base64-js "^1.5.1" form-data "^4.0.0" - isomorphic-ws "^4.0.1" - jsonwebtoken "~9.0.0" - ws "^7.5.10" + isomorphic-ws "^5.0.0" + jsonwebtoken "^9.0.2" + ws "^8.18.1" stream-composer@^1.0.2: version "1.0.2" @@ -8448,6 +8447,11 @@ ws@^7, ws@^7.5.10: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== +ws@^8.18.1: + version "8.18.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" + integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== + xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" From 4e6c4b76053567039850f8d6a5397a26a5044598 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj <31964049+isekovanic@users.noreply.github.com> Date: Fri, 7 Mar 2025 17:10:09 +0100 Subject: [PATCH 03/60] chore: remove support for react-native-document-picker (#3000) --- package/native-package/package.json | 4 --- .../src/optionalDependencies/pickDocument.ts | 27 +++---------------- 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/package/native-package/package.json b/package/native-package/package.json index 1ff4600b5e..54d86fcbba 100644 --- a/package/native-package/package.json +++ b/package/native-package/package.json @@ -29,7 +29,6 @@ "react-native": ">=0.67.0", "react-native-audio-recorder-player": ">=3.6.4", "react-native-blob-util": ">=0.19.9", - "react-native-document-picker": ">=9.3.0", "@react-native-documents/picker": ">=10.1.1", "react-native-haptic-feedback": ">=2.2.0", "react-native-image-picker": ">=7.1.2", @@ -49,9 +48,6 @@ "react-native-share": { "optional": true }, - "react-native-document-picker": { - "optional": true - }, "@react-native-documents/picker": { "optional": true }, diff --git a/package/native-package/src/optionalDependencies/pickDocument.ts b/package/native-package/src/optionalDependencies/pickDocument.ts index a0bab9279b..3ed801cec4 100644 --- a/package/native-package/src/optionalDependencies/pickDocument.ts +++ b/package/native-package/src/optionalDependencies/pickDocument.ts @@ -1,7 +1,7 @@ /** * Types are approximated from what we need from the DocumentPicker API. * - * For its full API, see https://github.com/rnmods/react-native-document-picker/blob/master/src/index.tsx + * For its full API, see https://github.com/react-native-documents/document-picker/blob/main/packages/document-picker/src/index.ts * */ type ResponseValue = { name: string; @@ -19,31 +19,12 @@ type DocumentPickerType = let DocumentPicker: DocumentPickerType; -let OldDocumentPicker: DocumentPickerType; -let NewDocumentPicker: DocumentPickerType; - -try { - NewDocumentPicker = require('@react-native-documents/picker'); -} catch (err) { - // we log below -} - try { - OldDocumentPicker = require('react-native-document-picker').default; + DocumentPicker = require('@react-native-documents/picker'); } catch (err) { - // we log below -} - -if (NewDocumentPicker) { - DocumentPicker = NewDocumentPicker; -} else if (OldDocumentPicker) { - DocumentPicker = OldDocumentPicker; - console.log( - "You're using the react-native-document-picker library, which is no longer supported and has moved to @react-native-documents/picker. Things might not work as intended. Please migrate to the new library as soon as possible !", - ); -} else { + // do nothing console.log( - 'Neither react-native-document-picker nor @react-native-documents/picker are installed.', + 'The @react-native-documents/picker is not installed. Installing it will enable you to pick and upload files from within your app.', ); } From 74a3978dd47ca307a3dd0e0ddd1349aff41ddffd Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Mon, 10 Mar 2025 17:25:24 +0100 Subject: [PATCH 04/60] BREAKING CHANGE: V7 release candidate --- .github/workflows/next-release.yml | 1 + .github/workflows/sdk-size-metrics.yml | 1 + release/release.config.js | 1 + 3 files changed, 3 insertions(+) diff --git a/.github/workflows/next-release.yml b/.github/workflows/next-release.yml index bf775df999..132ed96414 100644 --- a/.github/workflows/next-release.yml +++ b/.github/workflows/next-release.yml @@ -4,6 +4,7 @@ on: push: branches: - develop + - V7 jobs: publish-next: diff --git a/.github/workflows/sdk-size-metrics.yml b/.github/workflows/sdk-size-metrics.yml index 4a81c96d3f..dd99ca3686 100644 --- a/.github/workflows/sdk-size-metrics.yml +++ b/.github/workflows/sdk-size-metrics.yml @@ -9,6 +9,7 @@ on: branches: - develop - main + - V7 env: HOMEBREW_NO_INSTALL_CLEANUP: 1 # Disable cleanup for homebrew, we don't need it on CI diff --git a/release/release.config.js b/release/release.config.js index 57400db19a..2288f09105 100644 --- a/release/release.config.js +++ b/release/release.config.js @@ -82,6 +82,7 @@ module.exports = Promise.resolve().then(() => { const lernaPackage = require('../lerna.json'); return { + dryRun: true, extends: [`${__dirname}/monorepo-setup.js`], workspaces: lernaPackage.packages, filterPath: process.env.FILTER_PATH, From f519f8a29b1957cbb8c86a5fd0b574486341a291 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Mon, 10 Mar 2025 17:36:59 +0100 Subject: [PATCH 05/60] chore: add rc channel --- release/next.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/release/next.js b/release/next.js index 8d7eed4a4d..842284bc97 100644 --- a/release/next.js +++ b/release/next.js @@ -12,7 +12,12 @@ configPromise.then((config) => { name: 'develop', channel: 'beta', prerelease: 'beta', - } + }, + { + name: 'v7', + channel: 'rc', + prerelease: 'rc', + }, ], }).then((result) => { // This logics avoid a overflow of next tags in github by removing the last From f3599099fbf58f28977b05d4a14704d10a53a278 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Mon, 10 Mar 2025 17:43:58 +0100 Subject: [PATCH 06/60] fix: typo in branch name --- release/next.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/next.js b/release/next.js index 842284bc97..a2905ceeb5 100644 --- a/release/next.js +++ b/release/next.js @@ -14,7 +14,7 @@ configPromise.then((config) => { prerelease: 'beta', }, { - name: 'v7', + name: 'V7', channel: 'rc', prerelease: 'rc', }, From aca5620aee8a2a05f046e0d43656b3a644641b6a Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj <31964049+isekovanic@users.noreply.github.com> Date: Mon, 10 Mar 2025 17:56:36 +0100 Subject: [PATCH 07/60] feat: trigger breaking change for v7 (#3005) BREAKING CHANGE: Release V7 --- package/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/package/CHANGELOG.md b/package/CHANGELOG.md index b0a980aa7f..fc05ca8308 100644 --- a/package/CHANGELOG.md +++ b/package/CHANGELOG.md @@ -343,6 +343,7 @@ ### [5.39.3](https://github.com/GetStream/stream-chat-react-native/compare/v5.39.2...v5.39.3) (2024-10-15) + ### Bug Fixes - ChannelAvatar crash when used outside of ChannelList ([#2708](https://github.com/GetStream/stream-chat-react-native/issues/2708)) ([85f4ab2](https://github.com/GetStream/stream-chat-react-native/commit/85f4ab21adf4b0da636475f0285e3360d9b1309b)) From dfbdcb32da97a9765c1c5754b814291d0a4e29c8 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Mon, 10 Mar 2025 18:06:01 +0100 Subject: [PATCH 08/60] chore: remove dryRun --- release/release.config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/release/release.config.js b/release/release.config.js index 2288f09105..57400db19a 100644 --- a/release/release.config.js +++ b/release/release.config.js @@ -82,7 +82,6 @@ module.exports = Promise.resolve().then(() => { const lernaPackage = require('../lerna.json'); return { - dryRun: true, extends: [`${__dirname}/monorepo-setup.js`], workspaces: lernaPackage.packages, filterPath: process.env.FILTER_PATH, From 7243093eae07a3f42526bb1a31b8f471a42d983a Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Mon, 10 Mar 2025 18:43:02 +0100 Subject: [PATCH 09/60] chore: bump stream-chat version to latest rc --- package/package.json | 2 +- package/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package/package.json b/package/package.json index ca3186e7db..5baef6872e 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "9.0.0-rc.4", + "stream-chat": "9.0.0-rc.6", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/yarn.lock b/package/yarn.lock index 6b976cd60a..056fec9f00 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -7680,10 +7680,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat@9.0.0-rc.4: - version "9.0.0-rc.4" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.4.tgz#30ffd324069cd012372014efe3a6d94bf264963a" - integrity sha512-kVlDls6TXEWAlAQf6WLwNv3wDwVo0y9J536+NS8PFmkJKkBNfD9RGAbb4SuZNxeEpd+kAy3861vxspB1mpFEmQ== +stream-chat@9.0.0-rc.6: + version "9.0.0-rc.6" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.6.tgz#8c226a689367f4813edacc035d05697463c580c1" + integrity sha512-z4l1ngKMPCuOhSopFY+SFhBNWN8lr85IXBP2Ob2eNIC+6AE3CQ0ofc16O0h6Jk3bKLzY+EL7//XuPAbqPkoRiA== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" From 1f840647ffc2939a06e11963108ac72d374076d7 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 11 Mar 2025 11:48:23 +0100 Subject: [PATCH 10/60] chore: bump stream-chat to latest --- package/package.json | 2 +- package/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package/package.json b/package/package.json index 5baef6872e..8a89c80846 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "9.0.0-rc.6", + "stream-chat": "9.0.0-rc.7", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/yarn.lock b/package/yarn.lock index 056fec9f00..a7b5ea96e9 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -7680,10 +7680,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat@9.0.0-rc.6: - version "9.0.0-rc.6" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.6.tgz#8c226a689367f4813edacc035d05697463c580c1" - integrity sha512-z4l1ngKMPCuOhSopFY+SFhBNWN8lr85IXBP2Ob2eNIC+6AE3CQ0ofc16O0h6Jk3bKLzY+EL7//XuPAbqPkoRiA== +stream-chat@9.0.0-rc.7: + version "9.0.0-rc.7" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.7.tgz#c2c1ab17cda9c55a0068720164228b3d92852db7" + integrity sha512-hvwilti9vqEGBnD8v81/4s1IOgOKmzG+d/49BDGzrwUl8M2yDLvIWd93Xo4gj/+0edEgcOVaW4gncenEqXVR9A== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" From 228d55979e77dfcc1146f6554000126cdc0041d4 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj <31964049+isekovanic@users.noreply.github.com> Date: Wed, 12 Mar 2025 12:39:29 +0100 Subject: [PATCH 11/60] feat: introduce expo-video support (#3010) * feat: introduce support for expo-video * fix: remove redundant test * fix: add check for audio component --- examples/ExpoMessaging/app.json | 7 ++ examples/ExpoMessaging/package.json | 1 + examples/ExpoMessaging/yarn.lock | 13 ++-- examples/SampleApp/yarn.lock | 8 +-- package/expo-package/package.json | 6 +- .../src/optionalDependencies/AudioVideo.ts | 8 +-- .../src/optionalDependencies/Video.tsx | 69 ++++++++++++++---- package/expo-package/yarn.lock | 8 +-- package/native-package/package.json | 2 +- package/native-package/yarn.lock | 8 +-- .../components/ImageGallery/ImageGallery.tsx | 8 +++ .../__tests__/AnimatedVideoGallery.test.tsx | 72 ------------------- .../components/AnimatedGalleryVideo.tsx | 33 --------- .../components/ImageGalleryVideoControl.tsx | 6 +- package/src/native.ts | 3 + 15 files changed, 109 insertions(+), 143 deletions(-) diff --git a/examples/ExpoMessaging/app.json b/examples/ExpoMessaging/app.json index 4e9029e1df..e8dafe9cd7 100644 --- a/examples/ExpoMessaging/app.json +++ b/examples/ExpoMessaging/app.json @@ -48,6 +48,13 @@ { "microphonePermission": "$(PRODUCT_NAME) would like to use your microphone for voice recording." } + ], + [ + "expo-video", + { + "supportsBackgroundPlayback": true, + "supportsPictureInPicture": true + } ] ] } diff --git a/examples/ExpoMessaging/package.json b/examples/ExpoMessaging/package.json index 34a3a68621..98c2a59624 100644 --- a/examples/ExpoMessaging/package.json +++ b/examples/ExpoMessaging/package.json @@ -28,6 +28,7 @@ "expo-sharing": "~13.0.1", "expo-splash-screen": "~0.29.22", "expo-status-bar": "~2.0.1", + "expo-video": "^2.0.5", "react": "18.3.1", "react-dom": "18.3.1", "react-native": "0.77.1", diff --git a/examples/ExpoMessaging/yarn.lock b/examples/ExpoMessaging/yarn.lock index 0b8c9da5fe..80f64e229b 100644 --- a/examples/ExpoMessaging/yarn.lock +++ b/examples/ExpoMessaging/yarn.lock @@ -4363,6 +4363,11 @@ expo-status-bar@~2.0.1: resolved "https://registry.yarnpkg.com/expo-status-bar/-/expo-status-bar-2.0.1.tgz#fc07726346dc30fbb68aadb0d7890b34fba42eee" integrity sha512-AkIPX7jWHRPp83UBZ1iXtVvyr0g+DgBVvIXTtlmPtmUsm8Vq9Bb5IGj86PW8osuFlgoTVAg7HI/+Ok7yEYwiRg== +expo-video@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/expo-video/-/expo-video-2.0.5.tgz#5c5311b0a20dcb7897d06cd4f9d7fb0ce13711d9" + integrity sha512-K5Q4bFKtYq0wEC38mckWUYeaTXsmhl6duidhSdbA63VBy6cwxDOk8uPsFPTQD3FXKJg6wFB0z8ZUASSPuUaY5A== + expo@~52.0.36: version "52.0.37" resolved "https://registry.yarnpkg.com/expo/-/expo-52.0.37.tgz#159b5f3f9bedb2c56b36a815b8679a2602a406cc" @@ -7397,10 +7402,10 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.4: - version "9.0.0-rc.4" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.4.tgz#30ffd324069cd012372014efe3a6d94bf264963a" - integrity sha512-kVlDls6TXEWAlAQf6WLwNv3wDwVo0y9J536+NS8PFmkJKkBNfD9RGAbb4SuZNxeEpd+kAy3861vxspB1mpFEmQ== +stream-chat@9.0.0-rc.7: + version "9.0.0-rc.7" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.7.tgz#c2c1ab17cda9c55a0068720164228b3d92852db7" + integrity sha512-hvwilti9vqEGBnD8v81/4s1IOgOKmzG+d/49BDGzrwUl8M2yDLvIWd93Xo4gj/+0edEgcOVaW4gncenEqXVR9A== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index 5ab94d949a..dbf373fae6 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -7538,10 +7538,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.4: - version "9.0.0-rc.4" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.4.tgz#30ffd324069cd012372014efe3a6d94bf264963a" - integrity sha512-kVlDls6TXEWAlAQf6WLwNv3wDwVo0y9J536+NS8PFmkJKkBNfD9RGAbb4SuZNxeEpd+kAy3861vxspB1mpFEmQ== +stream-chat@9.0.0-rc.7: + version "9.0.0-rc.7" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.7.tgz#c2c1ab17cda9c55a0068720164228b3d92852db7" + integrity sha512-hvwilti9vqEGBnD8v81/4s1IOgOKmzG+d/49BDGzrwUl8M2yDLvIWd93Xo4gj/+0edEgcOVaW4gncenEqXVR9A== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/expo-package/package.json b/package/expo-package/package.json index 280e123587..8650264f5e 100644 --- a/package/expo-package/package.json +++ b/package/expo-package/package.json @@ -10,11 +10,12 @@ "main": "src/index.js", "types": "types/index.d.ts", "dependencies": { - "stream-chat-react-native-core": "6.6.7" + "stream-chat-react-native-core": "link:../" }, "peerDependencies": { "expo": ">=51.0.0", "expo-av": "*", + "expo-video": "*", "expo-clipboard": "*", "expo-document-picker": "*", "expo-file-system": "*", @@ -28,6 +29,9 @@ "expo-av": { "optional": true }, + "expo-video": { + "optional": true + }, "expo-clipboard": { "optional": true }, diff --git a/package/expo-package/src/optionalDependencies/AudioVideo.ts b/package/expo-package/src/optionalDependencies/AudioVideo.ts index 4505c97b69..486a47842f 100644 --- a/package/expo-package/src/optionalDependencies/AudioVideo.ts +++ b/package/expo-package/src/optionalDependencies/AudioVideo.ts @@ -1,19 +1,17 @@ -let VideoComponent; let AudioComponent; let RecordingObject; try { const audioVideoPackage = require('expo-av'); - VideoComponent = audioVideoPackage.Video; AudioComponent = audioVideoPackage.Audio; RecordingObject = audioVideoPackage.RecordingObject; } catch (e) { // do nothing } -if (!VideoComponent || !AudioComponent) { +if (!AudioComponent) { console.log( - 'Audio Video library is currently not installed. To allow in-app audio or video playback, install the "expo-av" package.', + 'Audio Video library is currently not installed. To allow in-app audio playback, install the "expo-av" package.', ); } -export { AudioComponent, VideoComponent, RecordingObject }; +export { AudioComponent, RecordingObject }; diff --git a/package/expo-package/src/optionalDependencies/Video.tsx b/package/expo-package/src/optionalDependencies/Video.tsx index ee56a3da2e..28876d528d 100644 --- a/package/expo-package/src/optionalDependencies/Video.tsx +++ b/package/expo-package/src/optionalDependencies/Video.tsx @@ -1,28 +1,71 @@ import React, { useEffect } from 'react'; -import { AudioComponent, VideoComponent } from './AudioVideo'; +import { useEventListener } from 'expo'; + +import { AudioComponent } from './AudioVideo'; + +let videoPackage; + +try { + videoPackage = require('expo-video'); +} catch (e) { + // do nothing +} + +if (!videoPackage) { + console.log( + 'The video library is currently not installed. To allow in-app video playback, install the "expo-video" package.', + ); +} + +const VideoComponent = videoPackage ? videoPackage.VideoView : null; +const useVideoPlayer = videoPackage ? videoPackage.useVideoPlayer : null; + +export const Video = videoPackage + ? ({ onLoadStart, onLoad, onEnd, onProgress, onBuffer, resizeMode, style, uri, videoRef }) => { + const player = useVideoPlayer(uri, (player) => { + player.timeUpdateEventInterval = 0.5; + videoRef.current = player; + }); + + useEventListener(player, 'statusChange', ({ status, oldStatus }) => { + if ((!oldStatus || oldStatus === 'idle') && status === 'loading') { + onLoadStart(); + } else if ((oldStatus === 'loading' || oldStatus === 'idle') && status === 'readyToPlay') { + onLoad({ duration: player.duration }); + onBuffer({ buffering: false }); + } else if (oldStatus === 'readyToPlay' && status === 'loading') { + onBuffer({ buffering: true }); + } + }); + + useEventListener(player, 'playToEnd', () => { + player.replay(); + onEnd(); + }); + + useEventListener(player, 'timeUpdate', ({ currentTime }) => + onProgress({ currentTime, seekableDuration: player.duration }), + ); -export const Video = VideoComponent - ? ({ onPlaybackStatusUpdate, paused, resizeMode, style, uri, videoRef }) => { // This is done so that the audio of the video is not muted when the phone is in silent mode for iOS. useEffect(() => { const initializeSound = async () => { - await AudioComponent.setAudioModeAsync({ - playsInSilentModeIOS: true, - }); + if (AudioComponent) { + await AudioComponent.setAudioModeAsync({ + playsInSilentModeIOS: true, + }); + } }; initializeSound(); }, []); return ( ); diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 11508bdd3a..4487dac896 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -4772,10 +4772,10 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.4: - version "9.0.0-rc.4" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.4.tgz#30ffd324069cd012372014efe3a6d94bf264963a" - integrity sha512-kVlDls6TXEWAlAQf6WLwNv3wDwVo0y9J536+NS8PFmkJKkBNfD9RGAbb4SuZNxeEpd+kAy3861vxspB1mpFEmQ== +stream-chat@9.0.0-rc.7: + version "9.0.0-rc.7" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.7.tgz#c2c1ab17cda9c55a0068720164228b3d92852db7" + integrity sha512-hvwilti9vqEGBnD8v81/4s1IOgOKmzG+d/49BDGzrwUl8M2yDLvIWd93Xo4gj/+0edEgcOVaW4gncenEqXVR9A== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/native-package/package.json b/package/native-package/package.json index 54d86fcbba..3ebcc27956 100644 --- a/package/native-package/package.json +++ b/package/native-package/package.json @@ -20,7 +20,7 @@ "types": "types/index.d.ts", "dependencies": { "es6-symbol": "^3.1.3", - "stream-chat-react-native-core": "6.6.7" + "stream-chat-react-native-core": "link:../" }, "peerDependencies": { "@react-native-camera-roll/camera-roll": ">=7.8.0", diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index a2084c513a..a6cd9f4090 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -3444,10 +3444,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.4: - version "9.0.0-rc.4" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.4.tgz#30ffd324069cd012372014efe3a6d94bf264963a" - integrity sha512-kVlDls6TXEWAlAQf6WLwNv3wDwVo0y9J536+NS8PFmkJKkBNfD9RGAbb4SuZNxeEpd+kAy3861vxspB1mpFEmQ== +stream-chat@9.0.0-rc.7: + version "9.0.0-rc.7" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.7.tgz#c2c1ab17cda9c55a0068720164228b3d92852db7" + integrity sha512-hvwilti9vqEGBnD8v81/4s1IOgOKmzG+d/49BDGzrwUl8M2yDLvIWd93Xo4gj/+0edEgcOVaW4gncenEqXVR9A== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/src/components/ImageGallery/ImageGallery.tsx b/package/src/components/ImageGallery/ImageGallery.tsx index f9242e1b6f..f9e5945203 100644 --- a/package/src/components/ImageGallery/ImageGallery.tsx +++ b/package/src/components/ImageGallery/ImageGallery.tsx @@ -472,6 +472,10 @@ export const ImageGallery = (props: Props) => { paused: imageGalleryAttachment.id === index ? false : true, })), ); + + if (videoRef.current?.play) { + videoRef.current.play(); + } } else { // If the status is true we simply set all the audio's paused state as true. setImageGalleryAttachments((prevImageGalleryAttachment) => @@ -480,6 +484,10 @@ export const ImageGallery = (props: Props) => { paused: true, })), ); + + if (videoRef.current?.pause) { + videoRef.current.pause(); + } } }; diff --git a/package/src/components/ImageGallery/__tests__/AnimatedVideoGallery.test.tsx b/package/src/components/ImageGallery/__tests__/AnimatedVideoGallery.test.tsx index f3673201ce..8a055d8fdd 100644 --- a/package/src/components/ImageGallery/__tests__/AnimatedVideoGallery.test.tsx +++ b/package/src/components/ImageGallery/__tests__/AnimatedVideoGallery.test.tsx @@ -155,76 +155,4 @@ describe('ImageGallery', () => { expect(spinnerComponent?.props.style[1].opacity).toBe(1); }); - - it('trigger onPlaybackStatusUpdate event handler of Video component', () => { - jest.spyOn(console, 'error'); - const handleLoadMock = jest.fn(); - const handleProgressMock = jest.fn(); - const handleEndMock = jest.fn(); - - render( - getComponent({ - handleEnd: handleEndMock, - handleLoad: handleLoadMock, - handleProgress: handleProgressMock, - offsetScale: { value: 1 } as SharedValue, - scale: { value: 1 } as SharedValue, - shouldRender: true, - source: { - uri: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', - }, - translateX: { value: 1 } as SharedValue, - }), - ); - - const videoComponent = screen.getByTestId('video-player'); - const spinnerComponent = screen.queryByLabelText('Spinner'); - - act(() => { - fireEvent(videoComponent, 'onPlaybackStatusUpdate', { - error: true, - isLoaded: false, - }); - }); - - expect(spinnerComponent?.props.style[1].opacity).toBe(1); - expect(console.error).toHaveBeenCalled(); - - act(() => { - fireEvent(videoComponent, 'onPlaybackStatusUpdate', { - isLoaded: true, - }); - }); - - expect(spinnerComponent?.props.style[1].opacity).toBe(0); - expect(handleLoadMock).toHaveBeenCalled(); - - act(() => { - fireEvent(videoComponent, 'onPlaybackStatusUpdate', { - isLoaded: true, - isPlaying: true, - }); - }); - - expect(handleProgressMock).toHaveBeenCalled(); - - act(() => { - fireEvent(videoComponent, 'onPlaybackStatusUpdate', { - isBuffering: true, - isLoaded: true, - }); - }); - - expect(spinnerComponent?.props.style[1].opacity).toBe(1); - - act(() => { - fireEvent(videoComponent, 'onPlaybackStatusUpdate', { - didJustFinish: true, - isLoaded: true, - isLooping: false, - }); - }); - - expect(handleEndMock).toHaveBeenCalled(); - }); }); diff --git a/package/src/components/ImageGallery/components/AnimatedGalleryVideo.tsx b/package/src/components/ImageGallery/components/AnimatedGalleryVideo.tsx index 32e98ab2da..62fa2149a9 100644 --- a/package/src/components/ImageGallery/components/AnimatedGalleryVideo.tsx +++ b/package/src/components/ImageGallery/components/AnimatedGalleryVideo.tsx @@ -5,7 +5,6 @@ import Animated, { SharedValue } from 'react-native-reanimated'; import { isVideoPlayerAvailable, - PlaybackStatus, Video, VideoPayloadData, VideoProgressData, @@ -98,37 +97,6 @@ export const AnimatedGalleryVideo = React.memo( } }; - const onPlayBackStatusUpdate = (playbackStatus: PlaybackStatus) => { - if (!playbackStatus.isLoaded) { - // Update your UI for the unloaded state - setOpacity(1); - if (playbackStatus.error) { - console.error(`Encountered a fatal error during playback: ${playbackStatus.error}`); - } - } else { - // Update your UI for the loaded state - setOpacity(0); - handleLoad(attachmentId, playbackStatus.durationMillis); - if (playbackStatus.isPlaying) { - // Update your UI for the playing state - handleProgress( - attachmentId, - playbackStatus.positionMillis / playbackStatus.durationMillis, - ); - } - - if (playbackStatus.isBuffering) { - // Update your UI for the buffering state - setOpacity(1); - } - - if (playbackStatus.didJustFinish && !playbackStatus.isLooping) { - // The player has just finished playing and will stop. Maybe you want to play something else? - handleEnd(); - } - } - }; - const animatedStyles = useAnimatedGalleryStyle({ index, offsetScale, @@ -162,7 +130,6 @@ export const AnimatedGalleryVideo = React.memo( onEnd={onEnd} onLoad={onLoad} onLoadStart={onLoadStart} - onPlaybackStatusUpdate={onPlayBackStatusUpdate} onProgress={onProgress} paused={paused} repeat={repeat} diff --git a/package/src/components/ImageGallery/components/ImageGalleryVideoControl.tsx b/package/src/components/ImageGallery/components/ImageGalleryVideoControl.tsx index 84efe99210..95c55fd937 100644 --- a/package/src/components/ImageGallery/components/ImageGalleryVideoControl.tsx +++ b/package/src/components/ImageGallery/components/ImageGalleryVideoControl.tsx @@ -60,10 +60,12 @@ export const ImageGalleryVideoControl = React.memo( } = useTheme(); const handlePlayPause = async () => { + // Note: Not particularly sure why this was ever added, but + // will keep it for now for backwards compatibility. if (progress === 1) { // For expo CLI - if (videoRef.current?.setPositionAsync) { - await videoRef.current.setPositionAsync(0); + if (videoRef.current?.replay) { + await videoRef.current.replay(); } } onPlayPause(); diff --git a/package/src/native.ts b/package/src/native.ts index 84b5b2a4d3..93f93cc8c5 100644 --- a/package/src/native.ts +++ b/package/src/native.ts @@ -288,6 +288,9 @@ export type VideoType = { seek?: (progress: number) => void; setPositionAsync?: (position: number) => void; style?: StyleProp; + play?: () => void; + pause?: () => void; + replay?: () => void; }; export let Video: React.ComponentType; From ad0dbc89e9115555a5419cdb6f1be33c20ef276b Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Wed, 12 Mar 2025 12:56:47 +0100 Subject: [PATCH 12/60] fix: lint issues --- .../ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts | 4 +--- .../src/components/ChannelPreview/hooks/useIsChannelMuted.ts | 5 +---- package/src/hooks/useTranslatedMessage.ts | 4 +--- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts b/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts index 05900ddcd0..379bbcba2a 100644 --- a/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts +++ b/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts @@ -8,9 +8,7 @@ import { useChatContext } from '../../../contexts/chatContext/ChatContext'; * * @returns {boolean} e.g., true */ -export const useChannelPreviewDisplayPresence = ( - channel: Channel, -) => { +export const useChannelPreviewDisplayPresence = (channel: Channel) => { const { client } = useChatContext(); const members = channel.state.members; const membersCount = Object.keys(members).length; diff --git a/package/src/components/ChannelPreview/hooks/useIsChannelMuted.ts b/package/src/components/ChannelPreview/hooks/useIsChannelMuted.ts index dadc1973fb..366271361b 100644 --- a/package/src/components/ChannelPreview/hooks/useIsChannelMuted.ts +++ b/package/src/components/ChannelPreview/hooks/useIsChannelMuted.ts @@ -4,16 +4,13 @@ import type { Channel } from 'stream-chat'; import { useChatContext } from '../../../contexts/chatContext/ChatContext'; - const defaultMuteStatus = { createdAt: null, expiresAt: null, muted: false, }; -export const useIsChannelMuted =( - channel: Channel, -) => { +export const useIsChannelMuted = (channel: Channel) => { const { client } = useChatContext(); const [muted, setMuted] = useState(() => channel.muteStatus()); diff --git a/package/src/hooks/useTranslatedMessage.ts b/package/src/hooks/useTranslatedMessage.ts index 206a47b7a8..ea7c113f56 100644 --- a/package/src/hooks/useTranslatedMessage.ts +++ b/package/src/hooks/useTranslatedMessage.ts @@ -4,9 +4,7 @@ import { useTranslationContext } from '../contexts/translationContext/Translatio type TranslationKey = `${TranslationLanguages}_text`; -export const useTranslatedMessage = ( - message?: MessageResponse | FormatMessageResponse, -) => { +export const useTranslatedMessage = (message?: MessageResponse | FormatMessageResponse) => { const { userLanguage } = useTranslationContext(); const translationKey: TranslationKey = `${userLanguage}_text`; From 35dc66e4950731e89de8854935964dece191a5bb Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Thu, 13 Mar 2025 11:18:19 +0100 Subject: [PATCH 13/60] fix: different types inference with latest stream-chat changes --- package/expo-package/yarn.lock | 8 ++++---- package/native-package/yarn.lock | 8 ++++---- package/package.json | 2 +- package/src/store/mappers/mapStorableToPoll.ts | 2 -- package/src/types/types.ts | 3 +-- package/yarn.lock | 8 ++++---- 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 4487dac896..0bda5364ca 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -4772,10 +4772,10 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.7: - version "9.0.0-rc.7" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.7.tgz#c2c1ab17cda9c55a0068720164228b3d92852db7" - integrity sha512-hvwilti9vqEGBnD8v81/4s1IOgOKmzG+d/49BDGzrwUl8M2yDLvIWd93Xo4gj/+0edEgcOVaW4gncenEqXVR9A== +stream-chat@9.0.0-rc.8: + version "9.0.0-rc.8" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.8.tgz#e188e481841493584691ae491916843d0ef5f9cd" + integrity sha512-P+Ksnu1cQQfL1t2/QTJ5rr/z2Jehvd2ap41xZgtfbJssHSD7ahe14TCF/1L7q4jjaNlZcTtLcKXCWbbOdKjDcg== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index a6cd9f4090..a13902278f 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -3444,10 +3444,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.7: - version "9.0.0-rc.7" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.7.tgz#c2c1ab17cda9c55a0068720164228b3d92852db7" - integrity sha512-hvwilti9vqEGBnD8v81/4s1IOgOKmzG+d/49BDGzrwUl8M2yDLvIWd93Xo4gj/+0edEgcOVaW4gncenEqXVR9A== +stream-chat@9.0.0-rc.8: + version "9.0.0-rc.8" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.8.tgz#e188e481841493584691ae491916843d0ef5f9cd" + integrity sha512-P+Ksnu1cQQfL1t2/QTJ5rr/z2Jehvd2ap41xZgtfbJssHSD7ahe14TCF/1L7q4jjaNlZcTtLcKXCWbbOdKjDcg== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/package.json b/package/package.json index 8a89c80846..c5d972a86e 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "9.0.0-rc.7", + "stream-chat": "9.0.0-rc.8", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/src/store/mappers/mapStorableToPoll.ts b/package/src/store/mappers/mapStorableToPoll.ts index b279350c8a..63a8eb7fc0 100644 --- a/package/src/store/mappers/mapStorableToPoll.ts +++ b/package/src/store/mappers/mapStorableToPoll.ts @@ -30,8 +30,6 @@ export const mapStorableToPoll = (pollRow: TableRow<'poll'>): PollResponse => { allow_answers, allow_user_suggested_options, answers_count, - // TODO: Investigate why this is now here, this is just a quickfix for now as we do not use it. - cid: '', created_at, created_by: JSON.parse(created_by), created_by_id, diff --git a/package/src/types/types.ts b/package/src/types/types.ts index 22606a3206..4b8d7ea321 100644 --- a/package/src/types/types.ts +++ b/package/src/types/types.ts @@ -65,9 +65,8 @@ export interface DefaultUserType { } export interface DefaultChannelType { - [key: string]: unknown; - image?: string; + name?: string; } export interface DefaultCommandType { diff --git a/package/yarn.lock b/package/yarn.lock index a7b5ea96e9..9c6c880a17 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -7680,10 +7680,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat@9.0.0-rc.7: - version "9.0.0-rc.7" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.7.tgz#c2c1ab17cda9c55a0068720164228b3d92852db7" - integrity sha512-hvwilti9vqEGBnD8v81/4s1IOgOKmzG+d/49BDGzrwUl8M2yDLvIWd93Xo4gj/+0edEgcOVaW4gncenEqXVR9A== +stream-chat@9.0.0-rc.8: + version "9.0.0-rc.8" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.8.tgz#e188e481841493584691ae491916843d0ef5f9cd" + integrity sha512-P+Ksnu1cQQfL1t2/QTJ5rr/z2Jehvd2ap41xZgtfbJssHSD7ahe14TCF/1L7q4jjaNlZcTtLcKXCWbbOdKjDcg== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" From a070115dae192a1a01ef6717b37c79b9179df11e Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Thu, 13 Mar 2025 11:30:06 +0100 Subject: [PATCH 14/60] chore(deps): update sample apps too --- examples/ExpoMessaging/yarn.lock | 8 ++++---- examples/SampleApp/ios/Podfile.lock | 6 +++--- examples/SampleApp/yarn.lock | 8 ++++---- examples/TypeScriptMessaging/yarn.lock | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/ExpoMessaging/yarn.lock b/examples/ExpoMessaging/yarn.lock index 80f64e229b..33622cec6e 100644 --- a/examples/ExpoMessaging/yarn.lock +++ b/examples/ExpoMessaging/yarn.lock @@ -7402,10 +7402,10 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.7: - version "9.0.0-rc.7" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.7.tgz#c2c1ab17cda9c55a0068720164228b3d92852db7" - integrity sha512-hvwilti9vqEGBnD8v81/4s1IOgOKmzG+d/49BDGzrwUl8M2yDLvIWd93Xo4gj/+0edEgcOVaW4gncenEqXVR9A== +stream-chat@9.0.0-rc.8: + version "9.0.0-rc.8" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.8.tgz#e188e481841493584691ae491916843d0ef5f9cd" + integrity sha512-P+Ksnu1cQQfL1t2/QTJ5rr/z2Jehvd2ap41xZgtfbJssHSD7ahe14TCF/1L7q4jjaNlZcTtLcKXCWbbOdKjDcg== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/examples/SampleApp/ios/Podfile.lock b/examples/SampleApp/ios/Podfile.lock index 047b8ed1e5..1b174153f1 100644 --- a/examples/SampleApp/ios/Podfile.lock +++ b/examples/SampleApp/ios/Podfile.lock @@ -2213,7 +2213,7 @@ PODS: - libwebp (~> 1.0) - SDWebImage/Core (~> 5.10) - SocketRocket (0.7.1) - - stream-chat-react-native (6.6.6): + - stream-chat-react-native (6.6.7): - DoubleConversion - glog - hermes-engine @@ -2637,9 +2637,9 @@ SPEC CHECKSUMS: SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - stream-chat-react-native: 3495d75137b4ded6b0cdf42395e89a484063c78f + stream-chat-react-native: 6b89c43ee042e7a6f00e6eaddf3228b712884846 Yoga: be02ca501b03c79d7027a6bbbd0a8db985034f11 PODFILE CHECKSUM: 4f662370295f8f9cee909f1a4c59a614999a209d -COCOAPODS: 1.14.3 +COCOAPODS: 1.16.2 diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index dbf373fae6..4c6031a89e 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -7538,10 +7538,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.7: - version "9.0.0-rc.7" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.7.tgz#c2c1ab17cda9c55a0068720164228b3d92852db7" - integrity sha512-hvwilti9vqEGBnD8v81/4s1IOgOKmzG+d/49BDGzrwUl8M2yDLvIWd93Xo4gj/+0edEgcOVaW4gncenEqXVR9A== +stream-chat@9.0.0-rc.8: + version "9.0.0-rc.8" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.8.tgz#e188e481841493584691ae491916843d0ef5f9cd" + integrity sha512-P+Ksnu1cQQfL1t2/QTJ5rr/z2Jehvd2ap41xZgtfbJssHSD7ahe14TCF/1L7q4jjaNlZcTtLcKXCWbbOdKjDcg== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/examples/TypeScriptMessaging/yarn.lock b/examples/TypeScriptMessaging/yarn.lock index 46c86fd953..4725572e1f 100644 --- a/examples/TypeScriptMessaging/yarn.lock +++ b/examples/TypeScriptMessaging/yarn.lock @@ -6929,10 +6929,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.4: - version "9.0.0-rc.4" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.4.tgz#30ffd324069cd012372014efe3a6d94bf264963a" - integrity sha512-kVlDls6TXEWAlAQf6WLwNv3wDwVo0y9J536+NS8PFmkJKkBNfD9RGAbb4SuZNxeEpd+kAy3861vxspB1mpFEmQ== +stream-chat@9.0.0-rc.8: + version "9.0.0-rc.8" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.8.tgz#e188e481841493584691ae491916843d0ef5f9cd" + integrity sha512-P+Ksnu1cQQfL1t2/QTJ5rr/z2Jehvd2ap41xZgtfbJssHSD7ahe14TCF/1L7q4jjaNlZcTtLcKXCWbbOdKjDcg== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" From 8ec76173a15304b563baae066e64b5441249f68f Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Thu, 13 Mar 2025 11:40:42 +0100 Subject: [PATCH 15/60] fix: remove generics from new hook --- package/src/hooks/useSyncClientEvents.ts | 35 ++++++++---------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/package/src/hooks/useSyncClientEvents.ts b/package/src/hooks/useSyncClientEvents.ts index 82d66207c3..7c3bcca5bf 100644 --- a/package/src/hooks/useSyncClientEvents.ts +++ b/package/src/hooks/useSyncClientEvents.ts @@ -3,40 +3,29 @@ import { useCallback } from 'react'; import type { Channel, EventTypes, StreamChat } from 'stream-chat'; import { useSyncExternalStore } from 'use-sync-external-store/shim'; -import { DefaultStreamChatGenerics } from '../types/types'; - const noop = () => {}; -export function useSyncClientEventsToChannel< - StreamChatGenerics extends DefaultStreamChatGenerics, - O, ->(_: { - channel: Channel; - client: StreamChat; - selector: (channel: Channel, client: StreamChat) => O; +export function useSyncClientEventsToChannel(_: { + channel: Channel; + client: StreamChat; + selector: (channel: Channel, client: StreamChat) => O; stateChangeEventKeys?: EventTypes[]; }): O; -export function useSyncClientEventsToChannel< - StreamChatGenerics extends DefaultStreamChatGenerics, - O, ->(_: { - selector: (channel: Channel, client: StreamChat) => O; - channel?: Channel | undefined; - client?: StreamChat | undefined; +export function useSyncClientEventsToChannel(_: { + selector: (channel: Channel, client: StreamChat) => O; + channel?: Channel | undefined; + client?: StreamChat | undefined; stateChangeEventKeys?: EventTypes[]; }): O | undefined; -export function useSyncClientEventsToChannel< - StreamChatGenerics extends DefaultStreamChatGenerics, - O, ->({ +export function useSyncClientEventsToChannel({ channel, client, selector, stateChangeEventKeys = ['all'], }: { - selector: (channel: Channel, client: StreamChat) => O; - channel?: Channel | undefined; - client?: StreamChat; + selector: (channel: Channel, client: StreamChat) => O; + channel?: Channel | undefined; + client?: StreamChat; stateChangeEventKeys?: EventTypes[]; }): O | undefined { const subscribe = useCallback( From e49b9c0df2a877ee83ed5a6ee8c4bd39543ea5aa Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Thu, 13 Mar 2025 11:44:50 +0100 Subject: [PATCH 16/60] fix: remove remnants from SCG and fix missing types --- .../useChannelPreviewDisplayName.test.tsx | 9 +-- .../useChannelPreviewDisplayPresence.test.tsx | 24 +++---- .../__tests__/useChannelPreviewMuted.test.tsx | 4 +- .../useLatestMessagePreview.test.tsx | 2 +- .../__tests__/ImageGallery.test.tsx | 12 ++-- .../__tests__/ImageGalleryFooter.test.tsx | 6 +- .../__tests__/ImageGalleryHeader.test.tsx | 6 +- .../__tests__/ImageGalleryOverlay.test.tsx | 2 +- .../__tests__/useMessageList.test.tsx | 2 +- .../__tests__/sendMessage.test.tsx | 8 +-- .../__tests__/updateMessage.test.tsx | 4 +- .../useMessageDetailsForState.test.tsx | 5 +- .../src/mock-builders/api/channelMocks.tsx | 68 +++++++++---------- 13 files changed, 73 insertions(+), 79 deletions(-) diff --git a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx index b9eb81ff02..cd61febef2 100644 --- a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx +++ b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx @@ -20,7 +20,7 @@ import { describe('useChannelPreviewDisplayName', () => { const clientUser = generateUser(); - let chatClient: StreamChat | StreamChat; + let chatClient: StreamChat | StreamChat; const CHARACTER_LENGTH = 15; beforeEach(async () => { @@ -34,7 +34,7 @@ describe('useChannelPreviewDisplayName', () => { const channelDisplayName = useChannelPreviewDisplayName( { data: { name: channelName }, - } as unknown as Channel, + } as unknown as Channel, CHARACTER_LENGTH, ); return {channelDisplayName}; @@ -71,10 +71,7 @@ describe('useChannelPreviewDisplayName', () => { const displayName = getChannelPreviewDisplayName({ characterLimit: characterLength, currentUserId, - members: members as unknown as Record< - string, - ChannelMemberResponse - >, + members: members as unknown as Record, }); expect(displayName).toEqual(expected); diff --git a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayPresence.test.tsx b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayPresence.test.tsx index f09e1b09a6..f793f1a927 100644 --- a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayPresence.test.tsx +++ b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayPresence.test.tsx @@ -11,9 +11,9 @@ describe('useChannelPreviewDisplayPresence', () => { // Mock user data const currentUserId = 'current-user'; const otherUserId = 'other-user'; - let chatClient: StreamChat; + let chatClient: StreamChat; - let mockChannel: Channel; + let mockChannel: Channel; beforeEach(async () => { jest.clearAllMocks(); @@ -27,14 +27,14 @@ describe('useChannelPreviewDisplayPresence', () => { state: { members: { [currentUserId]: { - user: { id: currentUserId, online: true } as UserResponse, + user: { id: currentUserId, online: true } as UserResponse, }, [otherUserId]: { - user: { id: otherUserId, online: false } as UserResponse, + user: { id: otherUserId, online: false } as UserResponse, }, }, }, - } as unknown as Channel; + } as unknown as Channel; // Mock the useChatContext hook jest @@ -53,17 +53,17 @@ describe('useChannelPreviewDisplayPresence', () => { state: { members: { [currentUserId]: { - user: { id: currentUserId } as UserResponse, + user: { id: currentUserId } as UserResponse, }, [otherUserId]: { - user: { id: otherUserId } as UserResponse, + user: { id: otherUserId } as UserResponse, }, [thirdUserId]: { - user: { id: thirdUserId } as UserResponse, + user: { id: thirdUserId } as UserResponse, }, }, }, - } as unknown as Channel; + } as unknown as Channel; const { result } = renderHook(() => useChannelPreviewDisplayPresence(channelWithThreeMembers)); expect(result.current).toBe(false); @@ -79,7 +79,7 @@ describe('useChannelPreviewDisplayPresence', () => { const onlineUser = { ...mockChannel.state.members[otherUserId].user, online: true, - } as UserResponse; + } as UserResponse; mockChannel.state.members[otherUserId].user = onlineUser; @@ -93,14 +93,14 @@ describe('useChannelPreviewDisplayPresence', () => { state: { members: { [currentUserId]: { - user: { id: currentUserId } as UserResponse, + user: { id: currentUserId } as UserResponse, }, 'null-user': { user: null, }, }, }, - } as unknown as Channel; + } as unknown as Channel; const { result } = renderHook(() => useChannelPreviewDisplayPresence(channelWithNullUser)); expect(result.current).toBe(false); diff --git a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewMuted.test.tsx b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewMuted.test.tsx index 06de03ae32..d83d0b5aff 100644 --- a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewMuted.test.tsx +++ b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewMuted.test.tsx @@ -10,7 +10,7 @@ import { useIsChannelMuted } from '../useIsChannelMuted'; describe('useChannelPreviewMuted', () => { const clientUser = generateUser(); - let chatClient: StreamChat | StreamChat; + let chatClient: StreamChat | StreamChat; beforeEach(async () => { chatClient = await getTestClientWithUser(clientUser); @@ -35,7 +35,7 @@ describe('useChannelPreviewMuted', () => { expiresAt: Date.now() + 5000, muted: false, }), - } as unknown as Channel; + } as unknown as Channel; it('should return the correct mute status', () => { const { result } = renderHook(() => useIsChannelMuted(mockChannel)); diff --git a/package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx b/package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx index 1173f00216..4787603abe 100644 --- a/package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx +++ b/package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx @@ -24,7 +24,7 @@ import { useLatestMessagePreview } from '../useLatestMessagePreview'; describe('useLatestMessagePreview', () => { const FORCE_UPDATE = 15; const clientUser = generateUser(); - let chatClient: StreamChat | StreamChat; + let chatClient: StreamChat | StreamChat; beforeEach(async () => { chatClient = await getTestClientWithUser(clientUser); diff --git a/package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx b/package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx index 402de210b0..5cf23b4f2f 100644 --- a/package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +++ b/package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx @@ -54,7 +54,7 @@ describe('ImageGallery', () => { generateVideoAttachment({ type: 'video' }), ], }), - ] as unknown as MessageType[], + ] as unknown as MessageType[], }), ); @@ -71,7 +71,7 @@ describe('ImageGallery', () => { }); render( getComponent({ - messages: [message] as unknown as MessageType[], + messages: [message] as unknown as MessageType[], }), ); @@ -100,7 +100,7 @@ describe('ImageGallery', () => { generateMessage({ attachments: [generateVideoAttachment({ type: 'video' })], }), - ] as unknown as MessageType[], + ] as unknown as MessageType[], }), ); @@ -126,7 +126,7 @@ describe('ImageGallery', () => { render( getComponent({ - messages: [message] as unknown as MessageType[], + messages: [message] as unknown as MessageType[], }), ); @@ -161,7 +161,7 @@ describe('ImageGallery', () => { generateMessage({ attachments: [generateVideoAttachment({ type: 'video' })], }), - ] as unknown as MessageType[], + ] as unknown as MessageType[], }), ); @@ -191,7 +191,7 @@ describe('ImageGallery', () => { }); render( getComponent({ - messages: [message] as unknown as MessageType[], + messages: [message] as unknown as MessageType[], }), ); diff --git a/package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx b/package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx index ca168a1471..dabac8e988 100644 --- a/package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx +++ b/package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx @@ -75,7 +75,7 @@ describe('ImageGalleryFooter', () => { generateMessage({ attachments: [generateVideoAttachment({ type: 'video' })], }), - ] as unknown as MessageType[], + ] as unknown as MessageType[], } as unknown as ImageGalleryContextValue } > @@ -130,7 +130,7 @@ describe('ImageGalleryFooter', () => { generateMessage({ attachments: [generateVideoAttachment({ type: 'video' })], }), - ] as unknown as MessageType[], + ] as unknown as MessageType[], } as unknown as ImageGalleryContextValue } > @@ -173,7 +173,7 @@ describe('ImageGalleryFooter', () => { generateMessage({ attachments: [generateImageAttachment()], }), - ] as unknown as MessageType[], + ] as unknown as MessageType[], } as unknown as ImageGalleryContextValue } > diff --git a/package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx b/package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx index a31d617d97..d2dc2c0d22 100644 --- a/package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx +++ b/package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx @@ -69,7 +69,7 @@ describe('ImageGalleryHeader', () => { generateMessage({ attachments: [generateImageAttachment()], }), - ] as unknown as MessageType[], + ] as unknown as MessageType[], } as unknown as ImageGalleryContextValue } > @@ -116,7 +116,7 @@ describe('ImageGalleryHeader', () => { generateMessage({ attachments: [generateVideoAttachment({ type: 'video' })], }), - ] as unknown as MessageType[], + ] as unknown as MessageType[], } as unknown as ImageGalleryContextValue } > @@ -156,7 +156,7 @@ describe('ImageGalleryHeader', () => { generateMessage({ attachments: [generateImageAttachment()], }), - ] as unknown as MessageType[], + ] as unknown as MessageType[], } as unknown as ImageGalleryContextValue } > diff --git a/package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx b/package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx index 557ded66cb..1d42ea204a 100644 --- a/package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx +++ b/package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx @@ -39,7 +39,7 @@ describe('ImageGalleryOverlay', () => { generateMessage({ attachments: [generateImageAttachment()], }), - ] as unknown as MessageType[], + ] as unknown as MessageType[], } as unknown as ImageGalleryContextValue } > diff --git a/package/src/components/MessageList/__tests__/useMessageList.test.tsx b/package/src/components/MessageList/__tests__/useMessageList.test.tsx index 4a29dba041..70329883fe 100644 --- a/package/src/components/MessageList/__tests__/useMessageList.test.tsx +++ b/package/src/components/MessageList/__tests__/useMessageList.test.tsx @@ -19,7 +19,7 @@ import { getTestClientWithUser } from '../../../mock-builders/mock'; import { useMessageList } from '../hooks/useMessageList'; const clientUser = generateUser(); -let chatClient: StreamChat | StreamChat; +let chatClient: StreamChat | StreamChat; beforeEach(async () => { chatClient = await getTestClientWithUser(clientUser); diff --git a/package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx b/package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx index 290f74f5b4..8b3a9277c1 100644 --- a/package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx @@ -40,7 +40,7 @@ describe("MessageInputContext's sendMessage", () => { setSelectedFiles: jest.fn(), setSelectedImages: jest.fn(), })); - const message: boolean | MessageType = generateMessage({ + const message: boolean | MessageType = generateMessage({ created_at: 'Sat Jul 02 2022 23:55:13 GMT+0530 (India Standard Time)', id: '7a85f744-cc89-4f82-a1d4-5456432cc8bf', updated_at: 'Sat Jul 02 2022 23:55:13 GMT+0530 (India Standard Time)', @@ -49,7 +49,7 @@ describe("MessageInputContext's sendMessage", () => { image: 'fc86ddcb-bac4-400c-9afd-b0c0a1c0cd33', name: '50cbdd0e-ca7e-4478-9e2c-be0f1ac6a995', }), - }) as unknown as MessageType; + }) as unknown as MessageType; it('exit sendMessage when file upload status failed', async () => { const initialProps = { @@ -223,7 +223,7 @@ describe("MessageInputContext's sendMessage", () => { it('exit sendMessage when image upload has an error and catch block is executed', () => { const setQuotedMessageStateMock = jest.fn(); const clearQuotedMessageStateMock = jest.fn(); - const generatedQuotedMessage: boolean | MessageType = message; + const generatedQuotedMessage: boolean | MessageType = message; const images = [ generateImageUploadPreview({ state: FileState.UPLOADED }), generateImageUploadPreview({ state: FileState.FINISHED }), @@ -268,7 +268,7 @@ describe("MessageInputContext's sendMessage", () => { const clearEditingStateMock = jest.fn(); const editMessageMock = jest.fn().mockResolvedValue({ data: {} }); const images = generateImageUploadPreview({ state: FileState.UPLOADED }); - const generatedMessage: boolean | MessageType = message; + const generatedMessage: boolean | MessageType = message; const initialProps = { clearEditingState: clearEditingStateMock, clearQuotedMessageState: clearQuotedMessageStateMock, diff --git a/package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx b/package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx index 3817268015..5aa66c3bb7 100644 --- a/package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx @@ -51,7 +51,7 @@ describe("MessageInputContext's updateMessage", () => { setSelectedImages: jest.fn(), })); const clearEditingStateMock = jest.fn(); - const generatedMessage: boolean | MessageType = generateMessage({ + const generatedMessage: boolean | MessageType = generateMessage({ created_at: 'Sat Jul 02 2022 23:55:13 GMT+0530 (India Standard Time)', id: '7a85f744-cc89-4f82-a1d4-5456432cc8bf', text: 'hey', @@ -61,7 +61,7 @@ describe("MessageInputContext's updateMessage", () => { image: 'fc86ddcb-bac4-400c-9afd-b0c0a1c0cd33', name: '50cbdd0e-ca7e-4478-9e2c-be0f1ac6a995', }), - }) as unknown as MessageType; + }) as unknown as MessageType; it('updateMessage throws error as clearEditingState is not available', async () => { const initialProps = { diff --git a/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx b/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx index eef52d4844..819be733af 100644 --- a/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx @@ -41,10 +41,7 @@ describe('useMessageDetailsForState', () => { it('fileUploads, imageUploads and mentionedUsers are not empty when attachments are present in message', () => { const { result } = renderHook( ({ initialValue, message }) => - useMessageDetailsForState( - message as unknown as MessageType | boolean, - initialValue, - ), + useMessageDetailsForState(message as unknown as MessageType | boolean, initialValue), { initialProps: { initialValue: '', diff --git a/package/src/mock-builders/api/channelMocks.tsx b/package/src/mock-builders/api/channelMocks.tsx index 787f862537..7c0b28244f 100644 --- a/package/src/mock-builders/api/channelMocks.tsx +++ b/package/src/mock-builders/api/channelMocks.tsx @@ -15,7 +15,7 @@ const channelName = 'okechukwu'; const CHANNEL = { data: { name: channelName }, state: { messages: [] }, -} as unknown as Channel; +} as unknown as Channel; const CHANNEL_WITH_MESSAGES_TEXT = { data: { name: channelName }, @@ -34,8 +34,8 @@ const CHANNEL_WITH_MESSAGES_TEXT = { id: 'ljkblk', text: 'jkbkbiubicbi', type: 'MessageLabel', - user: { id: 'okechukwu' } as unknown as UserResponse, - } as unknown as MessageResponse, + user: { id: 'okechukwu' } as unknown as UserResponse, + } as unknown as MessageResponse, { args: 'string', attachments: [], @@ -48,11 +48,11 @@ const CHANNEL_WITH_MESSAGES_TEXT = { id: 'jbkjb', text: 'jkbkbiubicbi', type: 'MessageLabel', - user: { id: 'okechukwu' } as unknown as UserResponse, - } as unknown as MessageResponse, + user: { id: 'okechukwu' } as unknown as UserResponse, + } as unknown as MessageResponse, ], }, -} as unknown as Channel; +} as unknown as Channel; const CHANNEL_WITH_DELETED_MESSAGES = { data: { name: channelName }, @@ -61,13 +61,13 @@ const CHANNEL_WITH_DELETED_MESSAGES = { messages: [ { type: 'deleted', - } as unknown as MessageResponse, + } as unknown as MessageResponse, { type: 'deleted', - } as unknown as MessageResponse, + } as unknown as MessageResponse, ], }, -} as unknown as Channel; +} as unknown as Channel; const CHANNEL_WITH_NO_MESSAGES = { data: { name: channelName }, @@ -75,7 +75,7 @@ const CHANNEL_WITH_NO_MESSAGES = { members: GROUP_CHANNEL_MEMBERS_MOCK, messages: [], }, -} as unknown as Channel; +} as unknown as Channel; const CHANNEL_WITH_MESSAGE_COMMAND = { data: { name: channelName }, @@ -92,8 +92,8 @@ const CHANNEL_WITH_MESSAGE_COMMAND = { created_at: new Date('2021-02-12T12:12:35.862Z'), deleted_at: new Date('2021-02-12T12:12:35.862Z'), id: 'ljkblk', - user: { id: 'okechukwu' } as unknown as UserResponse, - } as unknown as MessageResponse, + user: { id: 'okechukwu' } as unknown as UserResponse, + } as unknown as MessageResponse, { args: 'string', attachments: [], @@ -104,11 +104,11 @@ const CHANNEL_WITH_MESSAGE_COMMAND = { created_at: new Date('2021-02-12T12:12:35.862Z'), deleted_at: new Date('2021-02-12T12:12:35.862Z'), id: 'jbkjb', - user: { id: 'okechukwu' } as unknown as UserResponse, - } as unknown as MessageResponse, + user: { id: 'okechukwu' } as unknown as UserResponse, + } as unknown as MessageResponse, ], }, -} as unknown as Channel; +} as unknown as Channel; const CHANNEL_WITH_MESSAGES_ATTACHMENTS = { data: { name: channelName }, @@ -141,17 +141,17 @@ const CHANNEL_WITH_MESSAGES_ATTACHMENTS = { title: 'string', title_link: 'string', type: 'string', - } as Attachment, + } as Attachment, ], channel: CHANNEL, created_at: new Date('2021-02-12T12:12:35.862Z'), deleted_at: new Date('2021-02-12T12:12:35.862Z'), id: 'ljkblk', - user: { id: 'okechukwu' } as unknown as UserResponse, - } as unknown as MessageResponse, + user: { id: 'okechukwu' } as unknown as UserResponse, + } as unknown as MessageResponse, ], }, -} as unknown as Channel; +} as unknown as Channel; const LATEST_MESSAGE = { args: 'string', @@ -165,13 +165,13 @@ const LATEST_MESSAGE = { id: 'string', text: 'jkbkbiubicbi', type: 'MessageLabel', - user: { id: 'okechukwu' } as unknown as UserResponse, -} as unknown as MessageResponse; + user: { id: 'okechukwu' } as unknown as UserResponse, +} as unknown as MessageResponse; -const FORMATTED_MESSAGE: FormatMessageResponse = { +const FORMATTED_MESSAGE: FormatMessageResponse = { created_at: new Date('2021-02-12T12:12:35.862282Z'), id: '', - message: {} as unknown as MessageResponse, + message: {} as unknown as MessageResponse, pinned_at: new Date('2021-02-12T12:12:35.862282Z'), status: 'received', type: 'regular', @@ -193,9 +193,9 @@ const CHANNEL_WITH_MENTIONED_USERS = { { id: 'Max', name: 'Max' }, { id: 'Ada', name: 'Ada' }, { id: 'Enzo', name: 'Enzo' }, - ] as UserResponse[], + ] as UserResponse[], text: 'Max', - } as unknown as MessageResponse, + } as unknown as MessageResponse, { args: 'string', attachments: [], @@ -207,12 +207,12 @@ const CHANNEL_WITH_MENTIONED_USERS = { { id: 'Max', name: 'Max' }, { id: 'Ada', name: 'Ada' }, { id: 'Enzo', name: 'Enzo' }, - ] as UserResponse[], + ] as UserResponse[], text: 'Max', - } as unknown as MessageResponse, + } as unknown as MessageResponse, ], }, -} as unknown as Channel; +} as unknown as Channel; const CHANNEL_WITH_EMPTY_MESSAGE = { state: { @@ -229,8 +229,8 @@ const CHANNEL_WITH_EMPTY_MESSAGE = { { id: 'Max', name: 'Max' }, { id: 'Ada', name: 'Ada' }, { id: 'Enzo', name: 'Enzo' }, - ] as UserResponse[], - } as unknown as MessageResponse, + ] as UserResponse[], + } as unknown as MessageResponse, { args: 'string', attachments: [], @@ -242,11 +242,11 @@ const CHANNEL_WITH_EMPTY_MESSAGE = { { id: 'Max', name: 'Max' }, { id: 'Ada', name: 'Ada' }, { id: 'Enzo', name: 'Enzo' }, - ] as UserResponse[], - } as unknown as MessageResponse, + ] as UserResponse[], + } as unknown as MessageResponse, ], }, -} as unknown as Channel; +} as unknown as Channel; const CHANNEL_WITH_MESSAGES = { data: { name: channelName }, @@ -254,7 +254,7 @@ const CHANNEL_WITH_MESSAGES = { members: GROUP_CHANNEL_MEMBERS_MOCK, messages: [FORMATTED_MESSAGE, FORMATTED_MESSAGE], }, -} as unknown as Channel; +} as unknown as Channel; export { CHANNEL, From b3c67eb34d44aac04bf0cebb49135701a7baf7ed Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Thu, 13 Mar 2025 11:52:33 +0100 Subject: [PATCH 17/60] fix: lint issues --- .../ChannelList/hooks/listeners/useUserPresence.ts | 5 +---- .../hooks/__tests__/useChannelPreviewDisplayName.test.tsx | 2 +- .../__tests__/useChannelPreviewDisplayPresence.test.tsx | 1 - .../hooks/__tests__/useChannelPreviewMuted.test.tsx | 5 ++--- .../hooks/__tests__/useLatestMessagePreview.test.tsx | 2 +- .../ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts | 5 +---- .../components/MessageList/__tests__/useMessageList.test.tsx | 4 ++-- 7 files changed, 8 insertions(+), 16 deletions(-) diff --git a/package/src/components/ChannelList/hooks/listeners/useUserPresence.ts b/package/src/components/ChannelList/hooks/listeners/useUserPresence.ts index 32ad65dd52..c4e7c894ab 100644 --- a/package/src/components/ChannelList/hooks/listeners/useUserPresence.ts +++ b/package/src/components/ChannelList/hooks/listeners/useUserPresence.ts @@ -13,10 +13,7 @@ type Parameters = { * Hook to update the channel members when the user presence changes * @deprecated this hook will be removed in favour of the useChannelPreviewDisplayPresence to improve performance */ -export const useUserPresence = ({ - setChannels, - setForceUpdate, -}: Parameters) => { +export const useUserPresence = ({ setChannels, setForceUpdate }: Parameters) => { const { client } = useChatContext(); useEffect(() => { diff --git a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx index cd61febef2..664f3e5f0d 100644 --- a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx +++ b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx @@ -3,7 +3,7 @@ import { Text } from 'react-native'; import { render, screen, waitFor } from '@testing-library/react-native'; -import type { Channel, ChannelMemberResponse, DefaultGenerics, StreamChat } from 'stream-chat'; +import type { Channel, ChannelMemberResponse, StreamChat } from 'stream-chat'; import { GROUP_CHANNEL_MEMBERS_MOCK, diff --git a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayPresence.test.tsx b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayPresence.test.tsx index f793f1a927..2d18faf99b 100644 --- a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayPresence.test.tsx +++ b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayPresence.test.tsx @@ -4,7 +4,6 @@ import type { Channel, StreamChat, UserResponse } from 'stream-chat'; import type { ChatContextValue } from '../../../../contexts/chatContext/ChatContext'; import * as ChatContext from '../../../../contexts/chatContext/ChatContext'; import { getTestClientWithUser } from '../../../../mock-builders/mock'; -import { DefaultStreamChatGenerics } from '../../../../types/types'; import { useChannelPreviewDisplayPresence } from '../useChannelPreviewDisplayPresence'; describe('useChannelPreviewDisplayPresence', () => { diff --git a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewMuted.test.tsx b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewMuted.test.tsx index d83d0b5aff..1808d5cba9 100644 --- a/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewMuted.test.tsx +++ b/package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewMuted.test.tsx @@ -1,16 +1,15 @@ import { act, renderHook, waitFor } from '@testing-library/react-native'; -import { Channel, DefaultGenerics, StreamChat } from 'stream-chat'; +import { Channel, StreamChat } from 'stream-chat'; import * as ChatContext from '../../../../contexts/chatContext/ChatContext'; import dispatchNotificationChannelMutesUpdated from '../../../../mock-builders/event/notificationChannelMutesUpdated'; import { generateUser } from '../../../../mock-builders/generator/user'; import { getTestClientWithUser } from '../../../../mock-builders/mock'; -import { DefaultStreamChatGenerics } from '../../../../types/types'; import { useIsChannelMuted } from '../useIsChannelMuted'; describe('useChannelPreviewMuted', () => { const clientUser = generateUser(); - let chatClient: StreamChat | StreamChat; + let chatClient: StreamChat; beforeEach(async () => { chatClient = await getTestClientWithUser(clientUser); diff --git a/package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx b/package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx index 4787603abe..b1a95c2a63 100644 --- a/package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx +++ b/package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx @@ -2,7 +2,7 @@ import React, { FC } from 'react'; import { renderHook, waitFor } from '@testing-library/react-native'; -import type { DefaultGenerics, MessageResponse, StreamChat } from 'stream-chat'; +import type { MessageResponse, StreamChat } from 'stream-chat'; import { ChatContext, ChatContextValue } from '../../../../contexts/chatContext/ChatContext'; import { diff --git a/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts b/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts index 20b97e6775..2118e6e142 100644 --- a/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts +++ b/package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts @@ -12,10 +12,7 @@ import { useSyncClientEventsToChannel } from '../../../hooks/useSyncClientEvents * * NOTE: If you want to listen to the value changes where you call the hook, the selector should return primitive values instead of object. */ -const selector = ( - channel: Channel, - client: StreamChat, -) => { +const selector = (channel: Channel, client: StreamChat) => { const members = channel.state.members; const membersCount = Object.keys(members).length; const otherMember = Object.values(members).find((member) => member.user?.id !== client.userID); diff --git a/package/src/components/MessageList/__tests__/useMessageList.test.tsx b/package/src/components/MessageList/__tests__/useMessageList.test.tsx index 70329883fe..e9191a204d 100644 --- a/package/src/components/MessageList/__tests__/useMessageList.test.tsx +++ b/package/src/components/MessageList/__tests__/useMessageList.test.tsx @@ -2,7 +2,7 @@ import React, { FC } from 'react'; import { renderHook } from '@testing-library/react-native'; -import type { DefaultGenerics, StreamChat } from 'stream-chat'; +import type { StreamChat } from 'stream-chat'; import { useCreatePaginatedMessageListContext } from '../../../components/Channel/hooks/useCreatePaginatedMessageListContext'; import { @@ -19,7 +19,7 @@ import { getTestClientWithUser } from '../../../mock-builders/mock'; import { useMessageList } from '../hooks/useMessageList'; const clientUser = generateUser(); -let chatClient: StreamChat | StreamChat; +let chatClient: StreamChat; beforeEach(async () => { chatClient = await getTestClientWithUser(clientUser); From 1d28a1adcff377594361ca715353464189c228e1 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Thu, 13 Mar 2025 14:40:25 +0100 Subject: [PATCH 18/60] fix: replace TouchableOpacity with Pressable --- .../ChannelPreview/ChannelPreviewMessenger.tsx | 9 +++++---- .../src/components/MessageInput/MoreOptionsButton.tsx | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx b/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx index 11bb5741d3..8bcfe44c30 100644 --- a/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx +++ b/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { StyleSheet, View } from 'react-native'; -import { TouchableOpacity } from 'react-native-gesture-handler'; +import { Pressable } from 'react-native-gesture-handler'; import { ChannelAvatar } from './ChannelAvatar'; import type { ChannelPreviewProps } from './ChannelPreview'; @@ -130,13 +130,14 @@ const ChannelPreviewMessengerWithContext = (props: ChannelPreviewMessengerPropsW ); return ( - { if (onSelect) { onSelect(channel); } }} - style={[ + style={({ pressed }) => [ + { opacity: pressed ? 0.5 : 1 }, styles.container, { backgroundColor: white_snow, borderBottomColor: border }, container, @@ -164,7 +165,7 @@ const ChannelPreviewMessengerWithContext = (props: ChannelPreviewMessengerPropsW />
-
+ ); }; diff --git a/package/src/components/MessageInput/MoreOptionsButton.tsx b/package/src/components/MessageInput/MoreOptionsButton.tsx index 300453cd39..6427340abe 100644 --- a/package/src/components/MessageInput/MoreOptionsButton.tsx +++ b/package/src/components/MessageInput/MoreOptionsButton.tsx @@ -1,6 +1,6 @@ import React from 'react'; import type { GestureResponderEvent } from 'react-native'; -import { TouchableOpacity } from 'react-native-gesture-handler'; +import { Pressable } from 'react-native-gesture-handler'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { CircleRight } from '../../icons/CircleRight'; @@ -21,14 +21,14 @@ export const MoreOptionsButton = (props: MoreOptionsButtonProps) => { } = useTheme(); return ( - [{ opacity: pressed ? 0.5 : 1 }, moreOptionsButton]} testID='more-options-button' > - + ); }; From 9154fdd5d6f613acef9bbb18f9e620e012e24a47 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Thu, 13 Mar 2025 14:54:21 +0100 Subject: [PATCH 19/60] fix: move to RN TouchableOpacity instead --- .../ChannelPreview/ChannelPreviewMessenger.tsx | 11 +++++------ .../src/components/MessageInput/MoreOptionsButton.tsx | 8 ++++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx b/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx index 8bcfe44c30..65f87b0b6b 100644 --- a/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx +++ b/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import { StyleSheet, View } from 'react-native'; -import { Pressable } from 'react-native-gesture-handler'; +import { StyleSheet, TouchableOpacity, View } from 'react-native'; import { ChannelAvatar } from './ChannelAvatar'; import type { ChannelPreviewProps } from './ChannelPreview'; @@ -130,14 +129,14 @@ const ChannelPreviewMessengerWithContext = (props: ChannelPreviewMessengerPropsW ); return ( - { if (onSelect) { onSelect(channel); } }} - style={({ pressed }) => [ - { opacity: pressed ? 0.5 : 1 }, + style={[ + // { opacity: pressed ? 0.5 : 1 }, styles.container, { backgroundColor: white_snow, borderBottomColor: border }, container, @@ -165,7 +164,7 @@ const ChannelPreviewMessengerWithContext = (props: ChannelPreviewMessengerPropsW /> - + ); }; diff --git a/package/src/components/MessageInput/MoreOptionsButton.tsx b/package/src/components/MessageInput/MoreOptionsButton.tsx index 6427340abe..5cda2d416d 100644 --- a/package/src/components/MessageInput/MoreOptionsButton.tsx +++ b/package/src/components/MessageInput/MoreOptionsButton.tsx @@ -1,6 +1,6 @@ import React from 'react'; +import { TouchableOpacity } from 'react-native'; import type { GestureResponderEvent } from 'react-native'; -import { Pressable } from 'react-native-gesture-handler'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { CircleRight } from '../../icons/CircleRight'; @@ -21,14 +21,14 @@ export const MoreOptionsButton = (props: MoreOptionsButtonProps) => { } = useTheme(); return ( - [{ opacity: pressed ? 0.5 : 1 }, moreOptionsButton]} + style={[moreOptionsButton]} testID='more-options-button' > - + ); }; From 9569c98615d8eacbf70540c45c020ec526ab090e Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Thu, 13 Mar 2025 16:04:12 +0100 Subject: [PATCH 20/60] chore(deps): update peer deps --- package/native-package/package.json | 4 +-- package/native-package/yarn.lock | 46 ++++++++++++++++++++++++++++- package/package.json | 4 +-- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/package/native-package/package.json b/package/native-package/package.json index 3ebcc27956..97f1549157 100644 --- a/package/native-package/package.json +++ b/package/native-package/package.json @@ -19,14 +19,14 @@ "main": "src/index.js", "types": "types/index.d.ts", "dependencies": { - "es6-symbol": "^3.1.3", + "es6-symbol": "^3.1.4", "stream-chat-react-native-core": "link:../" }, "peerDependencies": { "@react-native-camera-roll/camera-roll": ">=7.8.0", "@react-native-clipboard/clipboard": ">=1.14.1", "@stream-io/flat-list-mvcp": ">=0.10.3", - "react-native": ">=0.67.0", + "react-native": ">=0.71.0", "react-native-audio-recorder-player": ">=3.6.4", "react-native-blob-util": ">=0.19.9", "@react-native-documents/picker": ">=10.1.1", diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index a13902278f..c9e6abf748 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -1761,6 +1761,14 @@ d@1, d@^1.0.1: es5-ext "^0.10.50" type "^1.0.1" +d@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.2.tgz#2aefd554b81981e7dccf72d6842ae725cb17e5de" + integrity sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw== + dependencies: + es5-ext "^0.10.64" + type "^2.7.2" + dayjs@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.5.tgz#5600df4548fc2453b3f163ebb2abbe965ccfb986" @@ -1862,6 +1870,16 @@ es5-ext@^0.10.35, es5-ext@^0.10.50: es6-symbol "^3.1.3" next-tick "^1.1.0" +es5-ext@^0.10.62, es5-ext@^0.10.64, es5-ext@~0.10.14: + version "0.10.64" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" + integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + esniff "^2.0.1" + next-tick "^1.1.0" + es6-iterator@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" @@ -1879,6 +1897,14 @@ es6-symbol@^3.1.1, es6-symbol@^3.1.3: d "^1.0.1" ext "^1.1.2" +es6-symbol@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.4.tgz#f4e7d28013770b4208ecbf3e0bf14d3bcb557b8c" + integrity sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg== + dependencies: + d "^1.0.2" + ext "^1.7.0" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -1909,6 +1935,16 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +esniff@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" + integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== + dependencies: + d "^1.0.1" + es5-ext "^0.10.62" + event-emitter "^0.3.5" + type "^2.7.2" + esprima@^4.0.0, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -1919,6 +1955,14 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== + dependencies: + d "1" + es5-ext "~0.10.14" + event-target-shim@^5.0.0, event-target-shim@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" @@ -1929,7 +1973,7 @@ exponential-backoff@^3.1.1: resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.2.tgz#a8f26adb96bf78e8cd8ad1037928d5e5c0679d91" integrity sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA== -ext@^1.1.2: +ext@^1.1.2, ext@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== diff --git a/package/package.json b/package/package.json index c5d972a86e..cb8e1993e3 100644 --- a/package/package.json +++ b/package/package.json @@ -83,10 +83,10 @@ "peerDependencies": { "@op-engineering/op-sqlite": ">=9.3.0", "@react-native-community/netinfo": ">=11.3.1", - "react-native": ">=0.67.0", + "react-native": ">=0.71.0", "react-native-gesture-handler": ">=2.16.1", "react-native-reanimated": ">=3.16.0", - "react-native-svg": ">=12.3.0" + "react-native-svg": ">=13.6.0" }, "peerDependenciesMeta": { "@op-engineering/op-sqlite": { From 39f4f82529ef4378e9696f6b9fdd3d84b91695db Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Thu, 13 Mar 2025 16:30:42 +0100 Subject: [PATCH 21/60] chore: remove unused hooks --- .../useAddedToChannelNotification.ts | 76 ------------ .../hooks/listeners/useChannelDeleted.ts | 42 ------- .../hooks/listeners/useChannelHidden.ts | 43 ------- .../listeners/useChannelMemberUpdated.ts | 114 ------------------ .../hooks/listeners/useChannelTruncated.ts | 38 ------ .../hooks/listeners/useChannelVisible.ts | 55 --------- .../hooks/listeners/useNewMessage.ts | 91 -------------- .../listeners/useNewMessageNotification.ts | 67 ---------- .../useRemovedFromChannelNotification.ts | 41 ------- .../hooks/listeners/useUserPresence.ts | 49 -------- package/src/components/index.ts | 9 -- 11 files changed, 625 deletions(-) delete mode 100644 package/src/components/ChannelList/hooks/listeners/useAddedToChannelNotification.ts delete mode 100644 package/src/components/ChannelList/hooks/listeners/useChannelDeleted.ts delete mode 100644 package/src/components/ChannelList/hooks/listeners/useChannelHidden.ts delete mode 100644 package/src/components/ChannelList/hooks/listeners/useChannelMemberUpdated.ts delete mode 100644 package/src/components/ChannelList/hooks/listeners/useChannelTruncated.ts delete mode 100644 package/src/components/ChannelList/hooks/listeners/useChannelVisible.ts delete mode 100644 package/src/components/ChannelList/hooks/listeners/useNewMessage.ts delete mode 100644 package/src/components/ChannelList/hooks/listeners/useNewMessageNotification.ts delete mode 100644 package/src/components/ChannelList/hooks/listeners/useRemovedFromChannelNotification.ts delete mode 100644 package/src/components/ChannelList/hooks/listeners/useUserPresence.ts diff --git a/package/src/components/ChannelList/hooks/listeners/useAddedToChannelNotification.ts b/package/src/components/ChannelList/hooks/listeners/useAddedToChannelNotification.ts deleted file mode 100644 index c643732530..0000000000 --- a/package/src/components/ChannelList/hooks/listeners/useAddedToChannelNotification.ts +++ /dev/null @@ -1,76 +0,0 @@ -import React, { useEffect } from 'react'; - -import uniqBy from 'lodash/uniqBy'; - -import type { Channel, Event } from 'stream-chat'; - -import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; - -import type { ChannelListEventListenerOptions } from '../../../../types/types'; -import { getChannel } from '../../utils'; -import { findLastPinnedChannelIndex, findPinnedAtSortOrder } from '../utils'; - -type Parameters = { - setChannels: React.Dispatch>; - onAddedToChannel?: ( - setChannels: React.Dispatch>, - event: Event, - options?: ChannelListEventListenerOptions, - ) => void; - options?: ChannelListEventListenerOptions; -}; - -export const useAddedToChannelNotification = ({ - onAddedToChannel, - options, - setChannels, -}: Parameters) => { - const { client } = useChatContext(); - - useEffect(() => { - const handleEvent = async (event: Event) => { - if (typeof onAddedToChannel === 'function') { - onAddedToChannel(setChannels, event, options); - } else { - if (!options) { - return; - } - const { sort } = options; - if (event.channel?.id && event.channel?.type) { - const channel = await getChannel({ - client, - id: event.channel.id, - type: event.channel.type, - }); - - const pinnedAtSort = findPinnedAtSortOrder({ sort }); - - setChannels((channels) => { - if (!channels) { - return channels; - } - - // handle pinning - let lastPinnedChannelIndex: number | null = null; - - const newChannels = [...channels]; - if (pinnedAtSort === 1 || pinnedAtSort === -1) { - lastPinnedChannelIndex = findLastPinnedChannelIndex({ channels: newChannels }); - const newTargetChannelIndex = - typeof lastPinnedChannelIndex === 'number' ? lastPinnedChannelIndex + 1 : 0; - - newChannels.splice(newTargetChannelIndex, 0, channel); - return newChannels; - } - - return uniqBy([channel, ...channels], 'cid'); - }); - } - } - }; - - const listener = client?.on('notification.added_to_channel', handleEvent); - return () => listener?.unsubscribe(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); -}; diff --git a/package/src/components/ChannelList/hooks/listeners/useChannelDeleted.ts b/package/src/components/ChannelList/hooks/listeners/useChannelDeleted.ts deleted file mode 100644 index 195f5780cb..0000000000 --- a/package/src/components/ChannelList/hooks/listeners/useChannelDeleted.ts +++ /dev/null @@ -1,42 +0,0 @@ -import React, { useEffect } from 'react'; - -import type { Channel, Event } from 'stream-chat'; - -import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; - -type Parameters = { - setChannels: React.Dispatch>; - onChannelDeleted?: ( - setChannels: React.Dispatch>, - event: Event, - ) => void; -}; - -export const useChannelDeleted = ({ onChannelDeleted, setChannels }: Parameters) => { - const { client } = useChatContext(); - - useEffect(() => { - const handleEvent = (event: Event) => { - if (typeof onChannelDeleted === 'function') { - onChannelDeleted(setChannels, event); - } else { - setChannels((channels) => { - if (!channels) { - return channels; - } - const index = channels.findIndex( - (channel) => channel.cid === (event.cid || event.channel?.cid), - ); - if (index >= 0) { - channels.splice(index, 1); - } - return [...channels]; - }); - } - }; - - const listener = client?.on('channel.deleted', handleEvent); - return () => listener?.unsubscribe(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); -}; diff --git a/package/src/components/ChannelList/hooks/listeners/useChannelHidden.ts b/package/src/components/ChannelList/hooks/listeners/useChannelHidden.ts deleted file mode 100644 index 74a75b3693..0000000000 --- a/package/src/components/ChannelList/hooks/listeners/useChannelHidden.ts +++ /dev/null @@ -1,43 +0,0 @@ -import React, { useEffect } from 'react'; - -import type { Channel, Event } from 'stream-chat'; - -import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; - -type Parameters = { - setChannels: React.Dispatch>; - onChannelHidden?: ( - setChannels: React.Dispatch>, - event: Event, - ) => void; -}; - -export const useChannelHidden = ({ onChannelHidden, setChannels }: Parameters) => { - const { client } = useChatContext(); - - useEffect(() => { - const handleEvent = (event: Event) => { - if (typeof onChannelHidden === 'function') { - onChannelHidden(setChannels, event); - } else { - setChannels((channels) => { - if (!channels) { - return channels; - } - - const index = channels.findIndex( - (channel) => channel.cid === (event.cid || event.channel?.cid), - ); - if (index >= 0) { - channels.splice(index, 1); - } - return [...channels]; - }); - } - }; - - const listener = client?.on('channel.hidden', handleEvent); - return () => listener?.unsubscribe(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); -}; diff --git a/package/src/components/ChannelList/hooks/listeners/useChannelMemberUpdated.ts b/package/src/components/ChannelList/hooks/listeners/useChannelMemberUpdated.ts deleted file mode 100644 index 33a45e2b97..0000000000 --- a/package/src/components/ChannelList/hooks/listeners/useChannelMemberUpdated.ts +++ /dev/null @@ -1,114 +0,0 @@ -import React, { useEffect } from 'react'; - -import type { Channel, Event } from 'stream-chat'; - -import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; - -import type { ChannelListEventListenerOptions } from '../../../../types/types'; -import { - findLastPinnedChannelIndex, - findPinnedAtSortOrder, - isChannelArchived, - isChannelPinned, - shouldConsiderArchivedChannels, - shouldConsiderPinnedChannels, -} from '../utils'; - -type Parameters = { - lockChannelOrder: boolean; - setChannels: React.Dispatch>; - onChannelMemberUpdated?: ( - lockChannelOrder: boolean, - setChannels: React.Dispatch>, - event: Event, - options?: ChannelListEventListenerOptions, - ) => void; - options?: ChannelListEventListenerOptions; -}; - -export const useChannelMemberUpdated = ({ - lockChannelOrder, - onChannelMemberUpdated, - options, - setChannels, -}: Parameters) => { - const { client } = useChatContext(); - - useEffect(() => { - const handleEvent = (event: Event) => { - if (typeof onChannelMemberUpdated === 'function') { - onChannelMemberUpdated(lockChannelOrder, setChannels, event, options); - } else { - if (!options) { - return; - } - const { filters, sort } = options; - if (!event.member?.user || event.member.user.id !== client.userID || !event.channel_type) { - return; - } - const channelType = event.channel_type; - const channelId = event.channel_id; - - const considerPinnedChannels = shouldConsiderPinnedChannels(sort); - const considerArchivedChannels = shouldConsiderArchivedChannels(filters); - const pinnedAtSort = findPinnedAtSortOrder({ sort }); - - setChannels((currentChannels) => { - if (!currentChannels) { - return currentChannels; - } - - const targetChannel = client.channel(channelType, channelId); - // assumes that channel instances are not changing - const targetChannelIndex = currentChannels.indexOf(targetChannel); - const targetChannelExistsWithinList = targetChannelIndex >= 0; - - const isTargetChannelPinned = isChannelPinned(targetChannel); - const isTargetChannelArchived = isChannelArchived(targetChannel); - - if (!considerPinnedChannels || lockChannelOrder) { - return currentChannels; - } - - const newChannels = [...currentChannels]; - - if (targetChannelExistsWithinList) { - newChannels.splice(targetChannelIndex, 1); - } - - // handle archiving (remove channel) - if ( - // When archived filter true, and channel is unarchived - (considerArchivedChannels && !isTargetChannelArchived && filters?.archived) || - // When archived filter false, and channel is archived - (considerArchivedChannels && isTargetChannelArchived && !filters?.archived) - ) { - return newChannels; - } - - // handle pinning - let lastPinnedChannelIndex: number | null = null; - - if (pinnedAtSort === 1 || (pinnedAtSort === -1 && !isTargetChannelPinned)) { - lastPinnedChannelIndex = findLastPinnedChannelIndex({ channels: newChannels }); - } - const newTargetChannelIndex = - typeof lastPinnedChannelIndex === 'number' ? lastPinnedChannelIndex + 1 : 0; - - // skip re-render if the position of the channel does not change - if (currentChannels[newTargetChannelIndex] === targetChannel) { - return currentChannels; - } - - newChannels.splice(newTargetChannelIndex, 0, targetChannel); - - return newChannels; - }); - } - }; - - const listener = client?.on('member.updated', handleEvent); - return () => listener?.unsubscribe(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); -}; diff --git a/package/src/components/ChannelList/hooks/listeners/useChannelTruncated.ts b/package/src/components/ChannelList/hooks/listeners/useChannelTruncated.ts deleted file mode 100644 index e2fa7fb1f7..0000000000 --- a/package/src/components/ChannelList/hooks/listeners/useChannelTruncated.ts +++ /dev/null @@ -1,38 +0,0 @@ -import React, { useEffect } from 'react'; - -import type { Channel, Event } from 'stream-chat'; - -import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; - -type Parameters = { - refreshList: () => void; - setChannels: React.Dispatch>; - setForceUpdate: React.Dispatch>; - onChannelTruncated?: ( - setChannels: React.Dispatch>, - event: Event, - ) => void; -}; - -export const useChannelTruncated = ({ - onChannelTruncated, - refreshList, - setChannels, - setForceUpdate, -}: Parameters) => { - const { client } = useChatContext(); - - useEffect(() => { - const handleEvent = (event: Event) => { - if (typeof onChannelTruncated === 'function') { - onChannelTruncated(setChannels, event); - } - refreshList(); - setForceUpdate((count) => count + 1); - }; - - const listener = client?.on('channel.truncated', handleEvent); - return () => listener?.unsubscribe(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); -}; diff --git a/package/src/components/ChannelList/hooks/listeners/useChannelVisible.ts b/package/src/components/ChannelList/hooks/listeners/useChannelVisible.ts deleted file mode 100644 index 2e3b84496a..0000000000 --- a/package/src/components/ChannelList/hooks/listeners/useChannelVisible.ts +++ /dev/null @@ -1,55 +0,0 @@ -import React, { useEffect } from 'react'; - -import type { Channel, Event } from 'stream-chat'; - -import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; - -import type { ChannelListEventListenerOptions } from '../../../../types/types'; -import { getChannel, moveChannelUp } from '../../utils'; - -type Parameters = { - setChannels: React.Dispatch>; - onChannelVisible?: ( - setChannels: React.Dispatch>, - event: Event, - options?: ChannelListEventListenerOptions, - ) => void; - options?: ChannelListEventListenerOptions; -}; - -export const useChannelVisible = ({ onChannelVisible, options, setChannels }: Parameters) => { - const { client } = useChatContext(); - - useEffect(() => { - const handleEvent = async (event: Event) => { - if (typeof onChannelVisible === 'function') { - onChannelVisible(setChannels, event); - } else { - if (!options) { - return; - } - const { sort } = options; - if (event.channel_id && event.channel_type) { - const channel = await getChannel({ - client, - id: event.channel_id, - type: event.channel_type, - }); - setChannels((channels) => - channels - ? moveChannelUp({ - channels, - channelToMove: channel, - sort, - }) - : channels, - ); - } - } - }; - - const listener = client?.on('channel.visible', handleEvent); - return () => listener?.unsubscribe(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); -}; diff --git a/package/src/components/ChannelList/hooks/listeners/useNewMessage.ts b/package/src/components/ChannelList/hooks/listeners/useNewMessage.ts deleted file mode 100644 index 915a10ebeb..0000000000 --- a/package/src/components/ChannelList/hooks/listeners/useNewMessage.ts +++ /dev/null @@ -1,91 +0,0 @@ -import React, { useEffect } from 'react'; - -import type { Channel, Event } from 'stream-chat'; - -import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; - -import type { ChannelListEventListenerOptions } from '../../../../types/types'; -import { moveChannelUp } from '../../utils'; -import { - isChannelArchived, - isChannelPinned, - shouldConsiderArchivedChannels, - shouldConsiderPinnedChannels, -} from '../utils'; - -type Parameters = { - lockChannelOrder: boolean; - setChannels: React.Dispatch>; - onNewMessage?: ( - lockChannelOrder: boolean, - setChannels: React.Dispatch>, - event: Event, - options?: ChannelListEventListenerOptions, - ) => void; - options?: ChannelListEventListenerOptions; -}; - -export const useNewMessage = ({ - lockChannelOrder, - onNewMessage, - options, - setChannels, -}: Parameters) => { - const { client } = useChatContext(); - - useEffect(() => { - const handleEvent = (event: Event) => { - if (typeof onNewMessage === 'function') { - onNewMessage(lockChannelOrder, setChannels, event, options); - } else { - if (!options) { - return; - } - const { filters, sort } = options; - const considerPinnedChannels = shouldConsiderPinnedChannels(sort); - const considerArchivedChannels = shouldConsiderArchivedChannels(filters); - - const channelType = event.channel_type; - const channelId = event.channel_id; - - if (!channelType || !channelId) { - return; - } - - setChannels((channels) => { - if (!channels) { - return channels; - } - const targetChannel = client.channel(channelType, channelId); - const targetChannelIndex = channels.indexOf(targetChannel); - - const isTargetChannelArchived = isChannelArchived(targetChannel); - const isTargetChannelPinned = isChannelPinned(targetChannel); - - if ( - // When archived filter false, and channel is archived - (considerArchivedChannels && isTargetChannelArchived && !filters?.archived) || - // When archived filter true, and channel is unarchived - (considerArchivedChannels && !isTargetChannelArchived && filters?.archived) || - // If the channel is pinned and we are not considering pinned channels - (isTargetChannelPinned && considerPinnedChannels) || - lockChannelOrder - ) { - return [...channels]; - } - - return moveChannelUp({ - channels, - channelToMove: targetChannel, - channelToMoveIndexWithinChannels: targetChannelIndex, - sort, - }); - }); - } - }; - - const listener = client?.on('message.new', handleEvent); - return () => listener?.unsubscribe(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); -}; diff --git a/package/src/components/ChannelList/hooks/listeners/useNewMessageNotification.ts b/package/src/components/ChannelList/hooks/listeners/useNewMessageNotification.ts deleted file mode 100644 index 0d00e9808e..0000000000 --- a/package/src/components/ChannelList/hooks/listeners/useNewMessageNotification.ts +++ /dev/null @@ -1,67 +0,0 @@ -import React, { useEffect } from 'react'; - -import type { Channel, Event } from 'stream-chat'; - -import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; - -import type { ChannelListEventListenerOptions } from '../../../../types/types'; -import { getChannel, moveChannelUp } from '../../utils'; -import { isChannelArchived } from '../utils'; - -type Parameters = { - setChannels: React.Dispatch>; - onNewMessageNotification?: ( - setChannels: React.Dispatch>, - event: Event, - options?: ChannelListEventListenerOptions, - ) => void; - options?: ChannelListEventListenerOptions; -}; - -export const useNewMessageNotification = ({ - onNewMessageNotification, - options, - setChannels, -}: Parameters) => { - const { client } = useChatContext(); - - useEffect(() => { - const handleEvent = async (event: Event) => { - if (typeof onNewMessageNotification === 'function') { - onNewMessageNotification(setChannels, event, options); - } else { - if (!options) { - return; - } - const { filters, sort } = options; - if (event.channel?.id && event.channel?.type) { - const channel = await getChannel({ - client, - id: event.channel.id, - type: event.channel.type, - }); - - // Handle archived channels - const considerArchivedChannels = filters && filters.archived === false; - if (isChannelArchived(channel) && considerArchivedChannels) { - return; - } - - setChannels((channels) => - channels - ? moveChannelUp({ - channels, - channelToMove: channel, - sort, - }) - : channels, - ); - } - } - }; - - const listener = client?.on('notification.message_new', handleEvent); - return () => listener?.unsubscribe(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); -}; diff --git a/package/src/components/ChannelList/hooks/listeners/useRemovedFromChannelNotification.ts b/package/src/components/ChannelList/hooks/listeners/useRemovedFromChannelNotification.ts deleted file mode 100644 index e9a72e4754..0000000000 --- a/package/src/components/ChannelList/hooks/listeners/useRemovedFromChannelNotification.ts +++ /dev/null @@ -1,41 +0,0 @@ -import React, { useEffect } from 'react'; - -import type { Channel, Event } from 'stream-chat'; - -import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; - -type Parameters = { - setChannels: React.Dispatch>; - onRemovedFromChannel?: ( - setChannels: React.Dispatch>, - event: Event, - ) => void; -}; - -export const useRemovedFromChannelNotification = ({ - onRemovedFromChannel, - setChannels, -}: Parameters) => { - const { client } = useChatContext(); - - useEffect(() => { - const handleEvent = (event: Event) => { - if (typeof onRemovedFromChannel === 'function') { - onRemovedFromChannel(setChannels, event); - } else { - setChannels((channels) => { - if (!channels) { - return channels; - } - - const newChannels = channels.filter((channel) => channel.cid !== event.channel?.cid); - return [...newChannels]; - }); - } - }; - - const listener = client?.on('notification.removed_from_channel', handleEvent); - return () => listener?.unsubscribe(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); -}; diff --git a/package/src/components/ChannelList/hooks/listeners/useUserPresence.ts b/package/src/components/ChannelList/hooks/listeners/useUserPresence.ts deleted file mode 100644 index c4e7c894ab..0000000000 --- a/package/src/components/ChannelList/hooks/listeners/useUserPresence.ts +++ /dev/null @@ -1,49 +0,0 @@ -import React, { useEffect } from 'react'; - -import type { Channel, Event } from 'stream-chat'; - -import { useChatContext } from '../../../../contexts/chatContext/ChatContext'; - -type Parameters = { - setChannels: React.Dispatch>; - setForceUpdate: React.Dispatch>; -}; - -/** - * Hook to update the channel members when the user presence changes - * @deprecated this hook will be removed in favour of the useChannelPreviewDisplayPresence to improve performance - */ -export const useUserPresence = ({ setChannels, setForceUpdate }: Parameters) => { - const { client } = useChatContext(); - - useEffect(() => { - const handleEvent = (event: Event) => { - setChannels((channels) => { - if (!channels) { - return channels; - } - - const newChannels = channels.map((channel) => { - if (!event.user?.id || !channel.state.members[event.user.id]) { - return channel; - } - channel.state.members[event.user.id].user = event.user; - return channel; - }); - - return [...newChannels]; - }); - setForceUpdate((u) => u + 1); - }; - - const listeners = [ - client?.on('user.presence.changed', handleEvent), - client?.on('user.updated', handleEvent), - ]; - - return () => { - listeners?.forEach((l) => l?.unsubscribe()); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); -}; diff --git a/package/src/components/index.ts b/package/src/components/index.ts index 169c7f7900..355e497b6d 100644 --- a/package/src/components/index.ts +++ b/package/src/components/index.ts @@ -44,16 +44,7 @@ export * from './ChannelList/ChannelListHeaderErrorIndicator'; export * from './ChannelList/ChannelListHeaderNetworkDownIndicator'; export * from './ChannelList/ChannelListLoadingIndicator'; export * from './ChannelList/ChannelListMessenger'; -export * from './ChannelList/hooks/listeners/useAddedToChannelNotification'; -export * from './ChannelList/hooks/listeners/useChannelDeleted'; -export * from './ChannelList/hooks/listeners/useChannelHidden'; -export * from './ChannelList/hooks/listeners/useChannelMemberUpdated'; -export * from './ChannelList/hooks/listeners/useChannelTruncated'; export * from './ChannelList/hooks/listeners/useChannelUpdated'; -export * from './ChannelList/hooks/listeners/useNewMessage'; -export * from './ChannelList/hooks/listeners/useNewMessageNotification'; -export * from './ChannelList/hooks/listeners/useRemovedFromChannelNotification'; -export * from './ChannelList/hooks/listeners/useUserPresence'; export * from './ChannelList/hooks/useCreateChannelsContext'; export * from './ChannelList/hooks/usePaginatedChannels'; export * from './ChannelList/hooks/useChannelMembershipState'; From e8db2622e9b7d974c1e44793b1bc8733167626f1 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Thu, 13 Mar 2025 16:35:27 +0100 Subject: [PATCH 22/60] chore: remove deps scope --- release/release.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/release.config.js b/release/release.config.js index 57400db19a..d8ded1c92e 100644 --- a/release/release.config.js +++ b/release/release.config.js @@ -10,7 +10,7 @@ module.exports = Promise.resolve().then(() => { { preset: 'angular', releaseRules: [ - { type: 'chore', scope: 'deps', release: 'patch' }, + { type: 'chore', release: 'patch' }, { type: 'refactor', release: 'patch' }, ], parserOpts: { From 2f336f359eda9e2a3a931670d3c3686a8002336b Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 1 Apr 2025 22:57:17 +0200 Subject: [PATCH 23/60] fix: all instances of FormatMessageResponse in respect to the new llc changes --- examples/SampleApp/yarn.lock | 12 ++++++------ package/expo-package/yarn.lock | 13 +++++++++---- package/native-package/yarn.lock | 13 +++++++++---- package/package.json | 2 +- package/src/components/Attachment/Gallery.tsx | 1 + package/src/components/Channel/Channel.tsx | 4 ++-- package/src/components/MessageList/MessageList.tsx | 8 ++++---- .../hooks/useShouldScrollToRecentOnNewOwnMessage.ts | 4 ++-- .../__tests__/__snapshots__/Thread.test.js.snap | 6 ++++++ .../messageInputContext/MessageInputContext.tsx | 3 ++- .../__snapshots__/sendMessage.test.tsx.snap | 8 ++++++-- package/src/hooks/useTranslatedMessage.ts | 4 ++-- package/src/mock-builders/api/channelMocks.tsx | 10 ++-------- package/src/store/apis/insertReaction.ts | 4 ++-- package/src/store/apis/updateMessage.ts | 4 ++-- package/src/store/apis/updateReaction.ts | 4 ++-- package/src/store/mappers/mapMessageToStorable.ts | 4 ++-- package/src/utils/utils.ts | 10 ++++------ package/yarn.lock | 10 +++++----- 19 files changed, 69 insertions(+), 55 deletions(-) diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index 4c6031a89e..936f672a22 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -4075,7 +4075,7 @@ es6-iterator@^2.0.3: es5-ext "^0.10.35" es6-symbol "^3.1.1" -es6-symbol@^3.1.1, es6-symbol@^3.1.3: +es6-symbol@^3.1.1, es6-symbol@^3.1.3, es6-symbol@^3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.4.tgz#f4e7d28013770b4208ecbf3e0bf14d3bcb557b8c" integrity sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg== @@ -5854,7 +5854,7 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -linkifyjs@^4.1.1: +linkifyjs@^4.1.1, linkifyjs@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== @@ -7538,10 +7538,9 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.8: - version "9.0.0-rc.8" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.8.tgz#e188e481841493584691ae491916843d0ef5f9cd" - integrity sha512-P+Ksnu1cQQfL1t2/QTJ5rr/z2Jehvd2ap41xZgtfbJssHSD7ahe14TCF/1L7q4jjaNlZcTtLcKXCWbbOdKjDcg== +"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": + version "0.0.0-development" + resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -7550,6 +7549,7 @@ stream-chat@9.0.0-rc.8: form-data "^4.0.0" isomorphic-ws "^5.0.0" jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" ws "^8.18.1" strict-uri-encode@^2.0.0: diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 0bda5364ca..89f49712c7 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -3589,6 +3589,11 @@ linkifyjs@^4.1.1: resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.1.tgz#73d427e3bbaaf4ca8e71c589ad4ffda11a9a5fde" integrity sha512-zFN/CTVmbcVef+WaDXT63dNzzkfRBKT1j464NJQkV7iSgJU0sLBus9W0HBwnXK13/hf168pbrx/V/bjEHOXNHA== +linkifyjs@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" + integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -4772,10 +4777,9 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.8: - version "9.0.0-rc.8" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.8.tgz#e188e481841493584691ae491916843d0ef5f9cd" - integrity sha512-P+Ksnu1cQQfL1t2/QTJ5rr/z2Jehvd2ap41xZgtfbJssHSD7ahe14TCF/1L7q4jjaNlZcTtLcKXCWbbOdKjDcg== +"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": + version "0.0.0-development" + resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -4784,6 +4788,7 @@ stream-chat@9.0.0-rc.8: form-data "^4.0.0" isomorphic-ws "^5.0.0" jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" ws "^8.18.1" "string-width-cjs@npm:string-width@^4.2.0": diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index c9e6abf748..38eb6e1a30 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -2520,6 +2520,11 @@ linkifyjs@^4.1.1: resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.1.tgz#73d427e3bbaaf4ca8e71c589ad4ffda11a9a5fde" integrity sha512-zFN/CTVmbcVef+WaDXT63dNzzkfRBKT1j464NJQkV7iSgJU0sLBus9W0HBwnXK13/hf168pbrx/V/bjEHOXNHA== +linkifyjs@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" + integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -3488,10 +3493,9 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.8: - version "9.0.0-rc.8" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.8.tgz#e188e481841493584691ae491916843d0ef5f9cd" - integrity sha512-P+Ksnu1cQQfL1t2/QTJ5rr/z2Jehvd2ap41xZgtfbJssHSD7ahe14TCF/1L7q4jjaNlZcTtLcKXCWbbOdKjDcg== +"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": + version "0.0.0-development" + resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -3500,6 +3504,7 @@ stream-chat@9.0.0-rc.8: form-data "^4.0.0" isomorphic-ws "^5.0.0" jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" ws "^8.18.1" string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: diff --git a/package/package.json b/package/package.json index 0b710cb1f9..7c6bb21e16 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "9.0.0-rc.8", + "stream-chat": "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/src/components/Attachment/Gallery.tsx b/package/src/components/Attachment/Gallery.tsx index 13e26f59b4..cc6c11209f 100644 --- a/package/src/components/Attachment/Gallery.tsx +++ b/package/src/components/Attachment/Gallery.tsx @@ -605,6 +605,7 @@ export const Gallery = (props: GalleryProps) => { const videos = propVideos || contextVideos; const message = propMessage || contextMessage; + console.log('TEST: ', images, videos); if (!images.length && !videos.length) { return null; } diff --git a/package/src/components/Channel/Channel.tsx b/package/src/components/Channel/Channel.tsx index 8b339d59e3..2eb016c910 100644 --- a/package/src/components/Channel/Channel.tsx +++ b/package/src/components/Channel/Channel.tsx @@ -11,7 +11,7 @@ import { ChannelState, Channel as ChannelType, EventHandler, - FormatMessageResponse, + LocalMessage, MessageLabel, MessageResponse, Reaction, @@ -1009,7 +1009,7 @@ const ChannelWithContext = (props: PropsWithChildren) = }); } - const parseMessage = (message: FormatMessageResponse) => + const parseMessage = (message: LocalMessage) => ({ ...message, created_at: message.created_at.toString(), diff --git a/package/src/components/MessageList/MessageList.tsx b/package/src/components/MessageList/MessageList.tsx index e4c3e0d4b8..ac5f719376 100644 --- a/package/src/components/MessageList/MessageList.tsx +++ b/package/src/components/MessageList/MessageList.tsx @@ -10,7 +10,7 @@ import { ViewToken, } from 'react-native'; -import type { FormatMessageResponse } from 'stream-chat'; +import type { LocalMessage } from 'stream-chat'; import { isMessageWithStylesReadByAndDateSeparator, @@ -310,9 +310,9 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { * We need topMessage and channelLastRead values to set the initial scroll position. * So these values only get used if `initialScrollToFirstUnreadMessage` prop is true. */ - const topMessageBeforeUpdate = useRef(undefined); - const latestNonCurrentMessageBeforeUpdateRef = useRef(undefined); - const topMessageAfterUpdate: FormatMessageResponse | undefined = rawMessageList[0]; + const topMessageBeforeUpdate = useRef(undefined); + const latestNonCurrentMessageBeforeUpdateRef = useRef(undefined); + const topMessageAfterUpdate: LocalMessage | undefined = rawMessageList[0]; const shouldScrollToRecentOnNewOwnMessageRef = useShouldScrollToRecentOnNewOwnMessage( rawMessageList, diff --git a/package/src/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.ts b/package/src/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.ts index 76cdb4fe13..43c722d87f 100644 --- a/package/src/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.ts +++ b/package/src/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.ts @@ -1,9 +1,9 @@ import { useEffect, useRef } from 'react'; -import type { FormatMessageResponse } from 'stream-chat'; +import type { LocalMessage } from 'stream-chat'; export function useShouldScrollToRecentOnNewOwnMessage( - rawMessageList: FormatMessageResponse[], + rawMessageList: LocalMessage[], currentUserId?: string, ) { const lastFocusedOwnMessageId = useRef(''); diff --git a/package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap b/package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap index 8efc41d9f5..677fb17a45 100644 --- a/package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +++ b/package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap @@ -53,6 +53,7 @@ exports[`Thread should match thread snapshot 1`] = ` "created_at": 2020-05-05T14:50:00.000Z, "dateSeparator": undefined, "deleted_at": null, + "error": null, "groupStyles": [ "single", ], @@ -61,6 +62,7 @@ exports[`Thread should match thread snapshot 1`] = ` "message_text_updated_at": "2020-05-05T14:50:00.000Z", "parent_id": "b4612a73-fa2b-5787-bf71-1adc8f291a04", "pinned_at": null, + "quoted_message": null, "reaction_groups": null, "readBy": false, "status": "received", @@ -83,6 +85,7 @@ exports[`Thread should match thread snapshot 1`] = ` "created_at": 2020-05-05T14:50:00.000Z, "dateSeparator": undefined, "deleted_at": null, + "error": null, "groupStyles": [ "single", ], @@ -91,6 +94,7 @@ exports[`Thread should match thread snapshot 1`] = ` "message_text_updated_at": "2020-05-05T14:50:00.000Z", "parent_id": "b4612a73-fa2b-5787-bf71-1adc8f291a04", "pinned_at": null, + "quoted_message": null, "reaction_groups": null, "readBy": false, "status": "received", @@ -113,6 +117,7 @@ exports[`Thread should match thread snapshot 1`] = ` "created_at": 2020-05-05T14:50:00.000Z, "dateSeparator": 2020-05-05T14:50:00.000Z, "deleted_at": null, + "error": null, "groupStyles": [ "single", ], @@ -121,6 +126,7 @@ exports[`Thread should match thread snapshot 1`] = ` "message_text_updated_at": "2020-05-05T14:50:00.000Z", "parent_id": "b4612a73-fa2b-5787-bf71-1adc8f291a04", "pinned_at": null, + "quoted_message": null, "reaction_groups": null, "readBy": false, "status": "received", diff --git a/package/src/contexts/messageInputContext/MessageInputContext.tsx b/package/src/contexts/messageInputContext/MessageInputContext.tsx index 79df86633d..b8d0359cdf 100644 --- a/package/src/contexts/messageInputContext/MessageInputContext.tsx +++ b/package/src/contexts/messageInputContext/MessageInputContext.tsx @@ -998,7 +998,8 @@ export const MessageInputProvider = ({ const updatedMessage = { ...message, attachments, - mentioned_users: mentionedUsers, + // FIXME: Temp fix, check the implications of this. + mentioned_users: mentionedUsers.map((userId) => ({ id: userId })), quoted_message: undefined, text: prevText, ...customMessageData, diff --git a/package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap b/package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap index 7ce13b373f..27b76669e9 100644 --- a/package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap +++ b/package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap @@ -18,8 +18,12 @@ exports[`MessageInputContext's sendMessage exit sendMessage when edit message is "html": "

regular

", "id": "7a85f744-cc89-4f82-a1d4-5456432cc8bf", "mentioned_users": [ - "dummy1", - "dummy2", + { + "id": "dummy1", + }, + { + "id": "dummy2", + }, ], "quoted_message": undefined, "text": "", diff --git a/package/src/hooks/useTranslatedMessage.ts b/package/src/hooks/useTranslatedMessage.ts index ea7c113f56..628c6ef99a 100644 --- a/package/src/hooks/useTranslatedMessage.ts +++ b/package/src/hooks/useTranslatedMessage.ts @@ -1,10 +1,10 @@ -import type { FormatMessageResponse, MessageResponse, TranslationLanguages } from 'stream-chat'; +import type { LocalMessage, MessageResponse, TranslationLanguages } from 'stream-chat'; import { useTranslationContext } from '../contexts/translationContext/TranslationContext'; type TranslationKey = `${TranslationLanguages}_text`; -export const useTranslatedMessage = (message?: MessageResponse | FormatMessageResponse) => { +export const useTranslatedMessage = (message?: MessageResponse | LocalMessage) => { const { userLanguage } = useTranslationContext(); const translationKey: TranslationKey = `${userLanguage}_text`; diff --git a/package/src/mock-builders/api/channelMocks.tsx b/package/src/mock-builders/api/channelMocks.tsx index 7c0b28244f..35839a1e70 100644 --- a/package/src/mock-builders/api/channelMocks.tsx +++ b/package/src/mock-builders/api/channelMocks.tsx @@ -1,10 +1,4 @@ -import type { - Attachment, - Channel, - FormatMessageResponse, - MessageResponse, - UserResponse, -} from 'stream-chat'; +import type { Attachment, Channel, LocalMessage, MessageResponse, UserResponse } from 'stream-chat'; import { GROUP_CHANNEL_MEMBERS_MOCK, @@ -168,7 +162,7 @@ const LATEST_MESSAGE = { user: { id: 'okechukwu' } as unknown as UserResponse, } as unknown as MessageResponse; -const FORMATTED_MESSAGE: FormatMessageResponse = { +const FORMATTED_MESSAGE: LocalMessage = { created_at: new Date('2021-02-12T12:12:35.862282Z'), id: '', message: {} as unknown as MessageResponse, diff --git a/package/src/store/apis/insertReaction.ts b/package/src/store/apis/insertReaction.ts index 5819090b04..1ec6eb4111 100644 --- a/package/src/store/apis/insertReaction.ts +++ b/package/src/store/apis/insertReaction.ts @@ -1,4 +1,4 @@ -import type { FormatMessageResponse, MessageResponse, ReactionResponse } from 'stream-chat'; +import type { LocalMessage, MessageResponse, ReactionResponse } from 'stream-chat'; import { mapReactionToStorable } from '../mappers/mapReactionToStorable'; import { createUpdateQuery } from '../sqlite-utils/createUpdateQuery'; @@ -11,7 +11,7 @@ export const insertReaction = async ({ message, reaction, }: { - message: MessageResponse | FormatMessageResponse; + message: MessageResponse | LocalMessage; reaction: ReactionResponse; flush?: boolean; }) => { diff --git a/package/src/store/apis/updateMessage.ts b/package/src/store/apis/updateMessage.ts index 75ba87e21c..290a6fc794 100644 --- a/package/src/store/apis/updateMessage.ts +++ b/package/src/store/apis/updateMessage.ts @@ -1,4 +1,4 @@ -import type { FormatMessageResponse, MessageResponse } from 'stream-chat'; +import type { LocalMessage, MessageResponse } from 'stream-chat'; import { mapMessageToStorable } from '../mappers/mapMessageToStorable'; import { mapReactionToStorable } from '../mappers/mapReactionToStorable'; @@ -14,7 +14,7 @@ export const updateMessage = async ({ flush = true, message, }: { - message: MessageResponse | FormatMessageResponse; + message: MessageResponse | LocalMessage; flush?: boolean; }) => { const queries: PreparedQueries[] = []; diff --git a/package/src/store/apis/updateReaction.ts b/package/src/store/apis/updateReaction.ts index b355fbc270..ddd6ad9e50 100644 --- a/package/src/store/apis/updateReaction.ts +++ b/package/src/store/apis/updateReaction.ts @@ -1,4 +1,4 @@ -import type { FormatMessageResponse, MessageResponse, ReactionResponse } from 'stream-chat'; +import type { LocalMessage, MessageResponse, ReactionResponse } from 'stream-chat'; import { mapMessageToStorable } from '../mappers/mapMessageToStorable'; import { mapReactionToStorable } from '../mappers/mapReactionToStorable'; @@ -13,7 +13,7 @@ export const updateReaction = async ({ message, reaction, }: { - message: MessageResponse | FormatMessageResponse; + message: MessageResponse | LocalMessage; reaction: ReactionResponse; flush?: boolean; }) => { diff --git a/package/src/store/mappers/mapMessageToStorable.ts b/package/src/store/mappers/mapMessageToStorable.ts index e8f4484eef..74dda7adb9 100644 --- a/package/src/store/mappers/mapMessageToStorable.ts +++ b/package/src/store/mappers/mapMessageToStorable.ts @@ -1,11 +1,11 @@ -import type { FormatMessageResponse, MessageResponse } from 'stream-chat'; +import type { LocalMessage, MessageResponse } from 'stream-chat'; import { mapDateTimeToStorable } from './mapDateTimeToStorable'; import type { TableRow } from '../types'; export const mapMessageToStorable = ( - message: MessageResponse | FormatMessageResponse, + message: MessageResponse | LocalMessage, ): TableRow<'messages'> => { const { attachments, diff --git a/package/src/utils/utils.ts b/package/src/utils/utils.ts index 684bdae3f4..b31b1dc35d 100644 --- a/package/src/utils/utils.ts +++ b/package/src/utils/utils.ts @@ -2,7 +2,7 @@ import type React from 'react'; import dayjs from 'dayjs'; import EmojiRegex from 'emoji-regex'; -import type { ChannelState, FormatMessageResponse, MessageResponse } from 'stream-chat'; +import type { ChannelState, LocalMessage, MessageResponse } from 'stream-chat'; import { IconProps } from '../../src/icons/utils/base'; import { @@ -187,12 +187,10 @@ export const hasOnlyEmojis = (text: string) => { /** * Stringifies a message object - * @param {FormatMessageResponse} message - the message object to be stringified + * @param {LocalMessage} message - the message object to be stringified * @returns {string} The stringified message */ -export const stringifyMessage = ( - message: MessageResponse | FormatMessageResponse | MessageType, -): string => { +export const stringifyMessage = (message: MessageResponse | LocalMessage | MessageType): string => { const { deleted_at, i18n, @@ -224,7 +222,7 @@ export const stringifyMessage = ( * @param {messages} messages - the array of messages to be compared * @returns {string} The mapped message string */ -export const reduceMessagesToString = (messages: FormatMessageResponse[]): string => +export const reduceMessagesToString = (messages: LocalMessage[]): string => messages.map(stringifyMessage).join(); /** diff --git a/package/yarn.lock b/package/yarn.lock index 9c6c880a17..5e3502499d 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -5668,7 +5668,7 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -linkifyjs@^4.1.1: +linkifyjs@^4.1.1, linkifyjs@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== @@ -7680,10 +7680,9 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat@9.0.0-rc.8: - version "9.0.0-rc.8" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.8.tgz#e188e481841493584691ae491916843d0ef5f9cd" - integrity sha512-P+Ksnu1cQQfL1t2/QTJ5rr/z2Jehvd2ap41xZgtfbJssHSD7ahe14TCF/1L7q4jjaNlZcTtLcKXCWbbOdKjDcg== +"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": + version "0.0.0-development" + resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -7692,6 +7691,7 @@ stream-chat@9.0.0-rc.8: form-data "^4.0.0" isomorphic-ws "^5.0.0" jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" ws "^8.18.1" stream-composer@^1.0.2: From 98349dd1509130f94bc4dc14da14563634ed891b Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 1 Apr 2025 23:05:29 +0200 Subject: [PATCH 24/60] chore: ref branch specifically --- package/expo-package/yarn.lock | 2 +- package/native-package/yarn.lock | 2 +- package/package.json | 2 +- package/yarn.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 89f49712c7..3eb0e475f9 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -4777,7 +4777,7 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": +"stream-chat@https://github.com/GetStream/stream-chat-js.git#feat/message-composer": version "0.0.0-development" resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 38eb6e1a30..7cc1e2077f 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -3493,7 +3493,7 @@ statuses@~1.5.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": +"stream-chat@https://github.com/GetStream/stream-chat-js.git#feat/message-composer": version "0.0.0-development" resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: diff --git a/package/package.json b/package/package.json index 7c6bb21e16..faa36106d7 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917", + "stream-chat": "https://github.com/GetStream/stream-chat-js.git#feat/message-composer", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/yarn.lock b/package/yarn.lock index 5e3502499d..2a2d8bb5f2 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -7680,7 +7680,7 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": +"stream-chat@https://github.com/GetStream/stream-chat-js.git#feat/message-composer": version "0.0.0-development" resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: From a40724c5573ab37c4427ae81a1f1ec1238b85a18 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 1 Apr 2025 23:22:08 +0200 Subject: [PATCH 25/60] fix: try clearing cache --- .github/actions/install-and-build-sdk/action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/install-and-build-sdk/action.yml b/.github/actions/install-and-build-sdk/action.yml index 5ba82e4bc2..21b0649fa0 100644 --- a/.github/actions/install-and-build-sdk/action.yml +++ b/.github/actions/install-and-build-sdk/action.yml @@ -9,6 +9,7 @@ runs: - name: Install & Build the Core Package run: | cd package/ + yarn cache clean yarn --frozen-lockfile shell: bash - name: Install & Build the Native Package From 7ea6f383e3b5ada8d1d3ccf38805b4635228c9ef Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 1 Apr 2025 23:44:31 +0200 Subject: [PATCH 26/60] fix: remove cache clean --- .github/actions/install-and-build-sdk/action.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/actions/install-and-build-sdk/action.yml b/.github/actions/install-and-build-sdk/action.yml index 21b0649fa0..5ba82e4bc2 100644 --- a/.github/actions/install-and-build-sdk/action.yml +++ b/.github/actions/install-and-build-sdk/action.yml @@ -9,7 +9,6 @@ runs: - name: Install & Build the Core Package run: | cd package/ - yarn cache clean yarn --frozen-lockfile shell: bash - name: Install & Build the Native Package From fa903f0786d0a582e785d38df3463e6e3a4d4903 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Wed, 2 Apr 2025 08:25:05 +0200 Subject: [PATCH 27/60] fix: remove console.log --- package/src/components/Attachment/Gallery.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/package/src/components/Attachment/Gallery.tsx b/package/src/components/Attachment/Gallery.tsx index cc6c11209f..13e26f59b4 100644 --- a/package/src/components/Attachment/Gallery.tsx +++ b/package/src/components/Attachment/Gallery.tsx @@ -605,7 +605,6 @@ export const Gallery = (props: GalleryProps) => { const videos = propVideos || contextVideos; const message = propMessage || contextMessage; - console.log('TEST: ', images, videos); if (!images.length && !videos.length) { return null; } From fdc9774415a668897e75c31654d83805d6bf5c8d Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Wed, 2 Apr 2025 09:06:19 +0200 Subject: [PATCH 28/60] fix: use latest commit --- package/expo-package/yarn.lock | 2 +- package/native-package/yarn.lock | 2 +- package/package.json | 2 +- package/yarn.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 3eb0e475f9..89f49712c7 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -4777,7 +4777,7 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#feat/message-composer": +"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": version "0.0.0-development" resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 7cc1e2077f..38eb6e1a30 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -3493,7 +3493,7 @@ statuses@~1.5.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#feat/message-composer": +"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": version "0.0.0-development" resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: diff --git a/package/package.json b/package/package.json index faa36106d7..7c6bb21e16 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "https://github.com/GetStream/stream-chat-js.git#feat/message-composer", + "stream-chat": "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/yarn.lock b/package/yarn.lock index 2a2d8bb5f2..5e3502499d 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -7680,7 +7680,7 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -"stream-chat@https://github.com/GetStream/stream-chat-js.git#feat/message-composer": +"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": version "0.0.0-development" resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: From e01a1b0e8b04c185edf01983441ed6492637fbc1 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Wed, 2 Apr 2025 09:20:53 +0200 Subject: [PATCH 29/60] fix: use latest rc of llc --- package/expo-package/yarn.lock | 13 ++++--------- package/native-package/yarn.lock | 13 ++++--------- package/package.json | 2 +- package/yarn.lock | 10 +++++----- 4 files changed, 14 insertions(+), 24 deletions(-) diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 89f49712c7..64655579a7 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -3589,11 +3589,6 @@ linkifyjs@^4.1.1: resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.1.tgz#73d427e3bbaaf4ca8e71c589ad4ffda11a9a5fde" integrity sha512-zFN/CTVmbcVef+WaDXT63dNzzkfRBKT1j464NJQkV7iSgJU0sLBus9W0HBwnXK13/hf168pbrx/V/bjEHOXNHA== -linkifyjs@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" - integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -4777,9 +4772,10 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": - version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" +stream-chat@9.0.0-rc.9: + version "9.0.0-rc.9" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.9.tgz#e07593b214defd5d127080a5cfd965b5a79fda34" + integrity sha512-8nbfUXdhkXCBAzV9H+8mSqcjqtZT/mVKEVfv09RZTH7NuJgmSJ+SLpqFuLycyvwCdrAopMRJ0J3GjmnAHA3x8w== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -4788,7 +4784,6 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: form-data "^4.0.0" isomorphic-ws "^5.0.0" jsonwebtoken "^9.0.2" - linkifyjs "^4.2.0" ws "^8.18.1" "string-width-cjs@npm:string-width@^4.2.0": diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 38eb6e1a30..8152fe446f 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -2520,11 +2520,6 @@ linkifyjs@^4.1.1: resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.1.tgz#73d427e3bbaaf4ca8e71c589ad4ffda11a9a5fde" integrity sha512-zFN/CTVmbcVef+WaDXT63dNzzkfRBKT1j464NJQkV7iSgJU0sLBus9W0HBwnXK13/hf168pbrx/V/bjEHOXNHA== -linkifyjs@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" - integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -3493,9 +3488,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": - version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" +stream-chat@9.0.0-rc.9: + version "9.0.0-rc.9" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.9.tgz#e07593b214defd5d127080a5cfd965b5a79fda34" + integrity sha512-8nbfUXdhkXCBAzV9H+8mSqcjqtZT/mVKEVfv09RZTH7NuJgmSJ+SLpqFuLycyvwCdrAopMRJ0J3GjmnAHA3x8w== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -3504,7 +3500,6 @@ statuses@~1.5.0: form-data "^4.0.0" isomorphic-ws "^5.0.0" jsonwebtoken "^9.0.2" - linkifyjs "^4.2.0" ws "^8.18.1" string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: diff --git a/package/package.json b/package/package.json index 7c6bb21e16..2ef6c17041 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917", + "stream-chat": "9.0.0-rc.9", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/yarn.lock b/package/yarn.lock index 5e3502499d..eea17a86ae 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -5668,7 +5668,7 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -linkifyjs@^4.1.1, linkifyjs@^4.2.0: +linkifyjs@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== @@ -7680,9 +7680,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": - version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" +stream-chat@9.0.0-rc.9: + version "9.0.0-rc.9" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.9.tgz#e07593b214defd5d127080a5cfd965b5a79fda34" + integrity sha512-8nbfUXdhkXCBAzV9H+8mSqcjqtZT/mVKEVfv09RZTH7NuJgmSJ+SLpqFuLycyvwCdrAopMRJ0J3GjmnAHA3x8w== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -7691,7 +7692,6 @@ statuses@~1.5.0: form-data "^4.0.0" isomorphic-ws "^5.0.0" jsonwebtoken "^9.0.2" - linkifyjs "^4.2.0" ws "^8.18.1" stream-composer@^1.0.2: From eae044b299ea74e750ed171bc956dbbfd8fc1779 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Wed, 2 Apr 2025 09:24:43 +0200 Subject: [PATCH 30/60] chore: use specific commit again --- package/expo-package/yarn.lock | 13 +++++++++---- package/native-package/yarn.lock | 13 +++++++++---- package/package.json | 2 +- package/yarn.lock | 10 +++++----- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 64655579a7..89f49712c7 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -3589,6 +3589,11 @@ linkifyjs@^4.1.1: resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.1.tgz#73d427e3bbaaf4ca8e71c589ad4ffda11a9a5fde" integrity sha512-zFN/CTVmbcVef+WaDXT63dNzzkfRBKT1j464NJQkV7iSgJU0sLBus9W0HBwnXK13/hf168pbrx/V/bjEHOXNHA== +linkifyjs@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" + integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -4772,10 +4777,9 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.9: - version "9.0.0-rc.9" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.9.tgz#e07593b214defd5d127080a5cfd965b5a79fda34" - integrity sha512-8nbfUXdhkXCBAzV9H+8mSqcjqtZT/mVKEVfv09RZTH7NuJgmSJ+SLpqFuLycyvwCdrAopMRJ0J3GjmnAHA3x8w== +"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": + version "0.0.0-development" + resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -4784,6 +4788,7 @@ stream-chat@9.0.0-rc.9: form-data "^4.0.0" isomorphic-ws "^5.0.0" jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" ws "^8.18.1" "string-width-cjs@npm:string-width@^4.2.0": diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 8152fe446f..38eb6e1a30 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -2520,6 +2520,11 @@ linkifyjs@^4.1.1: resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.1.tgz#73d427e3bbaaf4ca8e71c589ad4ffda11a9a5fde" integrity sha512-zFN/CTVmbcVef+WaDXT63dNzzkfRBKT1j464NJQkV7iSgJU0sLBus9W0HBwnXK13/hf168pbrx/V/bjEHOXNHA== +linkifyjs@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" + integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -3488,10 +3493,9 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.9: - version "9.0.0-rc.9" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.9.tgz#e07593b214defd5d127080a5cfd965b5a79fda34" - integrity sha512-8nbfUXdhkXCBAzV9H+8mSqcjqtZT/mVKEVfv09RZTH7NuJgmSJ+SLpqFuLycyvwCdrAopMRJ0J3GjmnAHA3x8w== +"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": + version "0.0.0-development" + resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -3500,6 +3504,7 @@ stream-chat@9.0.0-rc.9: form-data "^4.0.0" isomorphic-ws "^5.0.0" jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" ws "^8.18.1" string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: diff --git a/package/package.json b/package/package.json index 2ef6c17041..7c6bb21e16 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "9.0.0-rc.9", + "stream-chat": "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/yarn.lock b/package/yarn.lock index eea17a86ae..5e3502499d 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -5668,7 +5668,7 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -linkifyjs@^4.1.1: +linkifyjs@^4.1.1, linkifyjs@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== @@ -7680,10 +7680,9 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat@9.0.0-rc.9: - version "9.0.0-rc.9" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.9.tgz#e07593b214defd5d127080a5cfd965b5a79fda34" - integrity sha512-8nbfUXdhkXCBAzV9H+8mSqcjqtZT/mVKEVfv09RZTH7NuJgmSJ+SLpqFuLycyvwCdrAopMRJ0J3GjmnAHA3x8w== +"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": + version "0.0.0-development" + resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -7692,6 +7691,7 @@ stream-chat@9.0.0-rc.9: form-data "^4.0.0" isomorphic-ws "^5.0.0" jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" ws "^8.18.1" stream-composer@^1.0.2: From 40dee7eb0f373024b1f66ad5dbbe1817553875b5 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Wed, 2 Apr 2025 14:40:20 +0200 Subject: [PATCH 31/60] fix: SCG remnants from merge --- examples/SampleApp/yarn.lock | 8 ++++---- .../components/MessageList/MessageList.tsx | 19 +++++-------------- .../components/ThreadFooterComponent.tsx | 15 ++++----------- 3 files changed, 13 insertions(+), 29 deletions(-) diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index 936f672a22..f92346e8f4 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -1969,10 +1969,10 @@ dependencies: merge-options "^3.0.4" -"@react-native-camera-roll/camera-roll@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@react-native-camera-roll/camera-roll/-/camera-roll-7.9.0.tgz#7b3d199b073e9f63d49852c44456c4fa0aa27e90" - integrity sha512-Ra0lB1G2H11MzL5aIH3bwlxU1zaHGSZeRs4lBXLBO64Ai1gUgZPR7TYgKDeeRPzNPtSbZKmzs+fuZ/7XoCf1SA== +"@react-native-camera-roll/camera-roll@^7.10.0": + version "7.10.0" + resolved "https://registry.yarnpkg.com/@react-native-camera-roll/camera-roll/-/camera-roll-7.10.0.tgz#5e9518d78a9cd87ddc8e68d03e31a608df5033ab" + integrity sha512-Zm1yHxxTQS2APsnnxUFoLnK+DMMTPqmIQ2z2pGtNyHRXAG40Nt4MLVB3tDJTWnuJLAG87BpTCEvpz49+u0YkUw== "@react-native-community/cli-clean@15.1.3": version "15.1.3" diff --git a/package/src/components/MessageList/MessageList.tsx b/package/src/components/MessageList/MessageList.tsx index f79295ea83..db0235eca9 100644 --- a/package/src/components/MessageList/MessageList.tsx +++ b/package/src/components/MessageList/MessageList.tsx @@ -10,7 +10,7 @@ import { ViewToken, } from 'react-native'; -import type { Channel, LocalMessage } from 'stream-chat'; +import type { Channel, Event, LocalMessage, MessageResponse } from 'stream-chat'; import { isMessageWithStylesReadByAndDateSeparator, @@ -104,19 +104,13 @@ const flatListViewabilityConfig: ViewabilityConfig = { viewAreaCoveragePercentThreshold: 1, }; -const hasReadLastMessage = ( - channel: Channel, - userId: string, -) => { +const hasReadLastMessage = (channel: Channel, userId: string) => { const latestMessageIdInChannel = channel.state.latestMessages.slice(-1)[0]?.id; const lastReadMessageIdServer = channel.state.read[userId]?.last_read_message_id; return latestMessageIdInChannel === lastReadMessageIdServer; }; -const getPreviousLastMessage = ( - messages: MessageType[], - newMessage?: MessageResponse, -) => { +const getPreviousLastMessage = (messages: MessageType[], newMessage?: MessageResponse) => { if (!newMessage) return; let previousLastMessage; for (let i = messages.length - 1; i >= 0; i--) { @@ -526,16 +520,13 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { ); }; - const handleEvent = async (event: Event) => { + const handleEvent = async (event: Event) => { const mainChannelUpdated = !event.message?.parent_id || event.message?.show_in_channel; // When the scrollToBottomButtonVisible is true, we need to manually update the channelUnreadState. if (scrollToBottomButtonVisible || channelUnreadState?.first_unread_message_id) { setChannelUnreadState((prev) => { const previousUnreadCount = prev?.unread_messages ?? 0; - const previousLastMessage = getPreviousLastMessage( - channel.state.messages, - event.message, - ); + const previousLastMessage = getPreviousLastMessage(channel.state.messages, event.message); return { ...(prev || {}), last_read: diff --git a/package/src/components/Thread/components/ThreadFooterComponent.tsx b/package/src/components/Thread/components/ThreadFooterComponent.tsx index 2344358b05..6af6a455e0 100644 --- a/package/src/components/Thread/components/ThreadFooterComponent.tsx +++ b/package/src/components/Thread/components/ThreadFooterComponent.tsx @@ -41,11 +41,8 @@ const styles = StyleSheet.create({ }, }); -type ThreadFooterComponentPropsWithContext = Pick, 'Message'> & - Pick< - ThreadContextValue, - 'parentMessagePreventPress' | 'thread' | 'threadInstance' - >; +type ThreadFooterComponentPropsWithContext = Pick & + Pick; export const InlineLoadingMoreThreadIndicator = () => { const { threadLoadingMore } = useThreadContext(); @@ -71,9 +68,7 @@ const selector = (nextValue: ThreadState) => replyCount: nextValue.replyCount, }) as const; -const ThreadFooterComponentWithContext = ( - props: ThreadFooterComponentPropsWithContext, -) => { +const ThreadFooterComponentWithContext = (props: ThreadFooterComponentPropsWithContext) => { const { Message, parentMessagePreventPress, thread, threadInstance } = props; const { t } = useTranslationContext(); const { vw } = useViewport(); @@ -204,9 +199,7 @@ const MemoizedThreadFooter = React.memo( export type ThreadFooterComponentProps = Partial> & Partial>; -export const ThreadFooterComponent = ( - props: ThreadFooterComponentProps, -) => { +export const ThreadFooterComponent = (props: ThreadFooterComponentProps) => { const { Message } = useMessagesContext(); const { parentMessagePreventPress, thread, threadInstance, threadLoadingMore } = useThreadContext(); From b94726690f6441e29169a70239106c4dd801c9a6 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Wed, 9 Apr 2025 18:07:33 +0200 Subject: [PATCH 32/60] fix: lint issues --- package/src/components/Channel/Channel.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/package/src/components/Channel/Channel.tsx b/package/src/components/Channel/Channel.tsx index 031f69e61a..5aed2134d1 100644 --- a/package/src/components/Channel/Channel.tsx +++ b/package/src/components/Channel/Channel.tsx @@ -1721,9 +1721,7 @@ const ChannelWithContext = (props: PropsWithChildren) = // once our memoization issues are fixed in most places in the app or we move to a reactive state store. const sendMessageRef = useRef(sendMessage); sendMessageRef.current = sendMessage; - const sendMessageStable = useCallback< - InputMessageInputContextValue['sendMessage'] - >((...args) => { + const sendMessageStable = useCallback((...args) => { return sendMessageRef.current(...args); }, []); From 491a957ccbb20596866706b9b22367e4caf68672 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Fri, 11 Apr 2025 01:01:48 +0200 Subject: [PATCH 33/60] fix: lint issues --- .../components/AutoCompleteInput/AutoCompleteInput.tsx | 9 ++------- package/src/components/MessageInput/MessageInput.tsx | 5 ++++- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx b/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx index 8a26239786..f057f3eb68 100644 --- a/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx +++ b/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx @@ -63,10 +63,7 @@ type AutoCompleteInputPropsWithContext = Pick< | 'text' | 'triggerSettings' > & - Pick< - SuggestionsContextValue, - 'closeSuggestions' | 'openSuggestions' | 'updateSuggestions' - > & + Pick & Pick & { /** * This is currently passed in from MessageInput to avoid rerenders @@ -461,9 +458,7 @@ const MemoizedAutoCompleteInput = React.memo( areEqual, ) as typeof AutoCompleteInputWithContext; -export const AutoCompleteInput = ( - props: AutoCompleteInputProps, -) => { +export const AutoCompleteInput = (props: AutoCompleteInputProps) => { const { giphyEnabled, additionalTextInputProps, diff --git a/package/src/components/MessageInput/MessageInput.tsx b/package/src/components/MessageInput/MessageInput.tsx index 10289083fc..564579ebca 100644 --- a/package/src/components/MessageInput/MessageInput.tsx +++ b/package/src/components/MessageInput/MessageInput.tsx @@ -104,7 +104,10 @@ const styles = StyleSheet.create({ }, }); -type MessageInputPropsWithContext = Pick & +type MessageInputPropsWithContext = Pick< + AttachmentPickerContextValue, + 'AttachmentPickerSelectionBar' +> & Pick & Pick & Pick< From b28252bf9b2c32c44d60cd26796f6ee54607ed2d Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Fri, 11 Apr 2025 04:33:07 +0530 Subject: [PATCH 34/60] fix: unify file and image types (#3050) * fix: unify file and image types * fix: refine types * fix: remove props from auto complete input --- examples/ExpoMessaging/package.json | 1 - examples/ExpoMessaging/yarn.lock | 23 ++-- examples/SampleApp/ios/Podfile.lock | 33 ++++- examples/SampleApp/package.json | 1 + examples/SampleApp/yarn.lock | 10 ++ examples/TypeScriptMessaging/yarn.lock | 12 +- package/expo-package/package.json | 5 +- .../src/optionalDependencies/getPhotos.ts | 13 +- .../src/optionalDependencies/pickDocument.ts | 12 +- .../src/optionalDependencies/pickImage.ts | 3 +- .../src/optionalDependencies/takePhoto.ts | 3 - package/expo-package/yarn.lock | 21 ++- package/native-package/package.json | 3 +- .../src/optionalDependencies/getPhotos.ts | 25 ++-- .../src/optionalDependencies/pickDocument.ts | 2 +- .../src/optionalDependencies/pickImage.ts | 3 +- .../src/optionalDependencies/takePhoto.ts | 4 - package/native-package/yarn.lock | 21 ++- .../components/Attachment/AudioAttachment.tsx | 4 +- .../Attachment/FileAttachmentGroup.tsx | 4 +- .../AttachmentPicker/AttachmentPicker.tsx | 14 +- .../components/AttachmentPickerItem.tsx | 46 ++----- .../AutoCompleteInput/AutoCompleteInput.tsx | 11 +- package/src/components/Channel/Channel.tsx | 2 +- .../MessageInput/FileUploadPreview.tsx | 111 ++++++--------- .../MessageInput/ImageUploadPreview.tsx | 4 +- .../components/MessageInput/MessageInput.tsx | 35 ++--- .../MessageInput/hooks/useAudioController.tsx | 11 +- .../AttachmentPickerContext.tsx | 9 +- .../MessageInputContext.tsx | 127 ++++++++++-------- .../hooks/useCreateMessageInputContext.ts | 4 +- .../hooks/useMessageDetailsForState.ts | 67 +++++---- .../messageInputContext/utils/utils.ts | 14 +- package/src/native.ts | 12 +- package/src/types/types.ts | 67 ++++----- package/src/utils/compressImage.ts | 7 +- package/src/utils/utils.ts | 18 ++- 37 files changed, 365 insertions(+), 397 deletions(-) diff --git a/examples/ExpoMessaging/package.json b/examples/ExpoMessaging/package.json index 98c2a59624..ed87be9264 100644 --- a/examples/ExpoMessaging/package.json +++ b/examples/ExpoMessaging/package.json @@ -23,7 +23,6 @@ "expo-image-manipulator": "~13.0.6", "expo-image-picker": "~16.0.6", "expo-linking": "~7.0.5", - "expo-media-library": "~17.0.6", "expo-router": "~4.0.17", "expo-sharing": "~13.0.1", "expo-splash-screen": "~0.29.22", diff --git a/examples/ExpoMessaging/yarn.lock b/examples/ExpoMessaging/yarn.lock index 33622cec6e..3c8557230b 100644 --- a/examples/ExpoMessaging/yarn.lock +++ b/examples/ExpoMessaging/yarn.lock @@ -4301,11 +4301,6 @@ expo-linking@~7.0.5: expo-constants "~17.0.5" invariant "^2.2.4" -expo-media-library@~17.0.6: - version "17.0.6" - resolved "https://registry.yarnpkg.com/expo-media-library/-/expo-media-library-17.0.6.tgz#355f5f5abf0b5b35cdf009f18567cbba12d8dc82" - integrity sha512-LUnfrddmee1xLOkyG2NN1l9xQbtvMX3fbM1brEGHg0SKSndvjod3FQdhTzZEYAariqW2RSxQR8v1IsheIoLQXg== - expo-modules-autolinking@2.0.8: version "2.0.8" resolved "https://registry.yarnpkg.com/expo-modules-autolinking/-/expo-modules-autolinking-2.0.8.tgz#b00c10ebb589ce2220548bbaee4865db1cf1f1f7" @@ -5540,6 +5535,11 @@ linkifyjs@^4.1.1: resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.1.tgz#73d427e3bbaaf4ca8e71c589ad4ffda11a9a5fde" integrity sha512-zFN/CTVmbcVef+WaDXT63dNzzkfRBKT1j464NJQkV7iSgJU0sLBus9W0HBwnXK13/hf168pbrx/V/bjEHOXNHA== +linkifyjs@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" + integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -5943,6 +5943,11 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" + integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -7402,10 +7407,9 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.8: - version "9.0.0-rc.8" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.8.tgz#e188e481841493584691ae491916843d0ef5f9cd" - integrity sha512-P+Ksnu1cQQfL1t2/QTJ5rr/z2Jehvd2ap41xZgtfbJssHSD7ahe14TCF/1L7q4jjaNlZcTtLcKXCWbbOdKjDcg== +"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": + version "0.0.0-development" + resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -7414,6 +7418,7 @@ stream-chat@9.0.0-rc.8: form-data "^4.0.0" isomorphic-ws "^5.0.0" jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" ws "^8.18.1" stream-slice@^0.1.2: diff --git a/examples/SampleApp/ios/Podfile.lock b/examples/SampleApp/ios/Podfile.lock index 37c20914c9..c732d5ddd0 100644 --- a/examples/SampleApp/ios/Podfile.lock +++ b/examples/SampleApp/ios/Podfile.lock @@ -1475,6 +1475,27 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga + - react-native-image-picker (8.2.0): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.11.18.00) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - react-native-netinfo (11.4.1): - React-Core - react-native-safe-area-context (5.2.0): @@ -2284,6 +2305,7 @@ DEPENDENCIES: - react-native-blob-util (from `../node_modules/react-native-blob-util`) - "react-native-cameraroll (from `../node_modules/@react-native-camera-roll/camera-roll`)" - "react-native-document-picker (from `../node_modules/@react-native-documents/picker`)" + - react-native-image-picker (from `../node_modules/react-native-image-picker`) - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-video (from `../node_modules/react-native-video`) @@ -2439,6 +2461,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-camera-roll/camera-roll" react-native-document-picker: :path: "../node_modules/@react-native-documents/picker" + react-native-image-picker: + :path: "../node_modules/react-native-image-picker" react-native-netinfo: :path: "../node_modules/@react-native-community/netinfo" react-native-safe-area-context: @@ -2557,7 +2581,7 @@ SPEC CHECKSUMS: op-sqlite: c33561ea312a2ae38aae032fd3a42635dc6b57e8 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 - RCT-Folly: 36fe2295e44b10d831836cc0d1daec5f8abcf809 + RCT-Folly: e78785aa9ba2ed998ea4151e314036f6c49e6d82 RCTDeprecation: b2eecf2d60216df56bc5e6be5f063826d3c1ee35 RCTRequired: 78522de7dc73b81f3ed7890d145fa341f5bb32ea RCTTypeSafety: c135dd2bf50402d87fd12884cbad5d5e64850edd @@ -2589,8 +2613,9 @@ SPEC CHECKSUMS: React-Mapbuffer: 0df2a235bd0182f5cbed6c5f095e66deca12e335 React-microtasksnativemodule: b31e56a980634f383221bfefd5111d04c14c110b react-native-blob-util: 875bbeee07e4ada135e4edf9fc7b22acf8d9721d - react-native-cameraroll: 36dc62b41c7943a79ac2f7cf4d3da10d4138513f + react-native-cameraroll: cdc91c4c953d1a18aa3ce88b5a25698025c8c4d2 react-native-document-picker: 19be73c0423e4bc886cef74ec282eff750698013 + react-native-image-picker: 1c620a65f900a47d6d12ec94874c6a1820ebea7d react-native-netinfo: f0a9899081c185db1de5bb2fdc1c88c202a059ac react-native-safe-area-context: 0b43456abcaaa3c8323bbfafe9c5f0f9511219d2 react-native-video: a225b4d4d3286f3253dc7b00a62e7c8e59d04d51 @@ -2637,9 +2662,9 @@ SPEC CHECKSUMS: SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - stream-chat-react-native: 6b89c43ee042e7a6f00e6eaddf3228b712884846 + stream-chat-react-native: aa6626ef9dd68e28b1239c9f2ee2fc7ce1fd3c3f Yoga: be02ca501b03c79d7027a6bbbd0a8db985034f11 PODFILE CHECKSUM: 4f662370295f8f9cee909f1a4c59a614999a209d -COCOAPODS: 1.16.2 +COCOAPODS: 1.14.3 diff --git a/examples/SampleApp/package.json b/examples/SampleApp/package.json index d8adbf0d48..a3c2e6e4c9 100644 --- a/examples/SampleApp/package.json +++ b/examples/SampleApp/package.json @@ -42,6 +42,7 @@ "react-native-fast-image": "^8.6.3", "react-native-gesture-handler": "^2.24.0", "react-native-haptic-feedback": "^2.3.3", + "react-native-image-picker": "^8.2.0", "react-native-reanimated": "^3.17.1", "react-native-safe-area-context": "^5.2.0", "react-native-screens": "^4.9.1", diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index f92346e8f4..27f23dcb57 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -6273,6 +6273,11 @@ mime@^2.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== +mime@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" + integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -6890,6 +6895,11 @@ react-native-haptic-feedback@^2.3.3: resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-2.3.3.tgz#88b6876e91399a69bd1b551fe1681b2f3dc1214e" integrity sha512-svS4D5PxfNv8o68m9ahWfwje5NqukM3qLS48+WTdhbDkNUkOhP9rDfDSRHzlhk4zq+ISjyw95EhLeh8NkKX5vQ== +react-native-image-picker@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/react-native-image-picker/-/react-native-image-picker-8.2.0.tgz#d8656fdd1a0f1ad262c9c129d4f75900b685e56e" + integrity sha512-jIGllQJuJIn0YKss/JEeb0Kos1HSsnIpU+i3bYxR27sOxSyDZQyP9dKR22olssQPlfH+rGNR/Jc6xKRkhm48vw== + react-native-is-edge-to-edge@1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.1.6.tgz#69ec13f70d76e9245e275eed4140d0873a78f902" diff --git a/examples/TypeScriptMessaging/yarn.lock b/examples/TypeScriptMessaging/yarn.lock index 4725572e1f..7643827d31 100644 --- a/examples/TypeScriptMessaging/yarn.lock +++ b/examples/TypeScriptMessaging/yarn.lock @@ -3564,7 +3564,7 @@ es6-iterator@^2.0.3: es5-ext "^0.10.35" es6-symbol "^3.1.1" -es6-symbol@^3.1.1, es6-symbol@^3.1.3: +es6-symbol@^3.1.1, es6-symbol@^3.1.3, es6-symbol@^3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.4.tgz#f4e7d28013770b4208ecbf3e0bf14d3bcb557b8c" integrity sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg== @@ -5287,7 +5287,7 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -linkifyjs@^4.1.1: +linkifyjs@^4.1.1, linkifyjs@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== @@ -6929,10 +6929,9 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.8: - version "9.0.0-rc.8" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.8.tgz#e188e481841493584691ae491916843d0ef5f9cd" - integrity sha512-P+Ksnu1cQQfL1t2/QTJ5rr/z2Jehvd2ap41xZgtfbJssHSD7ahe14TCF/1L7q4jjaNlZcTtLcKXCWbbOdKjDcg== +"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": + version "0.0.0-development" + resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -6941,6 +6940,7 @@ stream-chat@9.0.0-rc.8: form-data "^4.0.0" isomorphic-ws "^5.0.0" jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" ws "^8.18.1" strict-uri-encode@^2.0.0: diff --git a/package/expo-package/package.json b/package/expo-package/package.json index 879f5ad332..e9b1524eaf 100644 --- a/package/expo-package/package.json +++ b/package/expo-package/package.json @@ -10,12 +10,12 @@ "main": "src/index.js", "types": "types/index.d.ts", "dependencies": { + "mime": "^4.0.7", "stream-chat-react-native-core": "link:../" }, "peerDependencies": { "expo": ">=51.0.0", "expo-av": "*", - "expo-video": "*", "expo-clipboard": "*", "expo-document-picker": "*", "expo-file-system": "*", @@ -23,7 +23,8 @@ "expo-image-manipulator": "*", "expo-image-picker": "*", "expo-media-library": "*", - "expo-sharing": "*" + "expo-sharing": "*", + "expo-video": "*" }, "peerDependenciesMeta": { "expo-av": { diff --git a/package/expo-package/src/optionalDependencies/getPhotos.ts b/package/expo-package/src/optionalDependencies/getPhotos.ts index cd858364a2..c8f244a04a 100644 --- a/package/expo-package/src/optionalDependencies/getPhotos.ts +++ b/package/expo-package/src/optionalDependencies/getPhotos.ts @@ -1,4 +1,7 @@ import { Platform } from 'react-native'; +import mime from 'mime'; + +import type { File } from 'stream-chat-react-native-core'; let MediaLibrary; @@ -13,12 +16,11 @@ if (!MediaLibrary) { 'expo-media-library is not installed. Please install it or you can choose to install expo-image-picker for native image picker.', ); } -import type { Asset } from 'stream-chat-react-native-core'; import { getLocalAssetUri } from './getLocalAssetUri'; type ReturnType = { - assets: Array & { source: 'picker' }>; + assets: File[]; endCursor: string | undefined; hasNextPage: boolean; iOSLimited: boolean; @@ -52,14 +54,13 @@ export const getPhotos = MediaLibrary const assets = await Promise.all( results.assets.map(async (asset) => { const localUri = await getLocalAssetUri(asset.id); + const mimeType = mime.getType(asset.filename); return { duration: asset.duration * 1000, height: asset.height, - id: asset.id, name: asset.filename, - originalUri: asset.uri, - source: 'picker' as const, - type: asset.mediaType, + thumb_url: asset.mediaType === 'photo' ? undefined : asset.uri, + type: mimeType, uri: localUri || asset.uri, width: asset.width, }; diff --git a/package/expo-package/src/optionalDependencies/pickDocument.ts b/package/expo-package/src/optionalDependencies/pickDocument.ts index 6c12ebe74b..5071c8d729 100644 --- a/package/expo-package/src/optionalDependencies/pickDocument.ts +++ b/package/expo-package/src/optionalDependencies/pickDocument.ts @@ -38,13 +38,21 @@ export const pickDocument = DocumentPicker // Applicable to latest version of expo-document-picker if (assets) { return { - assets, + assets: assets.map((asset) => ({ + ...asset, + type: asset.mimeType, + })), cancelled: false, }; } // Applicable to older version of expo-document-picker return { - assets: [rest], + assets: [ + { + ...rest, + type: rest.mimeType, + }, + ], cancelled: false, }; } catch (err) { diff --git a/package/expo-package/src/optionalDependencies/pickImage.ts b/package/expo-package/src/optionalDependencies/pickImage.ts index 6b3df6e6af..25ef02f531 100644 --- a/package/expo-package/src/optionalDependencies/pickImage.ts +++ b/package/expo-package/src/optionalDependencies/pickImage.ts @@ -45,11 +45,10 @@ export const pickImage = ImagePicker duration: asset.duration, name: asset.fileName, size: asset.fileSize, - source: 'picker', type: asset.mimeType, uri: asset.uri, })); - return { assets, cancelled: false, source: 'picker' }; + return { assets, cancelled: false }; } else { return { cancelled: true }; } diff --git a/package/expo-package/src/optionalDependencies/takePhoto.ts b/package/expo-package/src/optionalDependencies/takePhoto.ts index 6baec01d2a..53580644ed 100644 --- a/package/expo-package/src/optionalDependencies/takePhoto.ts +++ b/package/expo-package/src/optionalDependencies/takePhoto.ts @@ -63,7 +63,6 @@ export const takePhoto = ImagePicker duration: photo.duration, // in milliseconds name: 'video_recording_' + date + '.' + photo.uri.split('.').pop(), size: photo.fileSize, - source: 'camera', type: photo.mimeType, uri: photo.uri, }; @@ -95,10 +94,8 @@ export const takePhoto = ImagePicker const date = new Date().toISOString().replace(clearFilter, '_'); return { cancelled: false, - mimeType: photo.mimeType, name: 'image_' + date + '.' + photo.uri.split('.').pop(), size: photo.fileSize, - source: 'camera', type: photo.mimeType, uri: photo.uri, ...size, diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 89f49712c7..640fb75626 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -3764,6 +3764,11 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" + integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -4777,19 +4782,9 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": - version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" - dependencies: - "@types/jsonwebtoken" "^9.0.8" - "@types/ws" "^8.5.14" - axios "^1.6.0" - base64-js "^1.5.1" - form-data "^4.0.0" - isomorphic-ws "^5.0.0" - jsonwebtoken "^9.0.2" - linkifyjs "^4.2.0" - ws "^8.18.1" +"stream-chat@link:../../../stream-chat-js": + version "0.0.0" + uid "" "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" diff --git a/package/native-package/package.json b/package/native-package/package.json index df1f2a040d..9a9c0eec19 100644 --- a/package/native-package/package.json +++ b/package/native-package/package.json @@ -20,16 +20,17 @@ "types": "types/index.d.ts", "dependencies": { "es6-symbol": "^3.1.4", + "mime": "^4.0.7", "stream-chat-react-native-core": "link:../" }, "peerDependencies": { "@react-native-camera-roll/camera-roll": ">=7.8.0", "@react-native-clipboard/clipboard": ">=1.14.1", + "@react-native-documents/picker": ">=10.1.1", "@stream-io/flat-list-mvcp": ">=0.10.3", "react-native": ">=0.71.0", "react-native-audio-recorder-player": ">=3.6.4", "react-native-blob-util": ">=0.19.9", - "@react-native-documents/picker": ">=10.1.1", "react-native-haptic-feedback": ">=2.2.0", "react-native-image-picker": ">=7.1.2", "react-native-share": ">=10.2.1", diff --git a/package/native-package/src/optionalDependencies/getPhotos.ts b/package/native-package/src/optionalDependencies/getPhotos.ts index bfbf051d37..0b1c0d22c9 100644 --- a/package/native-package/src/optionalDependencies/getPhotos.ts +++ b/package/native-package/src/optionalDependencies/getPhotos.ts @@ -1,4 +1,7 @@ import { PermissionsAndroid, Platform } from 'react-native'; +import mime from 'mime'; + +import type { File } from 'stream-chat-react-native-core'; let CameraRollDependency; @@ -11,12 +14,10 @@ try { ); } -import type { Asset } from 'stream-chat-react-native-core'; - import { getLocalAssetUri } from './getLocalAssetUri'; type ReturnType = { - assets: Array & { source: 'picker' }>; + assets: File[]; endCursor: string | undefined; hasNextPage: boolean; iOSLimited: boolean; @@ -90,16 +91,22 @@ export const getPhotos = CameraRollDependency const assets = await Promise.all( results.edges.map(async (edge) => { const originalUri = edge.node?.image?.uri; - const uri = getLocalAssetUri ? await getLocalAssetUri(originalUri) : originalUri; + const type = + Platform.OS === 'ios' + ? mime.getType(edge.node.image.filename as string) + : edge.node.type; + const isImage = type.includes('image'); + + const uri = + isImage && getLocalAssetUri ? await getLocalAssetUri(originalUri) : originalUri; + return { ...edge.node.image, - duration: edge.node.image.playableDuration * 1000, - // since we include filename, fileSize in the query, we can safely assume it will be defined name: edge.node.image.filename as string, - originalUri, + duration: edge.node.image.playableDuration * 1000, + thumb_url: isImage ? undefined : originalUri, size: edge.node.image.fileSize as number, - source: 'picker' as const, - type: edge.node.type, + type, uri, }; }), diff --git a/package/native-package/src/optionalDependencies/pickDocument.ts b/package/native-package/src/optionalDependencies/pickDocument.ts index 3ed801cec4..42aebe01bb 100644 --- a/package/native-package/src/optionalDependencies/pickDocument.ts +++ b/package/native-package/src/optionalDependencies/pickDocument.ts @@ -43,9 +43,9 @@ export const pickDocument = DocumentPicker return { assets: res.map(({ name, size, type, uri }) => ({ - mimeType: type, name, size, + type, uri, })), cancelled: false, diff --git a/package/native-package/src/optionalDependencies/pickImage.ts b/package/native-package/src/optionalDependencies/pickImage.ts index 770319b285..1d04e68753 100644 --- a/package/native-package/src/optionalDependencies/pickImage.ts +++ b/package/native-package/src/optionalDependencies/pickImage.ts @@ -26,11 +26,10 @@ export const pickImage = ImagePicker duration: asset.duration ? asset.duration * 1000 : undefined, // in milliseconds name: asset.fileName, size: asset.fileSize, - source: 'picker', type: asset.type, uri: asset.uri, })); - return { assets, cancelled: false, source: 'picker' }; + return { assets, cancelled: false }; } else { return { cancelled: true }; } diff --git a/package/native-package/src/optionalDependencies/takePhoto.ts b/package/native-package/src/optionalDependencies/takePhoto.ts index 477841ddc1..914dec735b 100644 --- a/package/native-package/src/optionalDependencies/takePhoto.ts +++ b/package/native-package/src/optionalDependencies/takePhoto.ts @@ -53,10 +53,8 @@ export const takePhoto = ImagePicker ...asset, cancelled: false, duration: asset.duration * 1000, - mimeType: asset.type, name: 'video_recording_' + date + '.' + asset.fileName.split('.').pop(), size: asset.fileSize, - source: 'camera', type: asset.type, uri: asset.uri, }; @@ -90,10 +88,8 @@ export const takePhoto = ImagePicker const date = new Date().toISOString().replace(clearFilter, '_'); return { cancelled: false, - mimeType: asset.type, name: 'video_recording_' + date + '.' + asset.fileName.split('.').pop(), size: asset.size, - source: 'camera', type: asset.type, uri: asset.uri, ...size, diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 38eb6e1a30..b6bab71d41 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -2864,6 +2864,11 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" + integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== + minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -3493,19 +3498,9 @@ statuses@~1.5.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": - version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" - dependencies: - "@types/jsonwebtoken" "^9.0.8" - "@types/ws" "^8.5.14" - axios "^1.6.0" - base64-js "^1.5.1" - form-data "^4.0.0" - isomorphic-ws "^5.0.0" - jsonwebtoken "^9.0.2" - linkifyjs "^4.2.0" - ws "^8.18.1" +"stream-chat@link:../../../stream-chat-js": + version "0.0.0" + uid "" string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" diff --git a/package/src/components/Attachment/AudioAttachment.tsx b/package/src/components/Attachment/AudioAttachment.tsx index f2b5333c38..7e0f0873fb 100644 --- a/package/src/components/Attachment/AudioAttachment.tsx +++ b/package/src/components/Attachment/AudioAttachment.tsx @@ -15,7 +15,7 @@ import { VideoProgressData, VideoSeekResponse, } from '../../native'; -import { FileTypes, type FileUpload } from '../../types/types'; +import { AudioUpload, FileTypes } from '../../types/types'; import { getTrimmedAttachmentTitle } from '../../utils/getTrimmedAttachmentTitle'; import { ProgressControl } from '../ProgressControl/ProgressControl'; import { WaveProgressBar } from '../ProgressControl/WaveProgressBar'; @@ -23,7 +23,7 @@ import { WaveProgressBar } from '../ProgressControl/WaveProgressBar'; dayjs.extend(duration); export type AudioAttachmentProps = { - item: Omit; + item: Omit; onLoad: (index: string, duration: number) => void; onPlayPause: (index: string, pausedStatus?: boolean) => void; onProgress: (index: string, progress: number) => void; diff --git a/package/src/components/Attachment/FileAttachmentGroup.tsx b/package/src/components/Attachment/FileAttachmentGroup.tsx index ab61c1e06b..dc9247b02a 100644 --- a/package/src/components/Attachment/FileAttachmentGroup.tsx +++ b/package/src/components/Attachment/FileAttachmentGroup.tsx @@ -114,7 +114,9 @@ const FileAttachmentGroupWithContext = (props: FileAttachmentGroupPropsWithConte duration: file.duration, file: { name: file.title as string, - uri: file.asset_url, + size: file.file_size || 0, + type: file.mime_type || '', + uri: file.asset_url || '', waveform_data: file.waveform_data, }, id: index.toString(), diff --git a/package/src/components/AttachmentPicker/AttachmentPicker.tsx b/package/src/components/AttachmentPicker/AttachmentPicker.tsx index 46f5284a03..2aeb3d6bb9 100644 --- a/package/src/components/AttachmentPicker/AttachmentPicker.tsx +++ b/package/src/components/AttachmentPicker/AttachmentPicker.tsx @@ -18,7 +18,7 @@ import { import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { useScreenDimensions } from '../../hooks/useScreenDimensions'; import { NativeHandlers } from '../../native'; -import type { Asset } from '../../types/types'; +import type { File } from '../../types/types'; import { BottomSheet } from '../BottomSheetCompatibility/BottomSheet'; import { BottomSheetFlatList } from '../BottomSheetCompatibility/BottomSheetFlatList'; @@ -108,7 +108,7 @@ export const AttachmentPicker = React.forwardRef( const [iOSLimited, setIosLimited] = useState(false); const hasNextPageRef = useRef(true); const [loadingPhotos, setLoadingPhotos] = useState(false); - const [photos, setPhotos] = useState([]); + const [photos, setPhotos] = useState([]); const attemptedToLoadPhotosOnOpenRef = useRef(false); const getMorePhotos = useCallback(async () => { @@ -245,14 +245,8 @@ export const AttachmentPicker = React.forwardRef( numberOfUploads: selectedFiles.length + selectedImages.length, // `id` is available for Expo MediaLibrary while Cameraroll doesn't share id therefore we use `uri` selected: - selectedImages.some((image) => - image.id - ? image.id === asset.id - : image.uri === asset.uri || image.originalUri === asset.uri, - ) || - selectedFiles.some((file) => - file.id ? file.id === asset.id : file.uri === asset.uri || file.originalUri === asset.uri, - ), + selectedImages.some((image) => image.uri === asset.uri) || + selectedFiles.some((file) => file.uri === asset.uri), selectedFiles, selectedImages, setSelectedFiles, diff --git a/package/src/components/AttachmentPicker/components/AttachmentPickerItem.tsx b/package/src/components/AttachmentPicker/components/AttachmentPickerItem.tsx index 1d86d8bb94..0eccbfd1a3 100644 --- a/package/src/components/AttachmentPicker/components/AttachmentPickerItem.tsx +++ b/package/src/components/AttachmentPicker/components/AttachmentPickerItem.tsx @@ -2,22 +2,19 @@ import React from 'react'; import { Alert, ImageBackground, StyleSheet, Text, View } from 'react-native'; -import { lookup } from 'mime-types'; - import { AttachmentPickerContextValue } from '../../../contexts/attachmentPickerContext/AttachmentPickerContext'; import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext'; import { useViewport } from '../../../hooks/useViewport'; import { Recorder } from '../../../icons'; -import type { Asset, File } from '../../../types/types'; +import type { File } from '../../../types/types'; import { getDurationLabelFromDuration } from '../../../utils/utils'; import { BottomSheetTouchableOpacity } from '../../BottomSheetCompatibility/BottomSheetTouchableOpacity'; - type AttachmentPickerItemType = Pick< AttachmentPickerContextValue, 'selectedFiles' | 'setSelectedFiles' | 'setSelectedImages' | 'selectedImages' | 'maxNumberOfFiles' > & { - asset: Asset; + asset: File; ImageOverlaySelectedComponent: React.ComponentType; numberOfUploads: number; selected: boolean; @@ -48,46 +45,25 @@ const AttachmentVideo = (props: AttachmentVideoProps) => { }, } = useTheme(); - const { duration: videoDuration, id: assetId, originalUri, uri } = asset; + const { duration: videoDuration, thumb_url, uri } = asset; - const durationLabel = getDurationLabelFromDuration(videoDuration); + const durationLabel = videoDuration ? getDurationLabelFromDuration(videoDuration) : '00:00'; const size = vw(100) / (numberOfAttachmentPickerImageColumns || 3) - 2; - /* Patches video files with uri and mimetype */ - const patchVideoFile = (files: File[]) => { - // We need a mime-type to upload a video file. - const mimeType = lookup(asset.name) || 'multipart/form-data'; - return [ - ...files, - { - duration: asset.duration, - id: asset.id, - mimeType, - name: asset.name, - originalUri, - size: asset.size, - uri, - }, - ]; - }; - const updateSelectedFiles = () => { if (numberOfUploads >= maxNumberOfFiles) { Alert.alert(t('Maximum number of files reached')); return; } - const files = patchVideoFile(selectedFiles); - setSelectedFiles(files); + setSelectedFiles([...selectedFiles, asset]); }; const onPressVideo = () => { if (selected) { setSelectedFiles((files) => // `id` is available for Expo MediaLibrary while Cameraroll doesn't share id therefore we use `uri` - files.filter((file) => - file.id ? file.id !== assetId : file.uri !== uri && file.originalUri !== uri, - ), + files.filter((file) => file.uri !== uri), ); } else { updateSelectedFiles(); @@ -97,7 +73,7 @@ const AttachmentVideo = (props: AttachmentVideoProps) => { return ( { const size = vw(100) / (numberOfAttachmentPickerImageColumns || 3) - 2; - const { id: assetId, originalUri, uri } = asset; + const { uri } = asset; const updateSelectedImages = () => { if (numberOfUploads >= maxNumberOfFiles) { @@ -160,11 +136,7 @@ const AttachmentImage = (props: AttachmentImageProps) => { const onPressImage = () => { if (selected) { // `id` is available for Expo MediaLibrary while Cameraroll doesn't share id therefore we use `uri` - setSelectedImages((images) => - images.filter((image) => - assetId ? image.id !== assetId : image.uri !== uri && originalUri !== uri, - ), - ); + setSelectedImages((images) => images.filter((image) => image.uri !== uri)); } else { updateSelectedImages(); } diff --git a/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx b/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx index f057f3eb68..d67b039b7d 100644 --- a/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx +++ b/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx @@ -77,14 +77,11 @@ export type AutoCompleteInputProps = Partial; const AutoCompleteInputWithContext = (props: AutoCompleteInputPropsWithContext) => { const { additionalTextInputProps, - autoCompleteSuggestionsLimit, closeSuggestions, cooldownActive = false, giphyActive, giphyEnabled, maxMessageLength, - mentionAllAppUsersEnabled, - mentionAllAppUsersQuery, numberOfLines, onChange, openSuggestions, @@ -92,10 +89,16 @@ const AutoCompleteInputWithContext = (props: AutoCompleteInputPropsWithContext) setInputBoxRef, t, text, - triggerSettings, updateSuggestions: updateSuggestionsContext, } = props; + const { + autoCompleteSuggestionsLimit, + mentionAllAppUsersEnabled, + mentionAllAppUsersQuery, + triggerSettings, + } = useMessageInputContext(); + const isTrackingStarted = useRef(false); const selectionEnd = useRef(0); const [textHeight, setTextHeight] = useState(0); diff --git a/package/src/components/Channel/Channel.tsx b/package/src/components/Channel/Channel.tsx index 8047794cbc..29aa2b2656 100644 --- a/package/src/components/Channel/Channel.tsx +++ b/package/src/components/Channel/Channel.tsx @@ -1302,7 +1302,7 @@ const ChannelWithContext = (props: PropsWithChildren) = } const response = doDocUploadRequest ? await doDocUploadRequest(file, channel) - : await channel.sendFile(file.uri, file.name, file.mimeType); + : await channel.sendFile(file.uri, file.name, file.type); attachment.asset_url = response.file; if (response.thumb_url) { attachment.thumb_url = response.thumb_url; diff --git a/package/src/components/MessageInput/FileUploadPreview.tsx b/package/src/components/MessageInput/FileUploadPreview.tsx index 0ec0fa78f9..accf612708 100644 --- a/package/src/components/MessageInput/FileUploadPreview.tsx +++ b/package/src/components/MessageInput/FileUploadPreview.tsx @@ -17,7 +17,7 @@ import { useTranslationContext } from '../../contexts/translationContext/Transla import { Close } from '../../icons/Close'; import { Warning } from '../../icons/Warning'; import { isSoundPackageAvailable } from '../../native'; -import type { FileUpload } from '../../types/types'; +import type { AudioUpload, FileUpload } from '../../types/types'; import { getTrimmedAttachmentTitle } from '../../utils/getTrimmedAttachmentTitle'; import { getDurationLabelFromDuration, @@ -123,26 +123,49 @@ const UnsupportedFileTypeOrFileSizeIndicator = ({ ); }; -type FileUploadPreviewPropsWithContext = Pick< - MessageInputContextValue, - 'fileUploads' | 'removeFile' | 'uploadFile' | 'setFileUploads' | 'AudioAttachmentUploadPreview' +export type FileUploadPreviewProps = Partial< + Pick< + MessageInputContextValue, + 'fileUploads' | 'removeFile' | 'uploadFile' | 'setFileUploads' | 'AudioAttachmentUploadPreview' + > > & - Pick & - Pick; + Partial> & + Partial>; -const FileUploadPreviewWithContext = (props: FileUploadPreviewPropsWithContext) => { +/** + * FileUploadPreview + * UI Component to preview the files set for upload + */ +export const FileUploadPreview = (props: FileUploadPreviewProps) => { const { - AudioAttachmentUploadPreview, - enableOfflineSupport, - FileAttachmentIcon, - fileUploads, - removeFile, - uploadFile, + AudioAttachmentUploadPreview: propAudioAttachmentUploadPreview, + enableOfflineSupport: propEnableOfflineSupport, + FileAttachmentIcon: propFileAttachmentIcon, + fileUploads: propFileUploads, + removeFile: propRemoveFile, + uploadFile: propUploadFile, } = props; - const [filesToDisplay, setFilesToDisplay] = useState([]); + const { enableOfflineSupport: contextEnableOfflineSupport } = useChatContext(); + const { + AudioAttachmentUploadPreview: contextAudioAttachmentUploadPreview, + fileUploads: contextFileUploads, + removeFile: contextRemoveFile, + uploadFile: contextUploadFile, + } = useMessageInputContext(); + const { FileAttachmentIcon: contextFileAttachmentIcon } = useMessagesContext(); - const flatListRef = useRef | null>(null); + const enableOfflineSupport = propEnableOfflineSupport ?? contextEnableOfflineSupport; + const AudioAttachmentUploadPreview = + propAudioAttachmentUploadPreview ?? contextAudioAttachmentUploadPreview; + const fileUploads = propFileUploads ?? contextFileUploads; + const removeFile = propRemoveFile ?? contextRemoveFile; + const uploadFile = propUploadFile ?? contextUploadFile; + const FileAttachmentIcon = propFileAttachmentIcon ?? contextFileAttachmentIcon; + + const [filesToDisplay, setFilesToDisplay] = useState([]); + + const flatListRef = useRef | null>(null); const [flatListWidth, setFlatListWidth] = useState(0); useEffect(() => { @@ -207,9 +230,9 @@ const FileUploadPreviewWithContext = (props: FileUploadPreviewPropsWithContext) }, } = useTheme(); - const renderItem = ({ item }: { item: FileUpload }) => { + const renderItem = ({ item }: { item: AudioUpload }) => { const indicatorType = getIndicatorTypeForFileState(item.state, enableOfflineSupport); - const isAudio = item.file.mimeType?.startsWith('audio/'); + const isAudio = item.file.type?.startsWith('audio/'); return ( <> @@ -241,7 +264,7 @@ const FileUploadPreviewWithContext = (props: FileUploadPreviewPropsWithContext) ]} > - + { - const { fileUploads: prevFileUploads } = prevProps; - const { fileUploads: nextFileUploads } = nextProps; - - return ( - prevFileUploads.length === nextFileUploads.length && - prevFileUploads.every( - (prevFileUpload, index) => - prevFileUpload.state === nextFileUploads[index].state && - prevFileUpload.paused === nextFileUploads[index].paused && - prevFileUpload.progress === nextFileUploads[index].progress && - prevFileUpload.duration === nextFileUploads[index].duration, - ) - ); -}; - -const MemoizedFileUploadPreview = React.memo( - FileUploadPreviewWithContext, - areEqual, -) as typeof FileUploadPreviewWithContext; - -export type FileUploadPreviewProps = Partial; - -/** - * FileUploadPreview - * UI Component to preview the files set for upload - */ -export const FileUploadPreview = (props: FileUploadPreviewProps) => { - const { enableOfflineSupport } = useChatContext(); - const { AudioAttachmentUploadPreview, fileUploads, removeFile, setFileUploads, uploadFile } = - useMessageInputContext(); - const { FileAttachmentIcon } = useMessagesContext(); - - return ( - - ); -}; - FileUploadPreview.displayName = 'FileUploadPreview{messageInput{fileUploadPreview}}'; diff --git a/package/src/components/MessageInput/ImageUploadPreview.tsx b/package/src/components/MessageInput/ImageUploadPreview.tsx index 9f7417e3c8..e1046f7ba6 100644 --- a/package/src/components/MessageInput/ImageUploadPreview.tsx +++ b/package/src/components/MessageInput/ImageUploadPreview.tsx @@ -20,7 +20,7 @@ import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { useTranslationContext } from '../../contexts/translationContext/TranslationContext'; import { Close } from '../../icons/Close'; import { Warning } from '../../icons/Warning'; -import type { ImageUpload } from '../../types/types'; +import type { FileUpload } from '../../types/types'; import { getIndicatorTypeForFileState, ProgressIndicatorTypes } from '../../utils/utils'; const IMAGE_PREVIEW_SIZE = 100; @@ -81,7 +81,7 @@ type ImageUploadPreviewPropsWithContext = Pick< export type ImageUploadPreviewProps = Partial; -type ImageUploadPreviewItem = { index: number; item: ImageUpload }; +type ImageUploadPreviewItem = { index: number; item: FileUpload }; export const UnsupportedImageTypeIndicator = ({ indicatorType, diff --git a/package/src/components/MessageInput/MessageInput.tsx b/package/src/components/MessageInput/MessageInput.tsx index 564579ebca..3f5761fa66 100644 --- a/package/src/components/MessageInput/MessageInput.tsx +++ b/package/src/components/MessageInput/MessageInput.tsx @@ -61,7 +61,7 @@ import { isImageMediaLibraryAvailable, NativeHandlers, } from '../../native'; -import type { Asset } from '../../types/types'; +import { compressedImageURI } from '../../utils/compressImage'; import { AIStates, useAIState } from '../AITypingIndicatorView'; import { AutoCompleteInput } from '../AutoCompleteInput/AutoCompleteInput'; import { CreatePoll } from '../Poll/CreatePollContent'; @@ -129,6 +129,7 @@ type MessageInputPropsWithContext = Pick< | 'clearEditingState' | 'clearQuotedMessageState' | 'closeAttachmentPicker' + | 'compressImageQuality' | 'editing' | 'FileUploadPreview' | 'fileUploads' @@ -198,6 +199,7 @@ const MessageInputWithContext = (props: MessageInputPropsWithContext) => { channel, closeAttachmentPicker, closePollCreationDialog, + compressImageQuality, cooldownEndsAt, CooldownTimer, CreatePollContent, @@ -348,7 +350,7 @@ const MessageInputWithContext = (props: MessageInputPropsWithContext) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [imagesForInput, imageUploadsLength]); - const uploadImagesHandler = () => { + const uploadImagesHandler = async () => { const imageToUpload = selectedImages.find((selectedImage) => { const uploadedImage = imageUploads.find( (imageUpload) => @@ -358,7 +360,11 @@ const MessageInputWithContext = (props: MessageInputPropsWithContext) => { }); if (imageToUpload) { - uploadNewImage(imageToUpload); + const compressedImage = await compressedImageURI(imageToUpload, compressImageQuality); + uploadNewImage({ + ...imageToUpload, + uri: compressedImage, + }); } }; @@ -456,16 +462,7 @@ const MessageInputWithContext = (props: MessageInputPropsWithContext) => { /** * User is editing some message which contains image attachments. **/ - setSelectedImages( - imageUploads - .map((imageUpload) => ({ - height: imageUpload.file.height, - source: imageUpload.file.source, - uri: imageUpload.url || imageUpload.file.uri, - width: imageUpload.file.width, - })) - .filter(Boolean) as Asset[], - ); + setSelectedImages(imageUploads.map((imageUpload) => imageUpload.file)); } } // eslint-disable-next-line react-hooks/exhaustive-deps @@ -490,15 +487,7 @@ const MessageInputWithContext = (props: MessageInputPropsWithContext) => { /** * User is editing some message which contains video attachments. **/ - setSelectedFiles( - fileUploads.map((fileUpload) => ({ - duration: fileUpload.file.duration, - mimeType: fileUpload.file.mimeType, - name: fileUpload.file.name, - size: fileUpload.file.size, - uri: fileUpload.file.uri, - })), - ); + setSelectedFiles(fileUploads.map((fileUpload) => fileUpload.file)); } } // eslint-disable-next-line react-hooks/exhaustive-deps @@ -1177,6 +1166,7 @@ export const MessageInput = (props: MessageInputProps) => { clearQuotedMessageState, closeAttachmentPicker, closePollCreationDialog, + compressImageQuality, cooldownEndsAt, CooldownTimer, CreatePollContent, @@ -1265,6 +1255,7 @@ export const MessageInput = (props: MessageInputProps) => { clearQuotedMessageState, closeAttachmentPicker, closePollCreationDialog, + compressImageQuality, cooldownEndsAt, CooldownTimer, CreatePollContent, diff --git a/package/src/components/MessageInput/hooks/useAudioController.tsx b/package/src/components/MessageInput/hooks/useAudioController.tsx index e9c63d131d..4919a9b74e 100644 --- a/package/src/components/MessageInput/hooks/useAudioController.tsx +++ b/package/src/components/MessageInput/hooks/useAudioController.tsx @@ -10,7 +10,8 @@ import { RecordingStatus, SoundReturnType, } from '../../../native'; -import { File, FileTypes } from '../../../types/types'; +import type { File } from '../../../types/types'; +import { FileTypes } from '../../../types/types'; import { resampleWaveformData } from '../utils/audioSampling'; import { normalizeAudioLevel } from '../utils/normalizeAudioLevel'; @@ -267,18 +268,18 @@ export const useAudioController = () => { const file: File = { duration: durationInSeconds, - mimeType: 'audio/aac', name: `audio_recording_${date}.aac`, - type: FileTypes.VoiceRecording, + size: 0, + type: 'audio/aac', uri: typeof recording !== 'string' ? (recording?.getURI() as string) : (recording as string), waveform_data: resampledWaveformData, }; if (multiSendEnabled) { - await uploadNewFile(file); + await uploadNewFile(file, FileTypes.VoiceRecording); } else { // FIXME: cannot call handleSubmit() directly as the function has stale reference to file uploads - await uploadNewFile(file); + await uploadNewFile(file, FileTypes.VoiceRecording); setIsScheduleForSubmit(true); } resetState(); diff --git a/package/src/contexts/attachmentPickerContext/AttachmentPickerContext.tsx b/package/src/contexts/attachmentPickerContext/AttachmentPickerContext.tsx index a8b34e29c1..189d6a80c7 100644 --- a/package/src/contexts/attachmentPickerContext/AttachmentPickerContext.tsx +++ b/package/src/contexts/attachmentPickerContext/AttachmentPickerContext.tsx @@ -2,7 +2,8 @@ import React, { PropsWithChildren, useContext, useEffect, useState } from 'react import { BottomSheetHandleProps } from '@gorhom/bottom-sheet'; -import type { Asset, File } from '../../types/types'; +import type { File } from '../../types/types'; + import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; @@ -82,11 +83,11 @@ export type AttachmentPickerContextValue = { maxNumberOfFiles: number; openPicker: () => void; selectedFiles: File[]; - selectedImages: Asset[]; + selectedImages: File[]; setBottomInset: React.Dispatch>; setMaxNumberOfFiles: React.Dispatch>; setSelectedFiles: React.Dispatch>; - setSelectedImages: React.Dispatch>; + setSelectedImages: React.Dispatch>; setSelectedPicker: React.Dispatch>; setTopInset: React.Dispatch>; topInset: number; @@ -124,7 +125,7 @@ export const AttachmentPickerProvider = ({ const [bottomInset, setBottomInset] = useState(bottomInsetValue ?? 0); const [maxNumberOfFiles, setMaxNumberOfFiles] = useState(10); - const [selectedImages, setSelectedImages] = useState([]); + const [selectedImages, setSelectedImages] = useState([]); const [selectedFiles, setSelectedFiles] = useState([]); const [selectedPicker, setSelectedPicker] = useState<'images'>(); const [topInset, setTopInset] = useState(topInsetValue ?? 0); diff --git a/package/src/contexts/messageInputContext/MessageInputContext.tsx b/package/src/contexts/messageInputContext/MessageInputContext.tsx index b00f75421d..ccc8978ae0 100644 --- a/package/src/contexts/messageInputContext/MessageInputContext.tsx +++ b/package/src/contexts/messageInputContext/MessageInputContext.tsx @@ -10,7 +10,6 @@ import React, { import { Alert, Keyboard, Linking, TextInput, TextInputProps } from 'react-native'; import uniq from 'lodash/uniq'; -import { lookup } from 'mime-types'; import { Attachment, logChatPromiseExecution, @@ -60,7 +59,7 @@ import { MediaTypes, NativeHandlers, } from '../../native'; -import { Asset, File, FileTypes, FileUpload, ImageUpload } from '../../types/types'; +import { File, FileTypes, FileUpload } from '../../types/types'; import { ACITriggerSettings, ACITriggerSettingsParams, @@ -73,6 +72,7 @@ import { FileStateValue, generateRandomId, getFileNameFromPath, + getFileTypeFromMimeType, isBouncedMessage, } from '../../utils/utils'; import { useAttachmentPickerContext } from '../attachmentPickerContext/AttachmentPickerContext'; @@ -161,7 +161,7 @@ export type LocalMessageInputContext = { * ``` * */ - imageUploads: ImageUpload[]; + imageUploads: FileUpload[]; inputBoxRef: React.MutableRefObject; isValidMessage: () => boolean; mentionedUsers: string[]; @@ -206,7 +206,7 @@ export type LocalMessageInputContext = { >; setFileUploads: React.Dispatch>; setGiphyActive: React.Dispatch>; - setImageUploads: React.Dispatch>; + setImageUploads: React.Dispatch>; /** * Ref callback to set reference on input box */ @@ -231,9 +231,9 @@ export type LocalMessageInputContext = { /** Function for attempting to upload a file */ uploadFile: ({ newFile }: { newFile: FileUpload }) => Promise; /** Function for attempting to upload an image */ - uploadImage: ({ newImage }: { newImage: ImageUpload }) => Promise; - uploadNewFile: (file: File) => Promise; - uploadNewImage: (image: Partial) => Promise; + uploadImage: ({ newImage }: { newImage: FileUpload }) => Promise; + uploadNewFile: (file: File, fileType?: FileTypes) => Promise; + uploadNewImage: (image: File) => Promise; }; export type InputMessageInputContextValue = { @@ -430,10 +430,7 @@ export type InputMessageInputContextValue = { * @overrideType Function */ doImageUploadRequest?: ( - file: { - name?: string; - uri?: string; - }, + file: File, channel: ChannelContextValue['channel'], ) => Promise; @@ -673,11 +670,11 @@ export const MessageInputProvider = ({ const takeAndUploadImage = async (mediaType?: MediaTypes) => { setSelectedPicker(undefined); closePicker(); - const photo = await NativeHandlers.takePhoto({ + const file = await NativeHandlers.takePhoto({ compressImageQuality: value.compressImageQuality, mediaType, }); - if (photo.askToOpenSettings) { + if (file.askToOpenSettings) { Alert.alert( t('Allow camera access in device settings'), t('Device camera is used to take photos or videos.'), @@ -687,11 +684,12 @@ export const MessageInputProvider = ({ ], ); } - if (!photo.cancelled) { - if (photo.type.includes('image')) { - await uploadNewImage(photo); + if (!file.cancelled) { + if (file.type.includes('image')) { + // We already compressed the image in the native handler, so we can upload it directly. + await uploadNewImage(file); } else { - await uploadNewFile({ ...photo, mimeType: photo.type, type: FileTypes.Video }); + await uploadNewFile(file); } } }; @@ -726,9 +724,13 @@ export const MessageInputProvider = ({ } result.assets.forEach(async (asset) => { if (asset.type.includes('image')) { - await uploadNewImage(asset); + const compressedURI = await compressedImageURI(asset, value.compressImageQuality); + await uploadNewImage({ + ...asset, + uri: compressedURI, + }); } else { - await uploadNewFile({ ...asset, mimeType: asset.type, type: FileTypes.Video }); + await uploadNewFile(asset); } }); } @@ -785,14 +787,15 @@ export const MessageInputProvider = ({ if (!result.cancelled && result.assets) { result.assets.forEach(async (asset) => { - /** - * TODO: The current tight coupling of images to the image - * picker does not allow images picked from the file picker - * to be rendered in a preview via the uploadNewImage call. - * This should be updated alongside allowing image a file - * uploads together. - */ - await uploadNewFile(asset); + if (asset.type.includes('image')) { + const compressedURI = await compressedImageURI(asset, value.compressImageQuality); + await uploadNewImage({ + ...asset, + uri: compressedURI, + }); + } else { + await uploadNewFile(asset); + } }); } }; @@ -840,15 +843,13 @@ export const MessageInputProvider = ({ } }; - const mapImageUploadToAttachment = (image: ImageUpload): Attachment => { - const mime_type: string | boolean = lookup(image.file.name as string); - const name = image.file.name as string; + const mapImageUploadToAttachment = (image: FileUpload): Attachment => { return { - fallback: name, + fallback: image.file.name, image_url: image.url, - mime_type: mime_type ? mime_type : undefined, - original_height: image.height, - original_width: image.width, + mime_type: image.file.type, + original_height: image.file.height, + original_width: image.file.width, originalImage: image.file, type: FileTypes.Image, }; @@ -859,7 +860,9 @@ export const MessageInputProvider = ({ return { fallback: file.file.name, image_url: file.url, - mime_type: file.file.mimeType, + mime_type: file.file.type, + original_height: file.file.height, + original_width: file.file.width, originalFile: file.file, type: FileTypes.Image, }; @@ -868,7 +871,7 @@ export const MessageInputProvider = ({ asset_url: file.url || file.file.uri, duration: file.file.duration, file_size: file.file.size, - mime_type: file.file.mimeType, + mime_type: file.file.type, originalFile: file.file, title: file.file.name, type: FileTypes.Audio, @@ -878,7 +881,7 @@ export const MessageInputProvider = ({ asset_url: file.url || file.file.uri, duration: file.file.duration, file_size: file.file.size, - mime_type: file.file.mimeType, + mime_type: file.file.type, originalFile: file.file, thumb_url: file.thumb_url, title: file.file.name, @@ -889,7 +892,7 @@ export const MessageInputProvider = ({ asset_url: file.url || file.file.uri, duration: file.file.duration, file_size: file.file.size, - mime_type: file.file.mimeType, + mime_type: file.file.type, originalFile: file.file, title: file.file.name, type: FileTypes.VoiceRecording, @@ -899,7 +902,7 @@ export const MessageInputProvider = ({ return { asset_url: file.url || file.file.uri, file_size: file.file.size, - mime_type: file.file.mimeType, + mime_type: file.file.type, originalFile: file.file, title: file.file.name, type: FileTypes.File, @@ -1150,7 +1153,7 @@ export const MessageInputProvider = ({ const regexCondition = /File (extension \.\w{2,4}|type \S+) is not supported/; const getUploadSetStateAction = - ( + ( id: string, fileState: FileStateValue, extraData: Partial = {}, @@ -1207,11 +1210,11 @@ export const MessageInputProvider = ({ client.createAbortControllerForNextRequest(), ); // Compress images selected through file picker when uploading them - if (file.mimeType?.includes('image')) { + if (file.type?.includes('image')) { const compressedUri = await compressedImageURI(file, value.compressImageQuality); - response = await channel.sendFile(compressedUri, filename, file.mimeType); + response = await channel.sendFile(compressedUri, filename, file.type); } else { - response = await channel.sendFile(file.uri, filename, file.mimeType); + response = await channel.sendFile(file.uri, filename, file.type); } uploadAbortControllerRef.current.delete(filename); } @@ -1234,7 +1237,7 @@ export const MessageInputProvider = ({ } }; - const uploadImage = async ({ newImage }: { newImage: ImageUpload }) => { + const uploadImage = async ({ newImage }: { newImage: FileUpload }) => { const { file, id } = newImage || {}; if (!file) { @@ -1248,17 +1251,16 @@ export const MessageInputProvider = ({ const filename = escapeRegExp(file.name ?? getFileNameFromPath(uri)); try { - const compressedUri = await compressedImageURI(file, value.compressImageQuality); - const contentType = lookup(filename) || 'multipart/form-data'; + const contentType = file.type || 'multipart/form-data'; if (value.doImageUploadRequest) { response = await value.doImageUploadRequest(file, channel); - } else if (compressedUri && channel) { + } else if (channel) { if (value.sendImageAsync) { uploadAbortControllerRef.current.set( filename, client.createAbortControllerForNextRequest(), ); - channel.sendImage(compressedUri, filename, contentType).then( + channel.sendImage(file.uri, filename, contentType).then( (res) => { uploadAbortControllerRef.current.delete(filename); if (asyncIds.includes(id)) { @@ -1272,7 +1274,7 @@ export const MessageInputProvider = ({ return prevAsyncUploads; }); } else { - const newImageUploads = getUploadSetStateAction( + const newImageUploads = getUploadSetStateAction( id, FileState.UPLOADED, { @@ -1291,13 +1293,13 @@ export const MessageInputProvider = ({ filename, client.createAbortControllerForNextRequest(), ); - response = await channel.sendImage(compressedUri, filename, contentType); + response = await channel.sendImage(file.uri, filename, contentType); uploadAbortControllerRef.current.delete(filename); } } if (Object.keys(response).length) { - const newImageUploads = getUploadSetStateAction(id, FileState.UPLOADED, { + const newImageUploads = getUploadSetStateAction(id, FileState.UPLOADED, { height: file.height, url: response.file, width: file.width, @@ -1317,7 +1319,12 @@ export const MessageInputProvider = ({ } }; - const uploadNewFile = async (file: File) => { + /** + * The fileType is optional and is used to override the file type detection. + * This is useful for voice recordings, where the file type is not always detected correctly. + * This will change if we unify the file uploads to attachments. + */ + const uploadNewFile = async (file: File, fileType?: FileTypes) => { try { const id: string = generateRandomId(); const fileConfig = getFileUploadConfig(); @@ -1339,16 +1346,16 @@ export const MessageInputProvider = ({ } const fileState = isAllowed ? FileState.UPLOADING : FileState.NOT_SUPPORTED; - - // If file type is explicitly provided while upload we use it, else we derive the file type. - const fileType = file.type || file.mimeType?.split('/')[0]; + const derivedFileType = fileType ?? getFileTypeFromMimeType(file.type); const newFile: FileUpload = { duration: file.duration || 0, file, - id: file.id || id, + id, + mime_type: file.type, state: fileState, - type: fileType, + thumb_url: file.thumb_url, + type: derivedFileType, url: file.uri, }; @@ -1365,7 +1372,7 @@ export const MessageInputProvider = ({ } }; - const uploadNewImage = async (image: Partial) => { + const uploadNewImage = async (image: File) => { try { const id = generateRandomId(); const imageUploadConfig = getImageUploadConfig(); @@ -1391,11 +1398,13 @@ export const MessageInputProvider = ({ const imageState = isAllowed ? FileState.UPLOADING : FileState.NOT_SUPPORTED; - const newImage: ImageUpload = { + const newImage: FileUpload = { file: image, height: image.height, id, + mime_type: image.type, state: imageState, + type: FileTypes.Image, url: image.uri, width: image.width, }; diff --git a/package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts b/package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts index 3bb587fd02..6fda3788f7 100644 --- a/package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts +++ b/package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts @@ -116,9 +116,7 @@ export const useCreateMessageInputContext = ({ UploadProgressIndicator, }: MessageInputContextValue & Pick) => { const editingdep = editing?.id; - const fileUploadsValue = fileUploads - .map(({ duration, paused, progress, state }) => `${state},${paused},${progress},${duration}`) - .join(); + const fileUploadsValue = fileUploads.map(({ state }) => state).join(); const imageUploadsValue = imageUploads.map(({ state }) => state).join(); const asyncUploadsValue = Object.keys(asyncUploads).join(); const mentionedUsersLength = mentionedUsers.length; diff --git a/package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts b/package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts index 6ad3bd227a..4900583c22 100644 --- a/package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts +++ b/package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts @@ -2,8 +2,8 @@ import { useEffect, useState } from 'react'; import { Attachment } from 'stream-chat'; -import { FileTypes, FileUpload, ImageUpload } from '../../../types/types'; -import { generateRandomId, stringifyMessage } from '../../../utils/utils'; +import { FileTypes, FileUpload } from '../../../types/types'; +import { generateRandomId, getFileTypeFromMimeType, stringifyMessage } from '../../../utils/utils'; import type { MessageInputContextValue } from '../MessageInputContext'; @@ -12,7 +12,7 @@ export const useMessageDetailsForState = ( initialValue?: string, ) => { const [fileUploads, setFileUploads] = useState([]); - const [imageUploads, setImageUploads] = useState([]); + const [imageUploads, setImageUploads] = useState([]); const [mentionedUsers, setMentionedUsers] = useState([]); const [numberOfUploads, setNumberOfUploads] = useState(0); @@ -48,66 +48,59 @@ export const useMessageDetailsForState = ( if (attachment.type === FileTypes.Audio) { return { file: { - duration: attachment.duration, - mimeType: attachment.mime_type, + duration: attachment.duration || 0, name: attachment.title || '', - size: attachment.file_size, - uri: attachment.asset_url, + size: attachment.file_size || 0, + type: attachment.mime_type || '', + uri: attachment.asset_url || '', }, id, state: 'finished', + type: FileTypes.Audio, url: attachment.asset_url, }; } else if (attachment.type === FileTypes.Video) { return { file: { - duration: attachment.duration, - mimeType: attachment.mime_type, + duration: attachment.duration || 0, name: attachment.title || '', - size: attachment.file_size, - uri: attachment.asset_url, + size: attachment.file_size || 0, + thumb_url: attachment.thumb_url || '', + type: attachment.mime_type || '', + uri: attachment.asset_url || '', }, id, state: 'finished', thumb_url: attachment.thumb_url, + type: FileTypes.Video, url: attachment.asset_url, }; } else if (attachment.type === FileTypes.VoiceRecording) { return { file: { - duration: attachment.duration, - mimeType: attachment.mime_type, + duration: attachment.duration || 0, name: attachment.title || '', - size: attachment.file_size, - uri: attachment.asset_url, + size: attachment.file_size || 0, + type: attachment.mime_type || '', + uri: attachment.asset_url || '', waveform_data: attachment.waveform_data, }, id, state: 'finished', - url: attachment.asset_url, - }; - } else if (attachment.type === FileTypes.File) { - return { - file: { - mimeType: attachment.mime_type, - name: attachment.title || '', - size: attachment.file_size, - uri: attachment.asset_url, - }, - id, - state: 'finished', + type: FileTypes.VoiceRecording, url: attachment.asset_url, }; } else { return { file: { - mimeType: attachment.mime_type, name: attachment.title || '', - size: attachment.file_size, - uri: attachment.asset_url, + size: attachment.file_size || 0, + type: attachment.mime_type || '', + uri: attachment.asset_url || '', }, id, state: 'finished', + type: getFileTypeFromMimeType(attachment.mime_type || ''), url: attachment.asset_url, }; } @@ -117,7 +110,7 @@ export const useMessageDetailsForState = ( if (message) { setText(message?.text || ''); const newFileUploads: FileUpload[] = []; - const newImageUploads: ImageUpload[] = []; + const newImageUploads: FileUpload[] = []; const attachments = Array.isArray(message.attachments) ? message.attachments : []; @@ -126,14 +119,16 @@ export const useMessageDetailsForState = ( const id = generateRandomId(); newImageUploads.push({ file: { - height: attachment.original_height, - name: attachment.fallback, - size: attachment.file_size, - type: attachment.type, - width: attachment.original_width, + height: attachment.original_height || 0, + name: attachment.fallback || '', + size: attachment.file_size || 0, + type: attachment.type || '', + uri: attachment.image_url || '', + width: attachment.original_width || 0, }, id, state: 'finished', + type: FileTypes.Image, url: attachment.image_url || attachment.asset_url || attachment.thumb_url, }); } else { diff --git a/package/src/contexts/messageInputContext/utils/utils.ts b/package/src/contexts/messageInputContext/utils/utils.ts index 4999a1f1ec..9fbc3ead8a 100644 --- a/package/src/contexts/messageInputContext/utils/utils.ts +++ b/package/src/contexts/messageInputContext/utils/utils.ts @@ -1,13 +1,13 @@ import { lookup } from 'mime-types'; import type { FileUploadConfig } from 'stream-chat'; -import { Asset, File } from '../../../types/types'; +import { File } from '../../../types/types'; export const MAX_FILE_SIZE_TO_UPLOAD = 100 * 1024 * 1024; // 100 MB type CheckUploadPermissionsParams = { config: FileUploadConfig; - file: File | Partial; + file: File; }; /** @@ -44,10 +44,9 @@ export const isUploadAllowed = ({ config, file }: CheckUploadPermissionsParams) } if (allowed_mime_types?.length) { - if (file.mimeType) { + if (file.type) { const allowed = allowed_mime_types.some( - (mimeType: string) => - file.mimeType && file.mimeType.toLowerCase() === mimeType.toLowerCase(), + (mimeType: string) => file.type && file.type.toLowerCase() === mimeType.toLowerCase(), ); if (!allowed) { @@ -66,10 +65,9 @@ export const isUploadAllowed = ({ config, file }: CheckUploadPermissionsParams) } if (blocked_mime_types?.length) { - if (file.mimeType) { + if (file.type) { const blocked = blocked_mime_types.some( - (mimeType: string) => - file.mimeType && file.mimeType.toLowerCase() === mimeType.toLowerCase(), + (mimeType: string) => file.type && file.type.toLowerCase() === mimeType.toLowerCase(), ); if (blocked) { diff --git a/package/src/native.ts b/package/src/native.ts index 88ce2ac038..ca2b816aee 100644 --- a/package/src/native.ts +++ b/package/src/native.ts @@ -1,8 +1,7 @@ import type React from 'react'; import { FlatList as DefaultFlatList, StyleProp, ViewStyle } from 'react-native'; -import type { Asset, File } from './types/types'; - +import type { File } from './types/types'; const fail = () => { throw Error( 'Native handler was not registered, you should import stream-chat-expo or stream-chat-react-native', @@ -31,7 +30,7 @@ type iOS14RefreshGallerySelection = () => Promise; type GetPhotos = ({ after, first }: { first: number; after?: string }) => | Promise<{ - assets: Array & { source: 'picker' }>; + assets: File[]; endCursor: string; hasNextPage: boolean; iOSLimited: boolean; @@ -47,7 +46,7 @@ type PickDocument = ({ maxNumberOfFiles }: { maxNumberOfFiles?: number }) => type PickImageAssetType = { askToOpenSettings?: boolean; - assets?: Array & { source: 'picker' }>; + assets?: File[]; cancelled?: boolean; }; @@ -67,8 +66,7 @@ type ShareOptions = { }; type ShareImage = (options: ShareOptions) => Promise | never; -type Photo = Omit & { - source: 'camera'; +type TakePhotoFileType = File & { askToOpenSettings?: boolean; cancelled?: boolean; }; @@ -78,7 +76,7 @@ export type MediaTypes = 'image' | 'video' | 'mixed'; type TakePhoto = (options: { compressImageQuality?: number; mediaType?: MediaTypes; -}) => Promise | never; +}) => Promise | never; type HapticFeedbackMethod = | 'impactHeavy' diff --git a/package/src/types/types.ts b/package/src/types/types.ts index 4b8d7ea321..3ed8c297ac 100644 --- a/package/src/types/types.ts +++ b/package/src/types/types.ts @@ -1,4 +1,4 @@ -import type { ChannelFilters, ChannelSort, ChannelState } from 'stream-chat'; +import type { ChannelFilters, ChannelSort, ChannelState, RNFile } from 'stream-chat'; import type { FileStateValue } from '../utils/utils'; @@ -12,51 +12,42 @@ export enum FileTypes { VoiceRecording = 'voiceRecording', } -export type Asset = { - duration: number; - height: number; - name: string; - source: 'camera' | 'picker'; - type: string; - uri: string; - width: number; - id?: string; - mimeType?: string; - originalUri?: string; - size?: number; -}; - -export type File = { - name: string; - duration?: number; - id?: string; - mimeType?: string; - originalUri?: string; - size?: number; - type?: FileTypes; - // The uri should be of type `string`. But is `string|undefined` because the same type is used for the response from Stream's Attachment. This shall be fixed. - uri?: string; - waveform_data?: number[]; -}; +export type File = RNFile; +/** + * This is nothing but a substitute for the attachment type prior to sending the message. + * This will change if we unify the file uploads to attachments. + */ export type FileUpload = { file: File; id: string; state: FileStateValue; - duration?: number; - paused?: boolean; - progress?: number; - thumb_url?: string; - type?: string; + + mime_type?: string; + + type?: FileTypes; url?: string; + + thumb_url?: string; + + duration?: number; waveform_data?: number[]; + + height?: number; + width?: number; }; + +export type AudioUpload = FileUpload & { + progress?: number; + paused?: boolean; +}; + export interface DefaultAttachmentType { duration?: number; file_size?: number; mime_type?: string; originalFile?: File; - originalImage?: Partial; + originalImage?: File; waveform_data?: number[]; } @@ -90,16 +81,6 @@ export interface DefaultReactionType {} export interface DefaultThreadType {} -/* eslint-enable @typescript-eslint/no-empty-object-type */ -export type ImageUpload = { - file: Partial; - id: string; - state: FileStateValue; - height?: number; - url?: string; - width?: number; -}; - export type Reaction = { id: string; name: string; diff --git a/package/src/utils/compressImage.ts b/package/src/utils/compressImage.ts index b3efe1a4ac..ff6b7a24f4 100644 --- a/package/src/utils/compressImage.ts +++ b/package/src/utils/compressImage.ts @@ -1,5 +1,5 @@ import { NativeHandlers } from '../native'; -import type { Asset } from '../types/types'; +import type { File } from '../types/types'; /** * Function to compress and Image and return the compressed Image URI @@ -7,7 +7,7 @@ import type { Asset } from '../types/types'; * @param compressImageQuality * @returns string */ -export const compressedImageURI = async (image: Partial, compressImageQuality?: number) => { +export const compressedImageURI = async (image: File, compressImageQuality?: number) => { const uri = image.uri || ''; /** * We skip compression if: @@ -15,8 +15,7 @@ export const compressedImageURI = async (image: Partial, compressImageQua * - the file has no height/width value to maintain for compression * - the compressImageQuality number is not present or is 1 (meaning no compression) */ - const compressedUri = await (image.source === 'camera' || - !image.height || + const compressedUri = await (!image.height || !image.width || typeof compressImageQuality !== 'number' || compressImageQuality === 1 diff --git a/package/src/utils/utils.ts b/package/src/utils/utils.ts index b31b1dc35d..a856ee4c26 100644 --- a/package/src/utils/utils.ts +++ b/package/src/utils/utils.ts @@ -12,7 +12,7 @@ import { import type { EmojiSearchIndex } from '../contexts/messageInputContext/MessageInputContext'; import { compiledEmojis } from '../emoji-data'; import type { TableRowJoinedUser } from '../store/types'; -import type { ValueOf } from '../types/types'; +import { FileTypes, ValueOf } from '../types/types'; export type ReactionData = { Icon: React.ComponentType; @@ -239,12 +239,28 @@ export const getFileNameFromPath = (path: string) => { return match ? match[0] : ''; }; +export const getFileTypeFromMimeType = (mimeType: string) => { + const fileType = mimeType.split('/')[0]; + if (fileType === 'image') { + return FileTypes.Image; + } else if (fileType === 'video') { + return FileTypes.Video; + } else if (fileType === 'audio') { + return FileTypes.Audio; + } + return FileTypes.File; +}; + /** * Utility to get the duration label from the duration in seconds. * @param duration number * @returns string */ export const getDurationLabelFromDuration = (duration: number) => { + if (!duration) { + return '00:00'; + } + const ONE_HOUR_IN_SECONDS = 3600; const ONE_HOUR_IN_MILLISECONDS = ONE_HOUR_IN_SECONDS * 1000; let durationLabel = '00:00'; From 9ab351d25828cc882cb9cd864f0d80a2a5d94d5c Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Fri, 11 Apr 2025 01:11:54 +0200 Subject: [PATCH 35/60] chore: update deps --- package/expo-package/yarn.lock | 16 +++++++++++++--- package/native-package/yarn.lock | 16 +++++++++++++--- package/package.json | 2 +- package/yarn.lock | 4 ++-- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 640fb75626..efc9b8b0c4 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -4782,9 +4782,19 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -"stream-chat@link:../../../stream-chat-js": - version "0.0.0" - uid "" +"stream-chat@https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50": + version "0.0.0-development" + resolved "https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50" + dependencies: + "@types/jsonwebtoken" "^9.0.8" + "@types/ws" "^8.5.14" + axios "^1.6.0" + base64-js "^1.5.1" + form-data "^4.0.0" + isomorphic-ws "^5.0.0" + jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" + ws "^8.18.1" "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index b6bab71d41..3542840d7a 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -3498,9 +3498,19 @@ statuses@~1.5.0: version "0.0.0" uid "" -"stream-chat@link:../../../stream-chat-js": - version "0.0.0" - uid "" +"stream-chat@https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50": + version "0.0.0-development" + resolved "https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50" + dependencies: + "@types/jsonwebtoken" "^9.0.8" + "@types/ws" "^8.5.14" + axios "^1.6.0" + base64-js "^1.5.1" + form-data "^4.0.0" + isomorphic-ws "^5.0.0" + jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" + ws "^8.18.1" string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" diff --git a/package/package.json b/package/package.json index 85c506df52..7d2f482578 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917", + "stream-chat": "https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/yarn.lock b/package/yarn.lock index 2928e5cd27..485972cc02 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -7772,9 +7772,9 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": +"stream-chat@https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50": version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" + resolved "https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" From e34273c2bd5b37a36ce6c317759207851baaa84c Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Fri, 11 Apr 2025 02:29:02 +0200 Subject: [PATCH 36/60] fix: failing tests and AutoCompleteInput type --- .../AutoCompleteInput/AutoCompleteInput.tsx | 21 +++++++++------- .../__tests__/AutoCompleteInput.test.js | 24 +++++++++---------- .../__tests__/FileUploadPreview.test.js | 2 +- .../__tests__/MessageInput.test.js | 4 +++- .../__snapshots__/sendMessage.test.tsx.snap | 8 +++---- 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx b/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx index d67b039b7d..66444b63e8 100644 --- a/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx +++ b/package/src/components/AutoCompleteInput/AutoCompleteInput.tsx @@ -72,15 +72,26 @@ type AutoCompleteInputPropsWithContext = Pick< cooldownActive?: boolean; }; -export type AutoCompleteInputProps = Partial; +export type AutoCompleteInputProps = Partial< + Omit< + AutoCompleteInputPropsWithContext, + | 'triggerSettings' + | 'mentionAllAppUsersQuery' + | 'mentionAllAppUsersEnabled' + | 'autoCompleteSuggestionsLimit' + > +>; const AutoCompleteInputWithContext = (props: AutoCompleteInputPropsWithContext) => { const { additionalTextInputProps, + autoCompleteSuggestionsLimit, closeSuggestions, cooldownActive = false, giphyActive, giphyEnabled, + mentionAllAppUsersEnabled, + mentionAllAppUsersQuery, maxMessageLength, numberOfLines, onChange, @@ -89,16 +100,10 @@ const AutoCompleteInputWithContext = (props: AutoCompleteInputPropsWithContext) setInputBoxRef, t, text, + triggerSettings, updateSuggestions: updateSuggestionsContext, } = props; - const { - autoCompleteSuggestionsLimit, - mentionAllAppUsersEnabled, - mentionAllAppUsersQuery, - triggerSettings, - } = useMessageInputContext(); - const isTrackingStarted = useRef(false); const selectionEnd = useRef(0); const [textHeight, setTextHeight] = useState(0); diff --git a/package/src/components/AutoCompleteInput/__tests__/AutoCompleteInput.test.js b/package/src/components/AutoCompleteInput/__tests__/AutoCompleteInput.test.js index c3755f1a22..009f019154 100644 --- a/package/src/components/AutoCompleteInput/__tests__/AutoCompleteInput.test.js +++ b/package/src/components/AutoCompleteInput/__tests__/AutoCompleteInput.test.js @@ -9,6 +9,7 @@ import { generateChannelResponse } from '../../../mock-builders/generator/channe import { generateUser } from '../../../mock-builders/generator/user'; import { getTestClientWithUser } from '../../../mock-builders/mock'; import { ACITriggerSettings } from '../../../utils/ACITriggerSettings'; +import { Channel } from '../../Channel/Channel'; import { Chat } from '../../Chat/Chat'; import { AutoCompleteInput } from '../AutoCompleteInput'; @@ -19,18 +20,17 @@ describe('AutoCompleteInput', () => { const getComponent = (props = {}) => ( - - - + + + + ); diff --git a/package/src/components/MessageInput/__tests__/FileUploadPreview.test.js b/package/src/components/MessageInput/__tests__/FileUploadPreview.test.js index c918ace10c..f0494f8392 100644 --- a/package/src/components/MessageInput/__tests__/FileUploadPreview.test.js +++ b/package/src/components/MessageInput/__tests__/FileUploadPreview.test.js @@ -332,8 +332,8 @@ describe('FileUploadPreview', () => { const fileUploads = [ generateFileUploadPreview({ id: 'file-upload-id-1', - mimeType: 'audio/mp3', state: FileState.UPLOADED, + type: 'audio/mp3', }), ]; const removeFile = jest.fn(); diff --git a/package/src/components/MessageInput/__tests__/MessageInput.test.js b/package/src/components/MessageInput/__tests__/MessageInput.test.js index 4fa3726c03..dc3749ead0 100644 --- a/package/src/components/MessageInput/__tests__/MessageInput.test.js +++ b/package/src/components/MessageInput/__tests__/MessageInput.test.js @@ -129,7 +129,9 @@ describe('MessageInput', () => { ); // Both for files and for images triggered in one test itself. - expect(Alert.alert).toHaveBeenCalledTimes(4); + await waitFor(() => { + expect(Alert.alert).toHaveBeenCalledTimes(4); + }); }); it('should start the audio recorder on long press and cleanup on unmount', async () => { diff --git a/package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap b/package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap index 27b76669e9..a4dd5829ed 100644 --- a/package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap +++ b/package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap @@ -46,7 +46,7 @@ exports[`MessageInputContext's sendMessage exit sendMessage when file upload sta { "asset_url": undefined, "file_size": undefined, - "mime_type": undefined, + "mime_type": "file", "originalFile": { "name": "dummy.pdf", "state": "uploaded", @@ -58,7 +58,7 @@ exports[`MessageInputContext's sendMessage exit sendMessage when file upload sta { "asset_url": undefined, "file_size": undefined, - "mime_type": undefined, + "mime_type": "video/mp4", "originalFile": { "name": "dummy.pdf", "state": "finished", @@ -70,7 +70,7 @@ exports[`MessageInputContext's sendMessage exit sendMessage when file upload sta { "asset_url": undefined, "file_size": undefined, - "mime_type": undefined, + "mime_type": "audio/mp3", "originalFile": { "name": "dummy.pdf", "state": "uploaded", @@ -82,7 +82,7 @@ exports[`MessageInputContext's sendMessage exit sendMessage when file upload sta { "asset_url": undefined, "file_size": undefined, - "mime_type": undefined, + "mime_type": "image/jpeg", "originalFile": { "name": "dummy.pdf", "state": "finished", From 3d461d029bfb1e7abed4d3faf4656ec1f8c8108a Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 15 Apr 2025 00:04:38 +0200 Subject: [PATCH 37/60] chore: update custom data module interfaces --- examples/ExpoMessaging/custom-types.d.ts | 44 +++++++++---------- examples/SampleApp/src/custom-types.d.ts | 44 +++++++++---------- .../TypeScriptMessaging/custom-types.d.ts | 44 +++++++++---------- .../types/stream-chat-common-custom-data.d.ts | 44 +++++++++---------- package/src/types/types.ts | 22 +++++----- 5 files changed, 99 insertions(+), 99 deletions(-) diff --git a/examples/ExpoMessaging/custom-types.d.ts b/examples/ExpoMessaging/custom-types.d.ts index fb15477e17..dcd62b8eb0 100644 --- a/examples/ExpoMessaging/custom-types.d.ts +++ b/examples/ExpoMessaging/custom-types.d.ts @@ -1,41 +1,41 @@ import { - DefaultAttachmentType, - DefaultMessageType, - DefaultChannelType, - DefaultCommandType, - DefaultEventType, - DefaultMemberType, - DefaultPollOptionType, - DefaultPollType, - DefaultReactionType, - DefaultThreadType, - DefaultUserType, + DefaultAttachmentData, + DefaultChannelData, + DefaultCommandData, + DefaultEventData, + DefaultMemberData, + DefaultMessageData, + DefaultPollData, + DefaultPollOptionData, + DefaultReactionData, + DefaultThreadData, + DefaultUserData, } from 'stream-chat-expo'; declare module 'stream-chat' { /* eslint-disable @typescript-eslint/no-empty-object-type */ - interface CustomAttachmentData extends DefaultAttachmentType {} + interface CustomAttachmentData extends DefaultAttachmentData {} - interface CustomChannelData extends DefaultChannelType {} + interface CustomChannelData extends DefaultChannelData {} - interface CustomCommandData extends DefaultCommandType {} + interface CustomCommandData extends DefaultCommandData {} - interface CustomEventData extends DefaultEventType {} + interface CustomEventData extends DefaultEventData {} - interface CustomMemberData extends DefaultMemberType {} + interface CustomMemberData extends DefaultMemberData {} - interface CustomUserData extends DefaultUserType {} + interface CustomUserData extends DefaultUserData {} - interface CustomMessageData extends DefaultMessageType {} + interface CustomMessageData extends DefaultMessageData {} - interface CustomPollOptionData extends DefaultPollOptionType {} + interface CustomPollOptionData extends DefaultPollOptionData {} - interface CustomPollData extends DefaultPollType {} + interface CustomPollData extends DefaultPollData {} - interface CustomReactionData extends DefaultReactionType {} + interface CustomReactionData extends DefaultReactionData {} - interface CustomThreadData extends DefaultThreadType {} + interface CustomThreadData extends DefaultThreadData {} /* eslint-enable @typescript-eslint/no-empty-object-type */ } diff --git a/examples/SampleApp/src/custom-types.d.ts b/examples/SampleApp/src/custom-types.d.ts index ac568a4d1d..2dfa7528d4 100644 --- a/examples/SampleApp/src/custom-types.d.ts +++ b/examples/SampleApp/src/custom-types.d.ts @@ -1,45 +1,45 @@ import { - DefaultAttachmentType, - DefaultMessageType, - DefaultChannelType, - DefaultCommandType, - DefaultEventType, - DefaultMemberType, - DefaultPollOptionType, - DefaultPollType, - DefaultReactionType, - DefaultThreadType, - DefaultUserType, + DefaultAttachmentData, + DefaultChannelData, + DefaultCommandData, + DefaultEventData, + DefaultMemberData, + DefaultMessageData, + DefaultPollData, + DefaultPollOptionData, + DefaultReactionData, + DefaultThreadData, + DefaultUserData, } from 'stream-chat-react-native'; declare module 'stream-chat' { /* eslint-disable @typescript-eslint/no-empty-object-type */ - interface CustomAttachmentData extends DefaultAttachmentType { + interface CustomAttachmentData extends DefaultAttachmentData { id?: string; } - interface CustomChannelData extends DefaultChannelType {} + interface CustomChannelData extends DefaultChannelData {} - interface CustomCommandData extends DefaultCommandType {} + interface CustomCommandData extends DefaultCommandData {} - interface CustomEventData extends DefaultEventType {} + interface CustomEventData extends DefaultEventData {} - interface CustomMemberData extends DefaultMemberType {} + interface CustomMemberData extends DefaultMemberData {} - interface CustomUserData extends DefaultUserType {} + interface CustomUserData extends DefaultUserData {} - interface CustomMessageData extends DefaultMessageType { + interface CustomMessageData extends DefaultMessageData { ai_generated?: boolean; } - interface CustomPollOptionData extends DefaultPollOptionType {} + interface CustomPollOptionData extends DefaultPollOptionData {} - interface CustomPollData extends DefaultPollType {} + interface CustomPollData extends DefaultPollData {} - interface CustomReactionData extends DefaultReactionType {} + interface CustomReactionData extends DefaultReactionData {} - interface CustomThreadData extends DefaultThreadType {} + interface CustomThreadData extends DefaultThreadData {} /* eslint-enable @typescript-eslint/no-empty-object-type */ } diff --git a/examples/TypeScriptMessaging/custom-types.d.ts b/examples/TypeScriptMessaging/custom-types.d.ts index f8641bab5f..e6400ab92a 100644 --- a/examples/TypeScriptMessaging/custom-types.d.ts +++ b/examples/TypeScriptMessaging/custom-types.d.ts @@ -1,41 +1,41 @@ import { - DefaultAttachmentType, - DefaultMessageType, - DefaultChannelType, - DefaultCommandType, - DefaultEventType, - DefaultMemberType, - DefaultPollOptionType, - DefaultPollType, - DefaultReactionType, - DefaultThreadType, - DefaultUserType, + DefaultAttachmentData, + DefaultChannelData, + DefaultCommandData, + DefaultEventData, + DefaultMemberData, + DefaultMessageData, + DefaultPollData, + DefaultPollOptionData, + DefaultReactionData, + DefaultThreadData, + DefaultUserData, } from 'stream-chat-react-native'; declare module 'stream-chat' { /* eslint-disable @typescript-eslint/no-empty-object-type */ - interface CustomAttachmentData extends DefaultAttachmentType {} + interface CustomAttachmentData extends DefaultAttachmentData {} - interface CustomChannelData extends DefaultChannelType {} + interface CustomChannelData extends DefaultChannelData {} - interface CustomCommandData extends DefaultCommandType {} + interface CustomCommandData extends DefaultCommandData {} - interface CustomEventData extends DefaultEventType {} + interface CustomEventData extends DefaultEventData {} - interface CustomMemberData extends DefaultMemberType {} + interface CustomMemberData extends DefaultMemberData {} - interface CustomUserData extends DefaultUserType {} + interface CustomUserData extends DefaultUserData {} - interface CustomMessageData extends DefaultMessageType {} + interface CustomMessageData extends DefaultMessageData {} - interface CustomPollOptionData extends DefaultPollOptionType {} + interface CustomPollOptionData extends DefaultPollOptionData {} - interface CustomPollData extends DefaultPollType {} + interface CustomPollData extends DefaultPollData {} - interface CustomReactionData extends DefaultReactionType {} + interface CustomReactionData extends DefaultReactionData {} - interface CustomThreadData extends DefaultThreadType {} + interface CustomThreadData extends DefaultThreadData {} /* eslint-enable @typescript-eslint/no-empty-object-type */ } diff --git a/package/src/types/stream-chat-common-custom-data.d.ts b/package/src/types/stream-chat-common-custom-data.d.ts index 78a5b46f1f..fb4a24ed4e 100644 --- a/package/src/types/stream-chat-common-custom-data.d.ts +++ b/package/src/types/stream-chat-common-custom-data.d.ts @@ -1,42 +1,42 @@ import 'stream-chat'; import { - DefaultAttachmentType, - DefaultChannelType, - DefaultCommandType, - DefaultEventType, - DefaultMemberType, - DefaultMessageType, - DefaultPollOptionType, - DefaultPollType, - DefaultReactionType, - DefaultThreadType, - DefaultUserType, + DefaultAttachmentData, + DefaultChannelData, + DefaultCommandData, + DefaultEventData, + DefaultMemberData, + DefaultMessageData, + DefaultPollData, + DefaultPollOptionData, + DefaultReactionData, + DefaultThreadData, + DefaultUserData, } from './types'; declare module 'stream-chat' { /* eslint-disable @typescript-eslint/no-empty-object-type */ - interface CustomAttachmentData extends DefaultAttachmentType {} + interface CustomAttachmentData extends DefaultAttachmentData {} - interface CustomChannelData extends DefaultChannelType {} + interface CustomChannelData extends DefaultChannelData {} - interface CustomCommandData extends DefaultCommandType {} + interface CustomCommandData extends DefaultCommandData {} - interface CustomEventData extends DefaultEventType {} + interface CustomEventData extends DefaultEventData {} - interface CustomMemberData extends DefaultMemberType {} + interface CustomMemberData extends DefaultMemberData {} - interface CustomUserData extends DefaultUserType {} + interface CustomUserData extends DefaultUserData {} - interface CustomMessageData extends DefaultMessageType {} + interface CustomMessageData extends DefaultMessageData {} - interface CustomPollOptionData extends DefaultPollOptionType {} + interface CustomPollOptionData extends DefaultPollOptionData {} - interface CustomPollData extends DefaultPollType {} + interface CustomPollData extends DefaultPollData {} - interface CustomReactionData extends DefaultReactionType {} + interface CustomReactionData extends DefaultReactionData {} - interface CustomThreadData extends DefaultThreadType {} + interface CustomThreadData extends DefaultThreadData {} /* eslint-enable @typescript-eslint/no-empty-object-type */ } diff --git a/package/src/types/types.ts b/package/src/types/types.ts index 3ed8c297ac..4786a37c17 100644 --- a/package/src/types/types.ts +++ b/package/src/types/types.ts @@ -42,7 +42,7 @@ export type AudioUpload = FileUpload & { paused?: boolean; }; -export interface DefaultAttachmentType { +export interface DefaultAttachmentData { duration?: number; file_size?: number; mime_type?: string; @@ -51,35 +51,35 @@ export interface DefaultAttachmentType { waveform_data?: number[]; } -export interface DefaultUserType { +export interface DefaultUserData { image?: string; } -export interface DefaultChannelType { +export interface DefaultChannelData { image?: string; name?: string; } -export interface DefaultCommandType { +export interface DefaultCommandData { flag: unknown; imgur: unknown; } /* eslint-disable @typescript-eslint/no-empty-object-type */ -export interface DefaultEventType {} +export interface DefaultEventData {} -export interface DefaultMemberType {} +export interface DefaultMemberData {} -export interface DefaultMessageType {} +export interface DefaultMessageData {} -export interface DefaultPollOptionType {} +export interface DefaultPollOptionData {} -export interface DefaultPollType {} +export interface DefaultPollData {} -export interface DefaultReactionType {} +export interface DefaultReactionData {} -export interface DefaultThreadType {} +export interface DefaultThreadData {} export type Reaction = { id: string; From ab7973fb76bca0cdeaf97dd4001fe4eb7e258467 Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Tue, 22 Apr 2025 14:17:54 +0530 Subject: [PATCH 38/60] fix: change RNFile to FileReference as per latest client changes (#3061) --- package/src/types/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/src/types/types.ts b/package/src/types/types.ts index 4786a37c17..9e3057ef4b 100644 --- a/package/src/types/types.ts +++ b/package/src/types/types.ts @@ -1,4 +1,4 @@ -import type { ChannelFilters, ChannelSort, ChannelState, RNFile } from 'stream-chat'; +import type { ChannelFilters, ChannelSort, ChannelState, FileReference } from 'stream-chat'; import type { FileStateValue } from '../utils/utils'; @@ -12,7 +12,7 @@ export enum FileTypes { VoiceRecording = 'voiceRecording', } -export type File = RNFile; +export type File = FileReference; /** * This is nothing but a substitute for the attachment type prior to sending the message. From 9375fa4f9c860ab641ad72f01da1f8147adb72a3 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Wed, 23 Apr 2025 10:38:46 +0200 Subject: [PATCH 39/60] fix: merge conflicts --- package/expo-package/yarn.lock | 4 +- package/native-package/yarn.lock | 4 +- package/package.json | 2 +- package/src/components/Channel/Channel.tsx | 513 +++++++++--------- .../hooks/useMessageListPagination.tsx | 104 ++-- .../MessageList/hooks/useMessageList.ts | 6 +- .../MessageInputContext.tsx | 130 ++--- package/yarn.lock | 4 +- 8 files changed, 387 insertions(+), 380 deletions(-) diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index efc9b8b0c4..80740ce589 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -4782,9 +4782,9 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50": +"stream-chat@https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936": version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50" + resolved "https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 3542840d7a..3a82da419d 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -3498,9 +3498,9 @@ statuses@~1.5.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50": +"stream-chat@https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936": version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50" + resolved "https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/package.json b/package/package.json index 4609495ea9..f253289a7e 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50", + "stream-chat": "https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/src/components/Channel/Channel.tsx b/package/src/components/Channel/Channel.tsx index b4dd8e9f2e..370511de88 100644 --- a/package/src/components/Channel/Channel.tsx +++ b/package/src/components/Channel/Channel.tsx @@ -1145,51 +1145,48 @@ const ChannelWithContext = (props: PropsWithChildren) = } }); - const loadChannelAroundMessage: ChannelContextValue['loadChannelAroundMessage'] = useStableCallback(async ({ - messageId: messageIdToLoadAround, - }): Promise => { - if (!messageIdToLoadAround) { - return; - } - try { - if (thread) { - setThreadLoadingMore(true); - try { - await channel.state.loadMessageIntoState(messageIdToLoadAround, thread.id); - setThreadLoadingMore(false); - setThreadMessages(channel.state.threads[thread.id]); - if (setTargetedMessage) { - setTargetedMessage(messageIdToLoadAround); - } - } catch (err) { - if (err instanceof Error) { - setError(err); - } else { - setError(true); + const loadChannelAroundMessage: ChannelContextValue['loadChannelAroundMessage'] = + useStableCallback(async ({ messageId: messageIdToLoadAround }): Promise => { + if (!messageIdToLoadAround) { + return; + } + try { + if (thread) { + setThreadLoadingMore(true); + try { + await channel.state.loadMessageIntoState(messageIdToLoadAround, thread.id); + setThreadLoadingMore(false); + setThreadMessages(channel.state.threads[thread.id]); + if (setTargetedMessage) { + setTargetedMessage(messageIdToLoadAround); + } + } catch (err) { + if (err instanceof Error) { + setError(err); + } else { + setError(true); + } + setThreadLoadingMore(false); } - setThreadLoadingMore(false); + } else { + await loadChannelAroundMessageFn({ + messageId: messageIdToLoadAround, + setTargetedMessage, + }); } - } else { - await loadChannelAroundMessageFn({ - messageId: messageIdToLoadAround, - setTargetedMessage, - }); + } catch (err) { + console.warn('Loading channel around message failed with error:', err); } - } catch (err) { - console.warn('Loading channel around message failed with error:', err); - } - }); + }); /** * MESSAGE METHODS */ - const updateMessage: MessagesContextValue['updateMessage'] = useStableCallback(( - updatedMessage, - extraState = {}, - ) => { - if (!channel) { - return; - } + const updateMessage: MessagesContextValue['updateMessage'] = useStableCallback( + (updatedMessage, extraState = {}, throttled = false) => { + if (!channel) { + return; + } channel.state.addMessageSorted(updatedMessage, true); if (throttled) { @@ -1202,13 +1199,15 @@ const ChannelWithContext = (props: PropsWithChildren) = extraState.threadMessages = channel.state.threads[updatedMessage.parent_id] || []; setThreadMessages(extraState.threadMessages); } - }); + }, + ); - const replaceMessage = useStableCallback((oldMessage: MessageResponse, newMessage: MessageResponse) => { - if (channel) { - channel.state.removeMessage(oldMessage); - channel.state.addMessageSorted(newMessage, true); - copyMessagesStateFromChannel(channel); + const replaceMessage = useStableCallback( + (oldMessage: MessageResponse, newMessage: MessageResponse) => { + if (channel) { + channel.state.removeMessage(oldMessage); + channel.state.addMessageSorted(newMessage, true); + copyMessagesStateFromChannel(channel); if (thread && newMessage.parent_id) { const threadMessages = channel.state.threads[newMessage.parent_id] || []; @@ -1218,43 +1217,44 @@ const ChannelWithContext = (props: PropsWithChildren) = }, ); - const createMessagePreview = useStableCallback(({ - attachments, - mentioned_users, - parent_id, - poll_id, - text, - ...extraFields - }: Partial) => { - // Exclude following properties from message.user within message preview, - // since they could be long arrays and have no meaning as sender of message. - // Storing such large value within user's table may cause sqlite queries to crash. - // @ts-ignore - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { channel_mutes, devices, mutes, ...messageUser } = client.user; - - const preview = { - __html: text, + const createMessagePreview = useStableCallback( + ({ attachments, - created_at: new Date(), - html: text, - id: `${client.userID}-${generateRandomId()}`, - mentioned_users: - mentioned_users?.map((userId) => ({ - id: userId, - })) || [], + mentioned_users, parent_id, poll_id, - reactions: [], - status: MessageStatusTypes.SENDING, text, - type: 'regular', - user: { - ...messageUser, - id: client.userID, - }, - ...extraFields, - } as unknown as MessageResponse; + ...extraFields + }: Partial) => { + // Exclude following properties from message.user within message preview, + // since they could be long arrays and have no meaning as sender of message. + // Storing such large value within user's table may cause sqlite queries to crash. + // @ts-ignore + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { channel_mutes, devices, mutes, ...messageUser } = client.user; + + const preview = { + __html: text, + attachments, + created_at: new Date(), + html: text, + id: `${client.userID}-${generateRandomId()}`, + mentioned_users: + mentioned_users?.map((userId) => ({ + id: userId, + })) || [], + parent_id, + poll_id, + reactions: [], + status: MessageStatusTypes.SENDING, + text, + type: 'regular', + user: { + ...messageUser, + id: client.userID, + }, + ...extraFields, + } as unknown as MessageResponse; /** * This is added to the message for local rendering prior to the message @@ -1266,10 +1266,11 @@ const ChannelWithContext = (props: PropsWithChildren) = (message) => message.id === preview.quoted_message_id, ); - preview.quoted_message = quotedMessage as MessageResponse['quoted_message']; - } - return preview; - }); + preview.quoted_message = quotedMessage as MessageResponse['quoted_message']; + } + return preview; + }, + ); const uploadPendingAttachments = useStableCallback(async (message: MessageResponse) => { const updatedMessage = { ...message }; @@ -1295,17 +1296,17 @@ const ChannelWithContext = (props: PropsWithChildren) = const compressedUri = await compressedImageURI(image, compressImageQuality); const contentType = lookup(filename) || 'multipart/form-data'; - const uploadResponse = doImageUploadRequest - ? await doImageUploadRequest(image, channel) - : await channel.sendImage(compressedUri, filename, contentType); + const uploadResponse = doImageUploadRequest + ? await doImageUploadRequest(image, channel) + : await channel.sendImage(compressedUri, filename, contentType); - attachment.image_url = uploadResponse.file; - delete attachment.originalFile; + attachment.image_url = uploadResponse.file; + delete attachment.originalFile; - await dbApi.updateMessage({ - message: { ...updatedMessage, cid: channel.cid }, - }); - } + await dbApi.updateMessage({ + message: { ...updatedMessage, cid: channel.cid }, + }); + } if ( (attachment.type === FileTypes.File || @@ -1330,64 +1331,64 @@ const ChannelWithContext = (props: PropsWithChildren) = attachment.thumb_url = response.thumb_url; } - delete attachment.originalFile; - await dbApi.updateMessage({ - message: { ...updatedMessage, cid: channel.cid }, - }); - } + delete attachment.originalFile; + await dbApi.updateMessage({ + message: { ...updatedMessage, cid: channel.cid }, + }); } } + } - return updatedMessage; - }, - ); + return updatedMessage; + }); - const sendMessageRequest = useStableCallback(async (message: MessageResponse, retrying?: boolean) => { - try { - const updatedMessage = await uploadPendingAttachments(message); - const extraFields = omit(updatedMessage, [ - '__html', - 'attachments', - 'created_at', - 'deleted_at', - 'html', - 'id', - 'latest_reactions', - 'mentioned_users', - 'own_reactions', - 'parent_id', - 'quoted_message', - 'reaction_counts', - 'reaction_groups', - 'reactions', - 'status', - 'text', - 'type', - 'updated_at', - 'user', - ]); - const { attachments, id, mentioned_users, parent_id, text } = updatedMessage; - if (!channel.id) { - return; - } + const sendMessageRequest = useStableCallback( + async (message: MessageResponse, retrying?: boolean) => { + try { + const updatedMessage = await uploadPendingAttachments(message); + const extraFields = omit(updatedMessage, [ + '__html', + 'attachments', + 'created_at', + 'deleted_at', + 'html', + 'id', + 'latest_reactions', + 'mentioned_users', + 'own_reactions', + 'parent_id', + 'quoted_message', + 'reaction_counts', + 'reaction_groups', + 'reactions', + 'status', + 'text', + 'type', + 'updated_at', + 'user', + ]); + const { attachments, id, mentioned_users, parent_id, text } = updatedMessage; + if (!channel.id) { + return; + } const mentionedUserIds = mentioned_users?.map((user) => user.id) || []; - const messageData = { - attachments, - id, - mentioned_users: mentionedUserIds, - parent_id, - text: patchMessageTextCommand(text ?? '', mentionedUserIds), - ...extraFields, - } as StreamMessage; - - let messageResponse = {} as SendMessageAPIResponse; - if (doSendMessageRequest) { - messageResponse = await doSendMessageRequest(channel?.cid || '', messageData); - } else if (channel) { - messageResponse = await channel.sendMessage(messageData); - } + const messageData = { + attachments, + id, + mentioned_users: mentionedUserIds, + parent_id, + text: patchMessageTextCommand(text ?? '', mentionedUserIds), + ...extraFields, + } as StreamMessage; + + let messageResponse = {} as SendMessageAPIResponse; + if (doSendMessageRequest) { + messageResponse = await doSendMessageRequest(channel?.cid || '', messageData); + } else if (channel) { + messageResponse = await channel.sendMessage(messageData); + } if (messageResponse.message) { messageResponse.message.status = MessageStatusTypes.RECEIVED; @@ -1420,10 +1421,11 @@ const ChannelWithContext = (props: PropsWithChildren) = }, ); - const sendMessage: InputMessageInputContextValue['sendMessage'] = useStableCallback(async (message) => { - if (channel?.state?.filterErrorMessages) { - channel.state.filterErrorMessages(); - } + const sendMessage: InputMessageInputContextValue['sendMessage'] = useStableCallback( + async (message) => { + if (channel?.state?.filterErrorMessages) { + channel.state.filterErrorMessages(); + } const messagePreview = createMessagePreview({ ...message, @@ -1448,53 +1450,60 @@ const ChannelWithContext = (props: PropsWithChildren) = } await sendMessageRequest(messagePreview); - }); + }, + ); - const retrySendMessage: MessagesContextValue['retrySendMessage'] = useStableCallback(async (message) => { - const statusPendingMessage = { - ...message, - status: MessageStatusTypes.SENDING, - }; + const retrySendMessage: MessagesContextValue['retrySendMessage'] = useStableCallback( + async (message) => { + const statusPendingMessage = { + ...message, + status: MessageStatusTypes.SENDING, + }; const messageWithoutReservedFields = removeReservedFields(statusPendingMessage); - // For bounced messages, we don't need to update the message, instead always send a new message. - if (!isBouncedMessage(message)) { - updateMessage(messageWithoutReservedFields as MessageResponse); - } + // For bounced messages, we don't need to update the message, instead always send a new message. + if (!isBouncedMessage(message)) { + updateMessage(messageWithoutReservedFields as MessageResponse); + } - await sendMessageRequest(messageWithoutReservedFields as MessageResponse, true); - }); + await sendMessageRequest(messageWithoutReservedFields as MessageResponse, true); + }, + ); - const editMessage: InputMessageInputContextValue['editMessage'] = useStableCallback((updatedMessage) => - doUpdateMessageRequest - ? doUpdateMessageRequest(channel?.cid || '', updatedMessage) - : client.updateMessage(updatedMessage)); + const editMessage: InputMessageInputContextValue['editMessage'] = useStableCallback( + (updatedMessage) => + doUpdateMessageRequest + ? doUpdateMessageRequest(channel?.cid || '', updatedMessage) + : client.updateMessage(updatedMessage), + ); const setEditingState: MessagesContextValue['setEditingState'] = useStableCallback((message) => { clearQuotedMessageState(); setEditing(message); }); - const setQuotedMessageState: MessagesContextValue['setQuotedMessageState'] = useStableCallback(( - messageOrBoolean, - ) => { - setQuotedMessage(messageOrBoolean); - }); + const setQuotedMessageState: MessagesContextValue['setQuotedMessageState'] = useStableCallback( + (messageOrBoolean) => { + setQuotedMessage(messageOrBoolean); + }, + ); - const clearEditingState: InputMessageInputContextValue['clearEditingState'] = useStableCallback(() => - setEditing(undefined)); + const clearEditingState: InputMessageInputContextValue['clearEditingState'] = useStableCallback( + () => setEditing(undefined), + ); - const clearQuotedMessageState: InputMessageInputContextValue['clearQuotedMessageState'] = useStableCallback(() => - setQuotedMessage(undefined)); + const clearQuotedMessageState: InputMessageInputContextValue['clearQuotedMessageState'] = + useStableCallback(() => setQuotedMessage(undefined)); /** * Removes the message from local state */ - const removeMessage: MessagesContextValue['removeMessage'] = useStableCallback(async (message) => { - if (channel) { - channel.state.removeMessage(message); - copyMessagesStateFromChannel(channel); + const removeMessage: MessagesContextValue['removeMessage'] = useStableCallback( + async (message) => { + if (channel) { + channel.state.removeMessage(message); + copyMessagesStateFromChannel(channel); if (thread) { setThreadMessages(channel.state.threads[thread.id] || []); @@ -1506,7 +1515,8 @@ const ChannelWithContext = (props: PropsWithChildren) = id: message.id, }); } - }); + }, + ); const sendReaction = useStableCallback(async (type: string, messageId: string) => { if (!channel?.id || !client.user) { @@ -1551,10 +1561,11 @@ const ChannelWithContext = (props: PropsWithChildren) = } }); - const deleteMessage: MessagesContextValue['deleteMessage'] = useStableCallback(async (message) => { - if (!channel.id) { - throw new Error('Channel has not been initialized yet'); - } + const deleteMessage: MessagesContextValue['deleteMessage'] = useStableCallback( + async (message) => { + if (!channel.id) { + throw new Error('Channel has not been initialized yet'); + } if (!enableOfflineSupport) { if (message.status === MessageStatusTypes.FAILED) { @@ -1565,44 +1576,43 @@ const ChannelWithContext = (props: PropsWithChildren) = return; } - if (message.status === MessageStatusTypes.FAILED) { - await DBSyncManager.dropPendingTasks({ messageId: message.id }); - await removeMessage(message); - } else { - const updatedMessage = { - ...message, - cid: channel.cid, - deleted_at: new Date().toISOString(), - type: 'deleted' as MessageLabel, - }; - updateMessage(updatedMessage); + if (message.status === MessageStatusTypes.FAILED) { + await DBSyncManager.dropPendingTasks({ messageId: message.id }); + await removeMessage(message); + } else { + const updatedMessage = { + ...message, + cid: channel.cid, + deleted_at: new Date().toISOString(), + type: 'deleted' as MessageLabel, + }; + updateMessage(updatedMessage); threadInstance?.upsertReplyLocally({ message: updatedMessage }); - const data = await DBSyncManager.queueTask({ - client, - task: { - channelId: channel.id, - channelType: channel.type, - messageId: message.id, - payload: [message.id], - type: 'delete-message', - }, - }); + const data = await DBSyncManager.queueTask({ + client, + task: { + channelId: channel.id, + channelType: channel.type, + messageId: message.id, + payload: [message.id], + type: 'delete-message', + }, + }); if (data?.message) { updateMessage({ ...data.message }); } } - }); + }, + ); - const deleteReaction: MessagesContextValue['deleteReaction'] = useStableCallback(async ( - type: string, - messageId: string, - ) => { - if (!channel?.id || !client.user) { - throw new Error('Channel has not been initialized'); - } + const deleteReaction: MessagesContextValue['deleteReaction'] = useStableCallback( + async (type: string, messageId: string) => { + if (!channel?.id || !client.user) { + throw new Error('Channel has not been initialized'); + } const payload: Parameters = [messageId, type]; @@ -1620,17 +1630,18 @@ const ChannelWithContext = (props: PropsWithChildren) = copyMessagesStateFromChannel(channel); - await DBSyncManager.queueTask({ - client, - task: { - channelId: channel.id, - channelType: channel.type, - messageId, - payload, - type: 'delete-reaction', - }, - }); - }); + await DBSyncManager.queueTask({ + client, + task: { + channelId: channel.id, + channelType: channel.type, + messageId, + payload, + type: 'delete-reaction', + }, + }); + }, + ); /** * THREAD METHODS @@ -1675,40 +1686,40 @@ const ChannelWithContext = (props: PropsWithChildren) = } setThreadLoadingMore(true); - try { - if (channel) { - const parentID = thread.id; - - /** - * In the channel is re-initializing, then threads may get wiped out during the process - * (check `addMessagesSorted` method on channel.state). In those cases, we still want to - * preserve the messages on active thread, so lets simply copy messages from UI state to - * `channel.state`. - */ - channel.state.threads[parentID] = threadMessages; - const oldestMessageID = threadMessages?.[0]?.id; - - const limit = 50; - const queryResponse = await channel.getReplies(parentID, { - id_lt: oldestMessageID, - limit, - }); + try { + if (channel) { + const parentID = thread.id; + + /** + * In the channel is re-initializing, then threads may get wiped out during the process + * (check `addMessagesSorted` method on channel.state). In those cases, we still want to + * preserve the messages on active thread, so lets simply copy messages from UI state to + * `channel.state`. + */ + channel.state.threads[parentID] = threadMessages; + const oldestMessageID = threadMessages?.[0]?.id; + + const limit = 50; + const queryResponse = await channel.getReplies(parentID, { + id_lt: oldestMessageID, + limit, + }); - const updatedHasMore = queryResponse.messages.length === limit; - const updatedThreadMessages = channel.state.threads[parentID] || []; - loadMoreThreadFinished(updatedHasMore, updatedThreadMessages); - } - } catch (err) { - console.warn('Message pagination request failed with error', err); - if (err instanceof Error) { - setError(err); - } else { - setError(true); - } - setThreadLoadingMore(false); - throw err; + const updatedHasMore = queryResponse.messages.length === limit; + const updatedThreadMessages = channel.state.threads[parentID] || []; + loadMoreThreadFinished(updatedHasMore, updatedThreadMessages); } - }); + } catch (err) { + console.warn('Message pagination request failed with error', err); + if (err instanceof Error) { + setError(err); + } else { + setError(true); + } + setThreadLoadingMore(false); + throw err; + } + }); const ownCapabilitiesContext = useCreateOwnCapabilitiesContext({ channel, diff --git a/package/src/components/Channel/hooks/useMessageListPagination.tsx b/package/src/components/Channel/hooks/useMessageListPagination.tsx index 46562e084e..4c6e454e20 100644 --- a/package/src/components/Channel/hooks/useMessageListPagination.tsx +++ b/package/src/components/Channel/hooks/useMessageListPagination.tsx @@ -134,69 +134,67 @@ export const useMessageListPagination = ({ channel }: { channel: Channel }) => { * * @param messageId If undefined, channel will be loaded at most recent message. */ - const loadChannelAroundMessage: ChannelContextValue['loadChannelAroundMessage'] = useStableCallback(async ({ - limit = 25, - messageId: messageIdToLoadAround, - setTargetedMessage, - }) => { - if (!messageIdToLoadAround) { - return; - } - setLoadingMore(true); - setLoading(true); - try { - await channel.state.loadMessageIntoState(messageIdToLoadAround, undefined, limit); - loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages); - jumpToMessageFinished(channel.state.messagePagination.hasNext, messageIdToLoadAround); + const loadChannelAroundMessage: ChannelContextValue['loadChannelAroundMessage'] = + useStableCallback( + async ({ limit = 25, messageId: messageIdToLoadAround, setTargetedMessage }) => { + if (!messageIdToLoadAround) { + return; + } + setLoadingMore(true); + setLoading(true); + try { + await channel.state.loadMessageIntoState(messageIdToLoadAround, undefined, limit); + loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages); + jumpToMessageFinished(channel.state.messagePagination.hasNext, messageIdToLoadAround); - if (setTargetedMessage) { - setTargetedMessage(messageIdToLoadAround); - } - } catch (error) { - setLoadingMore(false); - setLoading(false); - console.warn( - 'Message pagination(fetching messages in the channel around a message id) request failed with error:', - error, - ); - return; - } - }); + if (setTargetedMessage) { + setTargetedMessage(messageIdToLoadAround); + } + } catch (error) { + setLoadingMore(false); + setLoading(false); + console.warn( + 'Message pagination(fetching messages in the channel around a message id) request failed with error:', + error, + ); + return; + } + }, + ); /** * Fetch messages around a specific timestamp. */ - const fetchMessagesAround = useStableCallback(async ( - channel: Channel, - timestamp: string, - limit: number, - ): Promise => { - try { - const { messages } = await channel.query( - { messages: { created_at_around: timestamp, limit } }, - 'new', - ); - return messages; - } catch (error) { - console.error('Error fetching messages around timestamp:', error); - throw error; - } - }); + const fetchMessagesAround = useStableCallback( + async (channel: Channel, timestamp: string, limit: number): Promise => { + try { + const { messages } = await channel.query( + { messages: { created_at_around: timestamp, limit } }, + 'new', + ); + return messages; + } catch (error) { + console.error('Error fetching messages around timestamp:', error); + throw error; + } + }, + ); /** * Loads channel at first unread message. */ const loadChannelAtFirstUnreadMessage: ChannelContextValue['loadChannelAtFirstUnreadMessage'] = - useStableCallback(async ({ channelUnreadState, limit = 25, setChannelUnreadState, setTargetedMessage }) => { - try { - if (!channelUnreadState?.unread_messages) { - return; - } - const { first_unread_message_id, last_read, last_read_message_id } = channelUnreadState; - let firstUnreadMessageId = first_unread_message_id; - let lastReadMessageId = last_read_message_id; - let isInCurrentMessageSet = false; - const messagesState = channel.state.messages; + useStableCallback( + async ({ channelUnreadState, limit = 25, setChannelUnreadState, setTargetedMessage }) => { + try { + if (!channelUnreadState?.unread_messages) { + return; + } + const { first_unread_message_id, last_read, last_read_message_id } = channelUnreadState; + let firstUnreadMessageId = first_unread_message_id; + let lastReadMessageId = last_read_message_id; + let isInCurrentMessageSet = false; + const messagesState = channel.state.messages; // If the first unread message is already in the current message set, we don't need to load more messages. if (firstUnreadMessageId) { diff --git a/package/src/components/MessageList/hooks/useMessageList.ts b/package/src/components/MessageList/hooks/useMessageList.ts index 4dc40d8bd7..9760a0b90a 100644 --- a/package/src/components/MessageList/hooks/useMessageList.ts +++ b/package/src/components/MessageList/hooks/useMessageList.ts @@ -61,9 +61,7 @@ export const shouldIncludeMessageInList = ( } }; -export const useMessageList = ( - params: UseMessageListParams, -) => { +export const useMessageList = (params: UseMessageListParams) => { const { noGroupByUser, threadList } = params; const { client } = useChatContext(); const { hideDateSeparators, maxTimeBetweenGroupedMessages, read } = useChannelContext(); @@ -81,7 +79,7 @@ export const useMessageList = ( userID: client.userID, }); - const processedMessageList = useMemo[]>(() => { + const processedMessageList = useMemo(() => { const dateSeparators = getDateSeparators({ deletedMessagesVisibilityType, hideDateSeparators, diff --git a/package/src/contexts/messageInputContext/MessageInputContext.tsx b/package/src/contexts/messageInputContext/MessageInputContext.tsx index cec8afa6a3..ff47a4bf2a 100644 --- a/package/src/contexts/messageInputContext/MessageInputContext.tsx +++ b/package/src/contexts/messageInputContext/MessageInputContext.tsx @@ -830,20 +830,19 @@ export const MessageInputProvider = ({ setSelectedImages([]); } - setFileUploads([]); - setGiphyActive(false); - setShowMoreOptions(true); - setImageUploads([]); - setMentionedUsers([]); - setNumberOfUploads( - (prevNumberOfUploads) => prevNumberOfUploads - (pendingAttachments?.length || 0), - ); - setText(''); - if (value.editing) { - value.clearEditingState(); - } - }, - ); + setFileUploads([]); + setGiphyActive(false); + setShowMoreOptions(true); + setImageUploads([]); + setMentionedUsers([]); + setNumberOfUploads( + (prevNumberOfUploads) => prevNumberOfUploads - (pendingAttachments?.length || 0), + ); + setText(''); + if (value.editing) { + value.clearEditingState(); + } + }); const mapImageUploadToAttachment = useStableCallback((image: FileUpload): Attachment => { return { @@ -913,15 +912,16 @@ export const MessageInputProvider = ({ }); // TODO: Figure out why this is async, as it doesn't await any promise. - const sendMessage = useStableCallback(async ({ - customMessageData, - }: { - customMessageData?: Partial; - } = {}) => { - if (sending.current) { - return; - } - const linkInfos = parseLinksFromText(text); + const sendMessage = useStableCallback( + async ({ + customMessageData, + }: { + customMessageData?: Partial; + } = {}) => { + if (sending.current) { + return; + } + const linkInfos = parseLinksFromText(text); if (!channelCapabities.sendLinks && linkInfos.length > 0) { Alert.alert( @@ -939,19 +939,19 @@ export const MessageInputProvider = ({ const prevText = giphyEnabled && giphyActive ? `/giphy ${text}` : text; setText(''); - if (inputBoxRef.current) { - inputBoxRef.current.clear(); - } + if (inputBoxRef.current) { + inputBoxRef.current.clear(); + } - const attachments = [] as Attachment[]; - for (const image of imageUploads) { - if (enableOfflineSupport) { - if (image.state === FileState.NOT_SUPPORTED) { - return; + const attachments = [] as Attachment[]; + for (const image of imageUploads) { + if (enableOfflineSupport) { + if (image.state === FileState.NOT_SUPPORTED) { + return; + } + attachments.push(mapImageUploadToAttachment(image)); + continue; } - attachments.push(mapImageUploadToAttachment(image)); - continue; - } if ((!image || image.state === FileState.UPLOAD_FAILED) && !enableOfflineSupport) { continue; @@ -1007,16 +1007,16 @@ export const MessageInputProvider = ({ return; } - const message = value.editing; - if (message && message.type !== 'error') { - const updatedMessage = { - ...message, - attachments, - mentioned_users: mentionedUsers.map((userId) => ({ id: userId })), - quoted_message: undefined, - text: prevText, - ...customMessageData, - } as Parameters[0]; + const message = value.editing; + if (message && message.type !== 'error') { + const updatedMessage = { + ...message, + attachments, + mentioned_users: mentionedUsers.map((userId) => ({ id: userId })), + quoted_message: undefined, + text: prevText, + ...customMessageData, + } as Parameters[0]; // TODO: Remove this line and show an error when submit fails value.clearEditingState(); @@ -1030,25 +1030,25 @@ export const MessageInputProvider = ({ logChatPromiseExecution(updateMessagePromise, 'update message'); resetInput(attachments); - sending.current = false; - } else { - try { - /** - * If the message is bounced by moderation, we firstly remove the message from message list and then send a new message. - */ - if (message && isBouncedMessage(message as MessageType)) { - await removeMessage(message); - } - value.sendMessage({ - attachments, - mentioned_users: uniq(mentionedUsers), - /** Parent message id - in case of thread */ - parent_id: thread?.id, - quoted_message_id: value.quotedMessage ? value.quotedMessage.id : undefined, - show_in_channel: sendThreadMessageInChannel || undefined, - text: prevText, - ...customMessageData, - } as unknown as StreamMessage); + sending.current = false; + } else { + try { + /** + * If the message is bounced by moderation, we firstly remove the message from message list and then send a new message. + */ + if (message && isBouncedMessage(message as MessageType)) { + await removeMessage(message); + } + value.sendMessage({ + attachments, + mentioned_users: uniq(mentionedUsers), + /** Parent message id - in case of thread */ + parent_id: thread?.id, + quoted_message_id: value.quotedMessage ? value.quotedMessage.id : undefined, + show_in_channel: sendThreadMessageInChannel || undefined, + text: prevText, + ...customMessageData, + } as unknown as StreamMessage); value.clearQuotedMessageState(); sending.current = false; @@ -1158,8 +1158,8 @@ export const MessageInputProvider = ({ const regexCondition = /File (extension \.\w{2,4}|type \S+) is not supported/; - const getUploadSetStateAction = - useStableCallback(( + const getUploadSetStateAction = useStableCallback( + ( id: string, fileState: FileStateValue, extraData: Partial = {}, diff --git a/package/yarn.lock b/package/yarn.lock index 485972cc02..a13e2edd2e 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -7772,9 +7772,9 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -"stream-chat@https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50": +"stream-chat@https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936": version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#6d936386dbf69e33b8e146e5e48c20a74482eb50" + resolved "https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936" dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" From 4ad47a1513ed13757954d7369de94ae0df276c8e Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Wed, 23 Apr 2025 14:59:21 +0530 Subject: [PATCH 40/60] fix: remove MessageType type from the SDK --- package/src/components/Attachment/Gallery.tsx | 7 +-- package/src/components/Channel/Channel.tsx | 13 ++-- .../Channel/hooks/useChannelDataState.ts | 6 +- package/src/components/Chat/Chat.tsx | 9 --- .../__tests__/ImageGallery.test.tsx | 15 ++--- .../__tests__/ImageGalleryFooter.test.tsx | 9 +-- .../__tests__/ImageGalleryHeader.test.tsx | 9 +-- .../__tests__/ImageGalleryOverlay.test.tsx | 5 +- package/src/components/Message/Message.tsx | 34 ++++++----- .../Message/MessageSimple/MessageFooter.tsx | 5 +- .../Message/MessageSimple/MessageStatus.tsx | 35 ++++++----- .../MessageSimple/MessageTextContainer.tsx | 6 +- .../__tests__/MessageTextContainer.test.tsx | 9 +-- .../MessageSimple/utils/renderText.tsx | 5 +- .../Message/hooks/useCreateMessageContext.ts | 3 + .../Message/hooks/useMessageActionHandlers.ts | 4 +- .../Message/hooks/useMessageActions.tsx | 7 ++- .../components/MessageList/MessageList.tsx | 41 +++++++------ .../components/MessageList/MessageSystem.tsx | 4 +- .../MessageList/hooks/useMessageList.ts | 59 +++++++------------ .../MessageList/utils/getGroupStyles.ts | 10 ++-- .../utils/getLastReceivedMessage.ts | 6 +- .../__tests__/MessageUserReactions.test.tsx | 5 +- .../MessageMenu/hooks/useFetchReactions.ts | 5 +- .../src/components/Poll/components/Button.tsx | 6 +- .../components/PollResults/PollResultItem.tsx | 5 +- package/src/components/Reply/Reply.tsx | 3 +- .../components/ThreadFooterComponent.tsx | 1 + .../components/ThreadList/ThreadListItem.tsx | 10 ++-- .../contexts/debugContext/DebugContext.tsx | 6 +- .../ImageGalleryContext.tsx | 9 +-- .../messageContext/MessageContext.tsx | 10 ++-- .../MessageInputContext.tsx | 10 ++-- .../__tests__/sendMessage.test.tsx | 11 ++-- .../__tests__/updateMessage.test.tsx | 8 +-- .../useMessageDetailsForState.test.tsx | 30 ++++++---- .../messagesContext/MessagesContext.tsx | 39 ++++++------ .../src/contexts/pollContext/pollContext.tsx | 6 +- .../contexts/threadContext/ThreadContext.tsx | 10 ++-- .../threadsContext/ThreadListItemContext.tsx | 8 +-- package/src/utils/removeReservedFields.ts | 8 +-- package/src/utils/utils.ts | 15 ++--- 42 files changed, 236 insertions(+), 270 deletions(-) diff --git a/package/src/components/Attachment/Gallery.tsx b/package/src/components/Attachment/Gallery.tsx index 13e26f59b4..635a0e0b9e 100644 --- a/package/src/components/Attachment/Gallery.tsx +++ b/package/src/components/Attachment/Gallery.tsx @@ -1,7 +1,7 @@ import React, { useMemo } from 'react'; import { Pressable, StyleSheet, Text, View } from 'react-native'; -import type { Attachment } from 'stream-chat'; +import type { Attachment, LocalMessage } from 'stream-chat'; import { GalleryImage } from './GalleryImage'; import { ImageReloadIndicator } from './ImageReloadIndicator'; @@ -12,7 +12,6 @@ import { getGalleryImageBorderRadius } from './utils/getGalleryImageBorderRadius import { openUrlSafely } from './utils/openUrlSafely'; -import type { MessageType } from '../../components/MessageList/hooks/useMessageList'; import { useChatConfigContext } from '../../contexts/chatConfigContext/ChatConfigContext'; import { ImageGalleryContextValue, @@ -76,7 +75,7 @@ export type GalleryPropsWithContext = Pick< * * TODO: Fix circular dependencies of imports */ - message?: MessageType; + message?: LocalMessage; }; const GalleryWithContext = (props: GalleryPropsWithContext) => { @@ -241,7 +240,7 @@ type GalleryThumbnailProps = { colIndex: number; imagesAndVideos: Attachment[]; invertedDirections: boolean; - message: MessageType; + message: LocalMessage; numOfColumns: number; numOfRows: number; rowIndex: number; diff --git a/package/src/components/Channel/Channel.tsx b/package/src/components/Channel/Channel.tsx index 29aa2b2656..90e070eabd 100644 --- a/package/src/components/Channel/Channel.tsx +++ b/package/src/components/Channel/Channel.tsx @@ -169,7 +169,6 @@ import { ShowThreadMessageInChannelButton as ShowThreadMessageInChannelButtonDef import { StopMessageStreamingButton as DefaultStopMessageStreamingButton } from '../MessageInput/StopMessageStreamingButton'; import { UploadProgressIndicator as UploadProgressIndicatorDefault } from '../MessageInput/UploadProgressIndicator'; import { DateHeader as DateHeaderDefault } from '../MessageList/DateHeader'; -import type { MessageType } from '../MessageList/hooks/useMessageList'; import { InlineDateSeparator as InlineDateSeparatorDefault } from '../MessageList/InlineDateSeparator'; import { InlineUnreadIndicator as InlineUnreadIndicatorDefault } from '../MessageList/InlineUnreadIndicator'; import { MessageList as MessageListDefault } from '../MessageList/MessageList'; @@ -684,12 +683,12 @@ const ChannelWithContext = (props: PropsWithChildren) = }, } = useTheme(); const [deleted, setDeleted] = useState(false); - const [editing, setEditing] = useState(undefined); + const [editing, setEditing] = useState(undefined); const [error, setError] = useState(false); const [lastRead, setLastRead] = useState(); - const [quotedMessage, setQuotedMessage] = useState(undefined); - const [thread, setThread] = useState(threadProps || null); + const [quotedMessage, setQuotedMessage] = useState(undefined); + const [thread, setThread] = useState(threadProps || null); const [threadHasMore, setThreadHasMore] = useState(true); const [threadLoadingMore, setThreadLoadingMore] = useState(false); const [channelUnreadState, setChannelUnreadState] = useState( @@ -1546,7 +1545,7 @@ const ChannelWithContext = (props: PropsWithChildren) = const updatedMessage = { ...message, cid: channel.cid, - deleted_at: new Date().toISOString(), + deleted_at: new Date(), type: 'deleted' as MessageLabel, }; updateMessage(updatedMessage); @@ -1998,7 +1997,7 @@ const ChannelWithContext = (props: PropsWithChildren) = export type ChannelProps = Partial> & Pick & { - thread?: MessageType | ThreadType | null; + thread?: LocalMessage | ThreadType | null; }; /** @@ -2017,7 +2016,7 @@ export const Channel = (props: PropsWithChildren) => { const threadInstance = (threadFromProps as ThreadType)?.threadInstance as Thread; const threadMessage = ( threadInstance ? (threadFromProps as ThreadType).thread : threadFromProps - ) as MessageType; + ) as LocalMessage; const thread: ThreadType = { thread: threadMessage, diff --git a/package/src/components/Channel/hooks/useChannelDataState.ts b/package/src/components/Channel/hooks/useChannelDataState.ts index cfe6b18f9a..1a7990c27d 100644 --- a/package/src/components/Channel/hooks/useChannelDataState.ts +++ b/package/src/components/Channel/hooks/useChannelDataState.ts @@ -1,8 +1,6 @@ import { useCallback, useState } from 'react'; -import { Channel, ChannelState as StreamChannelState } from 'stream-chat'; - -import { MessageType } from '../../MessageList/hooks/useMessageList'; +import { Channel, LocalMessage, ChannelState as StreamChannelState } from 'stream-chat'; export const channelInitialState = { hasMore: true, @@ -38,7 +36,7 @@ export type ChannelMessagesState = { * The ChannelThreadState object */ export type ChannelThreadState = { - thread: MessageType | null; + thread: LocalMessage | null; threadHasMore?: boolean; threadLoadingMore?: boolean; threadMessages?: StreamChannelState['messages']; diff --git a/package/src/components/Chat/Chat.tsx b/package/src/components/Chat/Chat.tsx index cb832f8113..d8fe2e261b 100644 --- a/package/src/components/Chat/Chat.tsx +++ b/package/src/components/Chat/Chat.tsx @@ -308,15 +308,6 @@ const ChatWithContext = (props: PropsWithChildren) => { * - connectionRecovering - whether or not websocket is reconnecting * - isOnline - whether or not set user is active * - setActiveChannel - function to set the currently active channel - * - * The Chat Component takes the following generics in order: - * - At (AttachmentType) - custom Attachment object extension - * - Ct (ChannelType) - custom Channel object extension - * - Co (CommandType) - custom Command string union extension - * - Ev (EventType) - custom Event object extension - * - Me (MessageType) - custom Message object extension - * - Re (ReactionType) - custom Reaction object extension - * - Us (UserType) - custom User object extension */ export const Chat = (props: PropsWithChildren) => { const { style } = useOverlayContext(); diff --git a/package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx b/package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx index 59d046d42f..75867d2a57 100644 --- a/package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +++ b/package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx @@ -4,6 +4,8 @@ import type { SharedValue } from 'react-native-reanimated'; import { act, fireEvent, render, screen, waitFor } from '@testing-library/react-native'; +import { LocalMessage } from 'stream-chat'; + import { ImageGalleryContext, ImageGalleryContextValue, @@ -18,7 +20,6 @@ import { } from '../../../mock-builders/generator/attachment'; import { generateMessage } from '../../../mock-builders/generator/message'; -import type { MessageType } from '../../MessageList/hooks/useMessageList'; import { ImageGallery } from '../ImageGallery'; jest.mock('../../../native.ts', () => { @@ -56,7 +57,7 @@ describe('ImageGallery', () => { generateVideoAttachment({ type: 'video' }), ], }), - ] as unknown as MessageType[], + ] as unknown as LocalMessage[], }), ); @@ -73,7 +74,7 @@ describe('ImageGallery', () => { }); render( getComponent({ - messages: [message] as unknown as MessageType[], + messages: [message] as unknown as LocalMessage[], }), ); @@ -102,7 +103,7 @@ describe('ImageGallery', () => { generateMessage({ attachments: [generateVideoAttachment({ type: 'video' })], }), - ] as unknown as MessageType[], + ] as unknown as LocalMessage[], }), ); @@ -128,7 +129,7 @@ describe('ImageGallery', () => { render( getComponent({ - messages: [message] as unknown as MessageType[], + messages: [message] as unknown as LocalMessage[], }), ); @@ -163,7 +164,7 @@ describe('ImageGallery', () => { generateMessage({ attachments: [generateVideoAttachment({ type: 'video' })], }), - ] as unknown as MessageType[], + ] as unknown as LocalMessage[], }), ); @@ -193,7 +194,7 @@ describe('ImageGallery', () => { }); render( getComponent({ - messages: [message] as unknown as MessageType[], + messages: [message] as unknown as LocalMessage[], }), ); diff --git a/package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx b/package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx index 30c122cc86..f244a20d36 100644 --- a/package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx +++ b/package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx @@ -7,6 +7,8 @@ import { ReactTestInstance } from 'react-test-renderer'; import { render, screen, userEvent, waitFor } from '@testing-library/react-native'; +import { LocalMessage } from 'stream-chat'; + import { Chat } from '../../../components/Chat/Chat'; import { ImageGalleryContext, @@ -20,7 +22,6 @@ import { import { generateMessage } from '../../../mock-builders/generator/message'; import { getTestClientWithUser } from '../../../mock-builders/mock'; import { NativeHandlers } from '../../../native'; -import type { MessageType } from '../../MessageList/hooks/useMessageList'; import { ImageGallery, ImageGalleryCustomComponents } from '../ImageGallery'; jest.mock('../../../native.ts', () => { @@ -76,7 +77,7 @@ describe('ImageGalleryFooter', () => { generateMessage({ attachments: [generateVideoAttachment({ type: 'video' })], }), - ] as unknown as MessageType[], + ] as unknown as LocalMessage[], } as unknown as ImageGalleryContextValue } > @@ -131,7 +132,7 @@ describe('ImageGalleryFooter', () => { generateMessage({ attachments: [generateVideoAttachment({ type: 'video' })], }), - ] as unknown as MessageType[], + ] as unknown as LocalMessage[], } as unknown as ImageGalleryContextValue } > @@ -174,7 +175,7 @@ describe('ImageGalleryFooter', () => { generateMessage({ attachments: [generateImageAttachment()], }), - ] as unknown as MessageType[], + ] as unknown as LocalMessage[], } as unknown as ImageGalleryContextValue } > diff --git a/package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx b/package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx index 8c6042e510..7da00363b1 100644 --- a/package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx +++ b/package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx @@ -7,6 +7,8 @@ import { act } from 'react-test-renderer'; import { render, screen, userEvent, waitFor } from '@testing-library/react-native'; +import { LocalMessage } from 'stream-chat'; + import { Chat } from '../../../components/Chat/Chat'; import { ImageGalleryContext, @@ -24,7 +26,6 @@ import { import { generateMessage } from '../../../mock-builders/generator/message'; import { getTestClientWithUser } from '../../../mock-builders/mock'; -import type { MessageType } from '../../MessageList/hooks/useMessageList'; import { ImageGallery, ImageGalleryCustomComponents } from '../ImageGallery'; jest.mock('../../../native.ts', () => { @@ -71,7 +72,7 @@ describe('ImageGalleryHeader', () => { generateMessage({ attachments: [generateImageAttachment()], }), - ] as unknown as MessageType[], + ] as unknown as LocalMessage[], } as unknown as ImageGalleryContextValue } > @@ -118,7 +119,7 @@ describe('ImageGalleryHeader', () => { generateMessage({ attachments: [generateVideoAttachment({ type: 'video' })], }), - ] as unknown as MessageType[], + ] as unknown as LocalMessage[], } as unknown as ImageGalleryContextValue } > @@ -158,7 +159,7 @@ describe('ImageGalleryHeader', () => { generateMessage({ attachments: [generateImageAttachment()], }), - ] as unknown as MessageType[], + ] as unknown as LocalMessage[], } as unknown as ImageGalleryContextValue } > diff --git a/package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx b/package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx index 1d42ea204a..53da8b2eab 100644 --- a/package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx +++ b/package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx @@ -7,6 +7,8 @@ import { act } from 'react-test-renderer'; import { fireEvent, render, waitFor } from '@testing-library/react-native'; +import { LocalMessage } from 'stream-chat'; + import { Chat } from '../../../components/Chat/Chat'; import { ImageGalleryContext, @@ -20,7 +22,6 @@ import { generateImageAttachment } from '../../../mock-builders/generator/attach import { generateMessage } from '../../../mock-builders/generator/message'; import { getTestClientWithUser } from '../../../mock-builders/mock'; -import type { MessageType } from '../../MessageList/hooks/useMessageList'; import { ImageGalleryOverlay } from '../components/ImageGalleryOverlay'; describe('ImageGalleryOverlay', () => { @@ -39,7 +40,7 @@ describe('ImageGalleryOverlay', () => { generateMessage({ attachments: [generateImageAttachment()], }), - ] as unknown as MessageType[], + ] as unknown as LocalMessage[], } as unknown as ImageGalleryContextValue } > diff --git a/package/src/components/Message/Message.tsx b/package/src/components/Message/Message.tsx index 61161b7441..f898ececc9 100644 --- a/package/src/components/Message/Message.tsx +++ b/package/src/components/Message/Message.tsx @@ -1,7 +1,7 @@ import React, { useMemo, useState } from 'react'; import { GestureResponderEvent, Keyboard, StyleProp, View, ViewStyle } from 'react-native'; -import type { Attachment, UserResponse } from 'stream-chat'; +import type { Attachment, LocalMessage, UserResponse } from 'stream-chat'; import { useCreateMessageContext } from './hooks/useCreateMessageContext'; import { useMessageActionHandlers } from './hooks/useMessageActionHandlers'; @@ -42,11 +42,6 @@ import { } from '../../utils/utils'; import type { Thumbnail } from '../Attachment/utils/buildGallery/types'; -import { - isMessageWithStylesReadByAndDateSeparator, - MessageType, -} from '../MessageList/hooks/useMessageList'; - export type TouchableEmitter = | 'fileAttachment' | 'gallery' @@ -114,7 +109,7 @@ export type MessagePressableHandlerPayload = PressableHandlerPayload & { /** * Message object, on which interaction occurred. */ - message?: MessageType; + message?: LocalMessage; }; export type MessageActionHandlers = { @@ -130,7 +125,7 @@ export type MessageActionHandlers = { toggleMuteUser: () => Promise; toggleReaction: (reactionType: string) => Promise; unpinMessage: () => Promise; - threadReply?: (message: MessageType) => Promise; + threadReply?: (message: LocalMessage) => Promise; }; export type MessagePropsWithContext = Pick< @@ -141,7 +136,7 @@ export type MessagePropsWithContext = Pick< Partial< Omit > & - Pick & + Pick & Pick< MessagesContextValue, | 'sendReaction' @@ -194,7 +189,7 @@ export type MessagePropsWithContext = Pick< * * @param message A message object to open the thread upon. */ - onThreadSelect?: (message: MessageType) => void; + onThreadSelect?: (message: LocalMessage) => void; showUnreadUnderlay?: boolean; style?: StyleProp; }; @@ -252,6 +247,7 @@ const MessageWithContext = (props: MessagePropsWithContext) => { onThreadSelect, openThread, preventPress, + readBy, removeMessage, retrySendMessage, selectReaction, @@ -312,7 +308,7 @@ const MessageWithContext = (props: MessagePropsWithContext) => { } }; - const onPressQuotedMessage = (quotedMessage: MessageType) => { + const onPressQuotedMessage = (quotedMessage: LocalMessage) => { if (!goToMessage) { return; } @@ -329,7 +325,7 @@ const MessageWithContext = (props: MessagePropsWithContext) => { if (isEditedMessage(message)) { setIsEditedMessageOpen((prevState) => !prevState); } - const quotedMessage = message.quoted_message as MessageType; + const quotedMessage = message.quoted_message; if (error) { setIsErrorInMessage(true); /** @@ -693,6 +689,7 @@ const MessageWithContext = (props: MessagePropsWithContext) => { otherAttachments: attachments.other, preventPress, reactions, + readBy, setIsEditedMessageOpen, showAvatar, showMessageOverlay, @@ -759,6 +756,7 @@ const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWit members: prevMembers, message: prevMessage, messagesContext: prevMessagesContext, + readBy: prevReadBy, showUnreadUnderlay: prevShowUnreadUnderlay, t: prevT, } = prevProps; @@ -771,6 +769,7 @@ const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWit members: nextMembers, message: nextMessage, messagesContext: nextMessagesContext, + readBy: nextReadBy, showUnreadUnderlay: nextShowUnreadUnderlay, t: nextT, } = nextProps; @@ -814,8 +813,6 @@ const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWit const messageEqual = isPrevMessageTypeDeleted === isNextMessageTypeDeleted && - (isMessageWithStylesReadByAndDateSeparator(prevMessage) && prevMessage.readBy) === - (isMessageWithStylesReadByAndDateSeparator(nextMessage) && nextMessage.readBy) && prevMessage.status === nextMessage.status && prevMessage.type === nextMessage.type && prevMessage.text === nextMessage.text && @@ -888,6 +885,11 @@ const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWit return false; } + const readByEqual = prevReadBy === nextReadBy; + if (!readByEqual) { + return false; + } + const showUnreadUnderlayEqual = prevShowUnreadUnderlay === nextShowUnreadUnderlay; if (!showUnreadUnderlayEqual) { return false; @@ -917,9 +919,9 @@ const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWit const MemoizedMessage = React.memo(MessageWithContext, areEqual) as typeof MessageWithContext; export type MessageProps = Partial< - Omit + Omit > & - Pick; + Pick; /** * Message - A high level component which implements all the logic required for a message. diff --git a/package/src/components/Message/MessageSimple/MessageFooter.tsx b/package/src/components/Message/MessageSimple/MessageFooter.tsx index 6c5fb99c74..2f1af67c84 100644 --- a/package/src/components/Message/MessageSimple/MessageFooter.tsx +++ b/package/src/components/Message/MessageSimple/MessageFooter.tsx @@ -1,7 +1,7 @@ import React, { useMemo } from 'react'; import { StyleSheet, Text, View } from 'react-native'; -import type { Attachment } from 'stream-chat'; +import type { Attachment, LocalMessage } from 'stream-chat'; import type { MessageStatusProps } from './MessageStatus'; @@ -21,7 +21,6 @@ import { useTranslationContext } from '../../../contexts/translationContext/Tran import { Eye } from '../../../icons'; import { isEditedMessage, MessageStatusTypes } from '../../../utils/utils'; -import type { MessageType } from '../../MessageList/hooks/useMessageList'; type MessageFooterComponentProps = { date?: string | Date; @@ -271,7 +270,7 @@ export type MessageFooterProps = Partial> & MessageFooterComponentProps & { alignment?: Alignment; lastGroupMessage?: boolean; - message?: MessageType; + message?: LocalMessage; MessageStatus?: React.ComponentType; otherAttachments?: Attachment[]; showMessageStatus?: boolean; diff --git a/package/src/components/Message/MessageSimple/MessageStatus.tsx b/package/src/components/Message/MessageSimple/MessageStatus.tsx index f791fba607..b93ff79f54 100644 --- a/package/src/components/Message/MessageSimple/MessageStatus.tsx +++ b/package/src/components/Message/MessageSimple/MessageStatus.tsx @@ -13,13 +13,14 @@ import { Time } from '../../../icons/Time'; import { MessageStatusTypes } from '../../../utils/utils'; -import { isMessageWithStylesReadByAndDateSeparator } from '../../MessageList/hooks/useMessageList'; - -export type MessageStatusPropsWithContext = Pick; +export type MessageStatusPropsWithContext = Pick< + MessageContextValue, + 'message' | 'readBy' | 'threadList' +>; const MessageStatusWithContext = (props: MessageStatusPropsWithContext) => { const { channel } = useChannelContext(); - const { message, threadList } = props; + const { message, readBy, threadList } = props; const { theme: { @@ -42,17 +43,17 @@ const MessageStatusWithContext = (props: MessageStatusPropsWithContext) => { return null; } - if (isMessageWithStylesReadByAndDateSeparator(message)) { + if (readBy) { const members = channel?.state.members; const otherMembers = Object.values(members).filter( (member) => member.user_id !== message.user?.id, ); const hasOtherMembersGreaterThanOne = otherMembers.length > 1; - const hasReadByGreaterThanOne = typeof message.readBy === 'number' && message.readBy > 1; + const hasReadByGreaterThanOne = typeof readBy === 'number' && readBy > 1; const shouldDisplayReadByCount = hasOtherMembersGreaterThanOne && hasReadByGreaterThanOne; const countOfReadBy = - typeof message.readBy === 'number' && hasOtherMembersGreaterThanOne ? message.readBy - 1 : 0; - const showDoubleCheck = hasReadByGreaterThanOne || message.readBy === true; + typeof readBy === 'number' && hasOtherMembersGreaterThanOne ? readBy - 1 : 0; + const showDoubleCheck = hasReadByGreaterThanOne || readBy === true; return ( @@ -90,19 +91,21 @@ const areEqual = ( prevProps: MessageStatusPropsWithContext, nextProps: MessageStatusPropsWithContext, ) => { - const { message: prevMessage, threadList: prevThreadList } = prevProps; - const { message: nextMessage, threadList: nextThreadList } = nextProps; + const { message: prevMessage, readBy: prevReadBy, threadList: prevThreadList } = prevProps; + const { message: nextMessage, readBy: nextReadBy, threadList: nextThreadList } = nextProps; const threadListEqual = prevThreadList === nextThreadList; if (!threadListEqual) { return false; } + const readByEqual = prevReadBy === nextReadBy; + if (!readByEqual) { + return false; + } + const messageEqual = - prevMessage.status === nextMessage.status && - prevMessage.type === nextMessage.type && - (isMessageWithStylesReadByAndDateSeparator(prevMessage) && prevMessage.readBy) === - (isMessageWithStylesReadByAndDateSeparator(nextMessage) && nextMessage.readBy); + prevMessage.status === nextMessage.status && prevMessage.type === nextMessage.type; if (!messageEqual) { return false; } @@ -118,9 +121,9 @@ const MemoizedMessageStatus = React.memo( export type MessageStatusProps = Partial; export const MessageStatus = (props: MessageStatusProps) => { - const { message, threadList } = useMessageContext(); + const { message, readBy, threadList } = useMessageContext(); - return ; + return ; }; MessageStatus.displayName = 'MessageStatus{messageSimple{status}}'; diff --git a/package/src/components/Message/MessageSimple/MessageTextContainer.tsx b/package/src/components/Message/MessageSimple/MessageTextContainer.tsx index 30a4edb701..28b0ac70ca 100644 --- a/package/src/components/Message/MessageSimple/MessageTextContainer.tsx +++ b/package/src/components/Message/MessageSimple/MessageTextContainer.tsx @@ -1,6 +1,8 @@ import React from 'react'; import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'; +import { LocalMessage } from 'stream-chat'; + import { renderText, RenderTextParams } from './utils/renderText'; import { @@ -16,8 +18,6 @@ import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import type { MarkdownStyle, Theme } from '../../../contexts/themeContext/utils/theme'; import { useTranslatedMessage } from '../../../hooks/useTranslatedMessage'; -import type { MessageType } from '../../MessageList/hooks/useMessageList'; - const styles = StyleSheet.create({ textContainer: { maxWidth: 250, paddingHorizontal: 16 }, }); @@ -71,7 +71,7 @@ const MessageTextContainerWithContext = (props: MessageTextContainerPropsWithCon }, } = theme; - const translatedMessage = useTranslatedMessage(message) as MessageType; + const translatedMessage = useTranslatedMessage(message) as LocalMessage; if (!message.text) { return null; diff --git a/package/src/components/Message/MessageSimple/__tests__/MessageTextContainer.test.tsx b/package/src/components/Message/MessageSimple/__tests__/MessageTextContainer.test.tsx index c4abae945b..dd063bca25 100644 --- a/package/src/components/Message/MessageSimple/__tests__/MessageTextContainer.test.tsx +++ b/package/src/components/Message/MessageSimple/__tests__/MessageTextContainer.test.tsx @@ -3,6 +3,8 @@ import { Text } from 'react-native'; import { cleanup, render, waitFor } from '@testing-library/react-native'; +import { LocalMessage } from 'stream-chat'; + import { OverlayProvider } from '../../../../contexts/overlayContext/OverlayProvider'; import { ThemeProvider } from '../../../../contexts/themeContext/ThemeContext'; import { defaultTheme } from '../../../../contexts/themeContext/utils/theme'; @@ -17,7 +19,6 @@ import { generateStaticUser } from '../../../../mock-builders/generator/user'; import { getTestClientWithUser } from '../../../../mock-builders/mock'; import { Channel } from '../../../Channel/Channel'; import { Chat } from '../../../Chat/Chat'; -import type { MessageType } from '../../../MessageList/hooks/useMessageList'; import { MessageList } from '../../../MessageList/MessageList'; import { MessageTextContainer } from '../MessageTextContainer'; @@ -31,7 +32,7 @@ describe('MessageTextContainer', () => { }); const { getByTestId, getByText, rerender, toJSON } = render( - + , ); @@ -43,7 +44,7 @@ describe('MessageTextContainer', () => { rerender( {message?.text}} /> , @@ -61,7 +62,7 @@ describe('MessageTextContainer', () => { rerender( - + , ); diff --git a/package/src/components/Message/MessageSimple/utils/renderText.tsx b/package/src/components/Message/MessageSimple/utils/renderText.tsx index 1c894900b0..cf5e2828cc 100644 --- a/package/src/components/Message/MessageSimple/utils/renderText.tsx +++ b/package/src/components/Message/MessageSimple/utils/renderText.tsx @@ -26,7 +26,7 @@ import { State, } from 'simple-markdown'; -import type { UserResponse } from 'stream-chat'; +import type { LocalMessage, UserResponse } from 'stream-chat'; import { generateMarkdownText } from './generateMarkdownText'; @@ -34,7 +34,6 @@ import type { MessageContextValue } from '../../../../contexts/messageContext/Me import type { Colors, MarkdownStyle } from '../../../../contexts/themeContext/utils/theme'; import { escapeRegExp } from '../../../../utils/utils'; -import type { MessageType } from '../../../MessageList/hooks/useMessageList'; type ReactNodeOutput = NodeOutput; type ReactOutput = Output; @@ -162,7 +161,7 @@ export type RenderTextParams = Partial< Pick > & { colors: typeof Colors; - message: MessageType; + message: LocalMessage; markdownRules?: MarkdownRules; markdownStyles?: MarkdownStyle; messageOverlay?: boolean; diff --git a/package/src/components/Message/hooks/useCreateMessageContext.ts b/package/src/components/Message/hooks/useCreateMessageContext.ts index 942907c329..37a594c6f9 100644 --- a/package/src/components/Message/hooks/useCreateMessageContext.ts +++ b/package/src/components/Message/hooks/useCreateMessageContext.ts @@ -34,6 +34,7 @@ export const useCreateMessageContext = ({ otherAttachments, preventPress, reactions, + readBy, setIsEditedMessageOpen, showAvatar, showMessageOverlay, @@ -81,6 +82,7 @@ export const useCreateMessageContext = ({ otherAttachments, preventPress, reactions, + readBy, setIsEditedMessageOpen, showAvatar, showMessageOverlay, @@ -103,6 +105,7 @@ export const useCreateMessageContext = ({ stringifiedMessage, myMessageThemeString, reactionsValue, + readBy, showAvatar, showMessageStatus, threadList, diff --git a/package/src/components/Message/hooks/useMessageActionHandlers.ts b/package/src/components/Message/hooks/useMessageActionHandlers.ts index fbd24d43a6..7432e37597 100644 --- a/package/src/components/Message/hooks/useMessageActionHandlers.ts +++ b/package/src/components/Message/hooks/useMessageActionHandlers.ts @@ -1,7 +1,5 @@ import { Alert } from 'react-native'; -import type { MessageResponse } from 'stream-chat'; - import type { ChannelContextValue } from '../../../contexts/channelContext/ChannelContext'; import type { ChatContextValue } from '../../../contexts/chatContext/ChatContext'; import type { MessageContextValue } from '../../../contexts/messageContext/MessageContext'; @@ -62,7 +60,7 @@ export const useMessageActionHandlers = ({ { style: 'cancel', text: t('Cancel') }, { onPress: async () => { - await deleteMessage(message as MessageResponse); + await deleteMessage(message); }, style: 'destructive', text: t('Delete'), diff --git a/package/src/components/Message/hooks/useMessageActions.tsx b/package/src/components/Message/hooks/useMessageActions.tsx index 95b0114c6c..5b859148f9 100644 --- a/package/src/components/Message/hooks/useMessageActions.tsx +++ b/package/src/components/Message/hooks/useMessageActions.tsx @@ -1,5 +1,7 @@ import React from 'react'; +import { LocalMessage } from 'stream-chat'; + import { useMessageActionHandlers } from './useMessageActionHandlers'; import type { ChannelContextValue } from '../../../contexts/channelContext/ChannelContext'; @@ -27,7 +29,6 @@ import { import { removeReservedFields } from '../../../utils/removeReservedFields'; import { MessageStatusTypes } from '../../../utils/utils'; -import type { MessageType } from '../../MessageList/hooks/useMessageList'; import type { MessageActionType } from '../../MessageMenu/MessageActionListItem'; export type MessageActionsHookProps = Pick< @@ -60,7 +61,7 @@ export type MessageActionsHookProps = Pick< Pick & Pick & Pick & { - onThreadSelect?: (message: MessageType) => void; + onThreadSelect?: (message: LocalMessage) => void; }; export const useMessageActions = ({ @@ -293,7 +294,7 @@ export const useMessageActions = ({ dismissOverlay(); const messageWithoutReservedFields = removeReservedFields(message); if (handleRetry) { - handleRetry(messageWithoutReservedFields as MessageType); + handleRetry(messageWithoutReservedFields as LocalMessage); } await handleResendMessage(); diff --git a/package/src/components/MessageList/MessageList.tsx b/package/src/components/MessageList/MessageList.tsx index db0235eca9..a11ecfa589 100644 --- a/package/src/components/MessageList/MessageList.tsx +++ b/package/src/components/MessageList/MessageList.tsx @@ -12,11 +12,7 @@ import { import type { Channel, Event, LocalMessage, MessageResponse } from 'stream-chat'; -import { - isMessageWithStylesReadByAndDateSeparator, - MessageType, - useMessageList, -} from './hooks/useMessageList'; +import { useMessageList } from './hooks/useMessageList'; import { useShouldScrollToRecentOnNewOwnMessage } from './hooks/useShouldScrollToRecentOnNewOwnMessage'; import { InlineLoadingMoreIndicator } from './InlineLoadingMoreIndicator'; @@ -90,7 +86,7 @@ const styles = StyleSheet.create({ }, }); -const keyExtractor = (item: MessageType) => { +const keyExtractor = (item: LocalMessage) => { if (item.id) { return item.id; } @@ -110,7 +106,7 @@ const hasReadLastMessage = (channel: Channel, userId: string) => { return latestMessageIdInChannel === lastReadMessageIdServer; }; -const getPreviousLastMessage = (messages: MessageType[], newMessage?: MessageResponse) => { +const getPreviousLastMessage = (messages: LocalMessage[], newMessage?: MessageResponse) => { if (!newMessage) return; let previousLastMessage; for (let i = messages.length - 1; i >= 0; i--) { @@ -188,7 +184,7 @@ type MessageListPropsWithContext = Pick< * additionalFlatListProps={{ bounces: true, keyboardDismissMode: true }} /> * ``` */ - additionalFlatListProps?: Partial>; + additionalFlatListProps?: Partial>; /** * UI component for footer of message list. By default message list will use `InlineLoadingMoreIndicator` * as FooterComponent. If you want to implement your own inline loading indicator, you can access `loadingMore` @@ -230,7 +226,7 @@ type MessageListPropsWithContext = Pick< * }} * ``` */ - setFlatListRef?: (ref: FlatListType | null) => void; + setFlatListRef?: (ref: FlatListType | null) => void; }; /** @@ -321,10 +317,11 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { * NOTE: rawMessageList changes only when messages array state changes * processedMessageList changes on any state change */ - const { processedMessageList, rawMessageList } = useMessageList({ - noGroupByUser, - threadList, - }); + const { dateSeparators, messageGroupStyles, processedMessageList, rawMessageList, readData } = + useMessageList({ + noGroupByUser, + threadList, + }); const messageListLengthBeforeUpdate = useRef(0); const messageListLengthAfterUpdate = processedMessageList.length; @@ -353,7 +350,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { const onStartReachedInPromise = useRef | null>(null); const onEndReachedInPromise = useRef | null>(null); - const flatListRef = useRef | null>(null); + const flatListRef = useRef | null>(null); const channelResyncScrollSet = useRef(true); @@ -727,7 +724,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { // TODO: do not apply on RN 0.73 and above const shouldApplyAndroidWorkaround = inverted && Platform.OS === 'android'; - const renderItem = ({ index, item: message }: { index: number; item: MessageType }) => { + const renderItem = ({ index, item: message }: { index: number; item: LocalMessage }) => { if (!channel || channel.disconnected || (!channel.initialized && !channel.offlineMode)) { return null; } @@ -748,18 +745,20 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { const showUnreadUnderlay = !!shouldShowUnreadUnderlay && showUnreadSeparator; const wrapMessageInTheme = client.userID === message.user?.id && !!myMessageTheme; - const renderDateSeperator = isMessageWithStylesReadByAndDateSeparator(message) && - message.dateSeparator && ; + const renderDateSeperator = dateSeparators[message.id] && ( + + ); const renderMessage = ( { const scrollToIndexFailedRetryCountRef = useRef(0); const failScrollTimeoutId = useRef>(undefined); - const onScrollToIndexFailedRef = useRef['onScrollToIndexFailed']>( + const onScrollToIndexFailedRef = useRef['onScrollToIndexFailed']>( (info) => { // We got a failure as we tried to scroll to an item that was outside the render length if (!flatListRef.current) { @@ -1049,7 +1048,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { isListActive && ((threadList && thread) || (!threadList && !thread)) ) { - setMessages(messagesWithImages as MessageType[]); + setMessages(messagesWithImages as LocalMessage[]); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [ @@ -1078,7 +1077,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { onUserScrollEvent(event); }; - const refCallback = (ref: FlatListType) => { + const refCallback = (ref: FlatListType) => { flatListRef.current = ref; if (setFlatListRef) { diff --git a/package/src/components/MessageList/MessageSystem.tsx b/package/src/components/MessageList/MessageSystem.tsx index 39f3df564e..ddd12a11c3 100644 --- a/package/src/components/MessageList/MessageSystem.tsx +++ b/package/src/components/MessageList/MessageSystem.tsx @@ -1,7 +1,7 @@ import React, { useMemo } from 'react'; import { StyleProp, StyleSheet, Text, View, ViewStyle } from 'react-native'; -import type { MessageType } from './hooks/useMessageList'; +import { LocalMessage } from 'stream-chat'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { useTranslationContext } from '../../contexts/translationContext/TranslationContext'; @@ -10,7 +10,7 @@ import { getDateString } from '../../utils/i18n/getDateString'; export type MessageSystemProps = { /** Current [message object](https://getstream.io/chat/docs/#message_format) */ - message: MessageType; + message: LocalMessage; /** * Additional styles for the system message container. */ diff --git a/package/src/components/MessageList/hooks/useMessageList.ts b/package/src/components/MessageList/hooks/useMessageList.ts index 5c129ceb72..2ab4777ae5 100644 --- a/package/src/components/MessageList/hooks/useMessageList.ts +++ b/package/src/components/MessageList/hooks/useMessageList.ts @@ -1,4 +1,4 @@ -import type { ChannelState, MessageResponse } from 'stream-chat'; +import type { ChannelState } from 'stream-chat'; import { useLastReadData } from './useLastReadData'; @@ -22,22 +22,6 @@ export type UseMessageListParams = { export type GroupType = string; -export type MessagesWithStylesReadByAndDateSeparator = MessageResponse & { - groupStyles: GroupType[]; - readBy: boolean | number; - dateSeparator?: Date; -}; - -export type MessageType = - | ReturnType - | MessagesWithStylesReadByAndDateSeparator; - -// Type guards to check MessageType -export const isMessageWithStylesReadByAndDateSeparator = ( - message: MessageType, -): message is MessagesWithStylesReadByAndDateSeparator => - (message as MessagesWithStylesReadByAndDateSeparator).readBy !== undefined; - export const useMessageList = (params: UseMessageListParams) => { const { noGroupByUser, threadList } = params; const { client } = useChatContext(); @@ -72,34 +56,31 @@ export const useMessageList = (params: UseMessageListParams) => { userID: client.userID, }); - const messagesWithStylesReadByAndDateSeparator = messageList - .filter((msg) => { - const isMessageTypeDeleted = msg.type === 'deleted'; - if (deletedMessagesVisibilityType === 'sender') { - return !isMessageTypeDeleted || msg.user?.id === client.userID; - } else if (deletedMessagesVisibilityType === 'receiver') { - return !isMessageTypeDeleted || msg.user?.id !== client.userID; - } else if (deletedMessagesVisibilityType === 'never') { - return !isMessageTypeDeleted; - } else { - return msg; - } - }) - .map((msg) => ({ - ...msg, - dateSeparator: dateSeparators[msg.id] || undefined, - groupStyles: messageGroupStyles[msg.id] || ['single'], - readBy: msg.id ? readData[msg.id] || false : false, - })); + const messagesWithStyles = messageList.filter((msg) => { + const isMessageTypeDeleted = msg.type === 'deleted'; + if (deletedMessagesVisibilityType === 'sender') { + return !isMessageTypeDeleted || msg.user?.id === client.userID; + } else if (deletedMessagesVisibilityType === 'receiver') { + return !isMessageTypeDeleted || msg.user?.id !== client.userID; + } else if (deletedMessagesVisibilityType === 'never') { + return !isMessageTypeDeleted; + } else { + return msg; + } + }); - const processedMessageList = [ - ...messagesWithStylesReadByAndDateSeparator, - ].reverse() as MessageType[]; + const processedMessageList = [...messagesWithStyles].reverse(); return { + /** Date separators */ + dateSeparators, + /** Message group styles */ + messageGroupStyles, /** Messages enriched with dates/readby/groups and also reversed in order */ processedMessageList, /** Raw messages from the channel state */ rawMessageList: messageList, + /** Read data */ + readData, }; }; diff --git a/package/src/components/MessageList/utils/getGroupStyles.ts b/package/src/components/MessageList/utils/getGroupStyles.ts index 4ee09a1cec..5a8d93c0e5 100644 --- a/package/src/components/MessageList/utils/getGroupStyles.ts +++ b/package/src/components/MessageList/utils/getGroupStyles.ts @@ -1,10 +1,12 @@ +import { LocalMessage } from 'stream-chat'; + import type { DateSeparators } from './getDateSeparators'; import type { PaginatedMessageListContextValue } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext'; import type { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext'; import { isEditedMessage } from '../../../utils/utils'; -import type { GroupType, MessageType } from '../hooks/useMessageList'; +import type { GroupType } from '../hooks/useMessageList'; export type GetGroupStylesParams = { dateSeparators: DateSeparators; @@ -19,9 +21,9 @@ export type GroupStyle = '' | 'middle' | 'top' | 'bottom' | 'single'; const getGroupStyle = ( dateSeparators: DateSeparators, - message: MessageType, - previousMessage: MessageType, - nextMessage: MessageType, + message: LocalMessage, + previousMessage: LocalMessage, + nextMessage: LocalMessage, hideDateSeparators?: boolean, maxTimeBetweenGroupedMessages?: number, ): GroupStyle[] => { diff --git a/package/src/components/MessageList/utils/getLastReceivedMessage.ts b/package/src/components/MessageList/utils/getLastReceivedMessage.ts index 0f65de9ac7..2752950258 100644 --- a/package/src/components/MessageList/utils/getLastReceivedMessage.ts +++ b/package/src/components/MessageList/utils/getLastReceivedMessage.ts @@ -1,8 +1,8 @@ -import { MessageStatusTypes } from '../../../utils/utils'; +import { LocalMessage } from 'stream-chat'; -import type { MessageType } from '../hooks/useMessageList'; +import { MessageStatusTypes } from '../../../utils/utils'; -export const getLastReceivedMessage = (messages: MessageType[]) => { +export const getLastReceivedMessage = (messages: LocalMessage[]) => { /** * There are no status on dates so they will be skipped */ diff --git a/package/src/components/MessageMenu/__tests__/MessageUserReactions.test.tsx b/package/src/components/MessageMenu/__tests__/MessageUserReactions.test.tsx index 50db95dd39..30d6f243dc 100644 --- a/package/src/components/MessageMenu/__tests__/MessageUserReactions.test.tsx +++ b/package/src/components/MessageMenu/__tests__/MessageUserReactions.test.tsx @@ -4,7 +4,7 @@ import { Text } from 'react-native'; import { fireEvent, render } from '@testing-library/react-native'; -import { ReactionResponse } from 'stream-chat'; +import { LocalMessage, ReactionResponse } from 'stream-chat'; import { MessagesContextValue, @@ -17,7 +17,6 @@ import { TranslationProvider, } from '../../../contexts/translationContext/TranslationContext'; import { generateMessage } from '../../../mock-builders/generator/message'; -import { MessageType } from '../../MessageList/hooks/useMessageList'; import * as useFetchReactionsModule from '../hooks/useFetchReactions'; import { MessageUserReactions } from '../MessageUserReactions'; import { MessageUserReactionsItemProps } from '../MessageUserReactionsItem'; @@ -35,7 +34,7 @@ const defaultProps = { message: { ...generateMessage(), reaction_groups: { like: { count: 1, sum_scores: 1 }, love: { count: 1, sum_scores: 1 } }, - } as unknown as MessageType, + } as unknown as LocalMessage, supportedReactions: mockSupportedReactions, }; diff --git a/package/src/components/MessageMenu/hooks/useFetchReactions.ts b/package/src/components/MessageMenu/hooks/useFetchReactions.ts index f6c886dbdf..c91411c637 100644 --- a/package/src/components/MessageMenu/hooks/useFetchReactions.ts +++ b/package/src/components/MessageMenu/hooks/useFetchReactions.ts @@ -1,14 +1,13 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; -import { ReactionResponse, ReactionSort } from 'stream-chat'; +import { LocalMessage, ReactionResponse, ReactionSort } from 'stream-chat'; -import { MessageType } from '../../../components/MessageList/hooks/useMessageList'; import { useChatContext } from '../../../contexts/chatContext/ChatContext'; import { getReactionsForFilterSort } from '../../../store/apis/getReactionsforFilterSort'; export type UseFetchReactionParams = { limit?: number; - message?: MessageType; + message?: LocalMessage; reactionType?: string; sort?: ReactionSort; }; diff --git a/package/src/components/Poll/components/Button.tsx b/package/src/components/Poll/components/Button.tsx index 594c909c9e..533cc4dd61 100644 --- a/package/src/components/Poll/components/Button.tsx +++ b/package/src/components/Poll/components/Button.tsx @@ -1,14 +1,12 @@ import React from 'react'; import { Pressable, StyleSheet, Text } from 'react-native'; -import { Poll, PollOption } from 'stream-chat'; +import { LocalMessage, Poll, PollOption } from 'stream-chat'; import { useTheme } from '../../../contexts'; -import { MessageType } from '../../MessageList/hooks/useMessageList'; - export type PollButtonProps = { - onPress?: ({ message, poll }: { message: MessageType; poll: Poll }) => void; + onPress?: ({ message, poll }: { message: LocalMessage; poll: Poll }) => void; }; export type PollVoteButtonProps = { diff --git a/package/src/components/Poll/components/PollResults/PollResultItem.tsx b/package/src/components/Poll/components/PollResults/PollResultItem.tsx index 3a7a6421d9..7dad29fcca 100644 --- a/package/src/components/Poll/components/PollResults/PollResultItem.tsx +++ b/package/src/components/Poll/components/PollResults/PollResultItem.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useState } from 'react'; import { Modal, SafeAreaView, StyleSheet, Text, View } from 'react-native'; -import { Poll, PollOption, PollVote as PollVoteClass } from 'stream-chat'; +import { LocalMessage, Poll, PollOption, PollVote as PollVoteClass } from 'stream-chat'; import { PollOptionFullResults } from './PollOptionFullResults'; import { PollVote } from './PollVote'; @@ -13,7 +13,6 @@ import { useTranslationContext, } from '../../../../contexts'; -import { MessageType } from '../../../MessageList/hooks/useMessageList'; import { usePollState } from '../../hooks/usePollState'; import { GenericPollButton } from '../Button'; import { PollModalHeader } from '../PollModalHeader'; @@ -25,7 +24,7 @@ export type ShowAllVotesButtonProps = { option, poll, }: { - message: MessageType; + message: LocalMessage; option: PollOption; poll: Poll; }) => void; diff --git a/package/src/components/Reply/Reply.tsx b/package/src/components/Reply/Reply.tsx index 48299579ba..35ff5acceb 100644 --- a/package/src/components/Reply/Reply.tsx +++ b/package/src/components/Reply/Reply.tsx @@ -34,7 +34,6 @@ import { FileIcon as FileIconDefault } from '../Attachment/FileIcon'; import { VideoThumbnail } from '../Attachment/VideoThumbnail'; import { MessageAvatar as MessageAvatarDefault } from '../Message/MessageSimple/MessageAvatar'; import { MessageTextContainer } from '../Message/MessageSimple/MessageTextContainer'; -import { MessageType } from '../MessageList/hooks/useMessageList'; const styles = StyleSheet.create({ container: { @@ -177,7 +176,7 @@ const ReplyWithContext = (props: ReplyPropsWithContext) => { }, } = useTheme(); - const poll = client.polls.fromState((quotedMessage as MessageType)?.poll_id ?? ''); + const poll = client.polls.fromState(quotedMessage?.poll_id ?? ''); const { name: pollName }: ReplySelectorReturnType = useStateStore(poll?.state, selector) ?? {}; const messageText = quotedMessage ? quotedMessage.text : ''; diff --git a/package/src/components/Thread/components/ThreadFooterComponent.tsx b/package/src/components/Thread/components/ThreadFooterComponent.tsx index 6af6a455e0..7b1df5c268 100644 --- a/package/src/components/Thread/components/ThreadFooterComponent.tsx +++ b/package/src/components/Thread/components/ThreadFooterComponent.tsx @@ -101,6 +101,7 @@ const ThreadFooterComponentWithContext = (props: ThreadFooterComponentPropsWithC groupStyles={['single']} message={thread} preventPress={parentMessagePreventPress} + readBy={0} threadList /> diff --git a/package/src/components/ThreadList/ThreadListItem.tsx b/package/src/components/ThreadList/ThreadListItem.tsx index 72f3e3f850..e2cce5b64d 100644 --- a/package/src/components/ThreadList/ThreadListItem.tsx +++ b/package/src/components/ThreadList/ThreadListItem.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useMemo } from 'react'; import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; -import { Thread, ThreadState } from 'stream-chat'; +import { LocalMessage, Thread, ThreadState } from 'stream-chat'; import { TranslationContextValue, @@ -19,7 +19,6 @@ import { MessageBubble } from '../../icons'; import { getDateString } from '../../utils/i18n/getDateString'; import { Avatar } from '../Avatar/Avatar'; import { useChannelPreviewDisplayName } from '../ChannelPreview/hooks/useChannelPreviewDisplayName'; -import { MessageType } from '../MessageList/hooks/useMessageList'; export type ThreadListItemProps = { thread: Thread; @@ -76,7 +75,7 @@ const getTitleFromMessage = ({ }: { t: TranslationContextValue['t']; currentUserId?: string; - message?: MessageType | undefined; + message?: LocalMessage; }) => { const attachment = message?.attachments?.at(0); @@ -132,7 +131,10 @@ export const ThreadListItemComponent = () => { { if (onThreadSelect) { - onThreadSelect({ thread: parentMessage as MessageType, threadInstance: thread }, channel); + onThreadSelect( + { thread: parentMessage as LocalMessage, threadInstance: thread }, + channel, + ); } }} style={[styles.touchableWrapper, threadListItem.touchableWrapper]} diff --git a/package/src/contexts/debugContext/DebugContext.tsx b/package/src/contexts/debugContext/DebugContext.tsx index 02291f3dda..069c9af1af 100644 --- a/package/src/contexts/debugContext/DebugContext.tsx +++ b/package/src/contexts/debugContext/DebugContext.tsx @@ -1,8 +1,6 @@ import React, { PropsWithChildren, useContext, useRef } from 'react'; -import type { Channel, ChannelState, StreamChat } from 'stream-chat'; - -import type { MessageType } from '../../components/MessageList/hooks/useMessageList'; +import type { Channel, ChannelState, LocalMessage, StreamChat } from 'stream-chat'; import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; @@ -12,7 +10,7 @@ export type DebugDataType = data: Channel['data']; members: ChannelState['members']; }[] - | MessageType[]; + | LocalMessage[]; export type DebugContextValue = { eventType?: string; diff --git a/package/src/contexts/imageGalleryContext/ImageGalleryContext.tsx b/package/src/contexts/imageGalleryContext/ImageGalleryContext.tsx index eb68b53501..6643114a42 100644 --- a/package/src/contexts/imageGalleryContext/ImageGalleryContext.tsx +++ b/package/src/contexts/imageGalleryContext/ImageGalleryContext.tsx @@ -1,6 +1,7 @@ import React, { PropsWithChildren, useContext, useState } from 'react'; -import type { MessageType } from '../../components/MessageList/hooks/useMessageList'; +import { LocalMessage } from 'stream-chat'; + import type { UnknownType } from '../../types/types'; import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; @@ -12,8 +13,8 @@ type SelectedMessage = { }; export type ImageGalleryContextValue = { - messages: MessageType[]; - setMessages: React.Dispatch>; + messages: LocalMessage[]; + setMessages: React.Dispatch>; setSelectedMessage: React.Dispatch>; selectedMessage?: SelectedMessage; }; @@ -23,7 +24,7 @@ export const ImageGalleryContext = React.createContext( ); export const ImageGalleryProvider = ({ children }: PropsWithChildren) => { - const [messages, setMessages] = useState([]); + const [messages, setMessages] = useState([]); const [selectedMessage, setSelectedMessage] = useState(); return ( diff --git a/package/src/contexts/messageContext/MessageContext.tsx b/package/src/contexts/messageContext/MessageContext.tsx index 4b12d60f5c..8d4280478b 100644 --- a/package/src/contexts/messageContext/MessageContext.tsx +++ b/package/src/contexts/messageContext/MessageContext.tsx @@ -1,6 +1,6 @@ import React, { PropsWithChildren, useContext } from 'react'; -import type { Attachment } from 'stream-chat'; +import type { Attachment, LocalMessage } from 'stream-chat'; import type { ActionHandler } from '../../components/Attachment/Attachment'; import { ReactionSummary } from '../../components/Message/hooks/useProcessReactions'; @@ -8,7 +8,7 @@ import type { MessagePressableHandlerPayload, PressableHandlerPayload, } from '../../components/Message/Message'; -import type { GroupType, MessageType } from '../../components/MessageList/hooks/useMessageList'; +import type { GroupType } from '../../components/MessageList/hooks/useMessageList'; import type { ChannelContextValue } from '../../contexts/channelContext/ChannelContext'; import type { MessageContentType } from '../../contexts/messagesContext/MessagesContext'; import type { DeepPartial } from '../../contexts/themeContext/ThemeContext'; @@ -48,13 +48,13 @@ export type MessageContextValue = { /** * A factory function that determines whether a message is AI generated or not. */ - isMessageAIGenerated: (message: MessageType) => boolean; + isMessageAIGenerated: (message: LocalMessage) => boolean; /** Whether or not this is the active user's message */ isMyMessage: boolean; /** Whether or not this is the last message in a group of messages */ lastGroupMessage: boolean; /** Current [message object](https://getstream.io/chat/docs/#message_format) */ - message: MessageType; + message: LocalMessage; /** Order to render the message content */ messageContentOrder: MessageContentType[]; /** @@ -87,6 +87,8 @@ export type MessageContextValue = { /** The images attached to a message */ otherAttachments: Attachment[]; reactions: ReactionSummary[]; + /** Whether or not the message has been read by the current user */ + readBy: number | boolean; /** React set state function to set the state of `isEditedMessageOpen` */ setIsEditedMessageOpen: React.Dispatch>; /** diff --git a/package/src/contexts/messageInputContext/MessageInputContext.tsx b/package/src/contexts/messageInputContext/MessageInputContext.tsx index ccc8978ae0..4f63f0ce21 100644 --- a/package/src/contexts/messageInputContext/MessageInputContext.tsx +++ b/package/src/contexts/messageInputContext/MessageInputContext.tsx @@ -12,6 +12,7 @@ import { Alert, Keyboard, Linking, TextInput, TextInputProps } from 'react-nativ import uniq from 'lodash/uniq'; import { Attachment, + LocalMessage, logChatPromiseExecution, Message, SendFileAPIResponse, @@ -51,7 +52,6 @@ import type { MessageInputProps } from '../../components/MessageInput/MessageInp import type { MoreOptionsButtonProps } from '../../components/MessageInput/MoreOptionsButton'; import type { SendButtonProps } from '../../components/MessageInput/SendButton'; import type { UploadProgressIndicatorProps } from '../../components/MessageInput/UploadProgressIndicator'; -import type { MessageType } from '../../components/MessageList/hooks/useMessageList'; import type { Emoji } from '../../emoji-data'; import { isDocumentPickerAvailable, @@ -359,7 +359,7 @@ export type InputMessageInputContextValue = { SendButton: React.ComponentType; sendImageAsync: boolean; sendMessage: (message: Partial) => Promise; - setQuotedMessageState: (message: MessageType) => void; + setQuotedMessageState: (message: LocalMessage) => void; /** * Custom UI component to render checkbox with text ("Also send to channel") in Thread's input box. * When ticked, message will also be sent in parent channel. @@ -438,7 +438,7 @@ export type InputMessageInputContextValue = { * Variable that tracks the editing state. * It is defined with message type if the editing state is true, else its undefined. */ - editing?: MessageType; + editing?: LocalMessage; /** * Prop to override the default emoji search index in auto complete suggestion list. */ @@ -484,7 +484,7 @@ export type InputMessageInputContextValue = { */ onChangeText?: (newText: string) => void; openPollCreationDialog?: ({ sendMessage }: Pick) => void; - quotedMessage?: MessageType; + quotedMessage?: LocalMessage; SendMessageDisallowedIndicator?: React.ComponentType; /** * ref for input setter function @@ -1031,7 +1031,7 @@ export const MessageInputProvider = ({ /** * If the message is bounced by moderation, we firstly remove the message from message list and then send a new message. */ - if (message && isBouncedMessage(message as MessageType)) { + if (message && isBouncedMessage(message)) { await removeMessage(message); } value.sendMessage({ diff --git a/package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx b/package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx index 8b3a9277c1..322656999c 100644 --- a/package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx @@ -3,7 +3,8 @@ import { act } from 'react-test-renderer'; import { renderHook, waitFor } from '@testing-library/react-native'; -import type { MessageType } from '../../../components/MessageList/hooks/useMessageList'; +import { LocalMessage } from 'stream-chat'; + import { generateFileUploadPreview, generateImageUploadPreview, @@ -40,7 +41,7 @@ describe("MessageInputContext's sendMessage", () => { setSelectedFiles: jest.fn(), setSelectedImages: jest.fn(), })); - const message: boolean | MessageType = generateMessage({ + const message: LocalMessage | undefined = generateMessage({ created_at: 'Sat Jul 02 2022 23:55:13 GMT+0530 (India Standard Time)', id: '7a85f744-cc89-4f82-a1d4-5456432cc8bf', updated_at: 'Sat Jul 02 2022 23:55:13 GMT+0530 (India Standard Time)', @@ -49,7 +50,7 @@ describe("MessageInputContext's sendMessage", () => { image: 'fc86ddcb-bac4-400c-9afd-b0c0a1c0cd33', name: '50cbdd0e-ca7e-4478-9e2c-be0f1ac6a995', }), - }) as unknown as MessageType; + }) as unknown as LocalMessage; it('exit sendMessage when file upload status failed', async () => { const initialProps = { @@ -223,7 +224,7 @@ describe("MessageInputContext's sendMessage", () => { it('exit sendMessage when image upload has an error and catch block is executed', () => { const setQuotedMessageStateMock = jest.fn(); const clearQuotedMessageStateMock = jest.fn(); - const generatedQuotedMessage: boolean | MessageType = message; + const generatedQuotedMessage: boolean | LocalMessage = message; const images = [ generateImageUploadPreview({ state: FileState.UPLOADED }), generateImageUploadPreview({ state: FileState.FINISHED }), @@ -268,7 +269,7 @@ describe("MessageInputContext's sendMessage", () => { const clearEditingStateMock = jest.fn(); const editMessageMock = jest.fn().mockResolvedValue({ data: {} }); const images = generateImageUploadPreview({ state: FileState.UPLOADED }); - const generatedMessage: boolean | MessageType = message; + const generatedMessage: boolean | LocalMessage = message; const initialProps = { clearEditingState: clearEditingStateMock, clearQuotedMessageState: clearQuotedMessageStateMock, diff --git a/package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx b/package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx index 5aa66c3bb7..5e342b4488 100644 --- a/package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx @@ -3,9 +3,7 @@ import { act } from 'react-test-renderer'; import { renderHook } from '@testing-library/react-native'; -import type { StreamChat } from 'stream-chat'; - -import type { MessageType } from '../../../components/MessageList/hooks/useMessageList'; +import type { LocalMessage, StreamChat } from 'stream-chat'; import { ChatContextValue, ChatProvider } from '../../../contexts/chatContext/ChatContext'; import { generateMessage } from '../../../mock-builders/generator/message'; @@ -51,7 +49,7 @@ describe("MessageInputContext's updateMessage", () => { setSelectedImages: jest.fn(), })); const clearEditingStateMock = jest.fn(); - const generatedMessage: boolean | MessageType = generateMessage({ + const generatedMessage: boolean | LocalMessage = generateMessage({ created_at: 'Sat Jul 02 2022 23:55:13 GMT+0530 (India Standard Time)', id: '7a85f744-cc89-4f82-a1d4-5456432cc8bf', text: 'hey', @@ -61,7 +59,7 @@ describe("MessageInputContext's updateMessage", () => { image: 'fc86ddcb-bac4-400c-9afd-b0c0a1c0cd33', name: '50cbdd0e-ca7e-4478-9e2c-be0f1ac6a995', }), - }) as unknown as MessageType; + }) as unknown as LocalMessage; it('updateMessage throws error as clearEditingState is not available', async () => { const initialProps = { diff --git a/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx b/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx index 819be733af..c4270fd1d2 100644 --- a/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx @@ -1,6 +1,6 @@ import { renderHook } from '@testing-library/react-native'; -import type { MessageType } from '../../../components'; +import { LocalMessage } from 'stream-chat'; import { generateFileAttachment, @@ -13,24 +13,28 @@ import { generateUser } from '../../../mock-builders/generator/user'; import { useMessageDetailsForState } from '../hooks/useMessageDetailsForState'; describe('useMessageDetailsForState', () => { - it.each([[{ message: true }], [{ initialValue: '', message: true }]])( - 'test state of useMessageDetailsForState when initialProps differ', - () => { - const { result } = renderHook(({ message }) => useMessageDetailsForState(message), { - initialProps: { message: true }, - }); + it.each([ + [{ message: generateMessage({ text: 'Dummy text' }) }], + [{ initialValue: '', message: generateMessage({ text: 'Dummy text' }) }], + ])('test state of useMessageDetailsForState when initialProps differ', () => { + const { result } = renderHook( + ({ message }) => useMessageDetailsForState(message as unknown as LocalMessage), + { + initialProps: { message: generateMessage({ text: 'Dummy text' }) }, + }, + ); - expect(result.current.text).toBe(''); - }, - ); + expect(result.current.text).toBe(''); + }); it('showMoreOptions is true when initialValue and text is same', () => { const { result } = renderHook( - ({ initialValue, message }) => useMessageDetailsForState(message, initialValue), + ({ initialValue, message }) => + useMessageDetailsForState(message as unknown as LocalMessage, initialValue), { initialProps: { initialValue: 'Dummy text', - message: generateMessage({ text: 'Dummy text' }) as MessageType, + message: generateMessage({ text: 'Dummy text' }), }, }, ); @@ -41,7 +45,7 @@ describe('useMessageDetailsForState', () => { it('fileUploads, imageUploads and mentionedUsers are not empty when attachments are present in message', () => { const { result } = renderHook( ({ initialValue, message }) => - useMessageDetailsForState(message as unknown as MessageType | boolean, initialValue), + useMessageDetailsForState(message as unknown as LocalMessage, initialValue), { initialProps: { initialValue: '', diff --git a/package/src/contexts/messagesContext/MessagesContext.tsx b/package/src/contexts/messagesContext/MessagesContext.tsx index 7f4a73e40f..535b838247 100644 --- a/package/src/contexts/messagesContext/MessagesContext.tsx +++ b/package/src/contexts/messagesContext/MessagesContext.tsx @@ -2,7 +2,7 @@ import React, { PropsWithChildren, useContext } from 'react'; import { PressableProps, ViewProps } from 'react-native'; -import type { Attachment, ChannelState, MessageResponse } from 'stream-chat'; +import type { Attachment, ChannelState, LocalMessage, MessageResponse } from 'stream-chat'; import type { PollContentProps, StreamingMessageViewProps } from '../../components'; import type { AttachmentProps } from '../../components/Attachment/Attachment'; @@ -40,7 +40,6 @@ import type { ReactionListTopProps } from '../../components/Message/MessageSimpl import type { MarkdownRules } from '../../components/Message/MessageSimple/utils/renderText'; import type { MessageActionsParams } from '../../components/Message/utils/messageActions'; import type { DateHeaderProps } from '../../components/MessageList/DateHeader'; -import type { MessageType } from '../../components/MessageList/hooks/useMessageList'; import type { InlineDateSeparatorProps } from '../../components/MessageList/InlineDateSeparator'; import type { MessageListProps } from '../../components/MessageList/MessageList'; import type { MessageSystemProps } from '../../components/MessageList/MessageSystem'; @@ -107,7 +106,7 @@ export type MessagesContextValue = Pick; - deleteMessage: (message: MessageResponse) => Promise; + deleteMessage: (message: LocalMessage) => Promise; deleteReaction: (type: string, messageId: string) => Promise; /** Should keyboard be dismissed when messaged is touched */ @@ -289,15 +288,15 @@ export type MessagesContextValue = Pick Promise; + retrySendMessage: (message: LocalMessage) => Promise; /** * UI component for ScrollToBottomButton * Defaults to: [ScrollToBottomButton](https://getstream.io/chat/docs/sdk/reactnative/ui-components/scroll-to-bottom-button/) */ ScrollToBottomButton: React.ComponentType; sendReaction: (type: string, messageId: string) => Promise; - setEditingState: (message?: MessageType) => void; - setQuotedMessageState: (message?: MessageType) => void; + setEditingState: (message?: LocalMessage) => void; + setQuotedMessageState: (message?: LocalMessage) => void; /** * UI component for StreamingMessageView. Displays the text of a message with a typewriter animation. */ @@ -314,7 +313,7 @@ export type MessagesContextValue = Pick; UnreadMessagesNotification: React.ComponentType; updateMessage: ( - updatedMessage: MessageResponse, + updatedMessage: MessageResponse | LocalMessage, extraState?: { commands?: SuggestionCommand[]; messageInput?: string; @@ -376,29 +375,29 @@ export type MessagesContextValue = Pick Promise; + handleBan?: (message: LocalMessage) => Promise; /** Handler to access when a copy message action is invoked */ - handleCopy?: (message: MessageType) => Promise; + handleCopy?: (message: LocalMessage) => Promise; /** Handler to access when a delete message action is invoked */ - handleDelete?: (message: MessageType) => Promise; + handleDelete?: (message: LocalMessage) => Promise; /** Handler to access when an edit message action is invoked */ - handleEdit?: (message: MessageType) => void; + handleEdit?: (message: LocalMessage) => void; /** Handler to access when a flag message action is invoked */ - handleFlag?: (message: MessageType) => Promise; + handleFlag?: (message: LocalMessage) => Promise; /** Handler to access when a mark unread action is invoked */ - handleMarkUnread?: (message: MessageType) => Promise; + handleMarkUnread?: (message: LocalMessage) => Promise; /** Handler to access when a mute user action is invoked */ - handleMute?: (message: MessageType) => Promise; + handleMute?: (message: LocalMessage) => Promise; /** Handler to access when a pin/unpin user action is invoked*/ - handlePinMessage?: ((message: MessageType) => MessageActionType) | null; + handlePinMessage?: ((message: LocalMessage) => MessageActionType) | null; /** Handler to access when a quoted reply action is invoked */ - handleQuotedReply?: (message: MessageType) => Promise; + handleQuotedReply?: (message: LocalMessage) => Promise; /** Handler to process a reaction */ - handleReaction?: (message: MessageType, reactionType: string) => Promise; + handleReaction?: (message: LocalMessage, reactionType: string) => Promise; /** Handler to access when a retry action is invoked */ - handleRetry?: (message: MessageType) => Promise; + handleRetry?: (message: LocalMessage) => Promise; /** Handler to access when a thread reply action is invoked */ - handleThreadReply?: (message: MessageType) => Promise; + handleThreadReply?: (message: LocalMessage) => Promise; /** A flag specifying whether the poll creation button is available or not. */ hasCreatePoll?: boolean; /** Handler to deal with custom memoization logic of Attachment */ @@ -586,7 +585,7 @@ export type MessagesContextValue = Pick (reactionType: string) => Promise; + selectReaction?: (message: LocalMessage) => (reactionType: string) => Promise; /** * Boolean to enable/disable the message underlay background when there are unread messages in the Message List. diff --git a/package/src/contexts/pollContext/pollContext.tsx b/package/src/contexts/pollContext/pollContext.tsx index a6969ed48b..ec0ef46e8d 100644 --- a/package/src/contexts/pollContext/pollContext.tsx +++ b/package/src/contexts/pollContext/pollContext.tsx @@ -1,15 +1,13 @@ import React, { PropsWithChildren, useContext } from 'react'; -import { Poll } from 'stream-chat'; - -import { MessageType } from '../../components'; +import { LocalMessage, Poll } from 'stream-chat'; import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; export type PollContextValue = { - message: MessageType; + message: LocalMessage; poll: Poll; }; diff --git a/package/src/contexts/threadContext/ThreadContext.tsx b/package/src/contexts/threadContext/ThreadContext.tsx index 35ec53a7d2..d60d6b58b1 100644 --- a/package/src/contexts/threadContext/ThreadContext.tsx +++ b/package/src/contexts/threadContext/ThreadContext.tsx @@ -1,23 +1,21 @@ import React, { PropsWithChildren, useContext } from 'react'; -import { ChannelState, Thread } from 'stream-chat'; - -import type { MessageType } from '../../components/MessageList/hooks/useMessageList'; +import { ChannelState, LocalMessage, Thread } from 'stream-chat'; import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; import { isTestEnvironment } from '../utils/isTestEnvironment'; -export type ThreadType = { thread: MessageType; threadInstance: Thread }; +export type ThreadType = { thread: LocalMessage; threadInstance: Thread }; export type ThreadContextValue = { allowThreadMessagesInChannel: boolean; closeThread: () => void; loadMoreThread: () => Promise; - openThread: (message: MessageType) => void; + openThread: (message: LocalMessage) => void; reloadThread: () => void; setThreadLoadingMore: React.Dispatch>; - thread: MessageType | null; + thread: LocalMessage | null; threadHasMore: boolean; threadMessages: ChannelState['threads'][string]; loadMoreRecentThread?: (opts: { limit?: number }) => Promise; diff --git a/package/src/contexts/threadsContext/ThreadListItemContext.tsx b/package/src/contexts/threadsContext/ThreadListItemContext.tsx index 8602fb86e1..6a1bcd1e62 100644 --- a/package/src/contexts/threadsContext/ThreadListItemContext.tsx +++ b/package/src/contexts/threadsContext/ThreadListItemContext.tsx @@ -1,8 +1,6 @@ import React, { PropsWithChildren, useContext } from 'react'; -import { Channel, Thread } from 'stream-chat'; - -import { MessageType } from '../../components'; +import { Channel, LocalMessage, Thread } from 'stream-chat'; import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue'; @@ -10,9 +8,9 @@ export type ThreadListItemContextValue = { channel: Channel; dateString: string | number | undefined; deletedAtDateString: string | number | undefined; - lastReply: MessageType | undefined; + lastReply: LocalMessage | undefined; ownUnreadMessageCount: number; - parentMessage: MessageType | undefined; + parentMessage: LocalMessage | undefined; thread: Thread; }; diff --git a/package/src/utils/removeReservedFields.ts b/package/src/utils/removeReservedFields.ts index c2be8c6d2e..f32d59a3e1 100644 --- a/package/src/utils/removeReservedFields.ts +++ b/package/src/utils/removeReservedFields.ts @@ -1,10 +1,8 @@ -import type { MessageResponse } from 'stream-chat'; - -import type { MessageType } from '../components/MessageList/hooks/useMessageList'; +import type { LocalMessage, MessageResponse } from 'stream-chat'; export const removeReservedFields = ( - message: MessageType | MessageResponse, -): MessageType | MessageResponse => { + message: LocalMessage | MessageResponse, +): LocalMessage | MessageResponse => { const retryMessage = { ...message }; const reserved = [ 'cid', diff --git a/package/src/utils/utils.ts b/package/src/utils/utils.ts index a856ee4c26..5ec4c605f0 100644 --- a/package/src/utils/utils.ts +++ b/package/src/utils/utils.ts @@ -5,10 +5,6 @@ import EmojiRegex from 'emoji-regex'; import type { ChannelState, LocalMessage, MessageResponse } from 'stream-chat'; import { IconProps } from '../../src/icons/utils/base'; -import { - MessagesWithStylesReadByAndDateSeparator, - MessageType, -} from '../components/MessageList/hooks/useMessageList'; import type { EmojiSearchIndex } from '../contexts/messageInputContext/MessageInputContext'; import { compiledEmojis } from '../emoji-data'; import type { TableRowJoinedUser } from '../store/types'; @@ -78,7 +74,7 @@ export const getIndicatorTypeForFileState = ( * @param message * @returns boolean */ -export const isBlockedMessage = (message: MessageType | TableRowJoinedUser<'messages'>) => { +export const isBlockedMessage = (message: LocalMessage | TableRowJoinedUser<'messages'>) => { // The only indicator for the blocked message is its message type is error and that the message text contains "Message was blocked by moderation policies". const pattern = /\bMessage was blocked by moderation policies\b/; return message.type === 'error' && message.text && pattern.test(message.text); @@ -89,7 +85,7 @@ export const isBlockedMessage = (message: MessageType | TableRowJoinedUser<'mess * @param message * @returns boolean */ -export const isBouncedMessage = (message: MessageType) => +export const isBouncedMessage = (message: LocalMessage) => (message.type === 'error' && message?.moderation_details?.action === 'MESSAGE_RESPONSE_ACTION_BOUNCE') || message?.moderation?.action === 'bounce'; @@ -99,7 +95,7 @@ export const isBouncedMessage = (message: MessageType) => * @param message * @returns boolean */ -export const isEditedMessage = (message: MessageType) => !!message.message_text_updated_at; +export const isEditedMessage = (message: LocalMessage) => !!message.message_text_updated_at; /** * Default emoji search index for auto complete text input @@ -190,7 +186,7 @@ export const hasOnlyEmojis = (text: string) => { * @param {LocalMessage} message - the message object to be stringified * @returns {string} The stringified message */ -export const stringifyMessage = (message: MessageResponse | LocalMessage | MessageType): string => { +export const stringifyMessage = (message: MessageResponse | LocalMessage): string => { const { deleted_at, i18n, @@ -202,7 +198,6 @@ export const stringifyMessage = (message: MessageResponse | LocalMessage | Messa type, updated_at, } = message; - const readBy = (message as MessagesWithStylesReadByAndDateSeparator)?.readBy ?? ''; return `${ latest_reactions ? latest_reactions.map(({ type, user }) => `${type}${user?.id}`).join() : '' }${ @@ -214,7 +209,7 @@ export const stringifyMessage = (message: MessageResponse | LocalMessage | Messa ) .join() : '' - }${type}${deleted_at}${text}${readBy}${reply_count}${status}${updated_at}${JSON.stringify(i18n)}`; + }${type}${deleted_at}${text}${reply_count}${status}${updated_at}${JSON.stringify(i18n)}`; }; /** From ef3a2a7049849246d829d2f32d815d271987898b Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Wed, 23 Apr 2025 16:14:06 +0530 Subject: [PATCH 41/60] fix: resolve conflicts from V7 branch --- .../MessageList/hooks/useMessageList.ts | 46 +++++++++++++------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/package/src/components/MessageList/hooks/useMessageList.ts b/package/src/components/MessageList/hooks/useMessageList.ts index f905840572..a658b2dd60 100644 --- a/package/src/components/MessageList/hooks/useMessageList.ts +++ b/package/src/components/MessageList/hooks/useMessageList.ts @@ -63,21 +63,37 @@ export const useMessageList = (params: UseMessageListParams) => { userID: client.userID, }); - const dateSeparators = getDateSeparators({ - deletedMessagesVisibilityType, - hideDateSeparators, - messages: messageList, - userId: client.userID, - }); - - const messageGroupStyles = getMessagesGroupStyles({ - dateSeparators, - hideDateSeparators, - maxTimeBetweenGroupedMessages, - messages: messageList, - noGroupByUser, - userId: client.userID, - }); + const dateSeparators = useMemo( + () => + getDateSeparators({ + deletedMessagesVisibilityType, + hideDateSeparators, + messages: messageList, + userId: client.userID, + }), + [deletedMessagesVisibilityType, hideDateSeparators, messageList, client.userID], + ); + + const messageGroupStyles = useMemo( + () => + getMessagesGroupStyles({ + dateSeparators, + hideDateSeparators, + maxTimeBetweenGroupedMessages, + messages: messageList, + noGroupByUser, + userId: client.userID, + }), + [ + getMessagesGroupStyles, + dateSeparators, + hideDateSeparators, + maxTimeBetweenGroupedMessages, + messageList, + noGroupByUser, + client.userID, + ], + ); const processedMessageList = useMemo(() => { const newMessageList = []; From b1823a8ac8fbd5625aad5e510dd2201817635d19 Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Wed, 23 Apr 2025 17:07:50 +0530 Subject: [PATCH 42/60] fix: broken tests --- .../__tests__/MessageStatus.test.js | 16 ++++++++---- .../__snapshots__/Thread.test.js.snap | 15 ----------- .../useMessageDetailsForState.test.tsx | 25 ++++++++++--------- 3 files changed, 24 insertions(+), 32 deletions(-) diff --git a/package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js b/package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js index 400ed93719..85c4ab790f 100644 --- a/package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js +++ b/package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js @@ -72,26 +72,32 @@ describe('MessageStatus', () => { it('should render message status with read by container', async () => { const user = generateUser(); - const message = generateMessage({ readBy: 2, user }); + const message = generateMessage({ user }); + const readBy = 2; const { getByTestId, getByText, rerender, toJSON } = renderMessageStatus({ lastReceivedId: message.id, message, + readBy, }); await waitFor(() => { expect(getByTestId('read-by-container')).toBeTruthy(); - expect(getByText((message.readBy - 1).toString())).toBeTruthy(); + expect(getByText((readBy - 1).toString())).toBeTruthy(); }); const staticUser = generateStaticUser(0); - const staticMessage = generateMessage({ readBy: 2, staticUser }); + const staticMessage = generateMessage({ readBy, user: staticUser }); rerender( - + , @@ -100,7 +106,7 @@ describe('MessageStatus', () => { await waitFor(() => { expect(toJSON()).toMatchSnapshot(); expect(getByTestId('read-by-container')).toBeTruthy(); - expect(getByText((staticMessage.readBy - 1).toString())).toBeTruthy(); + expect(getByText((readBy - 1).toString())).toBeTruthy(); }); }); diff --git a/package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap b/package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap index f8970d93ef..31a66d0b23 100644 --- a/package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +++ b/package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap @@ -51,12 +51,8 @@ exports[`Thread should match thread snapshot 1`] = ` { "attachments": [], "created_at": 2020-05-05T14:50:00.000Z, - "dateSeparator": undefined, "deleted_at": null, "error": null, - "groupStyles": [ - "single", - ], "html": "

regular

", "id": "38ef6f7c-3090-5759-a37f-ab0053aadb96", "message_text_updated_at": "2020-05-05T14:50:00.000Z", @@ -64,7 +60,6 @@ exports[`Thread should match thread snapshot 1`] = ` "pinned_at": null, "quoted_message": null, "reaction_groups": null, - "readBy": false, "status": "received", "text": "Message6", "type": "regular", @@ -83,12 +78,8 @@ exports[`Thread should match thread snapshot 1`] = ` { "attachments": [], "created_at": 2020-05-05T14:50:00.000Z, - "dateSeparator": undefined, "deleted_at": null, "error": null, - "groupStyles": [ - "single", - ], "html": "

regular

", "id": "516efa25-5d29-5c9a-ad2d-4cc183e785bd", "message_text_updated_at": "2020-05-05T14:50:00.000Z", @@ -96,7 +87,6 @@ exports[`Thread should match thread snapshot 1`] = ` "pinned_at": null, "quoted_message": null, "reaction_groups": null, - "readBy": false, "status": "received", "text": "Message5", "type": "regular", @@ -115,12 +105,8 @@ exports[`Thread should match thread snapshot 1`] = ` { "attachments": [], "created_at": 2020-05-05T14:50:00.000Z, - "dateSeparator": 2020-05-05T14:50:00.000Z, "deleted_at": null, "error": null, - "groupStyles": [ - "single", - ], "html": "

regular

", "id": "82a83b16-b611-527c-b3ac-765ef6220490", "message_text_updated_at": "2020-05-05T14:50:00.000Z", @@ -128,7 +114,6 @@ exports[`Thread should match thread snapshot 1`] = ` "pinned_at": null, "quoted_message": null, "reaction_groups": null, - "readBy": false, "status": "received", "text": "Message4", "type": "regular", diff --git a/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx b/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx index c4270fd1d2..c39d95a712 100644 --- a/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx +++ b/package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx @@ -13,19 +13,20 @@ import { generateUser } from '../../../mock-builders/generator/user'; import { useMessageDetailsForState } from '../hooks/useMessageDetailsForState'; describe('useMessageDetailsForState', () => { - it.each([ - [{ message: generateMessage({ text: 'Dummy text' }) }], - [{ initialValue: '', message: generateMessage({ text: 'Dummy text' }) }], - ])('test state of useMessageDetailsForState when initialProps differ', () => { - const { result } = renderHook( - ({ message }) => useMessageDetailsForState(message as unknown as LocalMessage), - { - initialProps: { message: generateMessage({ text: 'Dummy text' }) }, - }, - ); + const message = generateMessage({ text: 'Dummy text' }); + it.each([[{ message }, { initialValue: '', message }]])( + 'test state of useMessageDetailsForState when initialProps differ', + () => { + const { result } = renderHook( + ({ message }) => useMessageDetailsForState(message as unknown as LocalMessage), + { + initialProps: { message }, + }, + ); - expect(result.current.text).toBe(''); - }); + expect(result.current.text).toBe(message.text); + }, + ); it('showMoreOptions is true when initialValue and text is same', () => { const { result } = renderHook( From b787c478bb2ac6991fba7263da69e9708665a095 Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Thu, 24 Apr 2025 11:41:29 +0530 Subject: [PATCH 43/60] fix: useMessageActions remove reserved fields logic --- package/src/components/Message/hooks/useMessageActions.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/package/src/components/Message/hooks/useMessageActions.tsx b/package/src/components/Message/hooks/useMessageActions.tsx index 5b859148f9..c4aef9d5f0 100644 --- a/package/src/components/Message/hooks/useMessageActions.tsx +++ b/package/src/components/Message/hooks/useMessageActions.tsx @@ -26,7 +26,6 @@ import { UserDelete, } from '../../../icons'; -import { removeReservedFields } from '../../../utils/removeReservedFields'; import { MessageStatusTypes } from '../../../utils/utils'; import type { MessageActionType } from '../../MessageMenu/MessageActionListItem'; @@ -292,9 +291,8 @@ export const useMessageActions = ({ const retry: MessageActionType = { action: async () => { dismissOverlay(); - const messageWithoutReservedFields = removeReservedFields(message); if (handleRetry) { - handleRetry(messageWithoutReservedFields as LocalMessage); + handleRetry(message); } await handleResendMessage(); From 65881a741b52a192b9ebf9f6c9f8be75dce75db7 Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Thu, 24 Apr 2025 13:55:40 +0530 Subject: [PATCH 44/60] revert: useMessageActions change --- package/src/components/Message/hooks/useMessageActions.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package/src/components/Message/hooks/useMessageActions.tsx b/package/src/components/Message/hooks/useMessageActions.tsx index c4aef9d5f0..5b859148f9 100644 --- a/package/src/components/Message/hooks/useMessageActions.tsx +++ b/package/src/components/Message/hooks/useMessageActions.tsx @@ -26,6 +26,7 @@ import { UserDelete, } from '../../../icons'; +import { removeReservedFields } from '../../../utils/removeReservedFields'; import { MessageStatusTypes } from '../../../utils/utils'; import type { MessageActionType } from '../../MessageMenu/MessageActionListItem'; @@ -291,8 +292,9 @@ export const useMessageActions = ({ const retry: MessageActionType = { action: async () => { dismissOverlay(); + const messageWithoutReservedFields = removeReservedFields(message); if (handleRetry) { - handleRetry(message); + handleRetry(messageWithoutReservedFields as LocalMessage); } await handleResendMessage(); From 3f6d11170bd46a540bf3dfaef0900909ef005543 Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Thu, 24 Apr 2025 17:34:41 +0530 Subject: [PATCH 45/60] fix: confine readBy data to Message Status component --- package/src/components/Message/Message.tsx | 17 ++---- .../Message/MessageSimple/MessageStatus.tsx | 1 - .../components/MessageList/MessageList.tsx | 4 +- .../MessageList/hooks/useLastReadData.ts | 29 ---------- .../MessageList/hooks/useMessageList.ts | 15 +---- .../MessageList/utils/getReadState.ts | 27 +++++++++ .../MessageList/utils/getReadStates.ts | 55 ------------------- package/src/components/index.ts | 2 +- 8 files changed, 37 insertions(+), 113 deletions(-) delete mode 100644 package/src/components/MessageList/hooks/useLastReadData.ts create mode 100644 package/src/components/MessageList/utils/getReadState.ts delete mode 100644 package/src/components/MessageList/utils/getReadStates.ts diff --git a/package/src/components/Message/Message.tsx b/package/src/components/Message/Message.tsx index f898ececc9..bdb8f7062b 100644 --- a/package/src/components/Message/Message.tsx +++ b/package/src/components/Message/Message.tsx @@ -41,6 +41,7 @@ import { MessageStatusTypes, } from '../../utils/utils'; import type { Thumbnail } from '../Attachment/utils/buildGallery/types'; +import { getReadState } from '../MessageList/utils/getReadState'; export type TouchableEmitter = | 'fileAttachment' @@ -136,7 +137,7 @@ export type MessagePropsWithContext = Pick< Partial< Omit > & - Pick & + Pick & Pick< MessagesContextValue, | 'sendReaction' @@ -247,7 +248,6 @@ const MessageWithContext = (props: MessagePropsWithContext) => { onThreadSelect, openThread, preventPress, - readBy, removeMessage, retrySendMessage, selectReaction, @@ -263,6 +263,7 @@ const MessageWithContext = (props: MessagePropsWithContext) => { threadList = false, updateMessage, } = props; + const { read } = useChannelContext(); const isMessageAIGenerated = messagesContext.isMessageAIGenerated; const isAIGenerated = useMemo( () => isMessageAIGenerated(message), @@ -277,6 +278,7 @@ const MessageWithContext = (props: MessagePropsWithContext) => { screenPadding, }, } = useTheme(); + const readBy = useMemo(() => getReadState(message, read), [message, read]); const showMessageOverlay = async (showMessageReactions = false, selectedReaction?: string) => { await dismissKeyboard(); @@ -756,7 +758,6 @@ const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWit members: prevMembers, message: prevMessage, messagesContext: prevMessagesContext, - readBy: prevReadBy, showUnreadUnderlay: prevShowUnreadUnderlay, t: prevT, } = prevProps; @@ -769,7 +770,6 @@ const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWit members: nextMembers, message: nextMessage, messagesContext: nextMessagesContext, - readBy: nextReadBy, showUnreadUnderlay: nextShowUnreadUnderlay, t: nextT, } = nextProps; @@ -885,11 +885,6 @@ const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWit return false; } - const readByEqual = prevReadBy === nextReadBy; - if (!readByEqual) { - return false; - } - const showUnreadUnderlayEqual = prevShowUnreadUnderlay === nextShowUnreadUnderlay; if (!showUnreadUnderlayEqual) { return false; @@ -919,9 +914,9 @@ const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWit const MemoizedMessage = React.memo(MessageWithContext, areEqual) as typeof MessageWithContext; export type MessageProps = Partial< - Omit + Omit > & - Pick; + Pick; /** * Message - A high level component which implements all the logic required for a message. diff --git a/package/src/components/Message/MessageSimple/MessageStatus.tsx b/package/src/components/Message/MessageSimple/MessageStatus.tsx index b93ff79f54..1552c775a5 100644 --- a/package/src/components/Message/MessageSimple/MessageStatus.tsx +++ b/package/src/components/Message/MessageSimple/MessageStatus.tsx @@ -10,7 +10,6 @@ import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { Check } from '../../../icons/Check'; import { CheckAll } from '../../../icons/CheckAll'; import { Time } from '../../../icons/Time'; - import { MessageStatusTypes } from '../../../utils/utils'; export type MessageStatusPropsWithContext = Pick< diff --git a/package/src/components/MessageList/MessageList.tsx b/package/src/components/MessageList/MessageList.tsx index cdd059bff4..37cb704d3d 100644 --- a/package/src/components/MessageList/MessageList.tsx +++ b/package/src/components/MessageList/MessageList.tsx @@ -318,7 +318,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { * NOTE: rawMessageList changes only when messages array state changes * processedMessageList changes on any state change */ - const { dateSeparators, messageGroupStyles, processedMessageList, rawMessageList, readData } = + const { dateSeparators, messageGroupStyles, processedMessageList, rawMessageList } = useMessageList({ noGroupByUser, threadList, @@ -766,7 +766,6 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { } message={message} onThreadSelect={onThreadSelect} - readBy={readData[message.id]} showUnreadUnderlay={showUnreadUnderlay} style={[messageContainer]} threadList={threadList} @@ -820,7 +819,6 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { modifiedTheme, myMessageTheme, onThreadSelect, - readData, screenPadding, shouldApplyAndroidWorkaround, shouldShowUnreadUnderlay, diff --git a/package/src/components/MessageList/hooks/useLastReadData.ts b/package/src/components/MessageList/hooks/useLastReadData.ts deleted file mode 100644 index 771a4b56cd..0000000000 --- a/package/src/components/MessageList/hooks/useLastReadData.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { useMemo } from 'react'; - -import type { ChannelState } from 'stream-chat'; - -import { PaginatedMessageListContextValue } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext'; -import { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext'; - -import { getReadStates } from '../utils/getReadStates'; - -type UseLastReadDataParams = { - messages: PaginatedMessageListContextValue['messages'] | ThreadContextValue['threadMessages']; - userID: string | undefined; - read?: ChannelState['read']; - returnAllReadData?: boolean; -}; - -export const useLastReadData = (props: UseLastReadDataParams) => { - const { messages, read, returnAllReadData = true, userID } = props; - - return useMemo( - () => - getReadStates( - messages.filter(({ user }) => user?.id === userID), - read, - returnAllReadData, - ), - [messages, read, returnAllReadData, userID], - ); -}; diff --git a/package/src/components/MessageList/hooks/useMessageList.ts b/package/src/components/MessageList/hooks/useMessageList.ts index a658b2dd60..f7b3f30f91 100644 --- a/package/src/components/MessageList/hooks/useMessageList.ts +++ b/package/src/components/MessageList/hooks/useMessageList.ts @@ -1,8 +1,6 @@ import { useMemo } from 'react'; -import type { ChannelState, LocalMessage } from 'stream-chat'; - -import { useLastReadData } from './useLastReadData'; +import type { LocalMessage } from 'stream-chat'; import { useChannelContext } from '../../../contexts/channelContext/ChannelContext'; import { useChatContext } from '../../../contexts/chatContext/ChatContext'; @@ -48,20 +46,13 @@ export const shouldIncludeMessageInList = ( export const useMessageList = (params: UseMessageListParams) => { const { noGroupByUser, threadList } = params; const { client } = useChatContext(); - const { hideDateSeparators, maxTimeBetweenGroupedMessages, read } = useChannelContext(); + const { hideDateSeparators, maxTimeBetweenGroupedMessages } = useChannelContext(); const { deletedMessagesVisibilityType, getMessagesGroupStyles = getGroupStyles } = useMessagesContext(); const { messages } = usePaginatedMessageListContext(); const { threadMessages } = useThreadContext(); const messageList = threadList ? threadMessages : messages; - const readList: ChannelState['read'] | undefined = threadList ? undefined : read; - - const readData = useLastReadData({ - messages: messageList, - read: readList, - userID: client.userID, - }); const dateSeparators = useMemo( () => @@ -119,7 +110,5 @@ export const useMessageList = (params: UseMessageListParams) => { processedMessageList, /** Raw messages from the channel state */ rawMessageList: messageList, - /** Read data */ - readData, }; }; diff --git a/package/src/components/MessageList/utils/getReadState.ts b/package/src/components/MessageList/utils/getReadState.ts new file mode 100644 index 0000000000..6b7821ca48 --- /dev/null +++ b/package/src/components/MessageList/utils/getReadState.ts @@ -0,0 +1,27 @@ +import { ChannelState, LocalMessage } from 'stream-chat'; + +/** + * Get the number of users who have read the message + * @param message - The message to get the read state for + * @param read - The read state of the channel + * @returns The number of users who have read the message + */ +export const getReadState = (message: LocalMessage, read?: ChannelState['read']) => { + if (!read) { + return 0; + } + + const readState = Object.values(read).reduce((acc, readState) => { + if (!readState.last_read) { + return acc; + } + + if (message.created_at && message.created_at < readState.last_read) { + return acc + 1; + } + + return acc; + }, 0); + + return readState; +}; diff --git a/package/src/components/MessageList/utils/getReadStates.ts b/package/src/components/MessageList/utils/getReadStates.ts deleted file mode 100644 index f8418b67ee..0000000000 --- a/package/src/components/MessageList/utils/getReadStates.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { ChannelState } from 'stream-chat'; - -import type { PaginatedMessageListContextValue } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext'; -import type { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext'; - -export const getReadStates = ( - messages: PaginatedMessageListContextValue['messages'] | ThreadContextValue['threadMessages'], - read?: ChannelState['read'], - returnAllReadData?: boolean, -) => { - const readData: Record = {}; - - if (read) { - /** - * Array is in reverse order so newest message is at 0, - * we find the index of the first message that is older - * than the last read and then set last read to that, or - * if there are no newer messages, the first message is - * last read message. - */ - Object.values(read).forEach((readState) => { - if (!readState.last_read) { - return; - } - - let userLastReadMsgId: string | undefined; - - // loop messages sent by current user and add read data for other users in channel - messages.forEach((msg) => { - if (msg.created_at && msg.created_at < readState.last_read) { - userLastReadMsgId = msg.id; - - if (returnAllReadData) { - // if true, save other user's read data for all messages they've read - if (!readData[userLastReadMsgId]) { - readData[userLastReadMsgId] = 0; - } - readData[userLastReadMsgId] = readData[userLastReadMsgId] + 1; - } - } - }); - - // if true, only save read data for other user's last read message - if (userLastReadMsgId && !returnAllReadData) { - if (!readData[userLastReadMsgId]) { - readData[userLastReadMsgId] = 0; - } - - readData[userLastReadMsgId] = readData[userLastReadMsgId] + 1; - } - }); - } - - return readData; -}; diff --git a/package/src/components/index.ts b/package/src/components/index.ts index 355e497b6d..8e45274fc2 100644 --- a/package/src/components/index.ts +++ b/package/src/components/index.ts @@ -148,7 +148,7 @@ export * from './MessageList/TypingIndicatorContainer'; export * from './MessageList/utils/getDateSeparators'; export * from './MessageList/utils/getGroupStyles'; export * from './MessageList/utils/getLastReceivedMessage'; -export * from './MessageList/utils/getReadStates'; +export * from './MessageList/utils/getReadState'; export * from './MessageMenu/MessageActionList'; export * from './MessageMenu/MessageActionListItem'; From 3038e7beddd22c392113e451ab2e4a29b9c55424 Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Fri, 25 Apr 2025 14:02:29 +0530 Subject: [PATCH 46/60] fix: change date separator and group styles to ref --- .../components/MessageList/MessageList.tsx | 17 +++++++------- .../MessageList/hooks/useMessageList.ts | 23 +++++++++++++------ .../MessageList/utils/getGroupStyles.ts | 2 +- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/package/src/components/MessageList/MessageList.tsx b/package/src/components/MessageList/MessageList.tsx index 37cb704d3d..a5fa2a9883 100644 --- a/package/src/components/MessageList/MessageList.tsx +++ b/package/src/components/MessageList/MessageList.tsx @@ -318,7 +318,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { * NOTE: rawMessageList changes only when messages array state changes * processedMessageList changes on any state change */ - const { dateSeparators, messageGroupStyles, processedMessageList, rawMessageList } = + const { dateSeparatorsRef, messageGroupStylesRef, processedMessageList, rawMessageList } = useMessageList({ noGroupByUser, threadList, @@ -493,7 +493,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { const onViewableItemsChanged = useRef(unstableOnViewableItemsChanged); onViewableItemsChanged.current = unstableOnViewableItemsChanged; - const stableOnViwableItemsChanged = useCallback( + const stableOnViewableItemsChanged = useCallback( ({ viewableItems }: { viewableItems: ViewToken[] | undefined }) => { onViewableItemsChanged.current({ viewableItems }); }, @@ -753,13 +753,14 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { const showUnreadUnderlay = !!shouldShowUnreadUnderlay && showUnreadSeparator; const wrapMessageInTheme = client.userID === message.user?.id && !!myMessageTheme; - const renderDateSeperator = dateSeparators[message.id] && ( - + const renderDateSeperator = dateSeparatorsRef.current[message.id] && ( + ); + const renderMessage = ( { channelUnreadState?.last_read_message_id, channelUnreadState?.unread_messages, client.userID, - dateSeparators, + dateSeparatorsRef, goToMessage, highlightedMessageId, lastReceivedId, messageContainer, - messageGroupStyles, + messageGroupStylesRef, modifiedTheme, myMessageTheme, onThreadSelect, @@ -1249,7 +1250,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => { onScrollEndDrag={onScrollEndDrag} onScrollToIndexFailed={onScrollToIndexFailedRef.current} onTouchEnd={dismissImagePicker} - onViewableItemsChanged={stableOnViwableItemsChanged} + onViewableItemsChanged={stableOnViewableItemsChanged} ref={refCallback} renderItem={renderItem} scrollEnabled={overlay === 'none'} diff --git a/package/src/components/MessageList/hooks/useMessageList.ts b/package/src/components/MessageList/hooks/useMessageList.ts index f7b3f30f91..3518ae1fd5 100644 --- a/package/src/components/MessageList/hooks/useMessageList.ts +++ b/package/src/components/MessageList/hooks/useMessageList.ts @@ -1,4 +1,4 @@ -import { useMemo } from 'react'; +import { useMemo, useRef } from 'react'; import type { LocalMessage } from 'stream-chat'; @@ -11,7 +11,7 @@ import { import { usePaginatedMessageListContext } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext'; import { useThreadContext } from '../../../contexts/threadContext/ThreadContext'; -import { getDateSeparators } from '../utils/getDateSeparators'; +import { DateSeparators, getDateSeparators } from '../utils/getDateSeparators'; import { getGroupStyles } from '../utils/getGroupStyles'; export type UseMessageListParams = { @@ -22,6 +22,10 @@ export type UseMessageListParams = { export type GroupType = string; +export type MessageGroupStyles = { + [key: string]: string[]; +}; + export const shouldIncludeMessageInList = ( message: LocalMessage, options: { deletedMessagesVisibilityType?: DeletedMessagesVisibilityType; userId?: string }, @@ -51,7 +55,6 @@ export const useMessageList = (params: UseMessageListParams) => { useMessagesContext(); const { messages } = usePaginatedMessageListContext(); const { threadMessages } = useThreadContext(); - const messageList = threadList ? threadMessages : messages; const dateSeparators = useMemo( @@ -65,10 +68,13 @@ export const useMessageList = (params: UseMessageListParams) => { [deletedMessagesVisibilityType, hideDateSeparators, messageList, client.userID], ); + const dateSeparatorsRef = useRef(dateSeparators); + dateSeparatorsRef.current = dateSeparators; + const messageGroupStyles = useMemo( () => getMessagesGroupStyles({ - dateSeparators, + dateSeparators: dateSeparatorsRef.current, hideDateSeparators, maxTimeBetweenGroupedMessages, messages: messageList, @@ -76,8 +82,8 @@ export const useMessageList = (params: UseMessageListParams) => { userId: client.userID, }), [ + dateSeparatorsRef, getMessagesGroupStyles, - dateSeparators, hideDateSeparators, maxTimeBetweenGroupedMessages, messageList, @@ -86,6 +92,9 @@ export const useMessageList = (params: UseMessageListParams) => { ], ); + const messageGroupStylesRef = useRef(messageGroupStyles); + messageGroupStylesRef.current = messageGroupStyles; + const processedMessageList = useMemo(() => { const newMessageList = []; for (const message of messageList) { @@ -103,9 +112,9 @@ export const useMessageList = (params: UseMessageListParams) => { return { /** Date separators */ - dateSeparators, + dateSeparatorsRef, /** Message group styles */ - messageGroupStyles, + messageGroupStylesRef, /** Messages enriched with dates/readby/groups and also reversed in order */ processedMessageList, /** Raw messages from the channel state */ diff --git a/package/src/components/MessageList/utils/getGroupStyles.ts b/package/src/components/MessageList/utils/getGroupStyles.ts index 5a8d93c0e5..19fbe4cbe1 100644 --- a/package/src/components/MessageList/utils/getGroupStyles.ts +++ b/package/src/components/MessageList/utils/getGroupStyles.ts @@ -40,7 +40,7 @@ const getGroupStyle = ( previousMessage.type === 'error' || userId !== previousMessage?.user?.id || !!isPrevMessageTypeDeleted || - (!hideDateSeparators && dateSeparators[message.id]) || + (!hideDateSeparators && dateSeparators[previousMessage.id]) || isEditedMessage(previousMessage); const isBottomMessage = From 54ce9c6cd6e4f28d071ae2458f38c5346d7e2430 Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Mon, 28 Apr 2025 11:39:12 +0530 Subject: [PATCH 47/60] fix: add app changes --- examples/SampleApp/App.tsx | 30 ++++++++----------- .../SampleApp/src/screens/ThreadScreen.tsx | 7 ++--- examples/SampleApp/src/types.ts | 6 ++-- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/examples/SampleApp/App.tsx b/examples/SampleApp/App.tsx index 467e316fac..1128c7bbf3 100644 --- a/examples/SampleApp/App.tsx +++ b/examples/SampleApp/App.tsx @@ -6,7 +6,6 @@ import { createStackNavigator } from '@react-navigation/stack'; import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context'; import { Chat, - MessageType, OverlayProvider, SqliteClient, ThemeProvider, @@ -36,7 +35,7 @@ import { SharedGroupsScreen } from './src/screens/SharedGroupsScreen'; import { ThreadScreen } from './src/screens/ThreadScreen'; import { UserSelectorScreen } from './src/screens/UserSelectorScreen'; -import type { StreamChat } from 'stream-chat'; +import type { LocalMessage, StreamChat } from 'stream-chat'; if (__DEV__) { DevSettings.addMenuItem('Reset local DB (offline storage)', () => { @@ -45,10 +44,7 @@ if (__DEV__) { }); } -import type { - StackNavigatorParamList, - UserSelectorParamList, -} from './src/types'; +import type { StackNavigatorParamList, UserSelectorParamList } from './src/types'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { navigateToChannel, RootNavigationRef } from './src/utils/RootNavigation'; import FastImage from 'react-native-fast-image'; @@ -106,18 +102,16 @@ const App = () => { } } }); - messaging - .getInitialNotification() - .then((remoteMessage) => { - if (remoteMessage) { - // Notification caused app to open from quit state on iOS - const channelId = remoteMessage.data?.channel_id as string; - if (channelId) { - // this will make the app to start with the channel screen with this channel id - initialChannelIdGlobalRef.current = channelId; - } + messaging.getInitialNotification().then((remoteMessage) => { + if (remoteMessage) { + // Notification caused app to open from quit state on iOS + const channelId = remoteMessage.data?.channel_id as string; + if (channelId) { + // this will make the app to start with the channel screen with this channel id + initialChannelIdGlobalRef.current = channelId; } - }); + } + }); return () => { unsubscribeOnNotificationOpen(); unsubscribeForegroundEvent(); @@ -170,7 +164,7 @@ const DrawerNavigator: React.FC = () => ( ); -const isMessageAIGenerated = (message: MessageType) => !!message.ai_generated; +const isMessageAIGenerated = (message: LocalMessage) => !!message.ai_generated; const DrawerNavigatorWrapper: React.FC<{ chatClient: StreamChat; diff --git a/examples/SampleApp/src/screens/ThreadScreen.tsx b/examples/SampleApp/src/screens/ThreadScreen.tsx index 56985986ac..9f7d27d75e 100644 --- a/examples/SampleApp/src/screens/ThreadScreen.tsx +++ b/examples/SampleApp/src/screens/ThreadScreen.tsx @@ -3,7 +3,6 @@ import { StyleSheet, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { Channel, - MessageType, Thread, ThreadType, useAttachmentPickerContext, @@ -17,7 +16,7 @@ import { ScreenHeader } from '../components/ScreenHeader'; import type { RouteProp } from '@react-navigation/native'; import type { StackNavigatorParamList } from '../types'; -import { ThreadState, UserResponse } from 'stream-chat'; +import { LocalMessage, ThreadState, UserResponse } from 'stream-chat'; const selector = (nextValue: ThreadState) => ({ parentMessage: nextValue.parentMessage }) as const; @@ -34,12 +33,12 @@ type ThreadScreenProps = { }; export type ThreadHeaderProps = { - thread: MessageType | ThreadType; + thread: LocalMessage | ThreadType; }; const ThreadHeader: React.FC = ({ thread }) => { const typing = useTypingString(); - let subtitleText = ((thread as MessageType)?.user as UserResponse)?.name; + let subtitleText = ((thread as LocalMessage)?.user as UserResponse)?.name; const { parentMessage } = useStateStore((thread as ThreadType)?.threadInstance?.state, selector) || {}; diff --git a/examples/SampleApp/src/types.ts b/examples/SampleApp/src/types.ts index 762f90ec7d..aeec68cf85 100644 --- a/examples/SampleApp/src/types.ts +++ b/examples/SampleApp/src/types.ts @@ -1,5 +1,5 @@ -import type { Channel, UserResponse } from 'stream-chat'; -import type { MessageType, ThreadType } from 'stream-chat-react-native'; +import type { Channel, LocalMessage, UserResponse } from 'stream-chat'; +import type { ThreadType } from 'stream-chat-react-native'; import type { Theme } from '@react-navigation/native'; export type DrawerNavigatorParamList = { @@ -38,7 +38,7 @@ export type StackNavigatorParamList = { }; ThreadScreen: { channel: Channel; - thread: MessageType | ThreadType; + thread: LocalMessage | ThreadType; }; }; From 5f62753fe9e5a1dab59f9e52200403cd53d53403 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Mon, 28 Apr 2025 22:06:10 +0200 Subject: [PATCH 48/60] fix: bump stream-chat to latest rc --- examples/SampleApp/ios/Podfile.lock | 8 ++++---- examples/SampleApp/yarn.lock | 7 ++++--- package/expo-package/yarn.lock | 7 ++++--- package/native-package/yarn.lock | 7 ++++--- package/package.json | 2 +- package/yarn.lock | 7 ++++--- 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/examples/SampleApp/ios/Podfile.lock b/examples/SampleApp/ios/Podfile.lock index c732d5ddd0..269ca91dd2 100644 --- a/examples/SampleApp/ios/Podfile.lock +++ b/examples/SampleApp/ios/Podfile.lock @@ -2234,7 +2234,7 @@ PODS: - libwebp (~> 1.0) - SDWebImage/Core (~> 5.10) - SocketRocket (0.7.1) - - stream-chat-react-native (6.6.8): + - stream-chat-react-native (6.7.3): - DoubleConversion - glog - hermes-engine @@ -2581,7 +2581,7 @@ SPEC CHECKSUMS: op-sqlite: c33561ea312a2ae38aae032fd3a42635dc6b57e8 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 - RCT-Folly: e78785aa9ba2ed998ea4151e314036f6c49e6d82 + RCT-Folly: 36fe2295e44b10d831836cc0d1daec5f8abcf809 RCTDeprecation: b2eecf2d60216df56bc5e6be5f063826d3c1ee35 RCTRequired: 78522de7dc73b81f3ed7890d145fa341f5bb32ea RCTTypeSafety: c135dd2bf50402d87fd12884cbad5d5e64850edd @@ -2662,9 +2662,9 @@ SPEC CHECKSUMS: SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - stream-chat-react-native: aa6626ef9dd68e28b1239c9f2ee2fc7ce1fd3c3f + stream-chat-react-native: e6555aac04d25ad09d9f219360dda7a00eb0d9d1 Yoga: be02ca501b03c79d7027a6bbbd0a8db985034f11 PODFILE CHECKSUM: 4f662370295f8f9cee909f1a4c59a614999a209d -COCOAPODS: 1.14.3 +COCOAPODS: 1.16.2 diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index 27f23dcb57..1849ff7e4e 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -7548,9 +7548,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": - version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" +stream-chat@9.0.0-rc.11: + version "9.0.0-rc.11" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.11.tgz#14d0d06a2eb330ef62fbde8ceb9d73e013412d2e" + integrity sha512-6ghT2MJu20twYxLktO30Hqiu6YpyLYY6i0ZTVxl5M3AxuZ5yf4FwU00T/wtyJPcssVF01A0fASZ8Ts1Hi2LLxQ== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 80740ce589..15a9bfa49a 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -4782,9 +4782,10 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936": - version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936" +stream-chat@9.0.0-rc.11: + version "9.0.0-rc.11" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.11.tgz#14d0d06a2eb330ef62fbde8ceb9d73e013412d2e" + integrity sha512-6ghT2MJu20twYxLktO30Hqiu6YpyLYY6i0ZTVxl5M3AxuZ5yf4FwU00T/wtyJPcssVF01A0fASZ8Ts1Hi2LLxQ== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 3a82da419d..c3aed8f335 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -3498,9 +3498,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936": - version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936" +stream-chat@9.0.0-rc.11: + version "9.0.0-rc.11" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.11.tgz#14d0d06a2eb330ef62fbde8ceb9d73e013412d2e" + integrity sha512-6ghT2MJu20twYxLktO30Hqiu6YpyLYY6i0ZTVxl5M3AxuZ5yf4FwU00T/wtyJPcssVF01A0fASZ8Ts1Hi2LLxQ== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/package.json b/package/package.json index f253289a7e..e2dd2c5bad 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936", + "stream-chat": "9.0.0-rc.11", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/yarn.lock b/package/yarn.lock index a13e2edd2e..800e7baf63 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -7772,9 +7772,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -"stream-chat@https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936": - version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#4ff638045e434cc091a1200ecff4749b428d6936" +stream-chat@9.0.0-rc.11: + version "9.0.0-rc.11" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.11.tgz#14d0d06a2eb330ef62fbde8ceb9d73e013412d2e" + integrity sha512-6ghT2MJu20twYxLktO30Hqiu6YpyLYY6i0ZTVxl5M3AxuZ5yf4FwU00T/wtyJPcssVF01A0fASZ8Ts1Hi2LLxQ== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" From e14c614613aeb9e679a3d37bb3bbae3e86a8650f Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 29 Apr 2025 11:19:22 +0200 Subject: [PATCH 49/60] chore: bump stream-chat version to latest rc again --- examples/SampleApp/yarn.lock | 8 ++++---- package/expo-package/yarn.lock | 8 ++++---- package/native-package/yarn.lock | 8 ++++---- package/package.json | 2 +- package/yarn.lock | 8 ++++---- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index 1849ff7e4e..c8212b882b 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -7548,10 +7548,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.11: - version "9.0.0-rc.11" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.11.tgz#14d0d06a2eb330ef62fbde8ceb9d73e013412d2e" - integrity sha512-6ghT2MJu20twYxLktO30Hqiu6YpyLYY6i0ZTVxl5M3AxuZ5yf4FwU00T/wtyJPcssVF01A0fASZ8Ts1Hi2LLxQ== +stream-chat@9.0.0-rc.13: + version "9.0.0-rc.13" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.13.tgz#90396d724bd5f81e2d8eb051c9c56b075892305f" + integrity sha512-qJPcHsQUfu0qMb7p7Bv9OnL6qID/qxYLKOIsG6KbUNEQHwkKSw/aDwExpvgJR7dXsUOLyLZFhVtYnFkAPDdJ3A== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 15a9bfa49a..9890717606 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -4782,10 +4782,10 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.11: - version "9.0.0-rc.11" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.11.tgz#14d0d06a2eb330ef62fbde8ceb9d73e013412d2e" - integrity sha512-6ghT2MJu20twYxLktO30Hqiu6YpyLYY6i0ZTVxl5M3AxuZ5yf4FwU00T/wtyJPcssVF01A0fASZ8Ts1Hi2LLxQ== +stream-chat@9.0.0-rc.13: + version "9.0.0-rc.13" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.13.tgz#90396d724bd5f81e2d8eb051c9c56b075892305f" + integrity sha512-qJPcHsQUfu0qMb7p7Bv9OnL6qID/qxYLKOIsG6KbUNEQHwkKSw/aDwExpvgJR7dXsUOLyLZFhVtYnFkAPDdJ3A== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index c3aed8f335..8bf1419659 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -3498,10 +3498,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.11: - version "9.0.0-rc.11" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.11.tgz#14d0d06a2eb330ef62fbde8ceb9d73e013412d2e" - integrity sha512-6ghT2MJu20twYxLktO30Hqiu6YpyLYY6i0ZTVxl5M3AxuZ5yf4FwU00T/wtyJPcssVF01A0fASZ8Ts1Hi2LLxQ== +stream-chat@9.0.0-rc.13: + version "9.0.0-rc.13" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.13.tgz#90396d724bd5f81e2d8eb051c9c56b075892305f" + integrity sha512-qJPcHsQUfu0qMb7p7Bv9OnL6qID/qxYLKOIsG6KbUNEQHwkKSw/aDwExpvgJR7dXsUOLyLZFhVtYnFkAPDdJ3A== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/package.json b/package/package.json index e2dd2c5bad..4c98ea2e4f 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "9.0.0-rc.11", + "stream-chat": "9.0.0-rc.13", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/yarn.lock b/package/yarn.lock index 800e7baf63..599c399294 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -7772,10 +7772,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat@9.0.0-rc.11: - version "9.0.0-rc.11" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.11.tgz#14d0d06a2eb330ef62fbde8ceb9d73e013412d2e" - integrity sha512-6ghT2MJu20twYxLktO30Hqiu6YpyLYY6i0ZTVxl5M3AxuZ5yf4FwU00T/wtyJPcssVF01A0fASZ8Ts1Hi2LLxQ== +stream-chat@9.0.0-rc.13: + version "9.0.0-rc.13" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.13.tgz#90396d724bd5f81e2d8eb051c9c56b075892305f" + integrity sha512-qJPcHsQUfu0qMb7p7Bv9OnL6qID/qxYLKOIsG6KbUNEQHwkKSw/aDwExpvgJR7dXsUOLyLZFhVtYnFkAPDdJ3A== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" From 8467b2256ce9aaff0b5fac8cffe72d0e6571e12c Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 29 Apr 2025 12:51:22 +0200 Subject: [PATCH 50/60] fix: thread messages state not updating properly --- .../src/contexts/channelsStateContext/useChannelState.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/package/src/contexts/channelsStateContext/useChannelState.ts b/package/src/contexts/channelsStateContext/useChannelState.ts index ae29f4d14f..348571c262 100644 --- a/package/src/contexts/channelsStateContext/useChannelState.ts +++ b/package/src/contexts/channelsStateContext/useChannelState.ts @@ -1,6 +1,6 @@ import { useCallback, useMemo } from 'react'; -import type { Channel as ChannelType } from 'stream-chat'; +import type { Channel as ChannelType, LocalMessage } from 'stream-chat'; import { useChannelsStateContext } from './ChannelsStateContext'; @@ -45,7 +45,7 @@ export function useChannelState( const cid = channel?.id || 'id'; // in case channel is not initialized, use generic id string for indexing const { setState, state } = useChannelsStateContext(); - const [threadMessages, setThreadMessages] = useStateManager( + const [threadMessages, setThreadMessagesInternal] = useStateManager( { cid, key: 'threadMessages', @@ -54,6 +54,10 @@ export function useChannelState( }, (threadId && channel?.state?.threads?.[threadId]) || [], ); + const setThreadMessages = useCallback( + (value: LocalMessage[]) => setThreadMessagesInternal([...value]), + [setThreadMessagesInternal], + ); return { setThreadMessages, From 33d158a3127e4ff5353abb0a2423e7c82c73b704 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 29 Apr 2025 13:05:23 +0200 Subject: [PATCH 51/60] chore: change type to inferred one --- package/src/contexts/channelsStateContext/useChannelState.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/src/contexts/channelsStateContext/useChannelState.ts b/package/src/contexts/channelsStateContext/useChannelState.ts index 348571c262..8500a90f18 100644 --- a/package/src/contexts/channelsStateContext/useChannelState.ts +++ b/package/src/contexts/channelsStateContext/useChannelState.ts @@ -1,6 +1,6 @@ import { useCallback, useMemo } from 'react'; -import type { Channel as ChannelType, LocalMessage } from 'stream-chat'; +import type { Channel as ChannelType } from 'stream-chat'; import { useChannelsStateContext } from './ChannelsStateContext'; @@ -55,7 +55,7 @@ export function useChannelState( (threadId && channel?.state?.threads?.[threadId]) || [], ); const setThreadMessages = useCallback( - (value: LocalMessage[]) => setThreadMessagesInternal([...value]), + (value: ChannelState['threadMessages']) => setThreadMessagesInternal([...value]), [setThreadMessagesInternal], ); From 948b6db67b5b0a758b48239e19e1e1d30051deb0 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 29 Apr 2025 14:27:41 +0200 Subject: [PATCH 52/60] fix: set correct core lib versions --- package/expo-package/package.json | 2 +- package/expo-package/yarn.lock | 87 +++++++++++++++++------------ package/native-package/package.json | 2 +- package/native-package/yarn.lock | 82 +++++++++++++++------------ 4 files changed, 101 insertions(+), 72 deletions(-) diff --git a/package/expo-package/package.json b/package/expo-package/package.json index 3f400da66e..0156009610 100644 --- a/package/expo-package/package.json +++ b/package/expo-package/package.json @@ -11,7 +11,7 @@ "types": "types/index.d.ts", "dependencies": { "mime": "^4.0.7", - "stream-chat-react-native-core": "link:../" + "stream-chat-react-native-core": "6.7.3" }, "peerDependencies": { "expo": ">=51.0.0", diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 9890717606..fb2bf5c35a 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -1101,6 +1101,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.27.0": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762" + integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.8.4": version "7.26.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.9.tgz#aa4c6facc65b9cb3f87d75125ffd47781b475433" @@ -1788,7 +1795,7 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== -"@types/jsonwebtoken@^9.0.8": +"@types/jsonwebtoken@~9.0.0": version "9.0.9" resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3" integrity sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ== @@ -1820,10 +1827,10 @@ dependencies: csstype "^3.0.2" -"@types/ws@^8.5.14": - version "8.18.0" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" - integrity sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw== +"@types/ws@^7.4.0": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== dependencies: "@types/node" "*" @@ -3350,10 +3357,10 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isomorphic-ws@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" - integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== jackspeak@^3.1.2: version "3.4.0" @@ -3460,7 +3467,7 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonwebtoken@^9.0.2: +jsonwebtoken@~9.0.0: version "9.0.2" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== @@ -3589,11 +3596,6 @@ linkifyjs@^4.1.1: resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.1.tgz#73d427e3bbaaf4ca8e71c589ad4ffda11a9a5fde" integrity sha512-zFN/CTVmbcVef+WaDXT63dNzzkfRBKT1j464NJQkV7iSgJU0sLBus9W0HBwnXK13/hf168pbrx/V/bjEHOXNHA== -linkifyjs@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" - integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -4778,24 +4780,39 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" integrity sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg== -"stream-chat-react-native-core@link:..": - version "0.0.0" - uid "" - -stream-chat@9.0.0-rc.13: - version "9.0.0-rc.13" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.13.tgz#90396d724bd5f81e2d8eb051c9c56b075892305f" - integrity sha512-qJPcHsQUfu0qMb7p7Bv9OnL6qID/qxYLKOIsG6KbUNEQHwkKSw/aDwExpvgJR7dXsUOLyLZFhVtYnFkAPDdJ3A== - dependencies: - "@types/jsonwebtoken" "^9.0.8" - "@types/ws" "^8.5.14" +stream-chat-react-native-core@6.7.3: + version "6.7.3" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" + integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== + dependencies: + "@gorhom/bottom-sheet" "^5.1.1" + dayjs "1.10.5" + emoji-regex "^10.3.0" + i18next "^21.6.14" + intl-pluralrules "^2.0.1" + linkifyjs "^4.1.1" + lodash-es "4.17.21" + mime-types "^2.1.34" + path "0.12.7" + react-native-markdown-package "1.8.2" + react-native-url-polyfill "^1.3.0" + stream-chat "^8.57.6" + use-sync-external-store "^1.4.0" + +stream-chat@^8.57.6: + version "8.60.0" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.60.0.tgz#b67d4fbb185da53fb8ac5fc5759986d6ad7e19a3" + integrity sha512-7FpO7Wno++r+n+x9aFuXtGYtNO06CIMd2Bxe3doYZLhMfS0nuaXloeFlGcMT0r4U/6bnguz1qQdDJUPNQAS8bQ== + dependencies: + "@babel/runtime" "^7.27.0" + "@types/jsonwebtoken" "~9.0.0" + "@types/ws" "^7.4.0" axios "^1.6.0" base64-js "^1.5.1" form-data "^4.0.0" - isomorphic-ws "^5.0.0" - jsonwebtoken "^9.0.2" - linkifyjs "^4.2.0" - ws "^8.18.1" + isomorphic-ws "^4.0.1" + jsonwebtoken "~9.0.0" + ws "^7.5.10" "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" @@ -5266,16 +5283,16 @@ ws@^6.2.3: dependencies: async-limiter "~1.0.0" +ws@^7.5.10: + version "7.5.10" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== + ws@^8.12.1: version "8.17.1" resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== -ws@^8.18.1: - version "8.18.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" - integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== - xcode@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/xcode/-/xcode-3.0.1.tgz#3efb62aac641ab2c702458f9a0302696146aa53c" diff --git a/package/native-package/package.json b/package/native-package/package.json index 1171d22bd6..aeab66435e 100644 --- a/package/native-package/package.json +++ b/package/native-package/package.json @@ -21,7 +21,7 @@ "dependencies": { "es6-symbol": "^3.1.4", "mime": "^4.0.7", - "stream-chat-react-native-core": "link:../" + "stream-chat-react-native-core": "6.7.3" }, "peerDependencies": { "@react-native-camera-roll/camera-roll": ">=7.8.0", diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 8bf1419659..1787a7c892 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -773,6 +773,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.27.0": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762" + integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.8.4": version "7.25.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb" @@ -1245,7 +1252,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jsonwebtoken@^9.0.8": +"@types/jsonwebtoken@~9.0.0": version "9.0.9" resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3" integrity sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ== @@ -1282,10 +1289,10 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== -"@types/ws@^8.5.14": - version "8.18.0" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" - integrity sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw== +"@types/ws@^7.4.0": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== dependencies: "@types/node" "*" @@ -2277,10 +2284,10 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isomorphic-ws@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" - integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== istanbul-lib-coverage@^3.2.0: version "3.2.2" @@ -2464,7 +2471,7 @@ json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonwebtoken@^9.0.2: +jsonwebtoken@~9.0.0: version "9.0.2" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== @@ -2520,11 +2527,6 @@ linkifyjs@^4.1.1: resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.1.tgz#73d427e3bbaaf4ca8e71c589ad4ffda11a9a5fde" integrity sha512-zFN/CTVmbcVef+WaDXT63dNzzkfRBKT1j464NJQkV7iSgJU0sLBus9W0HBwnXK13/hf168pbrx/V/bjEHOXNHA== -linkifyjs@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.2.0.tgz#9dd30222b9cbabec9c950e725ec00031c7fa3f08" - integrity sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw== - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -3494,24 +3496,39 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -"stream-chat-react-native-core@link:..": - version "0.0.0" - uid "" - -stream-chat@9.0.0-rc.13: - version "9.0.0-rc.13" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.13.tgz#90396d724bd5f81e2d8eb051c9c56b075892305f" - integrity sha512-qJPcHsQUfu0qMb7p7Bv9OnL6qID/qxYLKOIsG6KbUNEQHwkKSw/aDwExpvgJR7dXsUOLyLZFhVtYnFkAPDdJ3A== - dependencies: - "@types/jsonwebtoken" "^9.0.8" - "@types/ws" "^8.5.14" +stream-chat-react-native-core@6.7.3: + version "6.7.3" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" + integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== + dependencies: + "@gorhom/bottom-sheet" "^5.1.1" + dayjs "1.10.5" + emoji-regex "^10.3.0" + i18next "^21.6.14" + intl-pluralrules "^2.0.1" + linkifyjs "^4.1.1" + lodash-es "4.17.21" + mime-types "^2.1.34" + path "0.12.7" + react-native-markdown-package "1.8.2" + react-native-url-polyfill "^1.3.0" + stream-chat "^8.57.6" + use-sync-external-store "^1.4.0" + +stream-chat@^8.57.6: + version "8.60.0" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.60.0.tgz#b67d4fbb185da53fb8ac5fc5759986d6ad7e19a3" + integrity sha512-7FpO7Wno++r+n+x9aFuXtGYtNO06CIMd2Bxe3doYZLhMfS0nuaXloeFlGcMT0r4U/6bnguz1qQdDJUPNQAS8bQ== + dependencies: + "@babel/runtime" "^7.27.0" + "@types/jsonwebtoken" "~9.0.0" + "@types/ws" "^7.4.0" axios "^1.6.0" base64-js "^1.5.1" form-data "^4.0.0" - isomorphic-ws "^5.0.0" - jsonwebtoken "^9.0.2" - linkifyjs "^4.2.0" - ws "^8.18.1" + isomorphic-ws "^4.0.1" + jsonwebtoken "~9.0.0" + ws "^7.5.10" string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" @@ -3767,11 +3784,6 @@ ws@^7.5.10: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== -ws@^8.18.1: - version "8.18.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" - integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" From 77369b6b33d2e0acef0e084f9faf848ae99e38ae Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 29 Apr 2025 16:49:02 +0200 Subject: [PATCH 53/60] chore: bump stream-chat to latest rc again --- package/package.json | 2 +- package/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package/package.json b/package/package.json index 4c98ea2e4f..add95cc934 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "9.0.0-rc.13", + "stream-chat": "9.0.0-rc.14", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/yarn.lock b/package/yarn.lock index 599c399294..f40928f7b6 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -7772,10 +7772,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat@9.0.0-rc.13: - version "9.0.0-rc.13" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.13.tgz#90396d724bd5f81e2d8eb051c9c56b075892305f" - integrity sha512-qJPcHsQUfu0qMb7p7Bv9OnL6qID/qxYLKOIsG6KbUNEQHwkKSw/aDwExpvgJR7dXsUOLyLZFhVtYnFkAPDdJ3A== +stream-chat@9.0.0-rc.14: + version "9.0.0-rc.14" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.14.tgz#dd004add99e4fae24ec912f92bcb5487aa57a06f" + integrity sha512-dmRSWXkMljW+FNfui/Jy//Dn8ALWvNN25yaXaF4mcGgK5J+Qzq8mkK+YNeqp6VB3rVrotfFEGJk8Ma8FDhsFmA== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" From 75117d5b618b5df52ca3e3469d88f8809cc23777 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 29 Apr 2025 16:55:42 +0200 Subject: [PATCH 54/60] chore: update sample app yarn.locks as well --- examples/ExpoMessaging/yarn.lock | 64 ++++++++++++++++++++++-- examples/SampleApp/yarn.lock | 65 +++++++++++++++++++++--- examples/TypeScriptMessaging/yarn.lock | 69 ++++++++++++++++++++++++-- 3 files changed, 182 insertions(+), 16 deletions(-) diff --git a/examples/ExpoMessaging/yarn.lock b/examples/ExpoMessaging/yarn.lock index 3c8557230b..d1ccbb7dc6 100644 --- a/examples/ExpoMessaging/yarn.lock +++ b/examples/ExpoMessaging/yarn.lock @@ -1521,6 +1521,13 @@ dependencies: regenerator-runtime "^0.13.11" +"@babel/runtime@^7.27.0": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762" + integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.20.7", "@babel/template@^7.21.9": version "7.21.9" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.21.9.tgz#bf8dad2859130ae46088a99c1f265394877446fb" @@ -2881,7 +2888,7 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/jsonwebtoken@^9.0.8": +"@types/jsonwebtoken@^9.0.8", "@types/jsonwebtoken@~9.0.0": version "9.0.9" resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3" integrity sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ== @@ -2918,6 +2925,13 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== +"@types/ws@^7.4.0": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== + dependencies: + "@types/node" "*" + "@types/ws@^8.5.14": version "8.18.0" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" @@ -5142,6 +5156,11 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + isomorphic-ws@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" @@ -5401,7 +5420,7 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonwebtoken@^9.0.2: +jsonwebtoken@^9.0.2, jsonwebtoken@~9.0.0: version "9.0.2" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== @@ -7403,13 +7422,33 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" +stream-chat-react-native-core@6.7.3: + version "6.7.3" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" + integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== + dependencies: + "@gorhom/bottom-sheet" "^5.1.1" + dayjs "1.10.5" + emoji-regex "^10.3.0" + i18next "^21.6.14" + intl-pluralrules "^2.0.1" + linkifyjs "^4.1.1" + lodash-es "4.17.21" + mime-types "^2.1.34" + path "0.12.7" + react-native-markdown-package "1.8.2" + react-native-url-polyfill "^1.3.0" + stream-chat "^8.57.6" + use-sync-external-store "^1.4.0" + "stream-chat-react-native-core@link:../../package": version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": - version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" +stream-chat@9.0.0-rc.14: + version "9.0.0-rc.14" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.14.tgz#dd004add99e4fae24ec912f92bcb5487aa57a06f" + integrity sha512-dmRSWXkMljW+FNfui/Jy//Dn8ALWvNN25yaXaF4mcGgK5J+Qzq8mkK+YNeqp6VB3rVrotfFEGJk8Ma8FDhsFmA== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -7421,6 +7460,21 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: linkifyjs "^4.2.0" ws "^8.18.1" +stream-chat@^8.57.6: + version "8.60.0" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.60.0.tgz#b67d4fbb185da53fb8ac5fc5759986d6ad7e19a3" + integrity sha512-7FpO7Wno++r+n+x9aFuXtGYtNO06CIMd2Bxe3doYZLhMfS0nuaXloeFlGcMT0r4U/6bnguz1qQdDJUPNQAS8bQ== + dependencies: + "@babel/runtime" "^7.27.0" + "@types/jsonwebtoken" "~9.0.0" + "@types/ws" "^7.4.0" + axios "^1.6.0" + base64-js "^1.5.1" + form-data "^4.0.0" + isomorphic-ws "^4.0.1" + jsonwebtoken "~9.0.0" + ws "^7.5.10" + stream-slice@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/stream-slice/-/stream-slice-0.1.2.tgz#2dc4f4e1b936fb13f3eb39a2def1932798d07a4b" diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index c8212b882b..7b62d81752 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -996,6 +996,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.27.0": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762" + integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.25.0", "@babel/template@^7.25.9", "@babel/template@^7.26.9", "@babel/template@^7.3.3": version "7.26.9" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.26.9.tgz#4577ad3ddf43d194528cff4e1fa6b232fa609bb2" @@ -2558,7 +2565,7 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/jsonwebtoken@^9.0.8": +"@types/jsonwebtoken@^9.0.8", "@types/jsonwebtoken@~9.0.0": version "9.0.9" resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3" integrity sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ== @@ -2609,6 +2616,13 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== +"@types/ws@^7.4.0": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== + dependencies: + "@types/node" "*" + "@types/ws@^8.5.14": version "8.18.0" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" @@ -5224,6 +5238,11 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + isomorphic-ws@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" @@ -5768,7 +5787,7 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonwebtoken@^9.0.2: +jsonwebtoken@^9.0.2, jsonwebtoken@~9.0.0: version "9.0.2" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== @@ -7540,6 +7559,25 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +stream-chat-react-native-core@6.7.3: + version "6.7.3" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" + integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== + dependencies: + "@gorhom/bottom-sheet" "^5.1.1" + dayjs "1.10.5" + emoji-regex "^10.3.0" + i18next "^21.6.14" + intl-pluralrules "^2.0.1" + linkifyjs "^4.1.1" + lodash-es "4.17.21" + mime-types "^2.1.34" + path "0.12.7" + react-native-markdown-package "1.8.2" + react-native-url-polyfill "^1.3.0" + stream-chat "^8.57.6" + use-sync-external-store "^1.4.0" + "stream-chat-react-native-core@link:../../package": version "0.0.0" uid "" @@ -7548,10 +7586,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.13: - version "9.0.0-rc.13" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.13.tgz#90396d724bd5f81e2d8eb051c9c56b075892305f" - integrity sha512-qJPcHsQUfu0qMb7p7Bv9OnL6qID/qxYLKOIsG6KbUNEQHwkKSw/aDwExpvgJR7dXsUOLyLZFhVtYnFkAPDdJ3A== +stream-chat@9.0.0-rc.14: + version "9.0.0-rc.14" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.14.tgz#dd004add99e4fae24ec912f92bcb5487aa57a06f" + integrity sha512-dmRSWXkMljW+FNfui/Jy//Dn8ALWvNN25yaXaF4mcGgK5J+Qzq8mkK+YNeqp6VB3rVrotfFEGJk8Ma8FDhsFmA== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -7563,6 +7601,21 @@ stream-chat@9.0.0-rc.13: linkifyjs "^4.2.0" ws "^8.18.1" +stream-chat@^8.57.6: + version "8.60.0" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.60.0.tgz#b67d4fbb185da53fb8ac5fc5759986d6ad7e19a3" + integrity sha512-7FpO7Wno++r+n+x9aFuXtGYtNO06CIMd2Bxe3doYZLhMfS0nuaXloeFlGcMT0r4U/6bnguz1qQdDJUPNQAS8bQ== + dependencies: + "@babel/runtime" "^7.27.0" + "@types/jsonwebtoken" "~9.0.0" + "@types/ws" "^7.4.0" + axios "^1.6.0" + base64-js "^1.5.1" + form-data "^4.0.0" + isomorphic-ws "^4.0.1" + jsonwebtoken "~9.0.0" + ws "^7.5.10" + strict-uri-encode@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" diff --git a/examples/TypeScriptMessaging/yarn.lock b/examples/TypeScriptMessaging/yarn.lock index 7643827d31..08a7d6918c 100644 --- a/examples/TypeScriptMessaging/yarn.lock +++ b/examples/TypeScriptMessaging/yarn.lock @@ -996,6 +996,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.27.0": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762" + integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.25.0", "@babel/template@^7.25.9", "@babel/template@^7.26.9", "@babel/template@^7.3.3": version "7.26.9" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.26.9.tgz#4577ad3ddf43d194528cff4e1fa6b232fa609bb2" @@ -2047,7 +2054,7 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/jsonwebtoken@^9.0.8": +"@types/jsonwebtoken@^9.0.8", "@types/jsonwebtoken@~9.0.0": version "9.0.9" resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3" integrity sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ== @@ -2098,6 +2105,13 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== +"@types/ws@^7.4.0": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== + dependencies: + "@types/node" "*" + "@types/ws@^8.5.14": version "8.18.0" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" @@ -4657,6 +4671,11 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + isomorphic-ws@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" @@ -5201,7 +5220,7 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonwebtoken@^9.0.2: +jsonwebtoken@^9.0.2, jsonwebtoken@~9.0.0: version "9.0.2" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== @@ -5689,6 +5708,11 @@ mime@^2.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== +mime@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" + integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -6921,6 +6945,25 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +stream-chat-react-native-core@6.7.3: + version "6.7.3" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" + integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== + dependencies: + "@gorhom/bottom-sheet" "^5.1.1" + dayjs "1.10.5" + emoji-regex "^10.3.0" + i18next "^21.6.14" + intl-pluralrules "^2.0.1" + linkifyjs "^4.1.1" + lodash-es "4.17.21" + mime-types "^2.1.34" + path "0.12.7" + react-native-markdown-package "1.8.2" + react-native-url-polyfill "^1.3.0" + stream-chat "^8.57.6" + use-sync-external-store "^1.4.0" + "stream-chat-react-native-core@link:../../package": version "0.0.0" uid "" @@ -6929,9 +6972,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -"stream-chat@https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917": - version "0.0.0-development" - resolved "https://github.com/GetStream/stream-chat-js.git#9bc79358e9d0a23e0ff7e2a056711289e5bdf917" +stream-chat@9.0.0-rc.14: + version "9.0.0-rc.14" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.14.tgz#dd004add99e4fae24ec912f92bcb5487aa57a06f" + integrity sha512-dmRSWXkMljW+FNfui/Jy//Dn8ALWvNN25yaXaF4mcGgK5J+Qzq8mkK+YNeqp6VB3rVrotfFEGJk8Ma8FDhsFmA== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" @@ -6943,6 +6987,21 @@ statuses@~1.5.0: linkifyjs "^4.2.0" ws "^8.18.1" +stream-chat@^8.57.6: + version "8.60.0" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.60.0.tgz#b67d4fbb185da53fb8ac5fc5759986d6ad7e19a3" + integrity sha512-7FpO7Wno++r+n+x9aFuXtGYtNO06CIMd2Bxe3doYZLhMfS0nuaXloeFlGcMT0r4U/6bnguz1qQdDJUPNQAS8bQ== + dependencies: + "@babel/runtime" "^7.27.0" + "@types/jsonwebtoken" "~9.0.0" + "@types/ws" "^7.4.0" + axios "^1.6.0" + base64-js "^1.5.1" + form-data "^4.0.0" + isomorphic-ws "^4.0.1" + jsonwebtoken "~9.0.0" + ws "^7.5.10" + strict-uri-encode@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" From 10d934c00227ed198e205609ffbc0eb3781196c2 Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Wed, 30 Apr 2025 13:51:25 +0530 Subject: [PATCH 55/60] fix: keyboard taking full screen issue when the prefer cross-fade transition setting is enabled (#3073) * fix: respect the hasCommand channel prop as well * fix: keybaord taking full screen issue when the prefer cross-fade transition setting is enabled (#3072) * fix: keybaord taking full screen issue when the prefer cross-fade transition setting is enabled --- examples/SampleApp/yarn.lock | 19 ----------------- package/expo-package/yarn.lock | 21 +++---------------- package/native-package/yarn.lock | 21 +++---------------- package/src/components/Channel/Channel.tsx | 3 ++- .../KeyboardCompatibleView.tsx | 7 ++++++- 5 files changed, 14 insertions(+), 57 deletions(-) diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index 7b62d81752..75a203edc2 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -7559,25 +7559,6 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat-react-native-core@6.7.3: - version "6.7.3" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" - integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== - dependencies: - "@gorhom/bottom-sheet" "^5.1.1" - dayjs "1.10.5" - emoji-regex "^10.3.0" - i18next "^21.6.14" - intl-pluralrules "^2.0.1" - linkifyjs "^4.1.1" - lodash-es "4.17.21" - mime-types "^2.1.34" - path "0.12.7" - react-native-markdown-package "1.8.2" - react-native-url-polyfill "^1.3.0" - stream-chat "^8.57.6" - use-sync-external-store "^1.4.0" - "stream-chat-react-native-core@link:../../package": version "0.0.0" uid "" diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index fb2bf5c35a..65ca0901ba 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -4780,24 +4780,9 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" integrity sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg== -stream-chat-react-native-core@6.7.3: - version "6.7.3" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" - integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== - dependencies: - "@gorhom/bottom-sheet" "^5.1.1" - dayjs "1.10.5" - emoji-regex "^10.3.0" - i18next "^21.6.14" - intl-pluralrules "^2.0.1" - linkifyjs "^4.1.1" - lodash-es "4.17.21" - mime-types "^2.1.34" - path "0.12.7" - react-native-markdown-package "1.8.2" - react-native-url-polyfill "^1.3.0" - stream-chat "^8.57.6" - use-sync-external-store "^1.4.0" +"stream-chat-react-native-core@link:..": + version "0.0.0" + uid "" stream-chat@^8.57.6: version "8.60.0" diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 1787a7c892..a1ab68494b 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -3496,24 +3496,9 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat-react-native-core@6.7.3: - version "6.7.3" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" - integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== - dependencies: - "@gorhom/bottom-sheet" "^5.1.1" - dayjs "1.10.5" - emoji-regex "^10.3.0" - i18next "^21.6.14" - intl-pluralrules "^2.0.1" - linkifyjs "^4.1.1" - lodash-es "4.17.21" - mime-types "^2.1.34" - path "0.12.7" - react-native-markdown-package "1.8.2" - react-native-url-polyfill "^1.3.0" - stream-chat "^8.57.6" - use-sync-external-store "^1.4.0" +"stream-chat-react-native-core@link:..": + version "0.0.0" + uid "" stream-chat@^8.57.6: version "8.60.0" diff --git a/package/src/components/Channel/Channel.tsx b/package/src/components/Channel/Channel.tsx index fd32526b98..d8200a5fcd 100644 --- a/package/src/components/Channel/Channel.tsx +++ b/package/src/components/Channel/Channel.tsx @@ -553,6 +553,7 @@ const ChannelWithContext = (props: PropsWithChildren) = handleRetry, handleThreadReply, hasCameraPicker = isImagePickerAvailable(), + hasCommands, hasCreatePoll, // If pickDocument isn't available, default to hiding the file picker hasFilePicker = isDocumentPickerAvailable(), @@ -1809,7 +1810,7 @@ const ChannelWithContext = (props: PropsWithChildren) = FileUploadPreview, handleAttachButtonPress, hasCameraPicker, - hasCommands: (getChannelConfigSafely()?.commands ?? []).length > 0, + hasCommands: hasCommands ?? (getChannelConfigSafely()?.commands ?? []).length > 0, hasFilePicker, hasImagePicker, ImageUploadPreview, diff --git a/package/src/components/KeyboardCompatibleView/KeyboardCompatibleView.tsx b/package/src/components/KeyboardCompatibleView/KeyboardCompatibleView.tsx index 8f5c77f8f8..f130b32745 100644 --- a/package/src/components/KeyboardCompatibleView/KeyboardCompatibleView.tsx +++ b/package/src/components/KeyboardCompatibleView/KeyboardCompatibleView.tsx @@ -58,7 +58,12 @@ export class KeyboardCompatibleView extends React.Component< _relativeKeyboardHeight(keyboardFrame: KeyboardMetrics) { const frame = this._frame; - if (!frame || !keyboardFrame) { + /** + * With iOS 14 & Reduce Motion > Prefer Cross-Fade Transitions enabled, the keyboard position + * height is reported differently (0 instead of Y position value) which caused the view to take full height + * of the screen. + */ + if (!frame || !keyboardFrame || keyboardFrame.screenY === 0) { return 0; } From 36ceec1acd12e64cd35915606f43034e3fcd9e1f Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Wed, 30 Apr 2025 14:02:09 +0200 Subject: [PATCH 56/60] chore: bump stream-chat-js rc again --- examples/SampleApp/yarn.lock | 27 +++++++++++++++++++++++---- package/expo-package/yarn.lock | 21 ++++++++++++++++++--- package/native-package/yarn.lock | 21 ++++++++++++++++++--- package/package.json | 2 +- package/yarn.lock | 8 ++++---- 5 files changed, 64 insertions(+), 15 deletions(-) diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index 75a203edc2..bc3f345d37 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -7559,6 +7559,25 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +stream-chat-react-native-core@6.7.3: + version "6.7.3" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" + integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== + dependencies: + "@gorhom/bottom-sheet" "^5.1.1" + dayjs "1.10.5" + emoji-regex "^10.3.0" + i18next "^21.6.14" + intl-pluralrules "^2.0.1" + linkifyjs "^4.1.1" + lodash-es "4.17.21" + mime-types "^2.1.34" + path "0.12.7" + react-native-markdown-package "1.8.2" + react-native-url-polyfill "^1.3.0" + stream-chat "^8.57.6" + use-sync-external-store "^1.4.0" + "stream-chat-react-native-core@link:../../package": version "0.0.0" uid "" @@ -7567,10 +7586,10 @@ statuses@~1.5.0: version "0.0.0" uid "" -stream-chat@9.0.0-rc.14: - version "9.0.0-rc.14" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.14.tgz#dd004add99e4fae24ec912f92bcb5487aa57a06f" - integrity sha512-dmRSWXkMljW+FNfui/Jy//Dn8ALWvNN25yaXaF4mcGgK5J+Qzq8mkK+YNeqp6VB3rVrotfFEGJk8Ma8FDhsFmA== +stream-chat@9.0.0-rc.15: + version "9.0.0-rc.15" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.15.tgz#6a35f27c38be2e021a3e62abcffa40aaef84fc0a" + integrity sha512-n8IftP103jp8IVOUZA4mnOvEIbyzGTVjoL3rDm42apk8DRHz2/vdvgyTYUJysDNYh+Oxu5HwWObToKv1c/Bxdw== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 65ca0901ba..fb2bf5c35a 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -4780,9 +4780,24 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" integrity sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg== -"stream-chat-react-native-core@link:..": - version "0.0.0" - uid "" +stream-chat-react-native-core@6.7.3: + version "6.7.3" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" + integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== + dependencies: + "@gorhom/bottom-sheet" "^5.1.1" + dayjs "1.10.5" + emoji-regex "^10.3.0" + i18next "^21.6.14" + intl-pluralrules "^2.0.1" + linkifyjs "^4.1.1" + lodash-es "4.17.21" + mime-types "^2.1.34" + path "0.12.7" + react-native-markdown-package "1.8.2" + react-native-url-polyfill "^1.3.0" + stream-chat "^8.57.6" + use-sync-external-store "^1.4.0" stream-chat@^8.57.6: version "8.60.0" diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index a1ab68494b..1787a7c892 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -3496,9 +3496,24 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -"stream-chat-react-native-core@link:..": - version "0.0.0" - uid "" +stream-chat-react-native-core@6.7.3: + version "6.7.3" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" + integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== + dependencies: + "@gorhom/bottom-sheet" "^5.1.1" + dayjs "1.10.5" + emoji-regex "^10.3.0" + i18next "^21.6.14" + intl-pluralrules "^2.0.1" + linkifyjs "^4.1.1" + lodash-es "4.17.21" + mime-types "^2.1.34" + path "0.12.7" + react-native-markdown-package "1.8.2" + react-native-url-polyfill "^1.3.0" + stream-chat "^8.57.6" + use-sync-external-store "^1.4.0" stream-chat@^8.57.6: version "8.60.0" diff --git a/package/package.json b/package/package.json index add95cc934..d0552a6b7b 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "9.0.0-rc.14", + "stream-chat": "9.0.0-rc.15", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/yarn.lock b/package/yarn.lock index f40928f7b6..fb18e21514 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -7772,10 +7772,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat@9.0.0-rc.14: - version "9.0.0-rc.14" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.14.tgz#dd004add99e4fae24ec912f92bcb5487aa57a06f" - integrity sha512-dmRSWXkMljW+FNfui/Jy//Dn8ALWvNN25yaXaF4mcGgK5J+Qzq8mkK+YNeqp6VB3rVrotfFEGJk8Ma8FDhsFmA== +stream-chat@9.0.0-rc.15: + version "9.0.0-rc.15" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.15.tgz#6a35f27c38be2e021a3e62abcffa40aaef84fc0a" + integrity sha512-n8IftP103jp8IVOUZA4mnOvEIbyzGTVjoL3rDm42apk8DRHz2/vdvgyTYUJysDNYh+Oxu5HwWObToKv1c/Bxdw== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" From dbef2f3dbd25af97a95373d21e106d2ef59edda3 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Wed, 30 Apr 2025 14:06:15 +0200 Subject: [PATCH 57/60] chore: full reinstall after merge from develop --- examples/ExpoMessaging/yarn.lock | 21 ++++----- examples/SampleApp/yarn.lock | 15 +++---- examples/TypeScriptMessaging/yarn.lock | 23 ++++------ package/expo-package/yarn.lock | 13 ++---- package/native-package/yarn.lock | 59 +++----------------------- 5 files changed, 31 insertions(+), 100 deletions(-) diff --git a/examples/ExpoMessaging/yarn.lock b/examples/ExpoMessaging/yarn.lock index d1ccbb7dc6..0844d3817a 100644 --- a/examples/ExpoMessaging/yarn.lock +++ b/examples/ExpoMessaging/yarn.lock @@ -5962,11 +5962,6 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" - integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== - mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -7422,10 +7417,10 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: version "0.0.0" uid "" -stream-chat-react-native-core@6.7.3: - version "6.7.3" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" - integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== +stream-chat-react-native-core@6.7.4: + version "6.7.4" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.4.tgz#9709465e161e32cf358034a82c284cc16369397a" + integrity sha512-YCAXBfdbazFIpO1EI9Czd2QYaFCJX+i9q710L3xPB4mRuaNl2SL8kH+RTj4Ur9Fyl3u1fcDI+1o/iYnaap1Uwg== dependencies: "@gorhom/bottom-sheet" "^5.1.1" dayjs "1.10.5" @@ -7445,10 +7440,10 @@ stream-chat-react-native-core@6.7.3: version "0.0.0" uid "" -stream-chat@9.0.0-rc.14: - version "9.0.0-rc.14" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.14.tgz#dd004add99e4fae24ec912f92bcb5487aa57a06f" - integrity sha512-dmRSWXkMljW+FNfui/Jy//Dn8ALWvNN25yaXaF4mcGgK5J+Qzq8mkK+YNeqp6VB3rVrotfFEGJk8Ma8FDhsFmA== +stream-chat@9.0.0-rc.15: + version "9.0.0-rc.15" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.15.tgz#6a35f27c38be2e021a3e62abcffa40aaef84fc0a" + integrity sha512-n8IftP103jp8IVOUZA4mnOvEIbyzGTVjoL3rDm42apk8DRHz2/vdvgyTYUJysDNYh+Oxu5HwWObToKv1c/Bxdw== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index bc3f345d37..8d83387af4 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -4089,7 +4089,7 @@ es6-iterator@^2.0.3: es5-ext "^0.10.35" es6-symbol "^3.1.1" -es6-symbol@^3.1.1, es6-symbol@^3.1.3, es6-symbol@^3.1.4: +es6-symbol@^3.1.1, es6-symbol@^3.1.3: version "3.1.4" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.4.tgz#f4e7d28013770b4208ecbf3e0bf14d3bcb557b8c" integrity sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg== @@ -6292,11 +6292,6 @@ mime@^2.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== -mime@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" - integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== - mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -7559,10 +7554,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat-react-native-core@6.7.3: - version "6.7.3" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" - integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== +stream-chat-react-native-core@6.7.4: + version "6.7.4" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.4.tgz#9709465e161e32cf358034a82c284cc16369397a" + integrity sha512-YCAXBfdbazFIpO1EI9Czd2QYaFCJX+i9q710L3xPB4mRuaNl2SL8kH+RTj4Ur9Fyl3u1fcDI+1o/iYnaap1Uwg== dependencies: "@gorhom/bottom-sheet" "^5.1.1" dayjs "1.10.5" diff --git a/examples/TypeScriptMessaging/yarn.lock b/examples/TypeScriptMessaging/yarn.lock index 08a7d6918c..7efa5dd3e2 100644 --- a/examples/TypeScriptMessaging/yarn.lock +++ b/examples/TypeScriptMessaging/yarn.lock @@ -3578,7 +3578,7 @@ es6-iterator@^2.0.3: es5-ext "^0.10.35" es6-symbol "^3.1.1" -es6-symbol@^3.1.1, es6-symbol@^3.1.3, es6-symbol@^3.1.4: +es6-symbol@^3.1.1, es6-symbol@^3.1.3: version "3.1.4" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.4.tgz#f4e7d28013770b4208ecbf3e0bf14d3bcb557b8c" integrity sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg== @@ -5708,11 +5708,6 @@ mime@^2.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== -mime@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" - integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== - mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -6945,10 +6940,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat-react-native-core@6.7.3: - version "6.7.3" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" - integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== +stream-chat-react-native-core@6.7.4: + version "6.7.4" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.4.tgz#9709465e161e32cf358034a82c284cc16369397a" + integrity sha512-YCAXBfdbazFIpO1EI9Czd2QYaFCJX+i9q710L3xPB4mRuaNl2SL8kH+RTj4Ur9Fyl3u1fcDI+1o/iYnaap1Uwg== dependencies: "@gorhom/bottom-sheet" "^5.1.1" dayjs "1.10.5" @@ -6972,10 +6967,10 @@ stream-chat-react-native-core@6.7.3: version "0.0.0" uid "" -stream-chat@9.0.0-rc.14: - version "9.0.0-rc.14" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.14.tgz#dd004add99e4fae24ec912f92bcb5487aa57a06f" - integrity sha512-dmRSWXkMljW+FNfui/Jy//Dn8ALWvNN25yaXaF4mcGgK5J+Qzq8mkK+YNeqp6VB3rVrotfFEGJk8Ma8FDhsFmA== +stream-chat@9.0.0-rc.15: + version "9.0.0-rc.15" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.15.tgz#6a35f27c38be2e021a3e62abcffa40aaef84fc0a" + integrity sha512-n8IftP103jp8IVOUZA4mnOvEIbyzGTVjoL3rDm42apk8DRHz2/vdvgyTYUJysDNYh+Oxu5HwWObToKv1c/Bxdw== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14" diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index fb2bf5c35a..868f5ecd88 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -3766,11 +3766,6 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" - integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== - mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -4780,10 +4775,10 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" integrity sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg== -stream-chat-react-native-core@6.7.3: - version "6.7.3" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" - integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== +stream-chat-react-native-core@6.7.4: + version "6.7.4" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.4.tgz#9709465e161e32cf358034a82c284cc16369397a" + integrity sha512-YCAXBfdbazFIpO1EI9Czd2QYaFCJX+i9q710L3xPB4mRuaNl2SL8kH+RTj4Ur9Fyl3u1fcDI+1o/iYnaap1Uwg== dependencies: "@gorhom/bottom-sheet" "^5.1.1" dayjs "1.10.5" diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 1787a7c892..8e11eec07e 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -1768,14 +1768,6 @@ d@1, d@^1.0.1: es5-ext "^0.10.50" type "^1.0.1" -d@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.2.tgz#2aefd554b81981e7dccf72d6842ae725cb17e5de" - integrity sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw== - dependencies: - es5-ext "^0.10.64" - type "^2.7.2" - dayjs@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.5.tgz#5600df4548fc2453b3f163ebb2abbe965ccfb986" @@ -1877,16 +1869,6 @@ es5-ext@^0.10.35, es5-ext@^0.10.50: es6-symbol "^3.1.3" next-tick "^1.1.0" -es5-ext@^0.10.62, es5-ext@^0.10.64, es5-ext@~0.10.14: - version "0.10.64" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" - integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg== - dependencies: - es6-iterator "^2.0.3" - es6-symbol "^3.1.3" - esniff "^2.0.1" - next-tick "^1.1.0" - es6-iterator@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" @@ -1904,14 +1886,6 @@ es6-symbol@^3.1.1, es6-symbol@^3.1.3: d "^1.0.1" ext "^1.1.2" -es6-symbol@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.4.tgz#f4e7d28013770b4208ecbf3e0bf14d3bcb557b8c" - integrity sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg== - dependencies: - d "^1.0.2" - ext "^1.7.0" - escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -1942,16 +1916,6 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -esniff@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" - integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== - dependencies: - d "^1.0.1" - es5-ext "^0.10.62" - event-emitter "^0.3.5" - type "^2.7.2" - esprima@^4.0.0, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -1962,14 +1926,6 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== -event-emitter@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== - dependencies: - d "1" - es5-ext "~0.10.14" - event-target-shim@^5.0.0, event-target-shim@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" @@ -1980,7 +1936,7 @@ exponential-backoff@^3.1.1: resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.2.tgz#a8f26adb96bf78e8cd8ad1037928d5e5c0679d91" integrity sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA== -ext@^1.1.2, ext@^1.7.0: +ext@^1.1.2: version "1.7.0" resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== @@ -2866,11 +2822,6 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" - integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== - minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -3496,10 +3447,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat-react-native-core@6.7.3: - version "6.7.3" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.3.tgz#7e213c03a7414c85ec4ba9da247d9703878ab520" - integrity sha512-dYoYkVah7l4bmkI0vl7Ma6qD+xjsmeFWOdz7EVwbtR+B3HPMsgz8eRAmBj/p2xcSANxh1bPRD0iLlvD30vXyzg== +stream-chat-react-native-core@6.7.4: + version "6.7.4" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.4.tgz#9709465e161e32cf358034a82c284cc16369397a" + integrity sha512-YCAXBfdbazFIpO1EI9Czd2QYaFCJX+i9q710L3xPB4mRuaNl2SL8kH+RTj4Ur9Fyl3u1fcDI+1o/iYnaap1Uwg== dependencies: "@gorhom/bottom-sheet" "^5.1.1" dayjs "1.10.5" From 16c16a4b966985083ff18874e1917c252c1e6d8e Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Wed, 30 Apr 2025 14:38:26 +0200 Subject: [PATCH 58/60] fix: add back mistakenly removed mime dep --- examples/ExpoMessaging/yarn.lock | 5 +++++ examples/SampleApp/yarn.lock | 5 +++++ examples/TypeScriptMessaging/yarn.lock | 5 +++++ package/expo-package/package.json | 1 + package/expo-package/yarn.lock | 5 +++++ package/native-package/package.json | 1 + package/native-package/yarn.lock | 5 +++++ 7 files changed, 27 insertions(+) diff --git a/examples/ExpoMessaging/yarn.lock b/examples/ExpoMessaging/yarn.lock index 0844d3817a..ed40541c50 100644 --- a/examples/ExpoMessaging/yarn.lock +++ b/examples/ExpoMessaging/yarn.lock @@ -5962,6 +5962,11 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" + integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index 8d83387af4..165133484f 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -6292,6 +6292,11 @@ mime@^2.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== +mime@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" + integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" diff --git a/examples/TypeScriptMessaging/yarn.lock b/examples/TypeScriptMessaging/yarn.lock index 7efa5dd3e2..8f5d89874a 100644 --- a/examples/TypeScriptMessaging/yarn.lock +++ b/examples/TypeScriptMessaging/yarn.lock @@ -5708,6 +5708,11 @@ mime@^2.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== +mime@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" + integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" diff --git a/package/expo-package/package.json b/package/expo-package/package.json index ef01186a50..c0080f8f57 100644 --- a/package/expo-package/package.json +++ b/package/expo-package/package.json @@ -10,6 +10,7 @@ "main": "src/index.js", "types": "types/index.d.ts", "dependencies": { + "mime": "^4.0.7", "stream-chat-react-native-core": "6.7.4" }, "peerDependencies": { diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index 868f5ecd88..3b073df7e5 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -3766,6 +3766,11 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" + integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" diff --git a/package/native-package/package.json b/package/native-package/package.json index 99edac5e18..4ad8f4e23f 100644 --- a/package/native-package/package.json +++ b/package/native-package/package.json @@ -20,6 +20,7 @@ "types": "types/index.d.ts", "dependencies": { "es6-symbol": "^3.1.3", + "mime": "^4.0.7", "stream-chat-react-native-core": "6.7.4" }, "peerDependencies": { diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 8e11eec07e..91c31ab4ef 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -2822,6 +2822,11 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.7.tgz#0b7a98b08c63bd3c10251e797d67840c9bde9f13" + integrity sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ== + minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" From 2c1be78aef806636f786c53a36ef320385740e84 Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 6 May 2025 14:02:00 +0200 Subject: [PATCH 59/60] fix: revert gh action changes --- .github/workflows/check-pr.yml | 1 - .github/workflows/lint-pr-title.yml | 1 - .github/workflows/next-release.yml | 1 - .github/workflows/sample-distribution.yml | 10 +++++----- .github/workflows/sdk-size-metrics.yml | 1 - release/next.js | 5 ----- 6 files changed, 5 insertions(+), 14 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index f6553b02a5..1c78fed42a 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -6,7 +6,6 @@ on: - develop - main - 'v[0-9]+.[0-9]+.[0-9]+*beta*' - - V7 types: [opened, synchronize] jobs: diff --git a/.github/workflows/lint-pr-title.yml b/.github/workflows/lint-pr-title.yml index 5ea99347d7..ebb5e856ad 100644 --- a/.github/workflows/lint-pr-title.yml +++ b/.github/workflows/lint-pr-title.yml @@ -5,7 +5,6 @@ on: branches: - develop - 'v[0-9]+.[0-9]+.[0-9]+' - - V7 types: [opened, edited, synchronize] jobs: diff --git a/.github/workflows/next-release.yml b/.github/workflows/next-release.yml index 132ed96414..bf775df999 100644 --- a/.github/workflows/next-release.yml +++ b/.github/workflows/next-release.yml @@ -4,7 +4,6 @@ on: push: branches: - develop - - V7 jobs: publish-next: diff --git a/.github/workflows/sample-distribution.yml b/.github/workflows/sample-distribution.yml index fde95237ca..4bc3199398 100644 --- a/.github/workflows/sample-distribution.yml +++ b/.github/workflows/sample-distribution.yml @@ -13,7 +13,7 @@ on: jobs: build_and_deploy_ios_testflight_qa: - name: Build SampleApp iOS and Deploy-${{ github.ref == 'refs/heads/V7' }} + name: Build SampleApp iOS and Deploy-${{ github.ref == 'refs/heads/develop' }} runs-on: [macos-15] steps: - name: Connect Bot @@ -38,14 +38,14 @@ jobs: bundle exec pod install - name: Build and release Testflight QA working-directory: examples/SampleApp - run: bundle exec fastlane deploy_to_testflight_qa deploy:${{ github.ref == 'refs/heads/V7' }}; + run: bundle exec fastlane deploy_to_testflight_qa deploy:${{ github.ref == 'refs/heads/develop' }}; env: MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }} APPSTORE_API_KEY: ${{ secrets.APPSTORE_API_KEY }} build_and_deploy_android_s3: - name: Build SampleApp Android and Deploy-${{ github.ref == 'refs/heads/V7' }} + name: Build SampleApp Android and Deploy-${{ github.ref == 'refs/heads/develop' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -66,13 +66,13 @@ jobs: rm -rf $HOME/.gradle/caches/ && ./gradlew assembleRelease - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 - if: ${{ github.ref == 'refs/heads/V7' }} + if: ${{ github.ref == 'refs/heads/develop' }} with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1 - name: Upload APK - if: ${{ github.ref == 'refs/heads/V7' }} + if: ${{ github.ref == 'refs/heads/develop' }} # https://getstream.io/downloads/rn-sample-app.apk run: | cp examples/SampleApp/android/app/build/outputs/apk/release/app-release.apk rn-sample-app.apk diff --git a/.github/workflows/sdk-size-metrics.yml b/.github/workflows/sdk-size-metrics.yml index dd99ca3686..4a81c96d3f 100644 --- a/.github/workflows/sdk-size-metrics.yml +++ b/.github/workflows/sdk-size-metrics.yml @@ -9,7 +9,6 @@ on: branches: - develop - main - - V7 env: HOMEBREW_NO_INSTALL_CLEANUP: 1 # Disable cleanup for homebrew, we don't need it on CI diff --git a/release/next.js b/release/next.js index a2905ceeb5..55f91550e9 100644 --- a/release/next.js +++ b/release/next.js @@ -13,11 +13,6 @@ configPromise.then((config) => { channel: 'beta', prerelease: 'beta', }, - { - name: 'V7', - channel: 'rc', - prerelease: 'rc', - }, ], }).then((result) => { // This logics avoid a overflow of next tags in github by removing the last From 4b7dc50cbb74ceaf8f6e515b2a10f78bd3f3617d Mon Sep 17 00:00:00 2001 From: Ivan Sekovanikj Date: Tue, 6 May 2025 15:18:26 +0200 Subject: [PATCH 60/60] chore: bump stream-chat to latest stable major --- examples/ExpoMessaging/yarn.lock | 30 +++++++++++++------------- examples/SampleApp/yarn.lock | 30 +++++++++++++------------- examples/TypeScriptMessaging/yarn.lock | 30 +++++++++++++------------- package/package.json | 2 +- package/yarn.lock | 8 +++---- 5 files changed, 50 insertions(+), 50 deletions(-) diff --git a/examples/ExpoMessaging/yarn.lock b/examples/ExpoMessaging/yarn.lock index ed40541c50..48d77730ca 100644 --- a/examples/ExpoMessaging/yarn.lock +++ b/examples/ExpoMessaging/yarn.lock @@ -7445,21 +7445,6 @@ stream-chat-react-native-core@6.7.4: version "0.0.0" uid "" -stream-chat@9.0.0-rc.15: - version "9.0.0-rc.15" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.15.tgz#6a35f27c38be2e021a3e62abcffa40aaef84fc0a" - integrity sha512-n8IftP103jp8IVOUZA4mnOvEIbyzGTVjoL3rDm42apk8DRHz2/vdvgyTYUJysDNYh+Oxu5HwWObToKv1c/Bxdw== - dependencies: - "@types/jsonwebtoken" "^9.0.8" - "@types/ws" "^8.5.14" - axios "^1.6.0" - base64-js "^1.5.1" - form-data "^4.0.0" - isomorphic-ws "^5.0.0" - jsonwebtoken "^9.0.2" - linkifyjs "^4.2.0" - ws "^8.18.1" - stream-chat@^8.57.6: version "8.60.0" resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.60.0.tgz#b67d4fbb185da53fb8ac5fc5759986d6ad7e19a3" @@ -7475,6 +7460,21 @@ stream-chat@^8.57.6: jsonwebtoken "~9.0.0" ws "^7.5.10" +stream-chat@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0.tgz#cb22dcb8b7f070c623a13b6b75b212d560534d6c" + integrity sha512-I4+/DEp7dP3WBgRmqHaLswL+Y2fyQkUWJhYBS5zx4bpu1cYM6WEir9HYjToDNuJjltqa/FFIEF/tMPWr7iTc0A== + dependencies: + "@types/jsonwebtoken" "^9.0.8" + "@types/ws" "^8.5.14" + axios "^1.6.0" + base64-js "^1.5.1" + form-data "^4.0.0" + isomorphic-ws "^5.0.0" + jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" + ws "^8.18.1" + stream-slice@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/stream-slice/-/stream-slice-0.1.2.tgz#2dc4f4e1b936fb13f3eb39a2def1932798d07a4b" diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock index 165133484f..098e0553c2 100644 --- a/examples/SampleApp/yarn.lock +++ b/examples/SampleApp/yarn.lock @@ -7586,21 +7586,6 @@ stream-chat-react-native-core@6.7.4: version "0.0.0" uid "" -stream-chat@9.0.0-rc.15: - version "9.0.0-rc.15" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.15.tgz#6a35f27c38be2e021a3e62abcffa40aaef84fc0a" - integrity sha512-n8IftP103jp8IVOUZA4mnOvEIbyzGTVjoL3rDm42apk8DRHz2/vdvgyTYUJysDNYh+Oxu5HwWObToKv1c/Bxdw== - dependencies: - "@types/jsonwebtoken" "^9.0.8" - "@types/ws" "^8.5.14" - axios "^1.6.0" - base64-js "^1.5.1" - form-data "^4.0.0" - isomorphic-ws "^5.0.0" - jsonwebtoken "^9.0.2" - linkifyjs "^4.2.0" - ws "^8.18.1" - stream-chat@^8.57.6: version "8.60.0" resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.60.0.tgz#b67d4fbb185da53fb8ac5fc5759986d6ad7e19a3" @@ -7616,6 +7601,21 @@ stream-chat@^8.57.6: jsonwebtoken "~9.0.0" ws "^7.5.10" +stream-chat@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0.tgz#cb22dcb8b7f070c623a13b6b75b212d560534d6c" + integrity sha512-I4+/DEp7dP3WBgRmqHaLswL+Y2fyQkUWJhYBS5zx4bpu1cYM6WEir9HYjToDNuJjltqa/FFIEF/tMPWr7iTc0A== + dependencies: + "@types/jsonwebtoken" "^9.0.8" + "@types/ws" "^8.5.14" + axios "^1.6.0" + base64-js "^1.5.1" + form-data "^4.0.0" + isomorphic-ws "^5.0.0" + jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" + ws "^8.18.1" + strict-uri-encode@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" diff --git a/examples/TypeScriptMessaging/yarn.lock b/examples/TypeScriptMessaging/yarn.lock index 8f5d89874a..96279a2958 100644 --- a/examples/TypeScriptMessaging/yarn.lock +++ b/examples/TypeScriptMessaging/yarn.lock @@ -6972,21 +6972,6 @@ stream-chat-react-native-core@6.7.4: version "0.0.0" uid "" -stream-chat@9.0.0-rc.15: - version "9.0.0-rc.15" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.15.tgz#6a35f27c38be2e021a3e62abcffa40aaef84fc0a" - integrity sha512-n8IftP103jp8IVOUZA4mnOvEIbyzGTVjoL3rDm42apk8DRHz2/vdvgyTYUJysDNYh+Oxu5HwWObToKv1c/Bxdw== - dependencies: - "@types/jsonwebtoken" "^9.0.8" - "@types/ws" "^8.5.14" - axios "^1.6.0" - base64-js "^1.5.1" - form-data "^4.0.0" - isomorphic-ws "^5.0.0" - jsonwebtoken "^9.0.2" - linkifyjs "^4.2.0" - ws "^8.18.1" - stream-chat@^8.57.6: version "8.60.0" resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.60.0.tgz#b67d4fbb185da53fb8ac5fc5759986d6ad7e19a3" @@ -7002,6 +6987,21 @@ stream-chat@^8.57.6: jsonwebtoken "~9.0.0" ws "^7.5.10" +stream-chat@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0.tgz#cb22dcb8b7f070c623a13b6b75b212d560534d6c" + integrity sha512-I4+/DEp7dP3WBgRmqHaLswL+Y2fyQkUWJhYBS5zx4bpu1cYM6WEir9HYjToDNuJjltqa/FFIEF/tMPWr7iTc0A== + dependencies: + "@types/jsonwebtoken" "^9.0.8" + "@types/ws" "^8.5.14" + axios "^1.6.0" + base64-js "^1.5.1" + form-data "^4.0.0" + isomorphic-ws "^5.0.0" + jsonwebtoken "^9.0.2" + linkifyjs "^4.2.0" + ws "^8.18.1" + strict-uri-encode@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" diff --git a/package/package.json b/package/package.json index bbb2e0b891..fb0c16ef08 100644 --- a/package/package.json +++ b/package/package.json @@ -77,7 +77,7 @@ "path": "0.12.7", "react-native-markdown-package": "1.8.2", "react-native-url-polyfill": "^1.3.0", - "stream-chat": "9.0.0-rc.15", + "stream-chat": "^9.0.0", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { diff --git a/package/yarn.lock b/package/yarn.lock index fb18e21514..d52740d3f6 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -7772,10 +7772,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat@9.0.0-rc.15: - version "9.0.0-rc.15" - resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0-rc.15.tgz#6a35f27c38be2e021a3e62abcffa40aaef84fc0a" - integrity sha512-n8IftP103jp8IVOUZA4mnOvEIbyzGTVjoL3rDm42apk8DRHz2/vdvgyTYUJysDNYh+Oxu5HwWObToKv1c/Bxdw== +stream-chat@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.0.0.tgz#cb22dcb8b7f070c623a13b6b75b212d560534d6c" + integrity sha512-I4+/DEp7dP3WBgRmqHaLswL+Y2fyQkUWJhYBS5zx4bpu1cYM6WEir9HYjToDNuJjltqa/FFIEF/tMPWr7iTc0A== dependencies: "@types/jsonwebtoken" "^9.0.8" "@types/ws" "^8.5.14"