stream-chat-react-native-core 5.0.0-beta.0 → 5.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/lib/commonjs/components/Attachment/FileAttachment.js +16 -7
  2. package/lib/commonjs/components/Attachment/FileAttachment.js.map +1 -1
  3. package/lib/commonjs/components/Attachment/Gallery.js +19 -17
  4. package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
  5. package/lib/commonjs/components/Attachment/Giphy.js +10 -10
  6. package/lib/commonjs/components/Attachment/Giphy.js.map +1 -1
  7. package/lib/commonjs/components/Attachment/utils/getGiphyMimeType.js +15 -0
  8. package/lib/commonjs/components/Attachment/utils/getGiphyMimeType.js.map +1 -0
  9. package/lib/commonjs/components/Channel/Channel.js +1 -1
  10. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  11. package/lib/commonjs/components/ChannelList/hooks/listeners/useNewMessage.js +16 -4
  12. package/lib/commonjs/components/ChannelList/hooks/listeners/useNewMessage.js.map +1 -1
  13. package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js +12 -7
  14. package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
  15. package/lib/commonjs/components/ChannelPreview/ChannelPreview.js +10 -6
  16. package/lib/commonjs/components/ChannelPreview/ChannelPreview.js.map +1 -1
  17. package/lib/commonjs/components/ImageGallery/ImageGallery.js +38 -30
  18. package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
  19. package/lib/commonjs/components/ImageGallery/components/ImageGrid.js +2 -2
  20. package/lib/commonjs/components/ImageGallery/components/ImageGrid.js.map +1 -1
  21. package/lib/commonjs/components/ImageGallery/hooks/useImageGalleryGestures.js +6 -0
  22. package/lib/commonjs/components/ImageGallery/hooks/useImageGalleryGestures.js.map +1 -1
  23. package/lib/commonjs/components/Message/Message.js +6 -6
  24. package/lib/commonjs/components/Message/Message.js.map +1 -1
  25. package/lib/commonjs/components/Message/MessageSimple/MessageTextContainer.js +7 -3
  26. package/lib/commonjs/components/Message/MessageSimple/MessageTextContainer.js.map +1 -1
  27. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js +1 -1
  28. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  29. package/lib/commonjs/components/MessageList/MessageList.js +5 -5
  30. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  31. package/lib/commonjs/contexts/imageGalleryContext/ImageGalleryContext.js +13 -14
  32. package/lib/commonjs/contexts/imageGalleryContext/ImageGalleryContext.js.map +1 -1
  33. package/lib/commonjs/contexts/imageGalleryContext/ImageGalleryContext.md +1 -1
  34. package/lib/commonjs/index.js +13 -1
  35. package/lib/commonjs/index.js.map +1 -1
  36. package/lib/commonjs/mock-builders/DB/mock.js +1 -13
  37. package/lib/commonjs/mock-builders/DB/mock.js.map +1 -1
  38. package/lib/commonjs/mock-builders/event/messageNew.js +2 -0
  39. package/lib/commonjs/mock-builders/event/messageNew.js.map +1 -1
  40. package/lib/commonjs/store/QuickSqliteClient.js +7 -3
  41. package/lib/commonjs/store/QuickSqliteClient.js.map +1 -1
  42. package/lib/commonjs/store/apis/getChannels.js +2 -15
  43. package/lib/commonjs/store/apis/getChannels.js.map +1 -1
  44. package/lib/commonjs/store/apis/getChannelsForFilterSort.js +37 -0
  45. package/lib/commonjs/store/apis/getChannelsForFilterSort.js.map +1 -0
  46. package/lib/commonjs/store/apis/index.js +264 -0
  47. package/lib/commonjs/store/apis/index.js.map +1 -0
  48. package/lib/commonjs/store/apis/queries/selectChannelIdsForFilterSort.js +1 -1
  49. package/lib/commonjs/store/apis/queries/selectChannelIdsForFilterSort.js.map +1 -1
  50. package/lib/commonjs/store/apis/queries/selectChannels.js +2 -2
  51. package/lib/commonjs/store/apis/queries/selectChannels.js.map +1 -1
  52. package/lib/commonjs/store/sqlite-utils/appendWhereCluase.js +1 -2
  53. package/lib/commonjs/store/sqlite-utils/appendWhereCluase.js.map +1 -1
  54. package/lib/commonjs/test-utils/BetterSqlite.js +54 -0
  55. package/lib/commonjs/test-utils/BetterSqlite.js.map +1 -0
  56. package/lib/commonjs/version.json +1 -1
  57. package/lib/module/components/Attachment/FileAttachment.js +16 -7
  58. package/lib/module/components/Attachment/FileAttachment.js.map +1 -1
  59. package/lib/module/components/Attachment/Gallery.js +19 -17
  60. package/lib/module/components/Attachment/Gallery.js.map +1 -1
  61. package/lib/module/components/Attachment/Giphy.js +10 -10
  62. package/lib/module/components/Attachment/Giphy.js.map +1 -1
  63. package/lib/module/components/Attachment/utils/getGiphyMimeType.js +15 -0
  64. package/lib/module/components/Attachment/utils/getGiphyMimeType.js.map +1 -0
  65. package/lib/module/components/Channel/Channel.js +1 -1
  66. package/lib/module/components/Channel/Channel.js.map +1 -1
  67. package/lib/module/components/ChannelList/hooks/listeners/useNewMessage.js +16 -4
  68. package/lib/module/components/ChannelList/hooks/listeners/useNewMessage.js.map +1 -1
  69. package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js +12 -7
  70. package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
  71. package/lib/module/components/ChannelPreview/ChannelPreview.js +10 -6
  72. package/lib/module/components/ChannelPreview/ChannelPreview.js.map +1 -1
  73. package/lib/module/components/ImageGallery/ImageGallery.js +38 -30
  74. package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
  75. package/lib/module/components/ImageGallery/components/ImageGrid.js +2 -2
  76. package/lib/module/components/ImageGallery/components/ImageGrid.js.map +1 -1
  77. package/lib/module/components/ImageGallery/hooks/useImageGalleryGestures.js +6 -0
  78. package/lib/module/components/ImageGallery/hooks/useImageGalleryGestures.js.map +1 -1
  79. package/lib/module/components/Message/Message.js +6 -6
  80. package/lib/module/components/Message/Message.js.map +1 -1
  81. package/lib/module/components/Message/MessageSimple/MessageTextContainer.js +7 -3
  82. package/lib/module/components/Message/MessageSimple/MessageTextContainer.js.map +1 -1
  83. package/lib/module/components/Message/MessageSimple/utils/renderText.js +1 -1
  84. package/lib/module/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  85. package/lib/module/components/MessageList/MessageList.js +5 -5
  86. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  87. package/lib/module/contexts/imageGalleryContext/ImageGalleryContext.js +13 -14
  88. package/lib/module/contexts/imageGalleryContext/ImageGalleryContext.js.map +1 -1
  89. package/lib/module/contexts/imageGalleryContext/ImageGalleryContext.md +1 -1
  90. package/lib/module/index.js +13 -1
  91. package/lib/module/index.js.map +1 -1
  92. package/lib/module/mock-builders/DB/mock.js +1 -13
  93. package/lib/module/mock-builders/DB/mock.js.map +1 -1
  94. package/lib/module/mock-builders/event/messageNew.js +2 -0
  95. package/lib/module/mock-builders/event/messageNew.js.map +1 -1
  96. package/lib/module/store/QuickSqliteClient.js +7 -3
  97. package/lib/module/store/QuickSqliteClient.js.map +1 -1
  98. package/lib/module/store/apis/getChannels.js +2 -15
  99. package/lib/module/store/apis/getChannels.js.map +1 -1
  100. package/lib/module/store/apis/getChannelsForFilterSort.js +37 -0
  101. package/lib/module/store/apis/getChannelsForFilterSort.js.map +1 -0
  102. package/lib/module/store/apis/index.js +264 -0
  103. package/lib/module/store/apis/index.js.map +1 -0
  104. package/lib/module/store/apis/queries/selectChannelIdsForFilterSort.js +1 -1
  105. package/lib/module/store/apis/queries/selectChannelIdsForFilterSort.js.map +1 -1
  106. package/lib/module/store/apis/queries/selectChannels.js +2 -2
  107. package/lib/module/store/apis/queries/selectChannels.js.map +1 -1
  108. package/lib/module/store/sqlite-utils/appendWhereCluase.js +1 -2
  109. package/lib/module/store/sqlite-utils/appendWhereCluase.js.map +1 -1
  110. package/lib/module/test-utils/BetterSqlite.js +54 -0
  111. package/lib/module/test-utils/BetterSqlite.js.map +1 -0
  112. package/lib/module/version.json +1 -1
  113. package/lib/typescript/components/Attachment/Gallery.d.ts +1 -1
  114. package/lib/typescript/components/Attachment/Giphy.d.ts +1 -1
  115. package/lib/typescript/components/Attachment/utils/getGiphyMimeType.d.ts +6 -0
  116. package/lib/typescript/components/ImageGallery/components/ImageGrid.d.ts +1 -1
  117. package/lib/typescript/components/ImageGallery/hooks/useImageGalleryGestures.d.ts +2 -1
  118. package/lib/typescript/components/Message/Message.d.ts +9 -3
  119. package/lib/typescript/components/MessageList/MessageList.d.ts +1 -1
  120. package/lib/typescript/contexts/imageGalleryContext/ImageGalleryContext.d.ts +9 -10
  121. package/lib/typescript/index.d.ts +2 -0
  122. package/lib/typescript/store/QuickSqliteClient.d.ts +4 -0
  123. package/lib/typescript/store/apis/getChannels.d.ts +13 -5
  124. package/lib/typescript/store/apis/getChannelsForFilterSort.d.ts +17 -0
  125. package/lib/typescript/store/apis/index.d.ts +20 -0
  126. package/lib/typescript/store/apis/queries/selectChannelIdsForFilterSort.d.ts +10 -1
  127. package/lib/typescript/{__tests__/utils → test-utils}/BetterSqlite.d.ts +1 -1
  128. package/package.json +5 -4
  129. package/src/__tests__/offline-feature.test.js +1 -2
  130. package/src/components/Attachment/FileAttachment.tsx +3 -0
  131. package/src/components/Attachment/Gallery.tsx +20 -17
  132. package/src/components/Attachment/Giphy.tsx +8 -8
  133. package/src/components/Attachment/utils/getGiphyMimeType.ts +13 -0
  134. package/src/components/Channel/Channel.tsx +1 -1
  135. package/src/components/ChannelList/__tests__/ChannelList.test.js +28 -0
  136. package/src/components/ChannelList/hooks/listeners/useNewMessage.ts +18 -5
  137. package/src/components/ChannelList/hooks/usePaginatedChannels.ts +19 -10
  138. package/src/components/ChannelPreview/ChannelPreview.tsx +6 -3
  139. package/src/components/ImageGallery/ImageGallery.tsx +32 -19
  140. package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +6 -6
  141. package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx +3 -3
  142. package/src/components/ImageGallery/__tests__/ImageGalleryGrid.test.tsx +3 -3
  143. package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx +3 -3
  144. package/src/components/ImageGallery/components/ImageGrid.tsx +3 -3
  145. package/src/components/ImageGallery/hooks/useImageGalleryGestures.tsx +16 -0
  146. package/src/components/Message/Message.tsx +9 -1
  147. package/src/components/Message/MessageSimple/MessageTextContainer.tsx +22 -2
  148. package/src/components/Message/MessageSimple/__tests__/__snapshots__/MessageAvatar.test.js.snap +1 -0
  149. package/src/components/Message/MessageSimple/utils/renderText.tsx +1 -1
  150. package/src/components/MessageList/MessageList.tsx +6 -6
  151. package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +4 -0
  152. package/src/contexts/imageGalleryContext/ImageGalleryContext.md +1 -1
  153. package/src/contexts/imageGalleryContext/ImageGalleryContext.tsx +19 -14
  154. package/src/index.ts +3 -0
  155. package/src/mock-builders/DB/mock.ts +4 -9
  156. package/src/mock-builders/event/messageNew.js +2 -0
  157. package/src/store/QuickSqliteClient.ts +11 -7
  158. package/src/store/apis/getChannels.ts +17 -14
  159. package/src/store/apis/getChannelsForFilterSort.ts +45 -0
  160. package/src/store/apis/index.ts +20 -0
  161. package/src/store/apis/queries/selectChannelIdsForFilterSort.ts +12 -2
  162. package/src/store/apis/queries/selectChannels.ts +9 -3
  163. package/src/store/sqlite-utils/appendWhereCluase.ts +1 -2
  164. package/src/{__tests__/utils → test-utils}/BetterSqlite.js +1 -1
  165. package/src/version.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { GestureResponderEvent, StyleProp, ViewStyle } from 'react-native';
