stream-chat-react-native-core 4.8.0 → 4.9.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/Attachment/GallaryImage.js +41 -0
- package/lib/commonjs/components/Attachment/GallaryImage.js.map +1 -0
- package/lib/commonjs/components/Attachment/Gallery.js +101 -36
- package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
- package/lib/commonjs/components/Attachment/Giphy.js +118 -25
- package/lib/commonjs/components/Attachment/Giphy.js.map +1 -1
- package/lib/commonjs/components/Attachment/ImageLoadingFailedIndicator.js +105 -0
- package/lib/commonjs/components/Attachment/ImageLoadingFailedIndicator.js.map +1 -0
- package/lib/commonjs/components/Attachment/ImageLoadingIndicator.js +58 -0
- package/lib/commonjs/components/Attachment/ImageLoadingIndicator.js.map +1 -0
- package/lib/commonjs/components/Attachment/hooks/useLoadingImage.js +32 -0
- package/lib/commonjs/components/Attachment/hooks/useLoadingImage.js.map +1 -0
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteInput.js +3 -2
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteInput.js.map +1 -1
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionItem.js +1 -1
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionItem.js.map +1 -1
- package/lib/commonjs/components/Channel/Channel.js +23 -13
- package/lib/commonjs/components/Channel/Channel.js.map +1 -1
- package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js +4 -0
- package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/hooks/useLatestMessagePreview.js +43 -19
- package/lib/commonjs/components/ChannelPreview/hooks/useLatestMessagePreview.js.map +1 -1
- package/lib/commonjs/components/MessageInput/FileUploadPreview.js +28 -21
- package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
- package/lib/commonjs/components/MessageInput/ImageUploadPreview.js +16 -17
- package/lib/commonjs/components/MessageInput/ImageUploadPreview.js.map +1 -1
- package/lib/commonjs/components/RTLComponents/WritingDirectionAwareText.js +43 -0
- package/lib/commonjs/components/RTLComponents/WritingDirectionAwareText.js.map +1 -0
- package/lib/commonjs/components/Reply/Reply.js +7 -2
- package/lib/commonjs/components/Reply/Reply.js.map +1 -1
- package/lib/commonjs/contexts/messagesContext/MessagesContext.js +2 -2
- package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
- package/lib/commonjs/contexts/themeContext/utils/theme.js +4 -0
- package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/commonjs/mock-builders/api/channelMocks.js +299 -0
- package/lib/commonjs/mock-builders/api/channelMocks.js.map +1 -0
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Attachment/GallaryImage.js +41 -0
- package/lib/module/components/Attachment/GallaryImage.js.map +1 -0
- package/lib/module/components/Attachment/Gallery.js +101 -36
- package/lib/module/components/Attachment/Gallery.js.map +1 -1
- package/lib/module/components/Attachment/Giphy.js +118 -25
- package/lib/module/components/Attachment/Giphy.js.map +1 -1
- package/lib/module/components/Attachment/ImageLoadingFailedIndicator.js +105 -0
- package/lib/module/components/Attachment/ImageLoadingFailedIndicator.js.map +1 -0
- package/lib/module/components/Attachment/ImageLoadingIndicator.js +58 -0
- package/lib/module/components/Attachment/ImageLoadingIndicator.js.map +1 -0
- package/lib/module/components/Attachment/hooks/useLoadingImage.js +32 -0
- package/lib/module/components/Attachment/hooks/useLoadingImage.js.map +1 -0
- package/lib/module/components/AutoCompleteInput/AutoCompleteInput.js +3 -2
- package/lib/module/components/AutoCompleteInput/AutoCompleteInput.js.map +1 -1
- package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionItem.js +1 -1
- package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionItem.js.map +1 -1
- package/lib/module/components/Channel/Channel.js +23 -13
- package/lib/module/components/Channel/Channel.js.map +1 -1
- package/lib/module/components/Channel/hooks/useCreateMessagesContext.js +4 -0
- package/lib/module/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
- package/lib/module/components/ChannelPreview/hooks/useLatestMessagePreview.js +43 -19
- package/lib/module/components/ChannelPreview/hooks/useLatestMessagePreview.js.map +1 -1
- package/lib/module/components/MessageInput/FileUploadPreview.js +28 -21
- package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
- package/lib/module/components/MessageInput/ImageUploadPreview.js +16 -17
- package/lib/module/components/MessageInput/ImageUploadPreview.js.map +1 -1
- package/lib/module/components/RTLComponents/WritingDirectionAwareText.js +43 -0
- package/lib/module/components/RTLComponents/WritingDirectionAwareText.js.map +1 -0
- package/lib/module/components/Reply/Reply.js +7 -2
- package/lib/module/components/Reply/Reply.js.map +1 -1
- package/lib/module/contexts/messagesContext/MessagesContext.js +2 -2
- package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
- package/lib/module/contexts/themeContext/utils/theme.js +4 -0
- package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/module/mock-builders/api/channelMocks.js +299 -0
- package/lib/module/mock-builders/api/channelMocks.js.map +1 -0
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Attachment/GallaryImage.d.ts +5 -0
- package/lib/typescript/components/Attachment/Gallery.d.ts +1 -1
- package/lib/typescript/components/Attachment/Giphy.d.ts +1 -1
- package/lib/typescript/components/Attachment/ImageLoadingFailedIndicator.d.ts +3 -0
- package/lib/typescript/components/Attachment/ImageLoadingIndicator.d.ts +3 -0
- package/lib/typescript/components/Attachment/hooks/useLoadingImage.d.ts +7 -0
- package/lib/typescript/components/Channel/Channel.d.ts +1 -1
- package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts +1 -1
- package/lib/typescript/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.d.ts +1 -0
- package/lib/typescript/components/RTLComponents/WritingDirectionAwareText.d.ts +4 -0
- package/lib/typescript/components/Reply/__tests__/Reply.test.d.ts +1 -0
- package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +10 -0
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts +4 -0
- package/lib/typescript/mock-builders/api/channelMocks.d.ts +14 -0
- package/lib/typescript/mock-builders/api/getOrCreateChannel.d.ts +7 -0
- package/lib/typescript/mock-builders/api/useMockedApis.d.ts +1 -0
- package/lib/typescript/mock-builders/generator/channel.d.ts +116 -0
- package/package.json +3 -2
- package/src/components/Attachment/GallaryImage.tsx +22 -0
- package/src/components/Attachment/Gallery.tsx +68 -35
- package/src/components/Attachment/Giphy.tsx +68 -1
- package/src/components/Attachment/ImageLoadingFailedIndicator.tsx +56 -0
- package/src/components/Attachment/ImageLoadingIndicator.tsx +31 -0
- package/src/components/Attachment/__tests__/Attachment.test.js +9 -3
- package/src/components/Attachment/__tests__/Gallery.test.js +36 -1
- package/src/components/Attachment/__tests__/Giphy.test.js +110 -90
- package/src/components/Attachment/hooks/useLoadingImage.tsx +8 -0
- package/src/components/AutoCompleteInput/AutoCompleteInput.tsx +2 -1
- package/src/components/AutoCompleteInput/AutoCompleteSuggestionItem.tsx +1 -1
- package/src/components/Channel/Channel.tsx +8 -0
- package/src/components/Channel/hooks/useCreateMessagesContext.ts +4 -0
- package/src/components/ChannelPreview/__tests__/ChannelPreviewMessenger.test.js +0 -1
- package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx +145 -0
- package/src/components/ChannelPreview/hooks/useLatestMessagePreview.ts +50 -24
- package/src/components/MessageInput/FileUploadPreview.tsx +11 -8
- package/src/components/MessageInput/ImageUploadPreview.tsx +4 -5
- package/src/components/MessageInput/__tests__/__snapshots__/MessageInput.test.js.snap +1 -0
- package/src/components/RTLComponents/WritingDirectionAwareText.tsx +17 -0
- package/src/components/Reply/Reply.tsx +19 -3
- package/src/components/Reply/__tests__/Reply.test.tsx +48 -0
- package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +1 -0
- package/src/contexts/messagesContext/MessagesContext.tsx +15 -0
- package/src/contexts/themeContext/utils/theme.ts +8 -0
- package/src/mock-builders/api/channelMocks.tsx +272 -0
- package/src/version.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { MessagesContextValue } from '../../../contexts/messagesContext/MessagesContext';
|
|
2
2
|
import type { DefaultStreamChatGenerics } from '../../../types/types';
|
|
3
|
-
export declare const useCreateMessagesContext: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ additionalTouchableProps, Attachment, AttachmentActions, Card, CardCover, CardFooter, CardHeader, channelId, DateHeader, deletedMessagesVisibilityType, disableTypingIndicator, dismissKeyboardOnMessageTouch, enableMessageGroupingByUser, FileAttachment, FileAttachmentGroup, FileAttachmentIcon, FlatList, forceAlignMessages, formatDate, Gallery, Giphy, giphyVersion, handleBlock, handleCopy, handleDelete, handleEdit, handleFlag, handleMute, handlePinMessage, handleQuotedReply, handleReaction, handleRetry, handleThreadReply, initialScrollToFirstUnreadMessage, InlineDateSeparator, InlineUnreadIndicator, isAttachmentEqual, legacyImageViewerSwipeBehaviour, markdownRules, Message, messageActions, MessageAvatar, MessageContent, messageContentOrder, MessageDeleted, MessageFooter, MessageHeader, MessageList, MessagePinnedHeader, MessageReplies, MessageRepliesAvatars, MessageSimple, MessageStatus, MessageSystem, MessageText, myMessageTheme, onLongPressMessage, onPressInMessage, onPressMessage, OverlayReactionList, ReactionList, removeMessage, Reply, retrySendMessage, ScrollToBottomButton, selectReaction, setEditingState, setQuotedMessageState, supportedReactions, targetedMessage, TypingIndicator, TypingIndicatorContainer, updateMessage, UrlPreview, VideoThumbnail, }: MessagesContextValue<StreamChatGenerics> & {
|
|
3
|
+
export declare const useCreateMessagesContext: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ additionalTouchableProps, Attachment, AttachmentActions, Card, CardCover, CardFooter, CardHeader, channelId, DateHeader, deletedMessagesVisibilityType, disableTypingIndicator, dismissKeyboardOnMessageTouch, enableMessageGroupingByUser, FileAttachment, FileAttachmentGroup, FileAttachmentIcon, FlatList, forceAlignMessages, formatDate, Gallery, Giphy, giphyVersion, handleBlock, handleCopy, handleDelete, handleEdit, handleFlag, handleMute, handlePinMessage, handleQuotedReply, handleReaction, handleRetry, handleThreadReply, ImageLoadingFailedIndicator, ImageLoadingIndicator, initialScrollToFirstUnreadMessage, InlineDateSeparator, InlineUnreadIndicator, isAttachmentEqual, legacyImageViewerSwipeBehaviour, markdownRules, Message, messageActions, MessageAvatar, MessageContent, messageContentOrder, MessageDeleted, MessageFooter, MessageHeader, MessageList, MessagePinnedHeader, MessageReplies, MessageRepliesAvatars, MessageSimple, MessageStatus, MessageSystem, MessageText, myMessageTheme, onLongPressMessage, onPressInMessage, onPressMessage, OverlayReactionList, ReactionList, removeMessage, Reply, retrySendMessage, ScrollToBottomButton, selectReaction, setEditingState, setQuotedMessageState, supportedReactions, targetedMessage, TypingIndicator, TypingIndicatorContainer, updateMessage, UrlPreview, VideoThumbnail, }: MessagesContextValue<StreamChatGenerics> & {
|
|
4
4
|
/**
|
|
5
5
|
* To ensure we allow re-render, when channel is changed
|
|
6
6
|
*/
|
package/lib/typescript/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React, { PropsWithChildren } from 'react';
|
|
2
2
|
import type { TouchableOpacityProps } from 'react-native';
|
|
3
|
+
import type { ImageLoadingFailedIndicatorProps } from 'src/components/Attachment/ImageLoadingFailedIndicator';
|
|
4
|
+
import type { ImageLoadingIndicatorProps } from 'src/components/Attachment/ImageLoadingIndicator';
|
|
3
5
|
import type { MessagePinnedHeaderProps } from 'src/components/Message/MessageSimple/MessagePinnedHeader';
|
|
4
6
|
import type { Attachment, ChannelState, MessageResponse } from 'stream-chat';
|
|
5
7
|
import type { AttachmentProps } from '../../components/Attachment/Attachment';
|
|
@@ -96,6 +98,14 @@ export declare type MessagesContextValue<StreamChatGenerics extends DefaultStrea
|
|
|
96
98
|
* 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
|
|
97
99
|
* */
|
|
98
100
|
giphyVersion: keyof NonNullable<Attachment['giphy']>;
|
|
101
|
+
/**
|
|
102
|
+
* The indicator rendered when loading an image fails.
|
|
103
|
+
*/
|
|
104
|
+
ImageLoadingFailedIndicator: React.ComponentType<ImageLoadingFailedIndicatorProps>;
|
|
105
|
+
/**
|
|
106
|
+
* The indicator rendered when image is loading. By default renders <ActivityIndicator/>
|
|
107
|
+
*/
|
|
108
|
+
ImageLoadingIndicator: React.ComponentType<ImageLoadingIndicatorProps>;
|
|
99
109
|
/**
|
|
100
110
|
* When true, messageList will be scrolled at first unread message, when opened.
|
|
101
111
|
*/
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Channel, FormatMessageResponse, MessageResponse } from 'stream-chat';
|
|
2
|
+
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
3
|
+
declare const CHANNEL: Channel<DefaultStreamChatGenerics>;
|
|
4
|
+
declare const CHANNEL_WITH_MESSAGES_TEXT: Channel<DefaultStreamChatGenerics>;
|
|
5
|
+
declare const CHANNEL_WITH_DELETED_MESSAGES: Channel<DefaultStreamChatGenerics>;
|
|
6
|
+
declare const CHANNEL_WITH_NO_MESSAGES: Channel<DefaultStreamChatGenerics>;
|
|
7
|
+
declare const CHANNEL_WITH_MESSAGE_COMMAND: Channel<DefaultStreamChatGenerics>;
|
|
8
|
+
declare const CHANNEL_WITH_MESSAGES_ATTACHMENTS: Channel<DefaultStreamChatGenerics>;
|
|
9
|
+
declare const LATEST_MESSAGE: MessageResponse<DefaultStreamChatGenerics>;
|
|
10
|
+
declare const FORMATTED_MESSAGE: FormatMessageResponse<DefaultStreamChatGenerics>;
|
|
11
|
+
declare const CHANNEL_WITH_MENTIONED_USERS: Channel<DefaultStreamChatGenerics>;
|
|
12
|
+
declare const CHANNEL_WITH_EMPTY_MESSAGE: Channel<DefaultStreamChatGenerics>;
|
|
13
|
+
declare const CHANNEL_WITH_MESSAGES: Channel<DefaultStreamChatGenerics>;
|
|
14
|
+
export { CHANNEL, CHANNEL_WITH_EMPTY_MESSAGE, CHANNEL_WITH_MESSAGES, CHANNEL_WITH_MENTIONED_USERS, FORMATTED_MESSAGE, LATEST_MESSAGE, CHANNEL_WITH_MESSAGES_ATTACHMENTS, CHANNEL_WITH_MESSAGE_COMMAND as CHANNEL_WITH_MESSAGES_COMMAND, CHANNEL_WITH_NO_MESSAGES, CHANNEL_WITH_DELETED_MESSAGES, CHANNEL_WITH_MESSAGES_TEXT, };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function useMockedApis(client: any, apiResponses: any): void;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export function generateChannel(customValues: any): {
|
|
2
|
+
_client: {};
|
|
3
|
+
data: {
|
|
4
|
+
cid: string;
|
|
5
|
+
config: {
|
|
6
|
+
name: string;
|
|
7
|
+
type: string;
|
|
8
|
+
automod: string;
|
|
9
|
+
automod_behavior: string;
|
|
10
|
+
commands: {
|
|
11
|
+
args: string;
|
|
12
|
+
description: string;
|
|
13
|
+
name: string;
|
|
14
|
+
set: string;
|
|
15
|
+
}[];
|
|
16
|
+
connect_events: boolean;
|
|
17
|
+
created_at: string;
|
|
18
|
+
max_message_length: number;
|
|
19
|
+
message_retention: string;
|
|
20
|
+
mutes: boolean;
|
|
21
|
+
reactions: boolean;
|
|
22
|
+
read_events: boolean;
|
|
23
|
+
replies: boolean;
|
|
24
|
+
search: boolean;
|
|
25
|
+
typing_events: boolean;
|
|
26
|
+
updated_at: string;
|
|
27
|
+
uploads: boolean;
|
|
28
|
+
url_enrichment: boolean;
|
|
29
|
+
};
|
|
30
|
+
created_at: string;
|
|
31
|
+
created_by: {
|
|
32
|
+
banned: boolean;
|
|
33
|
+
created_at: string;
|
|
34
|
+
id: any;
|
|
35
|
+
image: any;
|
|
36
|
+
name: any;
|
|
37
|
+
online: boolean;
|
|
38
|
+
role: string;
|
|
39
|
+
updated_at: string;
|
|
40
|
+
};
|
|
41
|
+
frozen: boolean;
|
|
42
|
+
id: any;
|
|
43
|
+
own_capabilities: string[];
|
|
44
|
+
type: string;
|
|
45
|
+
updated_at: string;
|
|
46
|
+
};
|
|
47
|
+
id: any;
|
|
48
|
+
state: {
|
|
49
|
+
members: {};
|
|
50
|
+
messages: never[];
|
|
51
|
+
setIsUpToDate: jest.Mock<any, any>;
|
|
52
|
+
};
|
|
53
|
+
type: string;
|
|
54
|
+
};
|
|
55
|
+
export function generateChannelResponse(customValues?: {
|
|
56
|
+
channel: {};
|
|
57
|
+
id: any;
|
|
58
|
+
type: string;
|
|
59
|
+
}): {
|
|
60
|
+
channel: {
|
|
61
|
+
id: any;
|
|
62
|
+
type: string;
|
|
63
|
+
user: {
|
|
64
|
+
banned: boolean;
|
|
65
|
+
created_at: string;
|
|
66
|
+
id: any;
|
|
67
|
+
image: any;
|
|
68
|
+
name: any;
|
|
69
|
+
online: boolean;
|
|
70
|
+
role: string;
|
|
71
|
+
updated_at: string;
|
|
72
|
+
};
|
|
73
|
+
cid: string;
|
|
74
|
+
config: {
|
|
75
|
+
name: string;
|
|
76
|
+
type: string;
|
|
77
|
+
automod: string;
|
|
78
|
+
automod_behavior: string;
|
|
79
|
+
commands: {
|
|
80
|
+
args: string;
|
|
81
|
+
description: string;
|
|
82
|
+
name: string;
|
|
83
|
+
set: string;
|
|
84
|
+
}[];
|
|
85
|
+
connect_events: boolean;
|
|
86
|
+
created_at: string;
|
|
87
|
+
max_message_length: number;
|
|
88
|
+
message_retention: string;
|
|
89
|
+
mutes: boolean;
|
|
90
|
+
reactions: boolean;
|
|
91
|
+
read_events: boolean;
|
|
92
|
+
replies: boolean;
|
|
93
|
+
search: boolean;
|
|
94
|
+
typing_events: boolean;
|
|
95
|
+
updated_at: string;
|
|
96
|
+
uploads: boolean;
|
|
97
|
+
url_enrichment: boolean;
|
|
98
|
+
};
|
|
99
|
+
created_at: string;
|
|
100
|
+
created_by: {
|
|
101
|
+
banned: boolean;
|
|
102
|
+
created_at: string;
|
|
103
|
+
id: any;
|
|
104
|
+
image: any;
|
|
105
|
+
name: any;
|
|
106
|
+
online: boolean;
|
|
107
|
+
role: string;
|
|
108
|
+
updated_at: string;
|
|
109
|
+
};
|
|
110
|
+
frozen: boolean;
|
|
111
|
+
own_capabilities: string[];
|
|
112
|
+
updated_at: string;
|
|
113
|
+
};
|
|
114
|
+
members: never[];
|
|
115
|
+
messages: never[];
|
|
116
|
+
};
|
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": "4.
|
|
4
|
+
"version": "4.9.0-beta.3",
|
|
5
5
|
"author": {
|
|
6
6
|
"company": "Stream.io Inc",
|
|
7
7
|
"name": "Stream.io Inc"
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"prepare-distribution": "cd examples/SampleApp && npm version patch && react-native-version && git add ./ && git commit -m 'Bump build version' --no-verify",
|
|
35
35
|
"prettier": "prettier --list-different '**/*.{js,ts,tsx,md,json}' .eslintrc.json ../.prettierrc .babelrc",
|
|
36
36
|
"prettier-fix": "prettier --write '**/*.{js,ts,tsx,md,json}' .eslintrc.json ../.prettierrc .babelrc",
|
|
37
|
-
"test:
|
|
37
|
+
"test:coverage": "yarn test:unit --coverage",
|
|
38
|
+
"test:unit": "TZ=UTC jest",
|
|
38
39
|
"validate-translations": "node bin/validate-translations.js",
|
|
39
40
|
"get-version": "echo $npm_package_version",
|
|
40
41
|
"version": "bash ./bin/before-tag.sh",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ImageBackground, ImageProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { makeImageCompatibleUrl } from '../../utils/utils';
|
|
5
|
+
|
|
6
|
+
export const GalleryImage: React.FC<
|
|
7
|
+
Omit<ImageProps, 'height' | 'source'> & {
|
|
8
|
+
uri: string;
|
|
9
|
+
}
|
|
10
|
+
> = (props) => {
|
|
11
|
+
const { uri, ...rest } = props;
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<ImageBackground
|
|
15
|
+
{...rest}
|
|
16
|
+
accessibilityLabel='gallery-image'
|
|
17
|
+
source={{
|
|
18
|
+
uri: makeImageCompatibleUrl(uri),
|
|
19
|
+
}}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
3
3
|
|
|
4
|
+
import { GalleryImage } from './GallaryImage';
|
|
5
|
+
import { useLoadingImage } from './hooks/useLoadingImage';
|
|
4
6
|
import { buildGallery } from './utils/buildGallery/buildGallery';
|
|
5
7
|
|
|
6
8
|
import { getGalleryImageBorderRadius } from './utils/getGalleryImageBorderRadius';
|
|
@@ -27,25 +29,7 @@ import {
|
|
|
27
29
|
import { useTheme } from '../../contexts/themeContext/ThemeContext';
|
|
28
30
|
import { isVideoPackageAvailable } from '../../native';
|
|
29
31
|
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
30
|
-
import { getUrlWithoutParams
|
|
31
|
-
|
|
32
|
-
const GalleryImage: React.FC<
|
|
33
|
-
Omit<ImageProps, 'height' | 'source'> & {
|
|
34
|
-
uri: string;
|
|
35
|
-
}
|
|
36
|
-
> = (props) => {
|
|
37
|
-
const { uri, ...rest } = props;
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<Image
|
|
41
|
-
{...rest}
|
|
42
|
-
source={{
|
|
43
|
-
uri: makeImageCompatibleUrl(uri),
|
|
44
|
-
}}
|
|
45
|
-
testID='image-attachment-single'
|
|
46
|
-
/>
|
|
47
|
-
);
|
|
48
|
-
};
|
|
32
|
+
import { getUrlWithoutParams } from '../../utils/utils';
|
|
49
33
|
|
|
50
34
|
const MemoizedGalleryImage = React.memo(
|
|
51
35
|
GalleryImage,
|
|
@@ -54,7 +38,7 @@ const MemoizedGalleryImage = React.memo(
|
|
|
54
38
|
) as typeof GalleryImage;
|
|
55
39
|
|
|
56
40
|
const styles = StyleSheet.create({
|
|
57
|
-
|
|
41
|
+
errorTextSize: { fontSize: 10 },
|
|
58
42
|
galleryContainer: {
|
|
59
43
|
borderTopLeftRadius: 13,
|
|
60
44
|
borderTopRightRadius: 13,
|
|
@@ -62,7 +46,19 @@ const styles = StyleSheet.create({
|
|
|
62
46
|
flexWrap: 'wrap',
|
|
63
47
|
overflow: 'hidden',
|
|
64
48
|
},
|
|
65
|
-
imageContainer: {
|
|
49
|
+
imageContainer: {
|
|
50
|
+
alignItems: 'center',
|
|
51
|
+
display: 'flex',
|
|
52
|
+
flexDirection: 'row',
|
|
53
|
+
justifyContent: 'center',
|
|
54
|
+
padding: 1,
|
|
55
|
+
},
|
|
56
|
+
imageContainerStyle: { alignItems: 'center', flex: 1, justifyContent: 'center' },
|
|
57
|
+
imageLoadingIndicatorStyle: {
|
|
58
|
+
alignItems: 'center',
|
|
59
|
+
justifyContent: 'center',
|
|
60
|
+
position: 'absolute',
|
|
61
|
+
},
|
|
66
62
|
moreImagesContainer: {
|
|
67
63
|
alignItems: 'center',
|
|
68
64
|
justifyContent: 'center',
|
|
@@ -88,7 +84,11 @@ export type GalleryPropsWithContext<
|
|
|
88
84
|
> &
|
|
89
85
|
Pick<
|
|
90
86
|
MessagesContextValue<StreamChatGenerics>,
|
|
91
|
-
|
|
87
|
+
| 'additionalTouchableProps'
|
|
88
|
+
| 'legacyImageViewerSwipeBehaviour'
|
|
89
|
+
| 'VideoThumbnail'
|
|
90
|
+
| 'ImageLoadingIndicator'
|
|
91
|
+
| 'ImageLoadingFailedIndicator'
|
|
92
92
|
> &
|
|
93
93
|
Pick<OverlayContextValue, 'setOverlay'> & {
|
|
94
94
|
channelId: string | undefined;
|
|
@@ -118,6 +118,8 @@ const GalleryWithContext = <
|
|
|
118
118
|
alignment,
|
|
119
119
|
groupStyles,
|
|
120
120
|
hasThreadReplies,
|
|
121
|
+
ImageLoadingFailedIndicator,
|
|
122
|
+
ImageLoadingIndicator,
|
|
121
123
|
images,
|
|
122
124
|
legacyImageViewerSwipeBehaviour,
|
|
123
125
|
message,
|
|
@@ -133,6 +135,9 @@ const GalleryWithContext = <
|
|
|
133
135
|
VideoThumbnail,
|
|
134
136
|
} = props;
|
|
135
137
|
|
|
138
|
+
const { isLoadingImage, isLoadingImageError, setLoadingImage, setLoadingImageError } =
|
|
139
|
+
useLoadingImage();
|
|
140
|
+
|
|
136
141
|
const {
|
|
137
142
|
theme: {
|
|
138
143
|
colors: { overlay },
|
|
@@ -304,18 +309,37 @@ const GalleryWithContext = <
|
|
|
304
309
|
]}
|
|
305
310
|
/>
|
|
306
311
|
) : (
|
|
307
|
-
<
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
312
|
+
<View style={styles.imageContainerStyle}>
|
|
313
|
+
<MemoizedGalleryImage
|
|
314
|
+
onError={(error) => {
|
|
315
|
+
console.warn(error);
|
|
316
|
+
setLoadingImage(false);
|
|
317
|
+
setLoadingImageError(true);
|
|
318
|
+
}}
|
|
319
|
+
onLoadEnd={() => setLoadingImage(false)}
|
|
320
|
+
onLoadStart={() => setLoadingImage(true)}
|
|
321
|
+
resizeMode={resizeMode}
|
|
322
|
+
style={[
|
|
323
|
+
borderRadius,
|
|
324
|
+
image,
|
|
325
|
+
{
|
|
326
|
+
height: height - 1,
|
|
327
|
+
width: width - 1,
|
|
328
|
+
},
|
|
329
|
+
]}
|
|
330
|
+
uri={url}
|
|
331
|
+
/>
|
|
332
|
+
{isLoadingImage && (
|
|
333
|
+
<View style={{ position: 'absolute' }}>
|
|
334
|
+
<ImageLoadingIndicator style={styles.imageLoadingIndicatorStyle} />
|
|
335
|
+
</View>
|
|
336
|
+
)}
|
|
337
|
+
{isLoadingImageError && (
|
|
338
|
+
<View style={{ position: 'absolute' }}>
|
|
339
|
+
<ImageLoadingFailedIndicator style={styles.imageLoadingIndicatorStyle} />
|
|
340
|
+
</View>
|
|
341
|
+
)}
|
|
342
|
+
</View>
|
|
319
343
|
)}
|
|
320
344
|
{colIndex === numOfColumns - 1 &&
|
|
321
345
|
rowIndex === numOfRows - 1 &&
|
|
@@ -412,6 +436,8 @@ export const Gallery = <
|
|
|
412
436
|
alignment: propAlignment,
|
|
413
437
|
groupStyles: propGroupStyles,
|
|
414
438
|
hasThreadReplies,
|
|
439
|
+
ImageLoadingFailedIndicator: PropImageLoadingFailedIndicator,
|
|
440
|
+
ImageLoadingIndicator: PropImageLoadingIndicator,
|
|
415
441
|
images: propImages,
|
|
416
442
|
onLongPress: propOnLongPress,
|
|
417
443
|
onPress: propOnPress,
|
|
@@ -439,6 +465,8 @@ export const Gallery = <
|
|
|
439
465
|
} = useMessageContext<StreamChatGenerics>();
|
|
440
466
|
const {
|
|
441
467
|
additionalTouchableProps: contextAdditionalTouchableProps,
|
|
468
|
+
ImageLoadingFailedIndicator: ContextImageLoadingFailedIndicator,
|
|
469
|
+
ImageLoadingIndicator: ContextImageLoadingIndicator,
|
|
442
470
|
legacyImageViewerSwipeBehaviour,
|
|
443
471
|
VideoThumbnail: ContextVideoThumnbnail,
|
|
444
472
|
} = useMessagesContext<StreamChatGenerics>();
|
|
@@ -461,6 +489,9 @@ export const Gallery = <
|
|
|
461
489
|
const setOverlay = propSetOverlay || contextSetOverlay;
|
|
462
490
|
const threadList = propThreadList || contextThreadList;
|
|
463
491
|
const VideoThumbnail = PropVideoThumbnail || ContextVideoThumnbnail;
|
|
492
|
+
const ImageLoadingFailedIndicator =
|
|
493
|
+
PropImageLoadingFailedIndicator || ContextImageLoadingFailedIndicator;
|
|
494
|
+
const ImageLoadingIndicator = PropImageLoadingIndicator || ContextImageLoadingIndicator;
|
|
464
495
|
|
|
465
496
|
return (
|
|
466
497
|
<MemoizedGallery
|
|
@@ -470,6 +501,8 @@ export const Gallery = <
|
|
|
470
501
|
channelId: message?.cid,
|
|
471
502
|
groupStyles,
|
|
472
503
|
hasThreadReplies: hasThreadReplies || !!message?.reply_count,
|
|
504
|
+
ImageLoadingFailedIndicator,
|
|
505
|
+
ImageLoadingIndicator,
|
|
473
506
|
images,
|
|
474
507
|
legacyImageViewerSwipeBehaviour,
|
|
475
508
|
message,
|
|
@@ -3,6 +3,8 @@ import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
import type { Attachment } from 'stream-chat';
|
|
5
5
|
|
|
6
|
+
import { useLoadingImage } from './hooks/useLoadingImage';
|
|
7
|
+
|
|
6
8
|
import {
|
|
7
9
|
ImageGalleryContextValue,
|
|
8
10
|
useImageGalleryContext,
|
|
@@ -40,6 +42,11 @@ const styles = StyleSheet.create({
|
|
|
40
42
|
fontWeight: '600',
|
|
41
43
|
paddingVertical: 16,
|
|
42
44
|
},
|
|
45
|
+
centerChild: {
|
|
46
|
+
alignItems: 'center',
|
|
47
|
+
display: 'flex',
|
|
48
|
+
justifyContent: 'center',
|
|
49
|
+
},
|
|
43
50
|
container: {
|
|
44
51
|
overflow: 'hidden',
|
|
45
52
|
width: 270,
|
|
@@ -84,6 +91,17 @@ const styles = StyleSheet.create({
|
|
|
84
91
|
padding: 8,
|
|
85
92
|
width: '60%',
|
|
86
93
|
},
|
|
94
|
+
imageErrorIndicatorStyle: {
|
|
95
|
+
alignItems: 'center',
|
|
96
|
+
flex: 1,
|
|
97
|
+
justifyContent: 'center',
|
|
98
|
+
},
|
|
99
|
+
imageLoadingIndicatorStyle: {
|
|
100
|
+
alignItems: 'center',
|
|
101
|
+
flex: 1,
|
|
102
|
+
justifyContent: 'center',
|
|
103
|
+
position: 'absolute',
|
|
104
|
+
},
|
|
87
105
|
selectionContainer: {
|
|
88
106
|
borderBottomRightRadius: 0,
|
|
89
107
|
borderRadius: 16,
|
|
@@ -128,7 +146,13 @@ export type GiphyPropsWithContext<
|
|
|
128
146
|
| 'onPressIn'
|
|
129
147
|
| 'preventPress'
|
|
130
148
|
> &
|
|
131
|
-
Pick<
|
|
149
|
+
Pick<
|
|
150
|
+
MessagesContextValue<StreamChatGenerics>,
|
|
151
|
+
| 'giphyVersion'
|
|
152
|
+
| 'additionalTouchableProps'
|
|
153
|
+
| 'ImageLoadingIndicator'
|
|
154
|
+
| 'ImageLoadingFailedIndicator'
|
|
155
|
+
> & {
|
|
132
156
|
attachment: Attachment<StreamChatGenerics>;
|
|
133
157
|
} & Pick<OverlayContextValue, 'setOverlay'>;
|
|
134
158
|
|
|
@@ -142,6 +166,8 @@ const GiphyWithContext = <
|
|
|
142
166
|
attachment,
|
|
143
167
|
giphyVersion,
|
|
144
168
|
handleAction,
|
|
169
|
+
ImageLoadingFailedIndicator,
|
|
170
|
+
ImageLoadingIndicator,
|
|
145
171
|
isMyMessage,
|
|
146
172
|
message,
|
|
147
173
|
onLongPress,
|
|
@@ -155,6 +181,9 @@ const GiphyWithContext = <
|
|
|
155
181
|
|
|
156
182
|
const { actions, giphy: giphyData, image_url, thumb_url, title, type } = attachment;
|
|
157
183
|
|
|
184
|
+
const { isLoadingImage, isLoadingImageError, setLoadingImage, setLoadingImageError } =
|
|
185
|
+
useLoadingImage();
|
|
186
|
+
|
|
158
187
|
const {
|
|
159
188
|
theme: {
|
|
160
189
|
colors: { accent_blue, black, grey, grey_dark, grey_gainsboro, label_bg_transparent, white },
|
|
@@ -214,6 +243,13 @@ const GiphyWithContext = <
|
|
|
214
243
|
</View>
|
|
215
244
|
<View style={styles.selectionImageContainer}>
|
|
216
245
|
<Image
|
|
246
|
+
onError={(error) => {
|
|
247
|
+
console.warn(error);
|
|
248
|
+
setLoadingImage(false);
|
|
249
|
+
setLoadingImageError(true);
|
|
250
|
+
}}
|
|
251
|
+
onLoadEnd={() => setLoadingImage(false)}
|
|
252
|
+
onLoadStart={() => setLoadingImage(true)}
|
|
217
253
|
resizeMode='contain'
|
|
218
254
|
source={{ uri: makeImageCompatibleUrl(uri) }}
|
|
219
255
|
style={[styles.giphy, giphyDimensions, giphy]}
|
|
@@ -299,16 +335,36 @@ const GiphyWithContext = <
|
|
|
299
335
|
<View
|
|
300
336
|
style={[
|
|
301
337
|
styles.container,
|
|
338
|
+
styles.centerChild,
|
|
302
339
|
{ backgroundColor: isMyMessage ? grey_gainsboro : white },
|
|
303
340
|
container,
|
|
304
341
|
]}
|
|
305
342
|
>
|
|
306
343
|
<Image
|
|
344
|
+
accessibilityLabel='giphy-attachment-image'
|
|
345
|
+
onError={(error) => {
|
|
346
|
+
console.warn(error);
|
|
347
|
+
setLoadingImage(false);
|
|
348
|
+
setLoadingImageError(true);
|
|
349
|
+
}}
|
|
350
|
+
onLoadEnd={() => setLoadingImage(false)}
|
|
351
|
+
onLoadStart={() => setLoadingImage(true)}
|
|
307
352
|
resizeMode='contain'
|
|
308
353
|
source={{ uri: makeImageCompatibleUrl(uri) }}
|
|
309
354
|
style={[styles.giphy, giphyDimensions, giphy]}
|
|
310
355
|
testID='giphy-attachment-image'
|
|
311
356
|
/>
|
|
357
|
+
|
|
358
|
+
{isLoadingImageError && (
|
|
359
|
+
<View style={{ position: 'absolute' }}>
|
|
360
|
+
<ImageLoadingFailedIndicator style={styles.imageErrorIndicatorStyle} />
|
|
361
|
+
</View>
|
|
362
|
+
)}
|
|
363
|
+
{isLoadingImage && (
|
|
364
|
+
<View style={{ position: 'absolute' }}>
|
|
365
|
+
<ImageLoadingIndicator style={styles.imageLoadingIndicatorStyle} />
|
|
366
|
+
</View>
|
|
367
|
+
)}
|
|
312
368
|
<View style={[styles.giphyMask, giphyMask]}>
|
|
313
369
|
<View
|
|
314
370
|
style={[
|
|
@@ -387,12 +443,23 @@ export const Giphy = <
|
|
|
387
443
|
const { additionalTouchableProps, giphyVersion } = useMessagesContext<StreamChatGenerics>();
|
|
388
444
|
const { setImage, setImages } = useImageGalleryContext<StreamChatGenerics>();
|
|
389
445
|
const { setOverlay } = useOverlayContext();
|
|
446
|
+
|
|
447
|
+
const {
|
|
448
|
+
ImageLoadingFailedIndicator: ContextImageLoadingFailedIndicator,
|
|
449
|
+
ImageLoadingIndicator: ContextImageLoadingIndicator,
|
|
450
|
+
} = useMessagesContext<StreamChatGenerics>();
|
|
451
|
+
const ImageLoadingFailedIndicator =
|
|
452
|
+
ContextImageLoadingFailedIndicator || props.ImageLoadingFailedIndicator;
|
|
453
|
+
const ImageLoadingIndicator = ContextImageLoadingIndicator || props.ImageLoadingIndicator;
|
|
454
|
+
|
|
390
455
|
return (
|
|
391
456
|
<MemoizedGiphy
|
|
392
457
|
{...{
|
|
393
458
|
additionalTouchableProps,
|
|
394
459
|
giphyVersion,
|
|
395
460
|
handleAction,
|
|
461
|
+
ImageLoadingFailedIndicator,
|
|
462
|
+
ImageLoadingIndicator,
|
|
396
463
|
isMyMessage,
|
|
397
464
|
message,
|
|
398
465
|
onLongPress,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleSheet, Text, View, ViewProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { useTheme } from '../../contexts/themeContext/ThemeContext';
|
|
5
|
+
import { useTranslationContext } from '../../contexts/translationContext/TranslationContext';
|
|
6
|
+
|
|
7
|
+
import { Warning } from '../../icons';
|
|
8
|
+
|
|
9
|
+
const WARNING_ICON_SIZE = 14;
|
|
10
|
+
|
|
11
|
+
const styles = StyleSheet.create({
|
|
12
|
+
container: {
|
|
13
|
+
alignContent: 'center',
|
|
14
|
+
alignItems: 'center',
|
|
15
|
+
borderRadius: 20,
|
|
16
|
+
flexDirection: 'row',
|
|
17
|
+
justifyContent: 'center',
|
|
18
|
+
},
|
|
19
|
+
errorText: {
|
|
20
|
+
fontSize: 8,
|
|
21
|
+
justifyContent: 'center',
|
|
22
|
+
paddingHorizontal: 8,
|
|
23
|
+
},
|
|
24
|
+
warningIconStyle: {
|
|
25
|
+
borderRadius: 24,
|
|
26
|
+
marginLeft: 4,
|
|
27
|
+
marginTop: 6,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export type ImageLoadingFailedIndicatorProps = ViewProps;
|
|
32
|
+
|
|
33
|
+
export const ImageLoadingFailedIndicator = (props: ImageLoadingFailedIndicatorProps) => {
|
|
34
|
+
const {
|
|
35
|
+
theme: {
|
|
36
|
+
colors: { accent_red, overlay, white },
|
|
37
|
+
},
|
|
38
|
+
} = useTheme();
|
|
39
|
+
|
|
40
|
+
const { t } = useTranslationContext();
|
|
41
|
+
|
|
42
|
+
const { style, ...rest } = props;
|
|
43
|
+
return (
|
|
44
|
+
<View {...rest} accessibilityHint='image-loading-error' style={[style]}>
|
|
45
|
+
<View style={[styles.container, { backgroundColor: overlay }]}>
|
|
46
|
+
<Warning
|
|
47
|
+
height={WARNING_ICON_SIZE}
|
|
48
|
+
pathFill={accent_red}
|
|
49
|
+
style={styles.warningIconStyle}
|
|
50
|
+
width={WARNING_ICON_SIZE}
|
|
51
|
+
/>
|
|
52
|
+
<Text style={[styles.errorText, { color: white }]}>{t('Error loading')}</Text>
|
|
53
|
+
</View>
|
|
54
|
+
</View>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ActivityIndicator, StyleSheet, View, ViewProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { useTheme } from '../../contexts/themeContext/ThemeContext';
|
|
5
|
+
|
|
6
|
+
const styles = StyleSheet.create({
|
|
7
|
+
container: {
|
|
8
|
+
alignItems: 'center',
|
|
9
|
+
display: 'flex',
|
|
10
|
+
justifyContent: 'center',
|
|
11
|
+
width: '100%',
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export type ImageLoadingIndicatorProps = ViewProps;
|
|
16
|
+
|
|
17
|
+
export const ImageLoadingIndicator = (props: ImageLoadingIndicatorProps) => {
|
|
18
|
+
const {
|
|
19
|
+
theme: {
|
|
20
|
+
messageSimple: {
|
|
21
|
+
loadingIndicator: { container },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
} = useTheme();
|
|
25
|
+
const { style, ...rest } = props;
|
|
26
|
+
return (
|
|
27
|
+
<View {...rest} accessibilityHint='image-loading' style={[styles.container, container, style]}>
|
|
28
|
+
<ActivityIndicator />
|
|
29
|
+
</View>
|
|
30
|
+
);
|
|
31
|
+
};
|