stream-chat-react-native-core 5.6.0-beta.1 → 5.6.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.
- package/lib/commonjs/components/Channel/Channel.js +23 -17
- package/lib/commonjs/components/Channel/Channel.js.map +1 -1
- package/lib/commonjs/components/Chat/Chat.js +1 -1
- package/lib/commonjs/components/Chat/Chat.js.map +1 -1
- package/lib/commonjs/components/Chat/hooks/useAppSettings.js +51 -22
- package/lib/commonjs/components/Chat/hooks/useAppSettings.js.map +1 -1
- package/lib/commonjs/components/Chat/hooks/useIsOnline.js +1 -1
- package/lib/commonjs/components/Chat/hooks/useIsOnline.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGrid.js +4 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGrid.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGridHandle.js +2 -2
- package/lib/commonjs/components/ImageGallery/components/ImageGridHandle.js.map +1 -1
- package/lib/commonjs/contexts/chatContext/ChatContext.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +16 -7
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/commonjs/contexts/themeContext/utils/theme.js +1 -0
- package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/commonjs/native.js +1 -1
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/store/QuickSqliteClient.js +46 -1
- package/lib/commonjs/store/QuickSqliteClient.js.map +1 -1
- package/lib/commonjs/store/QuickSqliteClient_v4.js +112 -0
- package/lib/commonjs/store/QuickSqliteClient_v4.js.map +1 -0
- package/lib/commonjs/store/apis/getAppSettings.js +23 -0
- package/lib/commonjs/store/apis/getAppSettings.js.map +1 -0
- package/lib/commonjs/store/apis/getPendingTasks.js.map +1 -1
- package/lib/commonjs/store/apis/index.js +26 -0
- package/lib/commonjs/store/apis/index.js.map +1 -1
- package/lib/commonjs/store/apis/queries/selectChannels.js.map +1 -1
- package/lib/commonjs/store/apis/queries/selectMembersForChannels.js.map +1 -1
- package/lib/commonjs/store/apis/queries/selectMessagesForChannels.js.map +1 -1
- package/lib/commonjs/store/apis/queries/selectReactionsForMessages.js.map +1 -1
- package/lib/commonjs/store/apis/queries/selectReadsForChannels.js.map +1 -1
- package/lib/commonjs/store/apis/upsertAppSettings.js +26 -0
- package/lib/commonjs/store/apis/upsertAppSettings.js.map +1 -0
- package/lib/commonjs/store/schema.js +1 -0
- package/lib/commonjs/store/schema.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Channel/Channel.js +23 -17
- package/lib/module/components/Channel/Channel.js.map +1 -1
- package/lib/module/components/Chat/Chat.js +1 -1
- package/lib/module/components/Chat/Chat.js.map +1 -1
- package/lib/module/components/Chat/hooks/useAppSettings.js +51 -22
- package/lib/module/components/Chat/hooks/useAppSettings.js.map +1 -1
- package/lib/module/components/Chat/hooks/useIsOnline.js +1 -1
- package/lib/module/components/Chat/hooks/useIsOnline.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGrid.js +4 -1
- package/lib/module/components/ImageGallery/components/ImageGrid.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGridHandle.js +2 -2
- package/lib/module/components/ImageGallery/components/ImageGridHandle.js.map +1 -1
- package/lib/module/contexts/chatContext/ChatContext.js.map +1 -1
- package/lib/module/contexts/messageInputContext/MessageInputContext.js +16 -7
- package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/module/contexts/themeContext/utils/theme.js +1 -0
- package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/module/native.js +1 -1
- package/lib/module/native.js.map +1 -1
- package/lib/module/store/QuickSqliteClient.js +46 -1
- package/lib/module/store/QuickSqliteClient.js.map +1 -1
- package/lib/module/store/QuickSqliteClient_v4.js +112 -0
- package/lib/module/store/QuickSqliteClient_v4.js.map +1 -0
- package/lib/module/store/apis/getAppSettings.js +23 -0
- package/lib/module/store/apis/getAppSettings.js.map +1 -0
- package/lib/module/store/apis/getPendingTasks.js.map +1 -1
- package/lib/module/store/apis/index.js +26 -0
- package/lib/module/store/apis/index.js.map +1 -1
- package/lib/module/store/apis/queries/selectChannels.js.map +1 -1
- package/lib/module/store/apis/queries/selectMembersForChannels.js.map +1 -1
- package/lib/module/store/apis/queries/selectMessagesForChannels.js.map +1 -1
- package/lib/module/store/apis/queries/selectReactionsForMessages.js.map +1 -1
- package/lib/module/store/apis/queries/selectReadsForChannels.js.map +1 -1
- package/lib/module/store/apis/upsertAppSettings.js +26 -0
- package/lib/module/store/apis/upsertAppSettings.js.map +1 -0
- package/lib/module/store/schema.js +1 -0
- package/lib/module/store/schema.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Chat/hooks/useAppSettings.d.ts +2 -2
- package/lib/typescript/components/Chat/hooks/useIsOnline.d.ts +1 -1
- package/lib/typescript/contexts/chatContext/ChatContext.d.ts +1 -1
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts +1 -0
- package/lib/typescript/store/QuickSqliteClient.d.ts +4 -1
- package/lib/typescript/store/QuickSqliteClient_v4.d.ts +12 -0
- package/lib/typescript/store/apis/getAppSettings.d.ts +4 -0
- package/lib/typescript/store/apis/getPendingTasks.d.ts +1 -1
- package/lib/typescript/store/apis/index.d.ts +2 -0
- package/lib/typescript/store/apis/upsertAppSettings.d.ts +6 -0
- package/lib/typescript/store/schema.d.ts +1 -0
- package/package.json +2 -2
- package/src/components/Attachment/__tests__/Gallery.test.js +9 -2
- package/src/components/Attachment/__tests__/Giphy.test.js +9 -5
- package/src/components/Channel/Channel.tsx +11 -3
- package/src/components/Chat/Chat.tsx +1 -1
- package/src/components/Chat/hooks/__tests__/useAppSettings.test.tsx +1 -0
- package/src/components/Chat/hooks/useAppSettings.ts +19 -6
- package/src/components/Chat/hooks/useIsOnline.ts +1 -1
- package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +29 -15
- package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx +12 -6
- package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx +9 -4
- package/src/components/ImageGallery/components/ImageGrid.tsx +2 -1
- package/src/components/ImageGallery/components/ImageGridHandle.tsx +2 -2
- package/src/contexts/chatContext/ChatContext.tsx +1 -1
- package/src/contexts/messageInputContext/MessageInputContext.tsx +7 -0
- package/src/contexts/messageInputContext/__tests__/MessageInputContext.test.tsx +8 -3
- package/src/contexts/messageInputContext/__tests__/uploadFile.test.tsx +16 -6
- package/src/contexts/themeContext/utils/theme.ts +2 -0
- package/src/native.ts +1 -1
- package/src/store/QuickSqliteClient.ts +49 -5
- package/src/store/QuickSqliteClient_v4.ts +98 -0
- package/src/store/apis/getAppSettings.ts +19 -0
- package/src/store/apis/getPendingTasks.ts +2 -1
- package/src/store/apis/index.ts +2 -0
- package/src/store/apis/queries/selectChannels.ts +4 -1
- package/src/store/apis/queries/selectMembersForChannels.ts +1 -1
- package/src/store/apis/queries/selectMessagesForChannels.ts +1 -1
- package/src/store/apis/queries/selectReactionsForMessages.ts +1 -1
- package/src/store/apis/queries/selectReadsForChannels.ts +1 -1
- package/src/store/apis/upsertAppSettings.ts +23 -0
- package/src/store/schema.ts +2 -0
- package/src/version.json +1 -1
package/lib/module/version.json
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { AppSettingsAPIResponse, StreamChat } from 'stream-chat';
|
|
2
|
-
import type { DefaultStreamChatGenerics } from '
|
|
3
|
-
export declare const useAppSettings: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(client: StreamChat<StreamChatGenerics>, isOnline: boolean) => AppSettingsAPIResponse | null;
|
|
2
|
+
import type { DefaultStreamChatGenerics } from '../../../types/types';
|
|
3
|
+
export declare const useAppSettings: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(client: StreamChat<StreamChatGenerics>, isOnline: boolean | null, enableOfflineSupport: boolean) => AppSettingsAPIResponse | null;
|
|
@@ -8,5 +8,5 @@ import type { DefaultStreamChatGenerics } from '../../../types/types';
|
|
|
8
8
|
*/
|
|
9
9
|
export declare const useIsOnline: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(client: StreamChat<StreamChatGenerics>, closeConnectionOnBackground?: boolean) => {
|
|
10
10
|
connectionRecovering: boolean;
|
|
11
|
-
isOnline: boolean;
|
|
11
|
+
isOnline: boolean | null;
|
|
12
12
|
};
|
|
@@ -27,7 +27,7 @@ export declare type ChatContextValue<StreamChatGenerics extends DefaultStreamCha
|
|
|
27
27
|
connectionRecovering: boolean;
|
|
28
28
|
enableOfflineSupport: boolean;
|
|
29
29
|
ImageComponent: React.ComponentType<ImageProps>;
|
|
30
|
-
isOnline: boolean;
|
|
30
|
+
isOnline: boolean | null;
|
|
31
31
|
mutedUsers: Mute<StreamChatGenerics>[];
|
|
32
32
|
/**
|
|
33
33
|
* @param newChannel Channel to set as active.
|
|
@@ -2,6 +2,8 @@ import type { PreparedQueries } from './types';
|
|
|
2
2
|
/**
|
|
3
3
|
* QuickSqliteClient takes care of any direct interaction with sqlite.
|
|
4
4
|
* This way usage react-native-quick-sqlite package is scoped to a single class/file.
|
|
5
|
+
*
|
|
6
|
+
* TODO: Drop the support for v4 of react-native-quick-sqlite in the next major release.
|
|
5
7
|
*/
|
|
6
8
|
export declare class QuickSqliteClient {
|
|
7
9
|
static dbVersion: number;
|
|
@@ -9,10 +11,11 @@ export declare class QuickSqliteClient {
|
|
|
9
11
|
static dbLocation: string;
|
|
10
12
|
static getDbVersion: () => number;
|
|
11
13
|
static setDbVersion: (version: number) => number;
|
|
14
|
+
static isQuickSqliteV4: boolean;
|
|
12
15
|
static openDB: () => void;
|
|
13
16
|
static closeDB: () => void;
|
|
14
17
|
static executeSqlBatch: (queries: PreparedQueries[]) => void;
|
|
15
|
-
static executeSql: (query: string, params?: string[] | undefined) => any
|
|
18
|
+
static executeSql: (query: string, params?: string[] | undefined) => any;
|
|
16
19
|
static dropTables: () => void;
|
|
17
20
|
static deleteDatabase: () => boolean;
|
|
18
21
|
static initializeDatabase: () => void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PreparedQueries } from './types';
|
|
2
|
+
export declare class QuickSqliteClient_v4 {
|
|
3
|
+
static dbName: string;
|
|
4
|
+
static dbLocation: string;
|
|
5
|
+
static openDB: () => void;
|
|
6
|
+
static closeDB: () => void;
|
|
7
|
+
static executeSqlBatch: (queries: PreparedQueries[]) => void;
|
|
8
|
+
static executeSql: (query: string, params?: string[] | undefined) => any;
|
|
9
|
+
static deleteDatabase: () => boolean;
|
|
10
|
+
static updateUserPragmaVersion: (version: number) => void;
|
|
11
|
+
static getUserPragmaVersion: () => number;
|
|
12
|
+
}
|
|
@@ -4,6 +4,7 @@ export * from './deleteMessage';
|
|
|
4
4
|
export * from './deleteMessagesForChannel';
|
|
5
5
|
export * from './deleteReactions';
|
|
6
6
|
export * from './getAllChannelIds';
|
|
7
|
+
export * from './getAppSettings';
|
|
7
8
|
export * from './getChannelMessages';
|
|
8
9
|
export * from './getChannels';
|
|
9
10
|
export * from './getChannelsForFilterSort';
|
|
@@ -12,6 +13,7 @@ export * from './getMembers';
|
|
|
12
13
|
export * from './getReads';
|
|
13
14
|
export * from './updateMessage';
|
|
14
15
|
export * from './updateReaction';
|
|
16
|
+
export * from './upsertAppSettings';
|
|
15
17
|
export * from './upsertChannelData';
|
|
16
18
|
export * from './upsertChannels';
|
|
17
19
|
export * from './upsertCidsForQuery';
|
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.6.0-beta.
|
|
4
|
+
"version": "5.6.0-beta.3",
|
|
5
5
|
"author": {
|
|
6
6
|
"company": "Stream.io Inc",
|
|
7
7
|
"name": "Stream.io Inc"
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"path": "0.12.7",
|
|
80
80
|
"react-native-markdown-package": "1.8.2",
|
|
81
81
|
"react-native-url-polyfill": "^1.3.0",
|
|
82
|
-
"stream-chat": "
|
|
82
|
+
"stream-chat": "8.1.2"
|
|
83
83
|
},
|
|
84
84
|
"peerDependencies": {
|
|
85
85
|
"react-native-svg": "^12.1.0"
|
|
@@ -265,7 +265,10 @@ describe('Gallery', () => {
|
|
|
265
265
|
});
|
|
266
266
|
|
|
267
267
|
const component = await getComponent([image1]);
|
|
268
|
-
const { getByA11yLabel, getByAccessibilityHint } = render(component);
|
|
268
|
+
const { getByA11yLabel, getByAccessibilityHint, queryAllByTestId } = render(component);
|
|
269
|
+
await waitFor(() => {
|
|
270
|
+
expect(queryAllByTestId('gallery-container').length).toBe(1);
|
|
271
|
+
});
|
|
269
272
|
|
|
270
273
|
fireEvent(getByA11yLabel('Gallery Image'), 'error');
|
|
271
274
|
expect(getByAccessibilityHint('image-loading-error')).toBeTruthy();
|
|
@@ -278,7 +281,11 @@ describe('Gallery', () => {
|
|
|
278
281
|
});
|
|
279
282
|
|
|
280
283
|
const component = await getComponent([image1]);
|
|
281
|
-
const { getByA11yLabel, getByAccessibilityHint } = render(component);
|
|
284
|
+
const { getByA11yLabel, getByAccessibilityHint, queryAllByTestId } = render(component);
|
|
285
|
+
|
|
286
|
+
await waitFor(() => {
|
|
287
|
+
expect(queryAllByTestId('gallery-container').length).toBe(1);
|
|
288
|
+
});
|
|
282
289
|
|
|
283
290
|
fireEvent(getByA11yLabel('Gallery Image'), 'onLoadStart');
|
|
284
291
|
expect(getByAccessibilityHint('image-loading')).toBeTruthy();
|
|
@@ -274,8 +274,8 @@ describe('Giphy', () => {
|
|
|
274
274
|
});
|
|
275
275
|
});
|
|
276
276
|
|
|
277
|
-
it('should render a error indicator in giphy image', () => {
|
|
278
|
-
const { getByA11yLabel, getByAccessibilityHint } = render(
|
|
277
|
+
it('should render a error indicator in giphy image', async () => {
|
|
278
|
+
const { getByA11yLabel, getByAccessibilityHint, queryByTestId } = render(
|
|
279
279
|
<OverlayProvider>
|
|
280
280
|
<Chat client={chatClient}>
|
|
281
281
|
<Channel channel={channel}>
|
|
@@ -284,12 +284,15 @@ describe('Giphy', () => {
|
|
|
284
284
|
</Chat>
|
|
285
285
|
</OverlayProvider>,
|
|
286
286
|
);
|
|
287
|
+
await waitFor(() => {
|
|
288
|
+
expect(queryByTestId('giphy-attachment')).toBeTruthy();
|
|
289
|
+
});
|
|
287
290
|
|
|
288
291
|
fireEvent(getByA11yLabel('Giphy Attachment Image'), 'error');
|
|
289
292
|
expect(getByAccessibilityHint('image-loading-error')).toBeTruthy();
|
|
290
293
|
});
|
|
291
294
|
|
|
292
|
-
it('should render a loading indicator in giphy image and when successful render the image', () => {
|
|
295
|
+
it('should render a loading indicator in giphy image and when successful render the image', async () => {
|
|
293
296
|
const { getByA11yLabel, getByAccessibilityHint } = render(
|
|
294
297
|
<OverlayProvider>
|
|
295
298
|
<Chat client={chatClient}>
|
|
@@ -299,8 +302,9 @@ describe('Giphy', () => {
|
|
|
299
302
|
</Chat>
|
|
300
303
|
</OverlayProvider>,
|
|
301
304
|
);
|
|
302
|
-
|
|
303
|
-
|
|
305
|
+
await waitFor(() => {
|
|
306
|
+
expect(getByAccessibilityHint('image-loading')).toBeTruthy();
|
|
307
|
+
});
|
|
304
308
|
|
|
305
309
|
fireEvent(getByA11yLabel('Giphy Attachment Image'), 'onLoadStart');
|
|
306
310
|
|
|
@@ -74,7 +74,7 @@ import {
|
|
|
74
74
|
ThumbsUpReaction,
|
|
75
75
|
WutReaction,
|
|
76
76
|
} from '../../icons';
|
|
77
|
-
import { FlatList as FlatListDefault } from '../../native';
|
|
77
|
+
import { FlatList as FlatListDefault, pickDocument } from '../../native';
|
|
78
78
|
import * as dbApi from '../../store/apis';
|
|
79
79
|
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
80
80
|
import { addReactionToLocalState } from '../../utils/addReactionToLocalState';
|
|
@@ -455,7 +455,8 @@ const ChannelWithContext = <
|
|
|
455
455
|
handleRetry,
|
|
456
456
|
handleThreadReply,
|
|
457
457
|
hasCommands = true,
|
|
458
|
-
|
|
458
|
+
// If pickDocument isn't available, default to hiding the file picker
|
|
459
|
+
hasFilePicker = pickDocument !== null,
|
|
459
460
|
hasImagePicker = true,
|
|
460
461
|
hideDateSeparators = false,
|
|
461
462
|
hideStickyDateHeader = false,
|
|
@@ -1192,6 +1193,13 @@ const ChannelWithContext = <
|
|
|
1192
1193
|
text,
|
|
1193
1194
|
...extraFields
|
|
1194
1195
|
}: Partial<StreamMessage<StreamChatGenerics>>) => {
|
|
1196
|
+
// Exclude following properties from message.user within message preview,
|
|
1197
|
+
// since they could be long arrays and have no meaning as sender of message.
|
|
1198
|
+
// Storing such large value within user's table may cause sqlite queries to crash.
|
|
1199
|
+
// @ts-ignore
|
|
1200
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1201
|
+
const { channel_mutes, devices, mutes, ...messageUser } = client.user;
|
|
1202
|
+
|
|
1195
1203
|
const preview = {
|
|
1196
1204
|
__html: text,
|
|
1197
1205
|
attachments,
|
|
@@ -1209,7 +1217,7 @@ const ChannelWithContext = <
|
|
|
1209
1217
|
type: 'regular',
|
|
1210
1218
|
user: {
|
|
1211
1219
|
id: client.userID,
|
|
1212
|
-
...
|
|
1220
|
+
...messageUser,
|
|
1213
1221
|
},
|
|
1214
1222
|
...extraFields,
|
|
1215
1223
|
} as unknown as MessageResponse<StreamChatGenerics>;
|
|
@@ -196,7 +196,7 @@ const ChatWithContext = <
|
|
|
196
196
|
|
|
197
197
|
const setActiveChannel = (newChannel?: Channel<StreamChatGenerics>) => setChannel(newChannel);
|
|
198
198
|
|
|
199
|
-
const appSettings = useAppSettings(client, isOnline);
|
|
199
|
+
const appSettings = useAppSettings(client, isOnline, enableOfflineSupport);
|
|
200
200
|
|
|
201
201
|
const chatContext = useCreateChatContext({
|
|
202
202
|
appSettings,
|
|
@@ -1,23 +1,38 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import type { AppSettingsAPIResponse, StreamChat } from 'stream-chat';
|
|
4
|
-
import type { DefaultStreamChatGenerics } from 'stream-chat-react-native';
|
|
5
4
|
|
|
5
|
+
import * as dbApi from '../../../store/apis';
|
|
6
|
+
import type { DefaultStreamChatGenerics } from '../../../types/types';
|
|
6
7
|
export const useAppSettings = <
|
|
7
8
|
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
8
9
|
>(
|
|
9
10
|
client: StreamChat<StreamChatGenerics>,
|
|
10
|
-
isOnline: boolean,
|
|
11
|
+
isOnline: boolean | null,
|
|
12
|
+
enableOfflineSupport: boolean,
|
|
11
13
|
): AppSettingsAPIResponse | null => {
|
|
12
14
|
const [appSettings, setAppSettings] = useState<AppSettingsAPIResponse | null>(null);
|
|
13
15
|
const isMounted = useRef(true);
|
|
14
16
|
|
|
15
17
|
useEffect(() => {
|
|
16
|
-
async function
|
|
18
|
+
async function enforeAppSettings() {
|
|
19
|
+
if (!client.userID) return;
|
|
20
|
+
|
|
21
|
+
if (!isOnline && enableOfflineSupport) {
|
|
22
|
+
const appSettings = dbApi.getAppSettings({ currentUserId: client.userID });
|
|
23
|
+
setAppSettings(appSettings);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
17
27
|
try {
|
|
18
28
|
const appSettings = await client.getAppSettings();
|
|
19
29
|
if (isMounted.current) {
|
|
20
30
|
setAppSettings(appSettings);
|
|
31
|
+
enableOfflineSupport &&
|
|
32
|
+
dbApi.upsertAppSettings({
|
|
33
|
+
appSettings,
|
|
34
|
+
currentUserId: client.userID as string,
|
|
35
|
+
});
|
|
21
36
|
}
|
|
22
37
|
} catch (error: unknown) {
|
|
23
38
|
if (error instanceof Error) {
|
|
@@ -26,9 +41,7 @@ export const useAppSettings = <
|
|
|
26
41
|
}
|
|
27
42
|
}
|
|
28
43
|
|
|
29
|
-
|
|
30
|
-
getAppSettings();
|
|
31
|
-
}
|
|
44
|
+
enforeAppSettings();
|
|
32
45
|
|
|
33
46
|
return () => {
|
|
34
47
|
isMounted.current = false;
|
|
@@ -22,7 +22,7 @@ export const useIsOnline = <
|
|
|
22
22
|
client: StreamChat<StreamChatGenerics>,
|
|
23
23
|
closeConnectionOnBackground = true,
|
|
24
24
|
) => {
|
|
25
|
-
const [isOnline, setIsOnline] = useState(
|
|
25
|
+
const [isOnline, setIsOnline] = useState<boolean | null>(null);
|
|
26
26
|
const [connectionRecovering, setConnectionRecovering] = useState(false);
|
|
27
27
|
const isMounted = useIsMountedRef();
|
|
28
28
|
const clientExists = !!client;
|
|
@@ -4,7 +4,7 @@ import type { SharedValue } from 'react-native-reanimated';
|
|
|
4
4
|
|
|
5
5
|
import { act } from 'react-test-renderer';
|
|
6
6
|
|
|
7
|
-
import { fireEvent, render } from '@testing-library/react-native';
|
|
7
|
+
import { fireEvent, render, waitFor } from '@testing-library/react-native';
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
10
|
ImageGalleryContext,
|
|
@@ -45,7 +45,7 @@ const getComponent = (props: Partial<ImageGalleryContextValue>) => (
|
|
|
45
45
|
);
|
|
46
46
|
|
|
47
47
|
describe('ImageGallery', () => {
|
|
48
|
-
it('render image gallery component', () => {
|
|
48
|
+
it('render image gallery component', async () => {
|
|
49
49
|
const { queryAllByA11yLabel } = render(
|
|
50
50
|
getComponent({
|
|
51
51
|
messages: [
|
|
@@ -59,11 +59,14 @@ describe('ImageGallery', () => {
|
|
|
59
59
|
] as unknown as MessageType<DefaultStreamChatGenerics>[],
|
|
60
60
|
}),
|
|
61
61
|
);
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
|
|
63
|
+
await waitFor(() => {
|
|
64
|
+
expect(queryAllByA11yLabel('Image Item')).toHaveLength(2);
|
|
65
|
+
expect(queryAllByA11yLabel('Image Gallery Video')).toHaveLength(1);
|
|
66
|
+
});
|
|
64
67
|
});
|
|
65
68
|
|
|
66
|
-
it('handle handleLoad function when video item present and payload duration is available', () => {
|
|
69
|
+
it('handle handleLoad function when video item present and payload duration is available', async () => {
|
|
67
70
|
const attachment = generateVideoAttachment({ type: 'video' });
|
|
68
71
|
const message = generateMessage({
|
|
69
72
|
attachments: [attachment],
|
|
@@ -86,10 +89,13 @@ describe('ImageGallery', () => {
|
|
|
86
89
|
});
|
|
87
90
|
|
|
88
91
|
const videoDurationComponent = getByA11yLabel('Video Duration');
|
|
89
|
-
|
|
92
|
+
|
|
93
|
+
await waitFor(() => {
|
|
94
|
+
expect(videoDurationComponent.children[0]).toBe('00:10');
|
|
95
|
+
});
|
|
90
96
|
});
|
|
91
97
|
|
|
92
|
-
it('handle handleLoad function when video item present and payload duration is undefined', () => {
|
|
98
|
+
it('handle handleLoad function when video item present and payload duration is undefined', async () => {
|
|
93
99
|
const { getByA11yLabel } = render(
|
|
94
100
|
getComponent({
|
|
95
101
|
messages: [
|
|
@@ -109,10 +115,12 @@ describe('ImageGallery', () => {
|
|
|
109
115
|
});
|
|
110
116
|
|
|
111
117
|
const videoDurationComponent = getByA11yLabel('Video Duration');
|
|
112
|
-
|
|
118
|
+
await waitFor(() => {
|
|
119
|
+
expect(videoDurationComponent.children[0]).toBe('00:00');
|
|
120
|
+
});
|
|
113
121
|
});
|
|
114
122
|
|
|
115
|
-
it('handle handleProgress function when video item present and payload is well defined', () => {
|
|
123
|
+
it('handle handleProgress function when video item present and payload is well defined', async () => {
|
|
116
124
|
const attachment = generateVideoAttachment({ type: 'video' });
|
|
117
125
|
const message = generateMessage({
|
|
118
126
|
attachments: [attachment],
|
|
@@ -143,10 +151,12 @@ describe('ImageGallery', () => {
|
|
|
143
151
|
|
|
144
152
|
const progressDurationComponent = getByA11yLabel('Progress Duration');
|
|
145
153
|
|
|
146
|
-
|
|
154
|
+
await waitFor(() => {
|
|
155
|
+
expect(progressDurationComponent.children[0]).toBe('00:03');
|
|
156
|
+
});
|
|
147
157
|
});
|
|
148
158
|
|
|
149
|
-
it('handle handleProgress function when video item present and payload is not defined', () => {
|
|
159
|
+
it('handle handleProgress function when video item present and payload is not defined', async () => {
|
|
150
160
|
const { getByA11yLabel } = render(
|
|
151
161
|
getComponent({
|
|
152
162
|
messages: [
|
|
@@ -171,10 +181,12 @@ describe('ImageGallery', () => {
|
|
|
171
181
|
|
|
172
182
|
const progressDurationComponent = getByA11yLabel('Progress Duration');
|
|
173
183
|
|
|
174
|
-
|
|
184
|
+
await waitFor(() => {
|
|
185
|
+
expect(progressDurationComponent.children[0]).toBe('00:00');
|
|
186
|
+
});
|
|
175
187
|
});
|
|
176
188
|
|
|
177
|
-
it('handle handleEnd function when video item present', () => {
|
|
189
|
+
it('handle handleEnd function when video item present', async () => {
|
|
178
190
|
const attachment = generateVideoAttachment({ type: 'video' });
|
|
179
191
|
const message = generateMessage({
|
|
180
192
|
attachments: [attachment],
|
|
@@ -198,7 +210,9 @@ describe('ImageGallery', () => {
|
|
|
198
210
|
});
|
|
199
211
|
|
|
200
212
|
const progressDurationComponent = getByA11yLabel('Progress Duration');
|
|
201
|
-
|
|
202
|
-
|
|
213
|
+
await waitFor(() => {
|
|
214
|
+
expect(getByA11yLabel('Play Icon')).not.toBeUndefined();
|
|
215
|
+
expect(progressDurationComponent.children[0]).toBe('00:10');
|
|
216
|
+
});
|
|
203
217
|
});
|
|
204
218
|
});
|
|
@@ -97,10 +97,13 @@ describe('ImageGalleryFooter', () => {
|
|
|
97
97
|
</ImageGalleryContext.Provider>
|
|
98
98
|
</OverlayProvider>,
|
|
99
99
|
);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
|
|
101
|
+
await waitFor(() => {
|
|
102
|
+
expect(queryAllByText('Left element')).toHaveLength(1);
|
|
103
|
+
expect(queryAllByText('Right element')).toHaveLength(1);
|
|
104
|
+
expect(queryAllByText('Center element')).toHaveLength(1);
|
|
105
|
+
expect(queryAllByText('Video Control element')).toHaveLength(1);
|
|
106
|
+
});
|
|
104
107
|
});
|
|
105
108
|
|
|
106
109
|
it('render image gallery footer component with custom component footer Grid Icon and Share Icon component', async () => {
|
|
@@ -147,8 +150,11 @@ describe('ImageGalleryFooter', () => {
|
|
|
147
150
|
</ImageGalleryContext.Provider>
|
|
148
151
|
</OverlayProvider>,
|
|
149
152
|
);
|
|
150
|
-
|
|
151
|
-
|
|
153
|
+
|
|
154
|
+
await waitFor(() => {
|
|
155
|
+
expect(queryAllByText('Share Icon element')).toHaveLength(1);
|
|
156
|
+
expect(queryAllByText('Grid Icon element')).toHaveLength(1);
|
|
157
|
+
});
|
|
152
158
|
});
|
|
153
159
|
|
|
154
160
|
it('should trigger the share button onPress Handler', async () => {
|
|
@@ -90,9 +90,12 @@ describe('ImageGalleryHeader', () => {
|
|
|
90
90
|
</ImageGalleryContext.Provider>
|
|
91
91
|
</OverlayProvider>,
|
|
92
92
|
);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
|
|
94
|
+
await waitFor(() => {
|
|
95
|
+
expect(queryAllByText('Left element')).toHaveLength(1);
|
|
96
|
+
expect(queryAllByText('Right element')).toHaveLength(1);
|
|
97
|
+
expect(queryAllByText('Center element')).toHaveLength(1);
|
|
98
|
+
});
|
|
96
99
|
});
|
|
97
100
|
|
|
98
101
|
it('render image gallery header component with custom Close Icon component', async () => {
|
|
@@ -132,7 +135,9 @@ describe('ImageGalleryHeader', () => {
|
|
|
132
135
|
</ImageGalleryContext.Provider>
|
|
133
136
|
</OverlayProvider>,
|
|
134
137
|
);
|
|
135
|
-
|
|
138
|
+
await waitFor(() => {
|
|
139
|
+
expect(queryAllByText('Close Icon element')).toHaveLength(1);
|
|
140
|
+
});
|
|
136
141
|
});
|
|
137
142
|
|
|
138
143
|
it('should trigger the hideOverlay function on button onPress', async () => {
|
|
@@ -137,7 +137,7 @@ export const ImageGrid = <
|
|
|
137
137
|
theme: {
|
|
138
138
|
colors: { white },
|
|
139
139
|
imageGallery: {
|
|
140
|
-
grid: { contentContainer },
|
|
140
|
+
grid: { container, contentContainer },
|
|
141
141
|
},
|
|
142
142
|
},
|
|
143
143
|
} = useTheme();
|
|
@@ -165,6 +165,7 @@ export const ImageGrid = <
|
|
|
165
165
|
keyExtractor={(item, index) => `${item.uri}-${index}`}
|
|
166
166
|
numColumns={numberOfImageGalleryGridColumns || 3}
|
|
167
167
|
renderItem={renderItem}
|
|
168
|
+
style={container}
|
|
168
169
|
/>
|
|
169
170
|
);
|
|
170
171
|
};
|
|
@@ -13,8 +13,8 @@ const styles = StyleSheet.create({
|
|
|
13
13
|
},
|
|
14
14
|
handle: {
|
|
15
15
|
alignItems: 'center',
|
|
16
|
-
borderTopLeftRadius:
|
|
17
|
-
borderTopRightRadius:
|
|
16
|
+
borderTopLeftRadius: 12,
|
|
17
|
+
borderTopRightRadius: 12,
|
|
18
18
|
flexDirection: 'row',
|
|
19
19
|
height: 40,
|
|
20
20
|
justifyContent: 'center',
|
|
@@ -36,7 +36,7 @@ export type ChatContextValue<
|
|
|
36
36
|
connectionRecovering: boolean;
|
|
37
37
|
enableOfflineSupport: boolean;
|
|
38
38
|
ImageComponent: React.ComponentType<ImageProps>;
|
|
39
|
-
isOnline: boolean;
|
|
39
|
+
isOnline: boolean | null;
|
|
40
40
|
mutedUsers: Mute<StreamChatGenerics>[];
|
|
41
41
|
/**
|
|
42
42
|
* @param newChannel Channel to set as active.
|
|
@@ -575,6 +575,13 @@ export const MessageInputProvider = <
|
|
|
575
575
|
};
|
|
576
576
|
|
|
577
577
|
const pickFile = async () => {
|
|
578
|
+
if (pickDocument === null) {
|
|
579
|
+
console.log(
|
|
580
|
+
'The file picker is not installed. Check our Getting Started documentation to install it.',
|
|
581
|
+
);
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
|
|
578
585
|
if (numberOfUploads >= value.maxNumberOfFiles) {
|
|
579
586
|
Alert.alert('Maximum number of files reached');
|
|
580
587
|
return;
|
|
@@ -4,6 +4,7 @@ import type { TextInput } from 'react-native';
|
|
|
4
4
|
|
|
5
5
|
import { act, renderHook } from '@testing-library/react-hooks';
|
|
6
6
|
|
|
7
|
+
import { waitFor } from '@testing-library/react-native';
|
|
7
8
|
import type { AppSettingsAPIResponse, StreamChat } from 'stream-chat';
|
|
8
9
|
|
|
9
10
|
import { ChatContextValue, ChatProvider } from '../../../contexts/chatContext/ChatContext';
|
|
@@ -167,7 +168,7 @@ describe('MessageInputContext', () => {
|
|
|
167
168
|
expect(result.current.text).toBe('/');
|
|
168
169
|
});
|
|
169
170
|
|
|
170
|
-
it('openMentionPicker works', () => {
|
|
171
|
+
it('openMentionPicker works', async () => {
|
|
171
172
|
const { result } = renderHook(() => useMessageInputContext(), {
|
|
172
173
|
initialProps: {
|
|
173
174
|
editing: true,
|
|
@@ -180,7 +181,9 @@ describe('MessageInputContext', () => {
|
|
|
180
181
|
result.current.openMentionsPicker();
|
|
181
182
|
});
|
|
182
183
|
|
|
183
|
-
|
|
184
|
+
await waitFor(() => {
|
|
185
|
+
expect(result.current.text).toBe('@');
|
|
186
|
+
});
|
|
184
187
|
});
|
|
185
188
|
|
|
186
189
|
it('openAttachmentPicker works', async () => {
|
|
@@ -203,6 +206,8 @@ describe('MessageInputContext', () => {
|
|
|
203
206
|
result.current.openAttachmentPicker();
|
|
204
207
|
});
|
|
205
208
|
|
|
206
|
-
|
|
209
|
+
await waitFor(async () => {
|
|
210
|
+
expect(await result.current.pickFile()).toBe(undefined);
|
|
211
|
+
});
|
|
207
212
|
});
|
|
208
213
|
});
|
|
@@ -3,6 +3,8 @@ import { act } from 'react-test-renderer';
|
|
|
3
3
|
|
|
4
4
|
import { renderHook } from '@testing-library/react-hooks';
|
|
5
5
|
|
|
6
|
+
import { waitFor } from '@testing-library/react-native';
|
|
7
|
+
|
|
6
8
|
import { generateFileUploadPreview } from '../../../mock-builders/generator/attachment';
|
|
7
9
|
import type { DefaultStreamChatGenerics } from '../../../types/types';
|
|
8
10
|
import {
|
|
@@ -31,7 +33,7 @@ const Wrapper = <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultS
|
|
|
31
33
|
);
|
|
32
34
|
|
|
33
35
|
describe("MessageInputContext's uploadFile", () => {
|
|
34
|
-
it('uploadFile works', () => {
|
|
36
|
+
it('uploadFile works', async () => {
|
|
35
37
|
const doDocUploadRequestMock = jest.fn().mockResolvedValue({
|
|
36
38
|
file: {
|
|
37
39
|
url: '',
|
|
@@ -46,16 +48,20 @@ describe("MessageInputContext's uploadFile", () => {
|
|
|
46
48
|
wrapper: Wrapper,
|
|
47
49
|
});
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
await waitFor(() => {
|
|
52
|
+
expect(result.current.fileUploads).toHaveLength(0);
|
|
53
|
+
});
|
|
50
54
|
|
|
51
55
|
act(() => {
|
|
52
56
|
result.current.uploadFile({ newFile: generateFileUploadPreview({ state: '' }) });
|
|
53
57
|
});
|
|
54
58
|
|
|
55
|
-
|
|
59
|
+
await waitFor(() => {
|
|
60
|
+
expect(doDocUploadRequestMock).toHaveBeenCalled();
|
|
61
|
+
});
|
|
56
62
|
});
|
|
57
63
|
|
|
58
|
-
it('uploadFile catch block gets executed', () => {
|
|
64
|
+
it('uploadFile catch block gets executed', async () => {
|
|
59
65
|
const doDocUploadRequestMock = jest.fn().mockResolvedValue(new Error('This is an error'));
|
|
60
66
|
const { result } = renderHook(() => useMessageInputContext(), {
|
|
61
67
|
initialProps: {
|
|
@@ -65,12 +71,16 @@ describe("MessageInputContext's uploadFile", () => {
|
|
|
65
71
|
wrapper: Wrapper,
|
|
66
72
|
});
|
|
67
73
|
|
|
68
|
-
|
|
74
|
+
await waitFor(() => {
|
|
75
|
+
expect(result.current.fileUploads).toHaveLength(0);
|
|
76
|
+
});
|
|
69
77
|
|
|
70
78
|
act(() => {
|
|
71
79
|
result.current.uploadFile({ newFile: generateFileUploadPreview({ state: '' }) });
|
|
72
80
|
});
|
|
73
81
|
|
|
74
|
-
|
|
82
|
+
await waitFor(() => {
|
|
83
|
+
expect(result.current.fileUploads.length).toBe(0);
|
|
84
|
+
});
|
|
75
85
|
});
|
|
76
86
|
});
|