@sendbird/uikit-react-native 1.1.0 → 1.1.2
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/FileViewer.js +11 -13
- package/lib/commonjs/components/FileViewer.js.map +1 -1
- package/lib/commonjs/components/MessageRenderer/FileMessage/ImageFileMessage.js +47 -15
- package/lib/commonjs/components/MessageRenderer/FileMessage/ImageFileMessage.js.map +1 -1
- package/lib/commonjs/components/MessageRenderer/FileMessage/VideoFileMessage.js +51 -34
- package/lib/commonjs/components/MessageRenderer/FileMessage/VideoFileMessage.js.map +1 -1
- package/lib/commonjs/components/MessageRenderer/MessageIncomingSenderName.js +2 -1
- package/lib/commonjs/components/MessageRenderer/MessageIncomingSenderName.js.map +1 -1
- package/lib/commonjs/components/MessageRenderer/MessageOutgoingStatus.js +20 -56
- package/lib/commonjs/components/MessageRenderer/MessageOutgoingStatus.js.map +1 -1
- package/lib/commonjs/components/MessageRenderer/index.js +7 -2
- package/lib/commonjs/components/MessageRenderer/index.js.map +1 -1
- package/lib/commonjs/{components → containers}/GroupChannelPreviewContainer.js +30 -53
- package/lib/commonjs/containers/GroupChannelPreviewContainer.js.map +1 -0
- package/lib/commonjs/{InternalErrorBoundary.js → containers/InternalErrorBoundaryContainer.js} +5 -5
- package/lib/commonjs/containers/InternalErrorBoundaryContainer.js.map +1 -0
- package/lib/commonjs/{SendbirdUIKitContainer.js → containers/SendbirdUIKitContainer.js} +10 -10
- package/lib/commonjs/containers/SendbirdUIKitContainer.js.map +1 -0
- package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/SendInput.js +39 -6
- package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/SendInput.js.map +1 -1
- package/lib/commonjs/domain/groupChannelList/types.js.map +1 -1
- package/lib/commonjs/domain/groupChannelSettings/component/GroupChannelSettingsInfo.js +1 -1
- package/lib/commonjs/domain/groupChannelSettings/component/GroupChannelSettingsInfo.js.map +1 -1
- package/lib/commonjs/domain/groupChannelSettings/module/moduleContext.js +35 -2
- package/lib/commonjs/domain/groupChannelSettings/module/moduleContext.js.map +1 -1
- package/lib/commonjs/fragments/createGroupChannelFragment.js +1 -1
- package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
- package/lib/commonjs/fragments/createGroupChannelListFragment.js +6 -6
- package/lib/commonjs/fragments/createGroupChannelListFragment.js.map +1 -1
- package/lib/commonjs/index.js +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/{InternalLocalCacheStorage.js → libs/InternalLocalCacheStorage.js} +0 -0
- package/lib/commonjs/libs/InternalLocalCacheStorage.js.map +1 -0
- package/lib/commonjs/libs/SBUError.js +41 -0
- package/lib/commonjs/libs/SBUError.js.map +1 -0
- package/lib/commonjs/libs/SBUUtils.js +20 -0
- package/lib/commonjs/libs/SBUUtils.js.map +1 -0
- package/lib/commonjs/localization/StringSet.type.js +6 -0
- package/lib/commonjs/localization/StringSet.type.js.map +1 -1
- package/lib/commonjs/platform/createFileService.expo.js +6 -4
- package/lib/commonjs/platform/createFileService.expo.js.map +1 -1
- package/lib/commonjs/platform/createFileService.native.js +20 -8
- package/lib/commonjs/platform/createFileService.native.js.map +1 -1
- package/lib/commonjs/platform/types.js +4 -0
- package/lib/commonjs/platform/types.js.map +1 -1
- package/lib/commonjs/version.js +1 -1
- package/lib/commonjs/version.js.map +1 -1
- package/lib/module/components/FileViewer.js +13 -12
- package/lib/module/components/FileViewer.js.map +1 -1
- package/lib/module/components/MessageRenderer/FileMessage/ImageFileMessage.js +48 -17
- package/lib/module/components/MessageRenderer/FileMessage/ImageFileMessage.js.map +1 -1
- package/lib/module/components/MessageRenderer/FileMessage/VideoFileMessage.js +52 -35
- package/lib/module/components/MessageRenderer/FileMessage/VideoFileMessage.js.map +1 -1
- package/lib/module/components/MessageRenderer/MessageIncomingSenderName.js +2 -1
- package/lib/module/components/MessageRenderer/MessageIncomingSenderName.js.map +1 -1
- package/lib/module/components/MessageRenderer/MessageOutgoingStatus.js +17 -51
- package/lib/module/components/MessageRenderer/MessageOutgoingStatus.js.map +1 -1
- package/lib/module/components/MessageRenderer/index.js +7 -2
- package/lib/module/components/MessageRenderer/index.js.map +1 -1
- package/lib/module/{components → containers}/GroupChannelPreviewContainer.js +28 -51
- package/lib/module/containers/GroupChannelPreviewContainer.js.map +1 -0
- package/lib/module/{InternalErrorBoundary.js → containers/InternalErrorBoundaryContainer.js} +5 -5
- package/lib/module/containers/InternalErrorBoundaryContainer.js.map +1 -0
- package/lib/module/{SendbirdUIKitContainer.js → containers/SendbirdUIKitContainer.js} +10 -10
- package/lib/module/containers/SendbirdUIKitContainer.js.map +1 -0
- package/lib/module/domain/groupChannel/component/GroupChannelInput/SendInput.js +38 -7
- package/lib/module/domain/groupChannel/component/GroupChannelInput/SendInput.js.map +1 -1
- package/lib/module/domain/groupChannelList/types.js.map +1 -1
- package/lib/module/domain/groupChannelSettings/component/GroupChannelSettingsInfo.js +1 -1
- package/lib/module/domain/groupChannelSettings/component/GroupChannelSettingsInfo.js.map +1 -1
- package/lib/module/domain/groupChannelSettings/module/moduleContext.js +34 -3
- package/lib/module/domain/groupChannelSettings/module/moduleContext.js.map +1 -1
- package/lib/module/fragments/createGroupChannelFragment.js +1 -1
- package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
- package/lib/module/fragments/createGroupChannelListFragment.js +6 -6
- package/lib/module/fragments/createGroupChannelListFragment.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/{InternalLocalCacheStorage.js → libs/InternalLocalCacheStorage.js} +0 -0
- package/lib/module/libs/InternalLocalCacheStorage.js.map +1 -0
- package/lib/module/libs/SBUError.js +32 -0
- package/lib/module/libs/SBUError.js.map +1 -0
- package/lib/module/libs/SBUUtils.js +10 -0
- package/lib/module/libs/SBUUtils.js.map +1 -0
- package/lib/module/localization/StringSet.type.js +6 -0
- package/lib/module/localization/StringSet.type.js.map +1 -1
- package/lib/module/platform/createFileService.expo.js +5 -4
- package/lib/module/platform/createFileService.expo.js.map +1 -1
- package/lib/module/platform/createFileService.native.js +18 -8
- package/lib/module/platform/createFileService.native.js.map +1 -1
- package/lib/module/platform/types.js +1 -1
- package/lib/module/platform/types.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/module/version.js.map +1 -1
- package/lib/typescript/src/{components → containers}/GroupChannelPreviewContainer.d.ts +0 -0
- package/lib/typescript/src/{InternalErrorBoundary.d.ts → containers/InternalErrorBoundaryContainer.d.ts} +3 -3
- package/lib/typescript/src/{SendbirdUIKitContainer.d.ts → containers/SendbirdUIKitContainer.d.ts} +4 -4
- package/lib/typescript/src/domain/groupChannelList/types.d.ts +2 -2
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/{InternalLocalCacheStorage.d.ts → libs/InternalLocalCacheStorage.d.ts} +2 -2
- package/lib/typescript/src/libs/SBUError.d.ts +14 -0
- package/lib/typescript/src/libs/SBUUtils.d.ts +3 -0
- package/lib/typescript/src/localization/StringSet.type.d.ts +3 -0
- package/lib/typescript/src/platform/types.d.ts +2 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +5 -5
- package/src/components/FileViewer.tsx +19 -12
- package/src/components/MessageRenderer/FileMessage/ImageFileMessage.tsx +55 -12
- package/src/components/MessageRenderer/FileMessage/VideoFileMessage.tsx +38 -30
- package/src/components/MessageRenderer/MessageIncomingSenderName.tsx +1 -1
- package/src/components/MessageRenderer/MessageOutgoingStatus.tsx +13 -46
- package/src/components/MessageRenderer/index.tsx +5 -2
- package/src/{components → containers}/GroupChannelPreviewContainer.tsx +20 -37
- package/src/{InternalErrorBoundary.tsx → containers/InternalErrorBoundaryContainer.tsx} +4 -4
- package/src/{SendbirdUIKitContainer.tsx → containers/SendbirdUIKitContainer.tsx} +13 -13
- package/src/domain/groupChannel/component/GroupChannelInput/SendInput.tsx +28 -4
- package/src/domain/groupChannelList/types.ts +2 -2
- package/src/domain/groupChannelSettings/component/GroupChannelSettingsInfo.tsx +1 -1
- package/src/domain/groupChannelSettings/module/moduleContext.tsx +26 -3
- package/src/fragments/createGroupChannelFragment.tsx +1 -1
- package/src/fragments/createGroupChannelListFragment.tsx +6 -6
- package/src/index.ts +1 -1
- package/src/{InternalLocalCacheStorage.ts → libs/InternalLocalCacheStorage.ts} +1 -1
- package/src/libs/SBUError.ts +26 -0
- package/src/libs/SBUUtils.ts +9 -0
- package/src/localization/StringSet.type.ts +10 -0
- package/src/platform/createFileService.expo.ts +5 -4
- package/src/platform/createFileService.native.ts +17 -8
- package/src/platform/types.ts +3 -1
- package/src/version.ts +1 -1
- package/lib/commonjs/InternalErrorBoundary.js.map +0 -1
- package/lib/commonjs/InternalLocalCacheStorage.js.map +0 -1
- package/lib/commonjs/SendbirdUIKitContainer.js.map +0 -1
- package/lib/commonjs/components/GroupChannelPreviewContainer.js.map +0 -1
- package/lib/commonjs/components/SBUPressable.js +0 -45
- package/lib/commonjs/components/SBUPressable.js.map +0 -1
- package/lib/module/InternalErrorBoundary.js.map +0 -1
- package/lib/module/InternalLocalCacheStorage.js.map +0 -1
- package/lib/module/SendbirdUIKitContainer.js.map +0 -1
- package/lib/module/components/GroupChannelPreviewContainer.js.map +0 -1
- package/lib/module/components/SBUPressable.js +0 -33
- package/lib/module/components/SBUPressable.js.map +0 -1
- package/lib/typescript/src/components/SBUPressable.d.ts +0 -18
- package/src/components/SBUPressable.tsx +0 -40
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const VERSION = "1.1.
|
|
1
|
+
declare const VERSION = "1.1.2";
|
|
2
2
|
export default VERSION;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sendbird/uikit-react-native",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "react-native-uikit",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@sendbird/uikit-chat-hooks": "1.1.
|
|
45
|
-
"@sendbird/uikit-react-native-foundation": "1.1.
|
|
46
|
-
"@sendbird/uikit-utils": "1.1.
|
|
44
|
+
"@sendbird/uikit-chat-hooks": "1.1.2",
|
|
45
|
+
"@sendbird/uikit-react-native-foundation": "1.1.2",
|
|
46
|
+
"@sendbird/uikit-utils": "1.1.2"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@react-native-clipboard/clipboard": "^1.8.5",
|
|
@@ -159,5 +159,5 @@
|
|
|
159
159
|
"readmeFile": "./README.md",
|
|
160
160
|
"displayName": "@sendbird/uikit-react-native"
|
|
161
161
|
},
|
|
162
|
-
"gitHead": "
|
|
162
|
+
"gitHead": "3bfe51786e73bedc419116e447b79d6b57f9178c"
|
|
163
163
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
|
-
import { StatusBar, StyleSheet, View } from 'react-native';
|
|
2
|
+
import { StatusBar, StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
3
3
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
4
4
|
|
|
5
5
|
import {
|
|
@@ -14,10 +14,17 @@ import {
|
|
|
14
14
|
useUIKitTheme,
|
|
15
15
|
} from '@sendbird/uikit-react-native-foundation';
|
|
16
16
|
import type { SendbirdFileMessage } from '@sendbird/uikit-utils';
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
Logger,
|
|
19
|
+
getFileExtension,
|
|
20
|
+
getFileType,
|
|
21
|
+
isMyMessage,
|
|
22
|
+
toMegabyte,
|
|
23
|
+
truncate,
|
|
24
|
+
useIIFE,
|
|
25
|
+
} from '@sendbird/uikit-utils';
|
|
18
26
|
|
|
19
27
|
import { useLocalization, usePlatformService, useSendbirdChat } from '../hooks/useContext';
|
|
20
|
-
import SBUPressable from './SBUPressable';
|
|
21
28
|
|
|
22
29
|
type Props = {
|
|
23
30
|
fileMessage: SendbirdFileMessage;
|
|
@@ -191,14 +198,14 @@ const FileViewerHeader = ({ topInset, onClose, subtitle, title }: HeaderProps) =
|
|
|
191
198
|
{ paddingTop: topInset, height: defaultHeight + topInset, backgroundColor: palette.overlay01 },
|
|
192
199
|
]}
|
|
193
200
|
>
|
|
194
|
-
<
|
|
201
|
+
<TouchableOpacity onPress={onClose} style={styles.barButton}>
|
|
195
202
|
<Icon icon={'close'} size={24} color={palette.onBackgroundDark01} />
|
|
196
|
-
</
|
|
203
|
+
</TouchableOpacity>
|
|
197
204
|
<View style={styles.barTitleContainer}>
|
|
198
|
-
<Text h2 color={palette.onBackgroundDark01} style={styles.headerTitle}>
|
|
199
|
-
{title}
|
|
205
|
+
<Text h2 color={palette.onBackgroundDark01} style={styles.headerTitle} numberOfLines={1}>
|
|
206
|
+
{truncate(title, { mode: 'mid', maxLen: 18 })}
|
|
200
207
|
</Text>
|
|
201
|
-
<Text caption2 color={palette.onBackgroundDark01}>
|
|
208
|
+
<Text caption2 color={palette.onBackgroundDark01} numberOfLines={1}>
|
|
202
209
|
{subtitle}
|
|
203
210
|
</Text>
|
|
204
211
|
</View>
|
|
@@ -233,13 +240,13 @@ const FileViewerFooter = ({ bottomInset, deleteShown, onPressDelete, onPressDown
|
|
|
233
240
|
},
|
|
234
241
|
]}
|
|
235
242
|
>
|
|
236
|
-
<
|
|
243
|
+
<TouchableOpacity onPress={onPressDownload} style={styles.barButton}>
|
|
237
244
|
<Icon icon={'download'} size={24} color={palette.onBackgroundDark01} />
|
|
238
|
-
</
|
|
245
|
+
</TouchableOpacity>
|
|
239
246
|
<View style={styles.barTitleContainer} />
|
|
240
|
-
<
|
|
247
|
+
<TouchableOpacity onPress={onPressDelete} style={styles.barButton} disabled={!deleteShown}>
|
|
241
248
|
{deleteShown && <Icon icon={'delete'} size={24} color={palette.onBackgroundDark01} />}
|
|
242
|
-
</
|
|
249
|
+
</TouchableOpacity>
|
|
243
250
|
</View>
|
|
244
251
|
);
|
|
245
252
|
};
|
|
@@ -1,10 +1,39 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { Platform, StyleSheet, View } from 'react-native';
|
|
2
3
|
|
|
3
4
|
import { Icon, Image, createStyleSheet, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
|
|
4
|
-
import { getAvailableUriFromFileMessage } from '@sendbird/uikit-utils';
|
|
5
|
+
import { getAvailableUriFromFileMessage, useForceUpdate } from '@sendbird/uikit-utils';
|
|
5
6
|
|
|
6
7
|
import type { FileMessageProps } from './index';
|
|
7
8
|
|
|
9
|
+
const useRetry = (hasError: boolean, retryCount = 5) => {
|
|
10
|
+
if (Platform.OS === 'android') return '';
|
|
11
|
+
|
|
12
|
+
const forceUpdate = useForceUpdate();
|
|
13
|
+
const retryCountRef = useRef(1);
|
|
14
|
+
const retryTimeoutRef = useRef<NodeJS.Timeout>();
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (hasError) {
|
|
18
|
+
const reloadReservation = () => {
|
|
19
|
+
if (retryCountRef.current < retryCount) {
|
|
20
|
+
retryTimeoutRef.current = setTimeout(() => {
|
|
21
|
+
retryCountRef.current++;
|
|
22
|
+
reloadReservation();
|
|
23
|
+
forceUpdate();
|
|
24
|
+
}, retryCountRef.current * 5000);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
return reloadReservation();
|
|
29
|
+
} else {
|
|
30
|
+
return clearTimeout(retryTimeoutRef.current);
|
|
31
|
+
}
|
|
32
|
+
}, [hasError]);
|
|
33
|
+
|
|
34
|
+
return retryCountRef.current;
|
|
35
|
+
};
|
|
36
|
+
|
|
8
37
|
const ImageFileMessage = ({ message }: FileMessageProps) => {
|
|
9
38
|
const { colors } = useUIKitTheme();
|
|
10
39
|
const [imageNotFound, setImageNotFound] = useState(false);
|
|
@@ -12,18 +41,28 @@ const ImageFileMessage = ({ message }: FileMessageProps) => {
|
|
|
12
41
|
const fileUrl = getAvailableUriFromFileMessage(message);
|
|
13
42
|
const style = [styles.image, { backgroundColor: colors.onBackground04 }];
|
|
14
43
|
|
|
15
|
-
|
|
16
|
-
return <Icon containerStyle={style} icon={'thumbnail-none'} size={48} color={colors.onBackground02} />;
|
|
17
|
-
}
|
|
44
|
+
const key = useRetry(imageNotFound);
|
|
18
45
|
|
|
19
46
|
return (
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
47
|
+
<View style={style}>
|
|
48
|
+
<Image
|
|
49
|
+
key={key}
|
|
50
|
+
source={{ uri: fileUrl }}
|
|
51
|
+
style={[StyleSheet.absoluteFill, imageNotFound && styles.hide]}
|
|
52
|
+
resizeMode={'cover'}
|
|
53
|
+
resizeMethod={'resize'}
|
|
54
|
+
onError={() => setImageNotFound(true)}
|
|
55
|
+
onLoad={() => setImageNotFound(false)}
|
|
56
|
+
/>
|
|
57
|
+
{imageNotFound && (
|
|
58
|
+
<Icon
|
|
59
|
+
containerStyle={StyleSheet.absoluteFill}
|
|
60
|
+
icon={'thumbnail-none'}
|
|
61
|
+
size={48}
|
|
62
|
+
color={colors.onBackground02}
|
|
63
|
+
/>
|
|
64
|
+
)}
|
|
65
|
+
</View>
|
|
27
66
|
);
|
|
28
67
|
};
|
|
29
68
|
|
|
@@ -33,6 +72,10 @@ const styles = createStyleSheet({
|
|
|
33
72
|
maxWidth: 240,
|
|
34
73
|
height: 160,
|
|
35
74
|
borderRadius: 16,
|
|
75
|
+
overflow: 'hidden',
|
|
76
|
+
},
|
|
77
|
+
hide: {
|
|
78
|
+
display: 'none',
|
|
36
79
|
},
|
|
37
80
|
});
|
|
38
81
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { Icon, Image, createStyleSheet, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
|
|
@@ -7,35 +7,49 @@ import { getAvailableUriFromFileMessage } from '@sendbird/uikit-utils';
|
|
|
7
7
|
import { usePlatformService } from '../../../hooks/useContext';
|
|
8
8
|
import type { FileMessageProps } from './index';
|
|
9
9
|
|
|
10
|
-
const
|
|
11
|
-
const {
|
|
10
|
+
const useRetry = (videoFileUrl: string, retryCount = 5) => {
|
|
11
|
+
const [state, setState] = useState({ thumbnail: null as null | string, loading: true });
|
|
12
|
+
const retryCountRef = useRef(0);
|
|
13
|
+
const retryTimeoutRef = useRef<NodeJS.Timeout>();
|
|
12
14
|
|
|
13
15
|
const { mediaService } = usePlatformService();
|
|
14
|
-
const fileUrl = getAvailableUriFromFileMessage(message);
|
|
15
|
-
const style = [styles.image, { backgroundColor: colors.onBackground04 }];
|
|
16
16
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
17
|
+
const fetchThumbnail = () => {
|
|
18
|
+
return mediaService?.getVideoThumbnail({ url: videoFileUrl, timeMills: 1000 }).then((result) => {
|
|
19
|
+
setState({ loading: false, thumbnail: result?.path ?? null });
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
22
|
|
|
23
23
|
useEffect(() => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
if (!state.thumbnail) {
|
|
25
|
+
const reloadReservation = () => {
|
|
26
|
+
if (retryCountRef.current < retryCount) {
|
|
27
|
+
retryTimeoutRef.current = setTimeout(() => {
|
|
28
|
+
retryCountRef.current++;
|
|
29
|
+
reloadReservation();
|
|
30
|
+
fetchThumbnail();
|
|
31
|
+
}, retryCountRef.current * 5000);
|
|
31
32
|
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return reloadReservation();
|
|
36
|
+
} else {
|
|
37
|
+
return clearTimeout(retryTimeoutRef.current);
|
|
38
|
+
}
|
|
39
|
+
}, [state.thumbnail]);
|
|
40
|
+
|
|
41
|
+
return state;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const VideoFileMessage = ({ message }: FileMessageProps) => {
|
|
45
|
+
const { colors } = useUIKitTheme();
|
|
46
|
+
|
|
47
|
+
const fileUrl = getAvailableUriFromFileMessage(message);
|
|
48
|
+
const style = [styles.image, { backgroundColor: colors.onBackground04 }];
|
|
49
|
+
|
|
50
|
+
const { loading, thumbnail } = useRetry(fileUrl);
|
|
37
51
|
|
|
38
|
-
if (
|
|
52
|
+
if (loading) {
|
|
39
53
|
return (
|
|
40
54
|
<View style={[style, styles.container]}>
|
|
41
55
|
<PlayIcon />
|
|
@@ -45,13 +59,7 @@ const VideoFileMessage = ({ message }: FileMessageProps) => {
|
|
|
45
59
|
|
|
46
60
|
return (
|
|
47
61
|
<View style={styles.container}>
|
|
48
|
-
<Image
|
|
49
|
-
source={{ uri: state.thumbnail || fileUrl }}
|
|
50
|
-
style={style}
|
|
51
|
-
resizeMode={'cover'}
|
|
52
|
-
resizeMethod={'resize'}
|
|
53
|
-
onError={() => setState((prev) => ({ ...prev, imageNotFound: true }))}
|
|
54
|
-
/>
|
|
62
|
+
<Image source={{ uri: thumbnail || fileUrl }} style={style} resizeMode={'cover'} resizeMethod={'resize'} />
|
|
55
63
|
<PlayIcon />
|
|
56
64
|
</View>
|
|
57
65
|
);
|
|
@@ -18,7 +18,7 @@ const MessageIncomingSenderName = ({ message, grouping }: Props) => {
|
|
|
18
18
|
return (
|
|
19
19
|
<View style={styles.sender}>
|
|
20
20
|
{(message.isFileMessage() || message.isUserMessage()) && (
|
|
21
|
-
<Text caption1 color={colors.ui.message.incoming.enabled.textSenderName}>
|
|
21
|
+
<Text caption1 color={colors.ui.message.incoming.enabled.textSenderName} numberOfLines={1}>
|
|
22
22
|
{message.sender?.nickname || STRINGS.LABELS.USER_NO_NAME}
|
|
23
23
|
</Text>
|
|
24
24
|
)}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
|
|
3
|
+
import { useMessageOutgoingStatus } from '@sendbird/uikit-chat-hooks';
|
|
3
4
|
import { Icon, LoadingSpinner, createStyleSheet, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
|
|
4
5
|
import type { SendbirdGroupChannel, SendbirdMessage } from '@sendbird/uikit-utils';
|
|
5
|
-
import { isDifferentChannel, useForceUpdate, useUniqId } from '@sendbird/uikit-utils';
|
|
6
6
|
|
|
7
7
|
import { useSendbirdChat } from '../../hooks/useContext';
|
|
8
8
|
|
|
@@ -12,64 +12,31 @@ type Props = { channel: SendbirdGroupChannel; message: SendbirdMessage };
|
|
|
12
12
|
const MessageOutgoingStatus = ({ channel, message }: Props) => {
|
|
13
13
|
if (!message.isUserMessage() && !message.isFileMessage()) return null;
|
|
14
14
|
|
|
15
|
-
const { sdk
|
|
15
|
+
const { sdk } = useSendbirdChat();
|
|
16
16
|
const { colors } = useUIKitTheme();
|
|
17
|
+
const outgoingStatus = useMessageOutgoingStatus(sdk, channel, message);
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
const forceUpdate = useForceUpdate();
|
|
20
|
-
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
const handlerId = `MessageOutgoingStatus_${uniqId}`;
|
|
23
|
-
|
|
24
|
-
if (
|
|
25
|
-
message.sendingStatus === 'succeeded' &&
|
|
26
|
-
channel.getUnreadMemberCount(message) === 0 &&
|
|
27
|
-
channel.getUndeliveredMemberCount(message) === 0
|
|
28
|
-
) {
|
|
29
|
-
sdk.removeChannelHandler(handlerId);
|
|
30
|
-
} else {
|
|
31
|
-
const handler = new sdk.ChannelHandler();
|
|
32
|
-
|
|
33
|
-
handler.onReadReceiptUpdated = (eventChannel) => {
|
|
34
|
-
if (isDifferentChannel(channel, eventChannel)) return;
|
|
35
|
-
forceUpdate();
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
if (features.deliveryReceiptEnabled) {
|
|
39
|
-
handler.onDeliveryReceiptUpdated = (eventChannel) => {
|
|
40
|
-
if (isDifferentChannel(channel, eventChannel)) return;
|
|
41
|
-
forceUpdate();
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
sdk.addChannelHandler(handlerId, handler);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return () => {
|
|
49
|
-
sdk.removeChannelHandler(handlerId);
|
|
50
|
-
};
|
|
51
|
-
}, [message.sendingStatus]);
|
|
52
|
-
|
|
53
|
-
if (message.sendingStatus === 'pending') {
|
|
19
|
+
if (outgoingStatus === 'PENDING') {
|
|
54
20
|
return <LoadingSpinner size={SIZE} style={styles.container} />;
|
|
55
21
|
}
|
|
56
22
|
|
|
57
|
-
if (
|
|
23
|
+
if (outgoingStatus === 'FAILED') {
|
|
58
24
|
return <Icon icon={'error'} size={SIZE} color={colors.error} style={styles.container} />;
|
|
59
25
|
}
|
|
60
26
|
|
|
61
|
-
if (
|
|
27
|
+
if (outgoingStatus === 'READ') {
|
|
62
28
|
return <Icon icon={'done-all'} size={SIZE} color={colors.secondary} style={styles.container} />;
|
|
63
29
|
}
|
|
64
30
|
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
31
|
+
if (outgoingStatus === 'UNREAD' || outgoingStatus === 'DELIVERED') {
|
|
32
|
+
return <Icon icon={'done-all'} size={SIZE} color={colors.onBackground03} style={styles.container} />;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (outgoingStatus === 'UNDELIVERED') {
|
|
69
36
|
return <Icon icon={'done'} size={SIZE} color={colors.onBackground03} style={styles.container} />;
|
|
70
37
|
}
|
|
71
38
|
|
|
72
|
-
return
|
|
39
|
+
return null;
|
|
73
40
|
};
|
|
74
41
|
|
|
75
42
|
const styles = createStyleSheet({
|
|
@@ -107,9 +107,9 @@ const MessageRenderer: GroupChannelProps['Fragment']['renderMessage'] = ({
|
|
|
107
107
|
</View>
|
|
108
108
|
)}
|
|
109
109
|
{isIncoming && <MessageIncomingAvatar message={message} grouping={groupWithNext} />}
|
|
110
|
-
<View>
|
|
110
|
+
<View style={styles.bubbleContainer}>
|
|
111
111
|
{isIncoming && <MessageIncomingSenderName message={message} grouping={groupWithPrev} />}
|
|
112
|
-
<View style={styles.
|
|
112
|
+
<View style={styles.bubbleWrapper}>
|
|
113
113
|
{messageComponent}
|
|
114
114
|
{isIncoming && <MessageTime message={message} grouping={groupWithNext} style={styles.timeIncoming} />}
|
|
115
115
|
</View>
|
|
@@ -150,6 +150,9 @@ const styles = createStyleSheet({
|
|
|
150
150
|
maxWidth: 240,
|
|
151
151
|
},
|
|
152
152
|
bubbleContainer: {
|
|
153
|
+
flexShrink: 1,
|
|
154
|
+
},
|
|
155
|
+
bubbleWrapper: {
|
|
153
156
|
flexDirection: 'row',
|
|
154
157
|
alignItems: 'flex-end',
|
|
155
158
|
},
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
|
+
import { Pressable } from 'react-native';
|
|
2
3
|
|
|
3
|
-
import { useChannelHandler } from '@sendbird/uikit-chat-hooks';
|
|
4
|
+
import { useChannelHandler, useMessageOutgoingStatus } from '@sendbird/uikit-chat-hooks';
|
|
4
5
|
import {
|
|
5
6
|
GroupChannelPreview,
|
|
7
|
+
Icon,
|
|
6
8
|
LoadingSpinner,
|
|
7
9
|
createStyleSheet,
|
|
8
10
|
useUIKitTheme,
|
|
9
11
|
} from '@sendbird/uikit-react-native-foundation';
|
|
10
|
-
import Icon from '@sendbird/uikit-react-native-foundation/src/ui/Icon';
|
|
11
12
|
import {
|
|
12
13
|
SendbirdGroupChannel,
|
|
13
14
|
SendbirdUser,
|
|
@@ -15,14 +16,13 @@ import {
|
|
|
15
16
|
getFileType,
|
|
16
17
|
isDifferentChannel,
|
|
17
18
|
isMyMessage,
|
|
18
|
-
useForceUpdate,
|
|
19
19
|
useIIFE,
|
|
20
20
|
useUniqId,
|
|
21
21
|
} from '@sendbird/uikit-utils';
|
|
22
22
|
|
|
23
|
+
import ChannelCover from '../components/ChannelCover';
|
|
24
|
+
import { DEFAULT_LONG_PRESS_DELAY } from '../constants';
|
|
23
25
|
import { useLocalization, useSendbirdChat } from '../hooks/useContext';
|
|
24
|
-
import ChannelCover from './ChannelCover';
|
|
25
|
-
import SBUPressable from './SBUPressable';
|
|
26
26
|
|
|
27
27
|
const iconMapper = { audio: 'file-audio', image: 'photo', video: 'play', file: 'file-document' } as const;
|
|
28
28
|
|
|
@@ -37,7 +37,6 @@ const GroupChannelPreviewContainer = ({ onPress, onLongPress, channel }: Props)
|
|
|
37
37
|
const { colors } = useUIKitTheme();
|
|
38
38
|
|
|
39
39
|
const [typingUsers, setTypingUsers] = useState<SendbirdUser[]>([]);
|
|
40
|
-
const forceUpdate = useForceUpdate();
|
|
41
40
|
|
|
42
41
|
if (features.channelListTypingIndicatorEnabled) {
|
|
43
42
|
const typingId = useUniqId('GroupChannelPreviewContainer');
|
|
@@ -49,25 +48,7 @@ const GroupChannelPreviewContainer = ({ onPress, onLongPress, channel }: Props)
|
|
|
49
48
|
});
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
const receiptId = useUniqId('GroupChannelPreviewContainer');
|
|
54
|
-
useChannelHandler(sdk, `GroupChannelPreviewContainer_ReceiptStatus_${receiptId}`, {
|
|
55
|
-
onDeliveryReceiptUpdated(eventChannel) {
|
|
56
|
-
if (isDifferentChannel(channel, eventChannel)) return;
|
|
57
|
-
if (!eventChannel.isGroupChannel() || !eventChannel.lastMessage) return;
|
|
58
|
-
if (!isMyMessage(eventChannel.lastMessage, currentUser?.userId)) return;
|
|
59
|
-
|
|
60
|
-
forceUpdate();
|
|
61
|
-
},
|
|
62
|
-
onReadReceiptUpdated(eventChannel) {
|
|
63
|
-
if (isDifferentChannel(channel, eventChannel)) return;
|
|
64
|
-
if (!eventChannel.isGroupChannel() || !eventChannel.lastMessage) return;
|
|
65
|
-
if (!isMyMessage(eventChannel.lastMessage, currentUser?.userId)) return;
|
|
66
|
-
|
|
67
|
-
forceUpdate();
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
}
|
|
51
|
+
const outgoingStatus = useMessageOutgoingStatus(sdk, channel, channel.lastMessage);
|
|
71
52
|
|
|
72
53
|
const bodyText = useIIFE(() => {
|
|
73
54
|
if (typingUsers.length > 0) return STRINGS.LABELS.TYPING_INDICATOR_TYPINGS(typingUsers) || '';
|
|
@@ -76,6 +57,7 @@ const GroupChannelPreviewContainer = ({ onPress, onLongPress, channel }: Props)
|
|
|
76
57
|
|
|
77
58
|
const bodyIcon = useIIFE(() => {
|
|
78
59
|
if (!channel.lastMessage?.isFileMessage()) return undefined;
|
|
60
|
+
if (typingUsers.length > 0) return undefined;
|
|
79
61
|
return iconMapper[getFileType(channel.lastMessage.type || getFileExtension(channel.lastMessage.name))];
|
|
80
62
|
});
|
|
81
63
|
|
|
@@ -84,30 +66,31 @@ const GroupChannelPreviewContainer = ({ onPress, onLongPress, channel }: Props)
|
|
|
84
66
|
if (!features.channelListMessageReceiptStatusEnabled) return undefined;
|
|
85
67
|
if (!isMyMessage(channel.lastMessage, currentUser?.userId)) return undefined;
|
|
86
68
|
|
|
87
|
-
if (
|
|
69
|
+
if (outgoingStatus === 'PENDING') {
|
|
88
70
|
return <LoadingSpinner size={16} style={styles.titleCaptionIcon} />;
|
|
89
71
|
}
|
|
90
72
|
|
|
91
|
-
if (
|
|
73
|
+
if (outgoingStatus === 'FAILED') {
|
|
92
74
|
return <Icon icon={'error'} size={16} color={colors.error} style={styles.titleCaptionIcon} />;
|
|
93
75
|
}
|
|
94
76
|
|
|
95
|
-
if (
|
|
96
|
-
return <Icon icon={'done
|
|
77
|
+
if (outgoingStatus === 'UNDELIVERED') {
|
|
78
|
+
return <Icon icon={'done'} size={16} color={colors.onBackground03} containerStyle={styles.titleCaptionIcon} />;
|
|
97
79
|
}
|
|
98
80
|
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
81
|
+
if (outgoingStatus === 'DELIVERED' || outgoingStatus === 'UNREAD') {
|
|
82
|
+
return <Icon icon={'done-all'} size={16} color={colors.onBackground03} style={styles.titleCaptionIcon} />;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (outgoingStatus === 'READ') {
|
|
86
|
+
return <Icon icon={'done-all'} size={16} color={colors.secondary} style={styles.titleCaptionIcon} />;
|
|
104
87
|
}
|
|
105
88
|
|
|
106
|
-
return
|
|
89
|
+
return undefined;
|
|
107
90
|
});
|
|
108
91
|
|
|
109
92
|
return (
|
|
110
|
-
<
|
|
93
|
+
<Pressable delayLongPress={DEFAULT_LONG_PRESS_DELAY} onPress={onPress} onLongPress={onLongPress}>
|
|
111
94
|
<GroupChannelPreview
|
|
112
95
|
customCover={<ChannelCover channel={channel} size={56} />}
|
|
113
96
|
coverUrl={channel.coverUrl}
|
|
@@ -121,7 +104,7 @@ const GroupChannelPreviewContainer = ({ onPress, onLongPress, channel }: Props)
|
|
|
121
104
|
frozen={channel.isFrozen}
|
|
122
105
|
notificationOff={channel.myPushTriggerOption === 'off'}
|
|
123
106
|
/>
|
|
124
|
-
</
|
|
107
|
+
</Pressable>
|
|
125
108
|
);
|
|
126
109
|
};
|
|
127
110
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { ErrorInfo } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
|
|
4
|
-
import TypedPlaceholder from '
|
|
5
|
-
import type { ErrorBoundaryProps } from '
|
|
4
|
+
import TypedPlaceholder from '../components/TypedPlaceholder';
|
|
5
|
+
import type { ErrorBoundaryProps } from '../types';
|
|
6
6
|
|
|
7
7
|
const DefaultErrorBoundaryComponent = (props: ErrorBoundaryProps) => {
|
|
8
8
|
return (
|
|
@@ -12,7 +12,7 @@ const DefaultErrorBoundaryComponent = (props: ErrorBoundaryProps) => {
|
|
|
12
12
|
);
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
class
|
|
15
|
+
class InternalErrorBoundaryContainer extends React.PureComponent<{
|
|
16
16
|
onError?: (props: ErrorBoundaryProps) => void;
|
|
17
17
|
ErrorInfoComponent?: (props: ErrorBoundaryProps) => JSX.Element;
|
|
18
18
|
children?: React.ReactNode;
|
|
@@ -50,4 +50,4 @@ class InternalErrorBoundary extends React.PureComponent<{
|
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
export default
|
|
53
|
+
export default InternalErrorBoundaryContainer;
|
|
@@ -14,23 +14,23 @@ import {
|
|
|
14
14
|
} from '@sendbird/uikit-react-native-foundation';
|
|
15
15
|
import type { SendbirdChatSDK } from '@sendbird/uikit-utils';
|
|
16
16
|
|
|
17
|
-
import
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
import
|
|
24
|
-
import
|
|
25
|
-
import SBUDynamicModule from './platform/dynamicModule';
|
|
17
|
+
import { LocalizationProvider } from '../contexts/Localization';
|
|
18
|
+
import { PlatformServiceProvider } from '../contexts/PlatformService';
|
|
19
|
+
import { SendbirdChatProvider } from '../contexts/SendbirdChat';
|
|
20
|
+
import { useLocalization } from '../hooks/useContext';
|
|
21
|
+
import InternalLocalCacheStorage from '../libs/InternalLocalCacheStorage';
|
|
22
|
+
import StringSetEn from '../localization/StringSet.en';
|
|
23
|
+
import type { StringSet } from '../localization/StringSet.type';
|
|
24
|
+
import SBUDynamicModule from '../platform/dynamicModule';
|
|
26
25
|
import type {
|
|
27
26
|
ClipboardServiceInterface,
|
|
28
27
|
FileServiceInterface,
|
|
29
28
|
MediaServiceInterface,
|
|
30
29
|
NotificationServiceInterface,
|
|
31
|
-
} from '
|
|
32
|
-
import type { ErrorBoundaryProps, LocalCacheStorage } from '
|
|
33
|
-
import VERSION from '
|
|
30
|
+
} from '../platform/types';
|
|
31
|
+
import type { ErrorBoundaryProps, LocalCacheStorage } from '../types';
|
|
32
|
+
import VERSION from '../version';
|
|
33
|
+
import InternalErrorBoundaryContainer from './InternalErrorBoundaryContainer';
|
|
34
34
|
|
|
35
35
|
const NetInfo = SBUDynamicModule.get('@react-native-community/netinfo', 'warn');
|
|
36
36
|
|
|
@@ -159,7 +159,7 @@ const SendbirdUIKitContainer = ({
|
|
|
159
159
|
>
|
|
160
160
|
<LocalizedDialogProvider>
|
|
161
161
|
<ToastProvider dismissTimeout={toast?.dismissTimeout}>
|
|
162
|
-
<
|
|
162
|
+
<InternalErrorBoundaryContainer {...errorBoundary}>{children}</InternalErrorBoundaryContainer>
|
|
163
163
|
</ToastProvider>
|
|
164
164
|
</LocalizedDialogProvider>
|
|
165
165
|
</HeaderStyleProvider>
|