2
- import type { UserResponse } from 'stream-chat';
2
+ import type { Attachment, UserResponse } from 'stream-chat';
3
3
  import { ChannelContextValue } from '../../contexts/channelContext/ChannelContext';
4
4
  import { ChatContextValue } from '../../contexts/chatContext/ChatContext';
5
5
  import { KeyboardContextValue } from '../../contexts/keyboardContext/KeyboardContext';
@@ -24,12 +24,18 @@ export declare type UrlTouchableHandlerPayload = {
24
24
  url?: string;
25
25
  };
26
26
  };
27
+ export declare type FileAttachmentTouchableHandlerPayload<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = {
28
+ emitter: 'fileAttachment';
29
+ additionalInfo?: {
30
+ attachment?: Attachment<StreamChatGenerics>;
31
+ };
32
+ };
27
33
  export declare type TouchableHandlerPayload = {
28
34
  defaultHandler?: () => void;
29
35
  event?: GestureResponderEvent;
30
36
  } & ({
31
- emitter?: TouchableEmitter;
32
- } | TextMentionTouchableHandlerPayload | UrlTouchableHandlerPayload);
37
+ emitter?: Exclude<TouchableEmitter, 'textMention' | 'textLink' | 'card' | 'fileAttachment'>;
38
+ } | TextMentionTouchableHandlerPayload | UrlTouchableHandlerPayload | FileAttachmentTouchableHandlerPayload);
33
39
  export declare type MessageTouchableHandlerPayload<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = TouchableHandlerPayload & {
34
40
  actionHandlers?: MessageActionHandlers;
35
41
  additionalInfo?: Record<string, unknown>;
@@ -11,7 +11,7 @@ import { PaginatedMessageListContextValue } from '../../contexts/paginatedMessag
11
11
  import { ThreadContextValue } from '../../contexts/threadContext/ThreadContext';
12
12
  import { TranslationContextValue } from '../../contexts/translationContext/TranslationContext';
13
13
  import type { DefaultStreamChatGenerics } from '../../types/types';
14
- declare type MessageListPropsWithContext<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = Pick<AttachmentPickerContextValue, 'closePicker' | 'selectedPicker' | 'setSelectedPicker'> & Pick<ChannelContextValue<StreamChatGenerics>, 'channel' | 'disabled' | 'EmptyStateIndicator' | 'hideStickyDateHeader' | 'loadChannelAroundMessage' | 'loading' | 'LoadingIndicator' | 'markRead' | 'NetworkDownIndicator' | 'reloadChannel' | 'scrollToFirstUnreadThreshold' | 'setTargetedMessage' | 'StickyHeader' | 'targetedMessage'> & Pick<ChatContextValue<StreamChatGenerics>, 'client'> & Pick<ImageGalleryContextValue<StreamChatGenerics>, 'setImages'> & Pick<PaginatedMessageListContextValue<StreamChatGenerics>, 'hasNoMoreRecentMessagesToLoad' | 'loadMore' | 'loadMoreRecent'> & Pick<OverlayContextValue, 'overlay'> & Pick<MessagesContextValue<StreamChatGenerics>, 'deletedMessagesVisibilityType' | 'DateHeader' | 'disableTypingIndicator' | 'FlatList' | 'initialScrollToFirstUnreadMessage' | 'InlineDateSeparator' | 'InlineUnreadIndicator' | 'legacyImageViewerSwipeBehaviour' | 'Message' | 'ScrollToBottomButton' | 'MessageSystem' | 'myMessageTheme' | 'TypingIndicator' | 'TypingIndicatorContainer'> & Pick<ThreadContextValue<StreamChatGenerics>, 'loadMoreThread' | 'thread'> & Pick<TranslationContextValue, 't' | 'tDateTimeParser'> & {
14
+ declare type MessageListPropsWithContext<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = Pick<AttachmentPickerContextValue, 'closePicker' | 'selectedPicker' | 'setSelectedPicker'> & Pick<ChannelContextValue<StreamChatGenerics>, 'channel' | 'disabled' | 'EmptyStateIndicator' | 'hideStickyDateHeader' | 'loadChannelAroundMessage' | 'loading' | 'LoadingIndicator' | 'markRead' | 'NetworkDownIndicator' | 'reloadChannel' | 'scrollToFirstUnreadThreshold' | 'setTargetedMessage' | 'StickyHeader' | 'targetedMessage'> & Pick<ChatContextValue<StreamChatGenerics>, 'client'> & Pick<ImageGalleryContextValue<StreamChatGenerics>, 'setMessages'> & Pick<PaginatedMessageListContextValue<StreamChatGenerics>, 'hasNoMoreRecentMessagesToLoad' | 'loadMore' | 'loadMoreRecent'> & Pick<OverlayContextValue, 'overlay'> & Pick<MessagesContextValue<StreamChatGenerics>, 'deletedMessagesVisibilityType' | 'DateHeader' | 'disableTypingIndicator' | 'FlatList' | 'initialScrollToFirstUnreadMessage' | 'InlineDateSeparator' | 'InlineUnreadIndicator' | 'legacyImageViewerSwipeBehaviour' | 'Message' | 'ScrollToBottomButton' | 'MessageSystem' | 'myMessageTheme' | 'TypingIndicator' | 'TypingIndicatorContainer'> & Pick<ThreadContextValue<StreamChatGenerics>, 'loadMoreThread' | 'thread'> & Pick<TranslationContextValue, 't' | 'tDateTimeParser'> & {
15
15
  /**
16
16
  * Besides existing (default) UX behavior of underlying FlatList of MessageList component, if you want
17
17
  * to attach some additional props to underlying FlatList, you can add it to following prop.
@@ -1,19 +1,18 @@
1
1
  import React, { PropsWithChildren } from 'react';
2
2
  import type { MessageType } from '../../components/MessageList/hooks/useMessageList';
3
3
  import type { DefaultStreamChatGenerics, UnknownType } from '../../types/types';
4
+ declare type SelectedMessage = {
5
+ messageId?: string;
6
+ url?: string;
7
+ };
4
8
  export declare type ImageGalleryContextValue<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = {
5
- images: MessageType<StreamChatGenerics>[];
6
- setImage: React.Dispatch<React.SetStateAction<{
7
- messageId?: string;
8
- url?: string;
9
- } | undefined>>;
10
- setImages: React.Dispatch<React.SetStateAction<MessageType<StreamChatGenerics>[]>>;
11
- image?: {
12
- messageId?: string;
13
- url?: string;
14
- };
9
+ messages: MessageType<StreamChatGenerics>[];
10
+ setMessages: React.Dispatch<React.SetStateAction<MessageType<StreamChatGenerics>[]>>;
11
+ setSelectedMessage: React.Dispatch<React.SetStateAction<SelectedMessage | undefined>>;
12
+ selectedMessage?: SelectedMessage;
15
13
  };
16
14
  export declare const ImageGalleryContext: React.Context<ImageGalleryContextValue<DefaultStreamChatGenerics>>;
17
15
  export declare const ImageGalleryProvider: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ children, }: PropsWithChildren<UnknownType>) => JSX.Element;
18
16
  export declare const useImageGalleryContext: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>() => ImageGalleryContextValue<StreamChatGenerics>;
19
17
  export declare const withImageGalleryContext: <P extends UnknownType, StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(Component: React.ComponentType<P>) => React.FC<Omit<P, keyof ImageGalleryContextValue<StreamChatGenerics>>>;
18
+ export {};
@@ -17,3 +17,5 @@ export { default as trTranslations } from './i18n/tr.json';
17
17
  export { default as heTranslations } from './i18n/he.json';
18
18
  export { QuickSqliteClient } from './store/QuickSqliteClient';
19
19
  export { version } from './version.json';
20
+ import * as OfflineStoreApis from './store/apis';
21
+ export { OfflineStoreApis };
@@ -1,4 +1,8 @@
1
1
  import type { PreparedQueries } from './types';
2
+ /**
3
+ * QuickSqliteClient takes care of any direct interaction with sqlite.
4
+ * This way usage react-native-quick-sqlite package is scoped to a single class/file.
5
+ */
2
6
  export declare class QuickSqliteClient {
3
7
  static dbVersion: number;
4
8
  static dbName: string;
@@ -1,7 +1,15 @@
1
- import type { DefaultStreamChatGenerics } from 'src/types/types';
2
- import type { ChannelAPIResponse, ChannelFilters, ChannelSort } from 'stream-chat';
3
- export declare const getChannels: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ currentUserId, filters, sort, }: {
1
+ import type { ChannelAPIResponse } from 'stream-chat';
2
+ import type { DefaultStreamChatGenerics } from '../../types/types';
3
+ /**
4
+ * Returns the list of channels with state enriched for given channel ids.
5
+ *
6
+ * @param {Object} param
7
+ * @param {Array} param.channelIds List of channel ids to fetch.
8
+ * @param {Array} param.currentUserId Id of the current logged in user.
9
+ *
10
+ * @returns {Array} Channels with enriched state.
11
+ */
12
+ export declare const getChannels: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ channelIds, currentUserId, }: {
13
+ channelIds: string[];
4
14
  currentUserId: string;
5
- filters?: ChannelFilters<StreamChatGenerics> | undefined;
6
- sort?: ChannelSort<StreamChatGenerics> | undefined;
7
15
  }) => Omit<ChannelAPIResponse<StreamChatGenerics>, "duration">[];
@@ -0,0 +1,17 @@
1
+ import type { DefaultStreamChatGenerics } from 'src/types/types';
2
+ import type { ChannelAPIResponse, ChannelFilters, ChannelSort } from 'stream-chat';
3
+ /**
4
+ * Gets the channels from database for given filter and sort query.
5
+ *
6
+ * @param {Object} param
7
+ * @param {string} param.currentUserId Id of current logged in user
8
+ * @param {Object} param.filters Filters for channels https://getstream.io/chat/docs/javascript/query_channels/?language=javascript&q=su#query-parameters
9
+ * @param {Object} param.sort Sort for channels https://getstream.io/chat/docs/javascript/query_channels/?language=javascript&q=su#query-parameters
10
+ *
11
+ * @returns Array of channels corresponding to filters & sort. Returns null if filters + sort query doesn't exist in "channelQueries" table.
12
+ */
13
+ export declare const getChannelsForFilterSort: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ currentUserId, filters, sort, }: {
14
+ currentUserId: string;
15
+ filters?: ChannelFilters<StreamChatGenerics> | undefined;
16
+ sort?: ChannelSort<StreamChatGenerics> | undefined;
17
+ }) => Omit<ChannelAPIResponse<StreamChatGenerics>, "duration">[] | null;
@@ -0,0 +1,20 @@
1
+ export * from './deleteChannel';
2
+ export * from './deleteMember';
3
+ export * from './deleteMessagesForChannel';
4
+ export * from './deleteReactions';
5
+ export * from './getAllChannelIds';
6
+ export * from './getChannelMessages';
7
+ export * from './getChannels';
8
+ export * from './getChannelsForFilterSort';
9
+ export * from './getLastSyncedAt';
10
+ export * from './getMembers';
11
+ export * from './getReads';
12
+ export * from './updateMessage';
13
+ export * from './updateReaction';
14
+ export * from './upsertChannelData';
15
+ export * from './upsertChannels';
16
+ export * from './upsertCidsForQuery';
17
+ export * from './upsertLastSyncedAt';
18
+ export * from './upsertMembers';
19
+ export * from './upsertMessages';
20
+ export * from './upsertReads';
@@ -1,6 +1,15 @@
1
1
  import type { ChannelFilters, ChannelSort } from 'stream-chat';
2
2
  import type { DefaultStreamChatGenerics } from '../../../types/types';
3
+ /**
4
+ * Gets the channel ids from database for given filter and sort query.
5
+ *
6
+ * @param {Object} param
7
+ * @param {Object} param.filters Filters for channels https://getstream.io/chat/docs/javascript/query_channels/?language=javascript&q=su#query-parameters
8
+ * @param {Object} param.sort Sort for channels https://getstream.io/chat/docs/javascript/query_channels/?language=javascript&q=su#query-parameters
9
+ *
10
+ * @returns Array of channel ids corresponding to filters & sort. Returns null if filters + sort query doesn't exist in "channelQueries" table.
11
+ */
3
12
  export declare const selectChannelIdsForFilterSort: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ filters, sort, }: {
4
13
  filters?: ChannelFilters<StreamChatGenerics> | undefined;
5
14
  sort?: ChannelSort<StreamChatGenerics> | undefined;
6
- }) => string[];
15
+ }) => string[] | null;
@@ -3,6 +3,6 @@ export class BetterSqlite {
3
3
  static closeDB: () => void;
4
4
  static getTables: () => any;
5
5
  static dropAllTables: () => void;
6
- static selectFromTable: (table: any) => any;
6
+ static selectFromTable: (table: any) => any[];
7
7
  db: null;
8
8
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "stream-chat-react-native-core",
3
3
  "description": "The official React Native and Expo components for Stream Chat, a service for building chat applications",
4
- "version": "5.0.0-beta.0",
4
+ "version": "5.0.0-beta.3",
5
5
  "author": {
6
6
  "company": "Stream.io Inc",
7
7
  "name": "Stream.io Inc"
@@ -78,9 +78,9 @@
78
78
  "mime-types": "^2.1.34",
79
79
  "path": "0.12.7",
80
80
  "react-art": "^17.0.2",
81
- "react-native-markdown-package": "1.8.1",
81
+ "react-native-markdown-package": "1.8.2",
82
82
  "react-native-url-polyfill": "^1.3.0",
83
- "stream-chat": "7.0.0-offline-support.3"
83
+ "stream-chat": "7.0.0"
84
84
  },
85
85
  "peerDependencies": {
86
86
  "react-native-svg": "^12.1.0"
@@ -94,6 +94,7 @@
94
94
  "@babel/preset-env": "7.13.12",
95
95
  "@babel/preset-typescript": "7.13.0",
96
96
  "@babel/runtime": "^7.12.5",
97
+ "@types/better-sqlite3": "^7.6.0",
97
98
  "@react-native-community/eslint-config": "2.0.0",
98
99
  "@react-native-community/eslint-plugin": "1.1.0",
99
100
  "@react-native-community/netinfo": "6.0.0",
@@ -138,7 +139,7 @@
138
139
  "react-native-builder-bob": "0.18.1",
139
140
  "react-native-fs": "2.18.0",
140
141
  "react-native-gesture-handler": "2.3.1",
141
- "react-native-quick-sqlite": "^3.1.5",
142
+ "react-native-quick-sqlite": "^4.0.3",
142
143
  "react-native-reanimated": "2.7.0",
143
144
  "react-native-svg": "12.1.1",
144
145
  "react-native-typescript-transformer": "1.2.13",
@@ -6,8 +6,6 @@ import { act, cleanup, render, waitFor } from '@testing-library/react-native';
6
6
 
7
7
  import { v4 as uuidv4 } from 'uuid';
8
8
 
9
- import { BetterSqlite } from './utils/BetterSqlite';
10
-
11
9
  import { ChannelList } from '../components/ChannelList/ChannelList';
12
10
  import { Chat } from '../components/Chat/Chat';
13
11
  import { useChannelsContext } from '../contexts/channelsContext/ChannelsContext';
@@ -36,6 +34,7 @@ import { generateUser } from '../mock-builders/generator/user';
36
34
  import { getTestClientWithUser } from '../mock-builders/mock';
37
35
  import { convertFilterSortToQuery } from '../store/apis/utils/convertFilterSortToQuery';
38
36
  import { tables } from '../store/schema';
37
+ import { BetterSqlite } from '../test-utils/BetterSqlite';
39
38
 
40
39
  /**
41
40
  * We are gonna use following custom UI components for preview and list.
@@ -103,6 +103,7 @@ const FileAttachmentWithContext = <
103
103
  onLongPress={(event) => {
104
104
  if (onLongPress) {
105
105
  onLongPress({
106
+ additionalInfo: { attachment },
106
107
  emitter: 'fileAttachment',
107
108
  event,
108
109
  });
@@ -111,6 +112,7 @@ const FileAttachmentWithContext = <
111
112
  onPress={(event) => {
112
113
  if (onPress) {
113
114
  onPress({
115
+ additionalInfo: { attachment },
114
116
  defaultHandler: defaultOnPress,
115
117
  emitter: 'fileAttachment',
116
118
  event,
@@ -120,6 +122,7 @@ const FileAttachmentWithContext = <
120
122
  onPressIn={(event) => {
121
123
  if (onPressIn) {
122
124
  onPressIn({
125
+ additionalInfo: { attachment },
123
126
  defaultHandler: defaultOnPress,
124
127
  emitter: 'fileAttachment',
125
128
  event,
@@ -83,7 +83,7 @@ const styles = StyleSheet.create({
83
83
 
84
84
  export type GalleryPropsWithContext<
85
85
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
86
- > = Pick<ImageGalleryContextValue<StreamChatGenerics>, 'setImage' | 'setImages'> &
86
+ > = Pick<ImageGalleryContextValue<StreamChatGenerics>, 'setSelectedMessage' | 'setMessages'> &
87
87
  Pick<
88
88
  MessageContextValue<StreamChatGenerics>,
89
89
  | 'alignment'
@@ -141,9 +141,9 @@ const GalleryWithContext = <
141
141
  onPress,
142
142
  onPressIn,
143
143
  preventPress,
144
- setImage,
145
- setImages,
144
+ setMessages,
146
145
  setOverlay,
146
+ setSelectedMessage,
147
147
  threadList,
148
148
  videos,
149
149
  VideoThumbnail,
@@ -256,9 +256,9 @@ const GalleryWithContext = <
256
256
  onPressIn={onPressIn}
257
257
  preventPress={preventPress}
258
258
  rowIndex={rowIndex}
259
- setImage={setImage}
260
- setImages={setImages}
259
+ setMessages={setMessages}
261
260
  setOverlay={setOverlay}
261
+ setSelectedMessage={setSelectedMessage}
262
262
  thumbnail={thumbnail}
263
263
  VideoThumbnail={VideoThumbnail}
264
264
  />
@@ -296,7 +296,7 @@ type GalleryThumbnailProps<
296
296
  | 'ImageLoadingIndicator'
297
297
  | 'ImageLoadingFailedIndicator'
298
298
  > &
299
- Pick<ImageGalleryContextValue<StreamChatGenerics>, 'setImage' | 'setImages'> &
299
+ Pick<ImageGalleryContextValue<StreamChatGenerics>, 'setSelectedMessage' | 'setMessages'> &
300
300
  Pick<
301
301
  MessageContextValue<StreamChatGenerics>,
302
302
  'onLongPress' | 'onPress' | 'onPressIn' | 'preventPress'
@@ -322,9 +322,9 @@ const GalleryThumbnail = <
322
322
  onPressIn,
323
323
  preventPress,
324
324
  rowIndex,
325
- setImage,
326
- setImages,
325
+ setMessages,
327
326
  setOverlay,
327
+ setSelectedMessage,
328
328
  thumbnail,
329
329
  VideoThumbnail,
330
330
  }: GalleryThumbnailProps<StreamChatGenerics>) => {
@@ -342,11 +342,11 @@ const GalleryThumbnail = <
342
342
  // Added if-else to keep the logic readable, instead of DRY.
343
343
  // if - legacyImageViewerSwipeBehaviour is disabled
344
344
  // else - legacyImageViewerSwipeBehaviour is enabled
345
- setImages([message]);
346
- setImage({ messageId: message.id, url: thumbnail.url });
345
+ setMessages([message]);
346
+ setSelectedMessage({ messageId: message.id, url: thumbnail.url });
347
347
  setOverlay('gallery');
348
348
  } else if (legacyImageViewerSwipeBehaviour) {
349
- setImage({ messageId: message?.id, url: thumbnail.url });
349
+ setSelectedMessage({ messageId: message?.id, url: thumbnail.url });
350
350
  setOverlay('gallery');
351
351
  }
352
352
  };
@@ -580,23 +580,25 @@ export const Gallery = <
580
580
  ImageLoadingFailedIndicator: PropImageLoadingFailedIndicator,
581
581
  ImageLoadingIndicator: PropImageLoadingIndicator,
582
582
  images: propImages,
583
+ message: propMessage,
583
584
  onLongPress: propOnLongPress,
584
585
  onPress: propOnPress,
585
586
  onPressIn: propOnPressIn,
586
587
  preventPress: propPreventPress,
587
- setImage: propSetImage,
588
588
  setOverlay: propSetOverlay,
589
+ setSelectedMessage: propSetSelectedMessage,
589
590
  threadList: propThreadList,
590
591
  videos: propVideos,
591
592
  VideoThumbnail: PropVideoThumbnail,
592
593
  } = props;
593
594
 
594
- const { setImage: contextSetImage, setImages } = useImageGalleryContext<StreamChatGenerics>();
595
+ const { setMessages, setSelectedMessage: contextSetSelectedMessage } =
596
+ useImageGalleryContext<StreamChatGenerics>();
595
597
  const {
596
598
  alignment: contextAlignment,
597
599
  groupStyles: contextGroupStyles,
598
600
  images: contextImages,
599
- message,
601
+ message: contextMessage,
600
602
  onLongPress: contextOnLongPress,
601
603
  onPress: contextOnPress,
602
604
  onPressIn: contextOnPressIn,
@@ -615,6 +617,7 @@ export const Gallery = <
615
617
 
616
618
  const images = propImages || contextImages;
617
619
  const videos = propVideos || contextVideos;
620
+ const message = propMessage || contextMessage;
618
621
 
619
622
  if (!images.length && !videos.length) return null;
620
623
 
@@ -626,7 +629,7 @@ export const Gallery = <
626
629
  const onPress = propOnPress || contextOnPress;
627
630
  const preventPress =
628
631
  typeof propPreventPress === 'boolean' ? propPreventPress : contextPreventPress;
629
- const setImage = propSetImage || contextSetImage;
632
+ const setSelectedMessage = propSetSelectedMessage || contextSetSelectedMessage;
630
633
  const setOverlay = propSetOverlay || contextSetOverlay;
631
634
  const threadList = propThreadList || contextThreadList;
632
635
  const VideoThumbnail = PropVideoThumbnail || ContextVideoThumnbnail;
@@ -651,9 +654,9 @@ export const Gallery = <
651
654
  onPress,
652
655
  onPressIn,
653
656
  preventPress,
654
- setImage,
655
- setImages,
657
+ setMessages,
656
658
  setOverlay,
659
+ setSelectedMessage,
657
660
  threadList,
658
661
  videos,
659
662
  VideoThumbnail,
@@ -134,7 +134,7 @@ const styles = StyleSheet.create({
134
134
 
135
135
  export type GiphyPropsWithContext<
136
136
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
137
- > = Pick<ImageGalleryContextValue<StreamChatGenerics>, 'setImage' | 'setImages'> &
137
+ > = Pick<ImageGalleryContextValue<StreamChatGenerics>, 'setSelectedMessage' | 'setMessages'> &
138
138
  Pick<
139
139
  MessageContextValue<StreamChatGenerics>,
140
140
  | 'handleAction'
@@ -173,9 +173,9 @@ const GiphyWithContext = <
173
173
  onPress,
174
174
  onPressIn,
175
175
  preventPress,
176
- setImage,
177
- setImages,
176
+ setMessages,
178
177
  setOverlay,
178
+ setSelectedMessage,
179
179
  } = props;
180
180
 
181
181
  const { actions, giphy: giphyData, image_url, thumb_url, title, type } = attachment;
@@ -210,8 +210,8 @@ const GiphyWithContext = <
210
210
  const giphyDimensions: { height?: number; width?: number } = {};
211
211
 
212
212
  const defaultOnPress = () => {
213
- setImages([message]);
214
- setImage({ messageId: message.id, url: uri });
213
+ setMessages([message]);
214
+ setSelectedMessage({ messageId: message.id, url: uri });
215
215
  setOverlay('gallery');
216
216
  };
217
217
 
@@ -447,7 +447,7 @@ export const Giphy = <
447
447
  const { handleAction, isMyMessage, message, onLongPress, onPress, onPressIn, preventPress } =
448
448
  useMessageContext<StreamChatGenerics>();
449
449
  const { additionalTouchableProps, giphyVersion } = useMessagesContext<StreamChatGenerics>();
450
- const { setImage, setImages } = useImageGalleryContext<StreamChatGenerics>();
450
+ const { setMessages, setSelectedMessage } = useImageGalleryContext<StreamChatGenerics>();
451
451
  const { setOverlay } = useOverlayContext();
452
452
 
453
453
  const {
@@ -472,9 +472,9 @@ export const Giphy = <
472
472
  onPress,
473
473
  onPressIn,
474
474
  preventPress,
475
- setImage,
476
- setImages,
475
+ setMessages,
477
476
  setOverlay,
477
+ setSelectedMessage,
478
478
  }}
479
479
  {...props}
480
480
  />
@@ -0,0 +1,13 @@
1
+ /**
2
+ *
3
+ * @param giphyUrl The giphy attachment url
4
+ * @returns mimeType for the giphy attachment
5
+ */
6
+ export function getGiphyMimeType(giphyUrl: string): string {
7
+ if (giphyUrl.includes('.mp4')) {
8
+ return 'video/mp4';
9
+ } else if (giphyUrl.includes('.webp')) {
10
+ return 'image/webp';
11
+ }
12
+ return 'image/gif';
13
+ }
@@ -577,7 +577,7 @@ const ChannelWithContext = <
577
577
  const channelId = channel?.id || '';
578
578
  useEffect(() => {
579
579
  const initChannel = () => {
580
- if (!channel || !shouldSyncChannel || channel.staticState) return;
580
+ if (!channel || !shouldSyncChannel || channel.offlineMode) return;
581
581
  /**
582
582
  * Loading channel at first unread message requires channel to be initialized in the first place,
583
583
  * since we use read state on channel to decide what offset to load channel at.
@@ -246,6 +246,34 @@ describe('ChannelList', () => {
246
246
  });
247
247
  });
248
248
 
249
+ it('should add channel to top if channel is hidden from the list', async () => {
250
+ const { getAllByRole, getByTestId, getByText } = render(
251
+ <Chat client={chatClient}>
252
+ <ChannelList {...props} />
253
+ </Chat>,
254
+ );
255
+
256
+ await waitFor(() => expect(getByTestId('channel-list')).toBeTruthy());
257
+ act(() => dispatchChannelHiddenEvent(chatClient, testChannel3.channel));
258
+
259
+ const newItems = getAllByRole('list-item');
260
+ await waitFor(() => {
261
+ expect(newItems).toHaveLength(2);
262
+ });
263
+
264
+ const newMessage = sendNewMessageOnChannel3();
265
+
266
+ await waitFor(() => {
267
+ expect(getByText(newMessage.text)).toBeTruthy();
268
+ });
269
+
270
+ const items = getAllByRole('list-item');
271
+
272
+ await waitFor(() => {
273
+ expect(within(items[0]).getByText(newMessage.text)).toBeTruthy();
274
+ });
275
+ });
276
+
249
277
  it('should not alter order if `lockChannelOrder` prop is true', async () => {
250
278
  const { getAllByRole, getByTestId, getByText } = render(
251
279
  <Chat client={chatClient}>
@@ -24,11 +24,24 @@ export const useNewMessage = <
24
24
  useEffect(() => {
25
25
  const handleEvent = (event: Event<StreamChatGenerics>) => {
26
26
  setChannels((channels) => {
27
- if (!lockChannelOrder && event.cid) {
28
- return moveChannelUp<StreamChatGenerics>({
29
- channels,
30
- cid: event.cid,
31
- });
27
+ if (!lockChannelOrder && event.cid && event.channel_type && event.channel_id) {
28
+ const targetChannelIndex = channels.findIndex((c) => c.cid === event.cid);
29
+
30
+ if (targetChannelIndex >= 0) {
31
+ return moveChannelUp<StreamChatGenerics>({
32
+ channels,
33
+ cid: event.cid,
34
+ });
35
+ }
36
+
37
+ // If channel doesn't exist in existing list, check in activeChannels as well.
38
+ // It may happen that channel was hidden using channel.hide(). In that case
39
+ // We remove it from `channels` state, but its still being watched and exists in client.activeChannels.
40
+ const channel = client.channel(event.channel_type, event.channel_id);
41
+
42
+ if (channel.initialized) {
43
+ return [channel, ...channels];
44
+ }
32
45
  }
33
46
 
34
47
  return [...channels];
@@ -6,7 +6,7 @@ import { useActiveChannelsRefContext } from '../../../contexts/activeChannelsRef
6
6
  import { useChatContext } from '../../../contexts/chatContext/ChatContext';
7
7
  import { useIsMountedRef } from '../../../hooks/useIsMountedRef';
8
8
 
9
- import { getChannels } from '../../../store/apis/getChannels';
9
+ import { getChannelsForFilterSort } from '../../../store/apis/getChannelsForFilterSort';
10
10
  import type { DefaultStreamChatGenerics } from '../../../types/types';
11
11
  import { ONE_SECOND_IN_MS } from '../../../utils/date';
12
12
  import { MAX_QUERY_CHANNELS_LIMIT } from '../utils';
@@ -44,8 +44,10 @@ export const usePaginatedChannels = <
44
44
  sort = {},
45
45
  }: Parameters<StreamChatGenerics>) => {
46
46
  const { client } = useChatContext<StreamChatGenerics>();
47
-
48
- const [channels, setChannels] = useState<Channel<StreamChatGenerics>[]>([]);
47
+ const initialChannelsStateRef = useRef([]);
48
+ const [channels, setChannels] = useState<Channel<StreamChatGenerics>[]>(
49
+ initialChannelsStateRef.current,
50
+ );
49
51
  const [staticChannelsActive, setStaticChannelsActive] = useState<boolean>(true);
50
52
  const activeChannels = useActiveChannelsRefContext();
51
53
 
@@ -181,12 +183,19 @@ export const usePaginatedChannels = <
181
183
  if (!client?.user?.id) return;
182
184
  if (enableOfflineSupport) {
183
185
  try {
184
- const channelsFromDB = getChannels({ currentUserId: client.user.id, filters, sort });
185
- setChannels(
186
- client.hydrateActiveChannels(channelsFromDB, {
187
- staticState: true,
188
- }),
189
- );
186
+ const channelsFromDB = getChannelsForFilterSort({
187
+ currentUserId: client.user.id,
188
+ filters,
189
+ sort,
190
+ });
191
+
192
+ if (channelsFromDB) {
193
+ setChannels(
194
+ client.hydrateActiveChannels(channelsFromDB, {
195
+ offlineMode: true,
196
+ }),
197
+ );
198
+ }
190
199
  } catch (e) {
191
200
  console.warn('Failed to get channels from database: ', e);
192
201
  }
@@ -205,7 +214,7 @@ export const usePaginatedChannels = <
205
214
  loadingChannels:
206
215
  activeQueryType === 'queryLocalDB'
207
216
  ? true
208
- : activeQueryType === 'reload' && channels.length === 0,
217
+ : activeQueryType === 'reload' && channels === initialChannelsStateRef.current,
209
218
  loadingNextPage: activeQueryType === 'loadChannels',
210
219
  loadNextPage,
211
220
  refreshing: activeQueryType === 'refresh',
@@ -78,9 +78,12 @@ const ChannelPreviewWithContext = <
78
78
  };
79
79
 
80
80
  const handleUpdatedOrDeletedMessage = (event: Event<StreamChatGenerics>) => {
81
- if (event.message?.id === lastMessage?.id) {
82
- setLastMessage(event.message);
83
- }
81
+ setLastMessage((prevLastMessage) => {
82
+ if (prevLastMessage?.id === event.message?.id) {
83
+ return event.message;
84
+ }
85
+ return prevLastMessage;
86
+ });
84
87
  };
85
88
 
86
89
  const listeners = [