@sendbird/uikit-react-native-foundation 3.0.4 → 3.1.1
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/Icon/index.js +12 -0
- package/lib/commonjs/components/Icon/index.js.map +1 -1
- package/lib/commonjs/components/VideoThumbnail/index.js +115 -0
- package/lib/commonjs/components/VideoThumbnail/index.js.map +1 -0
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/theme/DarkUIKitTheme.js +2 -1
- package/lib/commonjs/theme/DarkUIKitTheme.js.map +1 -1
- package/lib/commonjs/theme/LightUIKitTheme.js +2 -1
- package/lib/commonjs/theme/LightUIKitTheme.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/ui/BottomSheet/index.js +1 -0
- package/lib/commonjs/ui/BottomSheet/index.js.map +1 -1
- package/lib/commonjs/ui/Dialog/DialogSheet.js +4 -3
- package/lib/commonjs/ui/Dialog/DialogSheet.js.map +1 -1
- package/lib/commonjs/ui/GroupChannelMessage/Message.file.image.js +1 -1
- package/lib/commonjs/ui/GroupChannelMessage/Message.file.image.js.map +1 -1
- package/lib/commonjs/ui/GroupChannelMessage/Message.file.js +6 -9
- package/lib/commonjs/ui/GroupChannelMessage/Message.file.js.map +1 -1
- package/lib/commonjs/ui/GroupChannelMessage/Message.file.video.js +10 -72
- package/lib/commonjs/ui/GroupChannelMessage/Message.file.video.js.map +1 -1
- package/lib/commonjs/ui/GroupChannelMessage/MessageContainer.js +7 -5
- package/lib/commonjs/ui/GroupChannelMessage/MessageContainer.js.map +1 -1
- package/lib/commonjs/ui/GroupChannelMessage/MessageOpenGraph.js +2 -2
- package/lib/commonjs/ui/GroupChannelMessage/MessageOpenGraph.js.map +1 -1
- package/lib/commonjs/ui/GroupChannelMessage/index.js.map +1 -1
- package/lib/commonjs/ui/OpenChannelMessage/Message.file.image.js +1 -1
- package/lib/commonjs/ui/OpenChannelMessage/Message.file.image.js.map +1 -1
- package/lib/commonjs/ui/OpenChannelMessage/Message.file.js +2 -8
- package/lib/commonjs/ui/OpenChannelMessage/Message.file.js.map +1 -1
- package/lib/commonjs/ui/OpenChannelMessage/Message.file.video.js +11 -78
- package/lib/commonjs/ui/OpenChannelMessage/Message.file.video.js.map +1 -1
- package/lib/commonjs/ui/OpenChannelMessage/Message.user.og.js +1 -1
- package/lib/commonjs/ui/OpenChannelMessage/Message.user.og.js.map +1 -1
- package/lib/module/components/Icon/index.js +12 -0
- package/lib/module/components/Icon/index.js.map +1 -1
- package/lib/module/components/VideoThumbnail/index.js +105 -0
- package/lib/module/components/VideoThumbnail/index.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/theme/DarkUIKitTheme.js +2 -1
- package/lib/module/theme/DarkUIKitTheme.js.map +1 -1
- package/lib/module/theme/LightUIKitTheme.js +2 -1
- package/lib/module/theme/LightUIKitTheme.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/ui/BottomSheet/index.js +1 -0
- package/lib/module/ui/BottomSheet/index.js.map +1 -1
- package/lib/module/ui/Dialog/DialogSheet.js +4 -3
- package/lib/module/ui/Dialog/DialogSheet.js.map +1 -1
- package/lib/module/ui/GroupChannelMessage/Message.file.image.js +2 -2
- package/lib/module/ui/GroupChannelMessage/Message.file.image.js.map +1 -1
- package/lib/module/ui/GroupChannelMessage/Message.file.js +7 -10
- package/lib/module/ui/GroupChannelMessage/Message.file.js.map +1 -1
- package/lib/module/ui/GroupChannelMessage/Message.file.video.js +11 -71
- package/lib/module/ui/GroupChannelMessage/Message.file.video.js.map +1 -1
- package/lib/module/ui/GroupChannelMessage/MessageContainer.js +7 -5
- package/lib/module/ui/GroupChannelMessage/MessageContainer.js.map +1 -1
- package/lib/module/ui/GroupChannelMessage/MessageOpenGraph.js +2 -2
- package/lib/module/ui/GroupChannelMessage/MessageOpenGraph.js.map +1 -1
- package/lib/module/ui/GroupChannelMessage/index.js.map +1 -1
- package/lib/module/ui/OpenChannelMessage/Message.file.image.js +2 -2
- package/lib/module/ui/OpenChannelMessage/Message.file.image.js.map +1 -1
- package/lib/module/ui/OpenChannelMessage/Message.file.js +2 -8
- package/lib/module/ui/OpenChannelMessage/Message.file.js.map +1 -1
- package/lib/module/ui/OpenChannelMessage/Message.file.video.js +12 -77
- package/lib/module/ui/OpenChannelMessage/Message.file.video.js.map +1 -1
- package/lib/module/ui/OpenChannelMessage/Message.user.og.js +1 -1
- package/lib/module/ui/OpenChannelMessage/Message.user.og.js.map +1 -1
- package/lib/typescript/src/components/Icon/index.d.ts +5 -0
- package/lib/typescript/src/components/VideoThumbnail/index.d.ts +13 -0
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/types.d.ts +1 -1
- package/lib/typescript/src/ui/BottomSheet/index.d.ts +1 -0
- package/lib/typescript/src/ui/Dialog/DialogSheet.d.ts +2 -1
- package/lib/typescript/src/ui/GroupChannelMessage/MessageContainer.d.ts +2 -2
- package/lib/typescript/src/ui/GroupChannelMessage/MessageOpenGraph.d.ts +1 -1
- package/lib/typescript/src/ui/GroupChannelMessage/index.d.ts +8 -0
- package/package.json +3 -3
- package/src/components/Icon/index.tsx +11 -7
- package/src/components/VideoThumbnail/index.tsx +107 -0
- package/src/index.ts +1 -0
- package/src/theme/DarkUIKitTheme.ts +1 -0
- package/src/theme/LightUIKitTheme.ts +1 -0
- package/src/types.ts +1 -1
- package/src/ui/BottomSheet/index.tsx +2 -0
- package/src/ui/Dialog/DialogSheet.tsx +6 -3
- package/src/ui/GroupChannelMessage/Message.file.image.tsx +2 -2
- package/src/ui/GroupChannelMessage/Message.file.tsx +4 -6
- package/src/ui/GroupChannelMessage/Message.file.video.tsx +12 -60
- package/src/ui/GroupChannelMessage/MessageContainer.tsx +18 -13
- package/src/ui/GroupChannelMessage/MessageOpenGraph.tsx +3 -3
- package/src/ui/GroupChannelMessage/index.ts +1 -0
- package/src/ui/OpenChannelMessage/Message.file.image.tsx +2 -2
- package/src/ui/OpenChannelMessage/Message.file.tsx +1 -3
- package/src/ui/OpenChannelMessage/Message.file.video.tsx +12 -55
- package/src/ui/OpenChannelMessage/Message.user.og.tsx +1 -1
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ export type { RegexTextPattern } from './components/RegexText';
|
|
|
14
14
|
export { default as Switch } from './components/Switch';
|
|
15
15
|
export { default as Text } from './components/Text';
|
|
16
16
|
export { default as TextInput } from './components/TextInput';
|
|
17
|
+
export { VideoThumbnail } from './components/VideoThumbnail';
|
|
17
18
|
|
|
18
19
|
/** UI **/
|
|
19
20
|
export { default as ActionMenu } from './ui/ActionMenu';
|
package/src/types.ts
CHANGED
|
@@ -93,7 +93,7 @@ export type ComponentColorTree = GetColorTree<{
|
|
|
93
93
|
ColorPart: {
|
|
94
94
|
Header: 'background' | 'borderBottom';
|
|
95
95
|
Button: 'background' | 'content';
|
|
96
|
-
Dialog: 'background' | 'text' | 'message' | 'highlight' | 'destructive';
|
|
96
|
+
Dialog: 'background' | 'text' | 'message' | 'highlight' | 'destructive' | 'blurred';
|
|
97
97
|
Input: 'text' | 'placeholder' | 'background' | 'highlight';
|
|
98
98
|
Badge: 'text' | 'background';
|
|
99
99
|
Placeholder: 'content' | 'highlight';
|
|
@@ -14,6 +14,7 @@ export type BottomSheetItem = {
|
|
|
14
14
|
iconColor?: string;
|
|
15
15
|
title: string;
|
|
16
16
|
titleColor?: string;
|
|
17
|
+
disabled?: boolean;
|
|
17
18
|
onPress: () => void;
|
|
18
19
|
}[];
|
|
19
20
|
HeaderComponent?: (props: HeaderProps) => JSX.Element;
|
|
@@ -44,6 +45,7 @@ const BottomSheet = ({ onDismiss, onHide, visible, sheetItems, HeaderComponent }
|
|
|
44
45
|
activeOpacity={0.75}
|
|
45
46
|
key={props.title + idx}
|
|
46
47
|
style={{ paddingLeft: left, paddingRight: right }}
|
|
48
|
+
disabled={props.disabled}
|
|
47
49
|
onPress={async () => {
|
|
48
50
|
await onHide();
|
|
49
51
|
try {
|
|
@@ -23,22 +23,25 @@ export type SheetItemProps = {
|
|
|
23
23
|
iconColor?: string;
|
|
24
24
|
title: string;
|
|
25
25
|
titleColor?: string;
|
|
26
|
+
disabled?: boolean;
|
|
26
27
|
};
|
|
27
|
-
const SheetItem = ({ icon, title, iconColor, titleColor }: SheetItemProps) => {
|
|
28
|
+
const SheetItem = ({ icon, title, iconColor, titleColor, disabled = false }: SheetItemProps) => {
|
|
28
29
|
const { colors } = useUIKitTheme();
|
|
29
30
|
return (
|
|
30
31
|
<View style={[styles.sheetItemContainer, { backgroundColor: colors.ui.dialog.default.none.background }]}>
|
|
31
32
|
{icon && (
|
|
32
33
|
<Icon
|
|
33
34
|
icon={icon}
|
|
34
|
-
color={
|
|
35
|
+
color={
|
|
36
|
+
iconColor ?? (disabled ? colors.ui.dialog.default.none.blurred : colors.ui.dialog.default.none.highlight)
|
|
37
|
+
}
|
|
35
38
|
containerStyle={styles.sheetItemIcon}
|
|
36
39
|
/>
|
|
37
40
|
)}
|
|
38
41
|
<Text
|
|
39
42
|
subtitle1
|
|
40
43
|
numberOfLines={1}
|
|
41
|
-
color={titleColor ?? colors.ui.dialog.default.none.text}
|
|
44
|
+
color={titleColor ?? (disabled ? colors.ui.dialog.default.none.blurred : colors.ui.dialog.default.none.text)}
|
|
42
45
|
style={styles.sheetItemText}
|
|
43
46
|
>
|
|
44
47
|
{title}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import type { SendbirdFileMessage } from '@sendbird/uikit-utils';
|
|
4
|
-
import {
|
|
4
|
+
import { getThumbnailUriFromFileMessage } from '@sendbird/uikit-utils';
|
|
5
5
|
|
|
6
6
|
import Box from '../../components/Box';
|
|
7
7
|
import ImageWithPlaceholder from '../../components/ImageWithPlaceholder';
|
|
@@ -20,7 +20,7 @@ const ImageFileMessage = (props: GroupChannelMessageProps<SendbirdFileMessage>)
|
|
|
20
20
|
<MessageContainer {...props}>
|
|
21
21
|
<Box style={styles.container} backgroundColor={colors.ui.groupChannelMessage[variant].enabled.background}>
|
|
22
22
|
<PressBox activeOpacity={0.8} onPress={onPress} onLongPress={onLongPress}>
|
|
23
|
-
<ImageWithPlaceholder source={{ uri:
|
|
23
|
+
<ImageWithPlaceholder source={{ uri: getThumbnailUriFromFileMessage(props.message) }} style={styles.image} />
|
|
24
24
|
</PressBox>
|
|
25
25
|
{props.children}
|
|
26
26
|
</Box>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { SendbirdFileMessage, getFileExtension, getFileType } from '@sendbird/uikit-utils';
|
|
3
|
+
import { SendbirdFileMessage, getFileExtension, getFileType, truncate } from '@sendbird/uikit-utils';
|
|
4
4
|
|
|
5
5
|
import Box from '../../components/Box';
|
|
6
6
|
import Icon from '../../components/Icon';
|
|
@@ -11,8 +11,6 @@ import useUIKitTheme from '../../theme/useUIKitTheme';
|
|
|
11
11
|
import MessageContainer from './MessageContainer';
|
|
12
12
|
import type { GroupChannelMessageProps } from './index';
|
|
13
13
|
|
|
14
|
-
const iconMapper = { audio: 'file-audio', image: 'photo', video: 'play', file: 'file-document' } as const;
|
|
15
|
-
|
|
16
14
|
type Props = GroupChannelMessageProps<SendbirdFileMessage>;
|
|
17
15
|
|
|
18
16
|
const FileMessage = (props: Props) => {
|
|
@@ -28,8 +26,8 @@ const FileMessage = (props: Props) => {
|
|
|
28
26
|
{({ pressed }) => (
|
|
29
27
|
<Box backgroundColor={pressed ? color.pressed.background : color.enabled.background} style={styles.container}>
|
|
30
28
|
<Box style={styles.bubble}>
|
|
31
|
-
<Icon
|
|
32
|
-
|
|
29
|
+
<Icon.File
|
|
30
|
+
fileType={fileType}
|
|
33
31
|
size={24}
|
|
34
32
|
containerStyle={{ backgroundColor: colors.background, padding: 2, borderRadius: 8, marginRight: 8 }}
|
|
35
33
|
/>
|
|
@@ -40,7 +38,7 @@ const FileMessage = (props: Props) => {
|
|
|
40
38
|
color={pressed ? color.pressed.textMsg : color.enabled.textMsg}
|
|
41
39
|
style={styles.name}
|
|
42
40
|
>
|
|
43
|
-
{props.strings?.fileName || props.message.name}
|
|
41
|
+
{truncate(props.strings?.fileName || props.message.name, { mode: 'mid', maxLen: 20 })}
|
|
44
42
|
</Text>
|
|
45
43
|
</Box>
|
|
46
44
|
{props.children}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import { StyleSheet } from 'react-native';
|
|
1
|
+
import React from 'react';
|
|
3
2
|
|
|
4
3
|
import type { SendbirdFileMessage } from '@sendbird/uikit-utils';
|
|
5
|
-
import {
|
|
4
|
+
import { getThumbnailUriFromFileMessage } from '@sendbird/uikit-utils';
|
|
6
5
|
|
|
7
6
|
import Box from '../../components/Box';
|
|
8
|
-
import Icon from '../../components/Icon';
|
|
9
|
-
import ImageWithPlaceholder from '../../components/ImageWithPlaceholder';
|
|
10
7
|
import PressBox from '../../components/PressBox';
|
|
8
|
+
import { VideoThumbnail } from '../../components/VideoThumbnail';
|
|
11
9
|
import createStyleSheet from '../../styles/createStyleSheet';
|
|
12
10
|
import useUIKitTheme from '../../theme/useUIKitTheme';
|
|
13
11
|
import MessageContainer from './MessageContainer';
|
|
@@ -15,41 +13,24 @@ import type { GroupChannelMessageProps } from './index';
|
|
|
15
13
|
|
|
16
14
|
type Props = GroupChannelMessageProps<
|
|
17
15
|
SendbirdFileMessage,
|
|
18
|
-
{
|
|
19
|
-
fetchThumbnailFromVideoSource: (uri: string) => Promise<{ path: string } | null>;
|
|
20
|
-
}
|
|
16
|
+
{ fetchThumbnailFromVideoSource: (uri: string) => Promise<{ path: string } | null> }
|
|
21
17
|
>;
|
|
22
18
|
|
|
23
19
|
const VideoFileMessage = (props: Props) => {
|
|
24
20
|
const { onPress, onLongPress, variant = 'incoming' } = props;
|
|
25
21
|
|
|
26
|
-
const { colors
|
|
27
|
-
const uri =
|
|
28
|
-
const { thumbnail, loading } = useRetry(() => props.fetchThumbnailFromVideoSource(uri));
|
|
22
|
+
const { colors } = useUIKitTheme();
|
|
23
|
+
const uri = getThumbnailUriFromFileMessage(props.message);
|
|
29
24
|
|
|
30
25
|
return (
|
|
31
26
|
<MessageContainer {...props}>
|
|
32
27
|
<Box style={styles.container} backgroundColor={colors.ui.groupChannelMessage[variant].enabled.background}>
|
|
33
|
-
<PressBox activeOpacity={0.8} onPress={onPress} onLongPress={onLongPress}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
) : (
|
|
40
|
-
<ImageWithPlaceholder source={{ uri: thumbnail ?? 'invalid-image' }} style={StyleSheet.absoluteFill} />
|
|
41
|
-
)}
|
|
42
|
-
|
|
43
|
-
{(loading || thumbnail !== null) && (
|
|
44
|
-
<Box style={StyleSheet.absoluteFill} alignItems={'center'} justifyContent={'center'}>
|
|
45
|
-
<Icon
|
|
46
|
-
icon={'play'}
|
|
47
|
-
size={28}
|
|
48
|
-
color={palette.onBackgroundLight02}
|
|
49
|
-
containerStyle={[styles.playIcon, { backgroundColor: palette.onBackgroundDark01 }]}
|
|
50
|
-
/>
|
|
51
|
-
</Box>
|
|
52
|
-
)}
|
|
28
|
+
<PressBox activeOpacity={0.8} onPress={onPress} onLongPress={onLongPress}>
|
|
29
|
+
<VideoThumbnail
|
|
30
|
+
style={styles.image}
|
|
31
|
+
source={uri}
|
|
32
|
+
fetchThumbnailFromVideoSource={props.fetchThumbnailFromVideoSource}
|
|
33
|
+
/>
|
|
53
34
|
</PressBox>
|
|
54
35
|
{props.children}
|
|
55
36
|
</Box>
|
|
@@ -57,35 +38,6 @@ const VideoFileMessage = (props: Props) => {
|
|
|
57
38
|
);
|
|
58
39
|
};
|
|
59
40
|
|
|
60
|
-
const useRetry = (fetch: () => Promise<{ path: string } | null>, retryCount = 5) => {
|
|
61
|
-
const [state, setState] = useState({ thumbnail: null as null | string, loading: true });
|
|
62
|
-
const retryCountRef = useRef(0);
|
|
63
|
-
const retryTimeoutRef = useRef<NodeJS.Timeout>();
|
|
64
|
-
const fetchThumbnail = useRef(fetch);
|
|
65
|
-
fetchThumbnail.current = fetch;
|
|
66
|
-
|
|
67
|
-
useEffect(() => {
|
|
68
|
-
if (!state.thumbnail) {
|
|
69
|
-
const reloadReservation = () => {
|
|
70
|
-
if (retryCountRef.current < retryCount) {
|
|
71
|
-
retryTimeoutRef.current = setTimeout(() => {
|
|
72
|
-
retryCountRef.current++;
|
|
73
|
-
reloadReservation();
|
|
74
|
-
fetchThumbnail.current().then((result) => {
|
|
75
|
-
setState({ loading: false, thumbnail: result?.path ?? null });
|
|
76
|
-
});
|
|
77
|
-
}, retryCountRef.current * 5000);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
return reloadReservation();
|
|
82
|
-
} else {
|
|
83
|
-
return clearTimeout(retryTimeoutRef.current);
|
|
84
|
-
}
|
|
85
|
-
}, [state.thumbnail]);
|
|
86
|
-
|
|
87
|
-
return state;
|
|
88
|
-
};
|
|
89
41
|
const styles = createStyleSheet({
|
|
90
42
|
container: {
|
|
91
43
|
borderRadius: 16,
|
|
@@ -28,6 +28,7 @@ MessageContainer.Incoming = function MessageContainerIncoming({
|
|
|
28
28
|
message,
|
|
29
29
|
onPressAvatar,
|
|
30
30
|
strings,
|
|
31
|
+
parentMessage,
|
|
31
32
|
}: Props) {
|
|
32
33
|
const { colors } = useUIKitTheme();
|
|
33
34
|
const color = colors.ui.groupChannelMessage.incoming;
|
|
@@ -42,7 +43,8 @@ MessageContainer.Incoming = function MessageContainerIncoming({
|
|
|
42
43
|
)}
|
|
43
44
|
</Box>
|
|
44
45
|
<Box flexShrink={1}>
|
|
45
|
-
{
|
|
46
|
+
{parentMessage}
|
|
47
|
+
{!groupedWithPrev && !message.parentMessage && (
|
|
46
48
|
<Box marginLeft={12} marginBottom={4}>
|
|
47
49
|
{(message.isFileMessage() || message.isUserMessage()) && (
|
|
48
50
|
<Text caption1 color={color.enabled.textSenderName} numberOfLines={1}>
|
|
@@ -73,24 +75,27 @@ MessageContainer.Outgoing = function MessageContainerOutgoing({
|
|
|
73
75
|
groupedWithNext,
|
|
74
76
|
strings,
|
|
75
77
|
sendingStatus,
|
|
78
|
+
parentMessage,
|
|
76
79
|
}: Props) {
|
|
77
80
|
const { colors } = useUIKitTheme();
|
|
78
81
|
const color = colors.ui.groupChannelMessage.outgoing;
|
|
79
82
|
|
|
80
83
|
return (
|
|
81
|
-
<Box
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
<
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
<Box>
|
|
85
|
+
{parentMessage}
|
|
86
|
+
<Box flexDirection={'row'} justifyContent={'flex-end'} alignItems={'flex-end'}>
|
|
87
|
+
<Box flexDirection={'row'} alignItems={'flex-end'} justifyContent={'center'}>
|
|
88
|
+
{sendingStatus && <Box marginRight={4}>{sendingStatus}</Box>}
|
|
89
|
+
{!groupedWithNext && (
|
|
90
|
+
<Box marginRight={4}>
|
|
91
|
+
<Text caption4 color={color.enabled.textTime}>
|
|
92
|
+
{strings?.sentDate ?? getMessageTimeFormat(new Date(message.createdAt))}
|
|
93
|
+
</Text>
|
|
94
|
+
</Box>
|
|
95
|
+
)}
|
|
96
|
+
</Box>
|
|
97
|
+
<Box style={styles.bubble}>{children}</Box>
|
|
92
98
|
</Box>
|
|
93
|
-
<Box style={styles.bubble}>{children}</Box>
|
|
94
99
|
</Box>
|
|
95
100
|
);
|
|
96
101
|
};
|
|
@@ -15,7 +15,7 @@ const MessageOpenGraph = ({
|
|
|
15
15
|
ogMetaData,
|
|
16
16
|
variant,
|
|
17
17
|
}: {
|
|
18
|
-
ogMetaData:
|
|
18
|
+
ogMetaData: NonNullable<SendbirdUserMessage['ogMetaData']>;
|
|
19
19
|
variant: 'outgoing' | 'incoming';
|
|
20
20
|
onPressURL?: (url: string) => void;
|
|
21
21
|
onLongPress?: () => void;
|
|
@@ -31,7 +31,7 @@ const MessageOpenGraph = ({
|
|
|
31
31
|
>
|
|
32
32
|
{({ pressed }) => (
|
|
33
33
|
<Box backgroundColor={pressed ? color.pressed.background : color.enabled.background}>
|
|
34
|
-
{
|
|
34
|
+
{!!ogMetaData.defaultImage && (
|
|
35
35
|
<ImageWithPlaceholder style={styles.ogImage} source={{ uri: ogMetaData.defaultImage.url }} />
|
|
36
36
|
)}
|
|
37
37
|
|
|
@@ -42,7 +42,7 @@ const MessageOpenGraph = ({
|
|
|
42
42
|
<Text numberOfLines={3} body2 color={colors.onBackground01} style={styles.ogTitle}>
|
|
43
43
|
{ogMetaData.title}
|
|
44
44
|
</Text>
|
|
45
|
-
{
|
|
45
|
+
{!!ogMetaData.description && (
|
|
46
46
|
<Text numberOfLines={1} caption2 color={colors.onBackground01} style={styles.ogDesc}>
|
|
47
47
|
{ogMetaData.description}
|
|
48
48
|
</Text>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import type { SendbirdFileMessage } from '@sendbird/uikit-utils';
|
|
4
|
-
import {
|
|
4
|
+
import { getThumbnailUriFromFileMessage } from '@sendbird/uikit-utils';
|
|
5
5
|
|
|
6
6
|
import Box from '../../components/Box';
|
|
7
7
|
import ImageWithPlaceholder from '../../components/ImageWithPlaceholder';
|
|
@@ -12,7 +12,7 @@ import type { OpenChannelMessageProps } from './index';
|
|
|
12
12
|
|
|
13
13
|
const ImageFileMessage = (props: OpenChannelMessageProps<SendbirdFileMessage>) => {
|
|
14
14
|
const { onPress, onLongPress, ...rest } = props;
|
|
15
|
-
const uri =
|
|
15
|
+
const uri = getThumbnailUriFromFileMessage(props.message);
|
|
16
16
|
return (
|
|
17
17
|
<MessageContainer {...rest}>
|
|
18
18
|
<Box borderRadius={8} overflow={'hidden'} style={styles.container}>
|
|
@@ -11,8 +11,6 @@ import useUIKitTheme from '../../theme/useUIKitTheme';
|
|
|
11
11
|
import MessageContainer from './MessageContainer';
|
|
12
12
|
import type { OpenChannelMessageProps } from './index';
|
|
13
13
|
|
|
14
|
-
const iconMapper = { audio: 'file-audio', image: 'photo', video: 'play', file: 'file-document' } as const;
|
|
15
|
-
|
|
16
14
|
type Props = {};
|
|
17
15
|
const FileMessage = (props: OpenChannelMessageProps<SendbirdFileMessage, Props>) => {
|
|
18
16
|
const { colors } = useUIKitTheme();
|
|
@@ -40,7 +38,7 @@ const FileMessage = (props: OpenChannelMessageProps<SendbirdFileMessage, Props>)
|
|
|
40
38
|
alignItems={'flex-start'}
|
|
41
39
|
backgroundColor={colors.background}
|
|
42
40
|
>
|
|
43
|
-
<Icon
|
|
41
|
+
<Icon.File fileType={type} size={32} />
|
|
44
42
|
</Box>
|
|
45
43
|
<Text
|
|
46
44
|
body3
|
|
@@ -1,84 +1,41 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import type { SendbirdFileMessage } from '@sendbird/uikit-utils';
|
|
4
|
-
import {
|
|
4
|
+
import { getThumbnailUriFromFileMessage } from '@sendbird/uikit-utils';
|
|
5
5
|
|
|
6
|
-
import Box from '../../components/Box';
|
|
7
|
-
import Icon from '../../components/Icon';
|
|
8
|
-
import ImageWithPlaceholder from '../../components/ImageWithPlaceholder';
|
|
9
6
|
import PressBox from '../../components/PressBox';
|
|
7
|
+
import { VideoThumbnail } from '../../components/VideoThumbnail';
|
|
10
8
|
import createStyleSheet from '../../styles/createStyleSheet';
|
|
11
|
-
import useUIKitTheme from '../../theme/useUIKitTheme';
|
|
12
9
|
import MessageContainer from './MessageContainer';
|
|
13
10
|
import type { OpenChannelMessageProps } from './index';
|
|
14
11
|
|
|
15
12
|
type Props = {
|
|
16
13
|
fetchThumbnailFromVideoSource: (uri: string) => Promise<{ path: string } | null>;
|
|
17
14
|
};
|
|
15
|
+
|
|
18
16
|
const VideoFileMessage = (props: OpenChannelMessageProps<SendbirdFileMessage, Props>) => {
|
|
19
|
-
const { colors, palette } = useUIKitTheme();
|
|
20
17
|
const { onPress, onLongPress, ...rest } = props;
|
|
21
|
-
const uri =
|
|
22
|
-
const { thumbnail, loading } = useRetry(() => props.fetchThumbnailFromVideoSource(uri));
|
|
18
|
+
const uri = getThumbnailUriFromFileMessage(props.message);
|
|
23
19
|
|
|
24
20
|
return (
|
|
25
21
|
<MessageContainer {...rest}>
|
|
26
22
|
<PressBox style={styles.container} activeOpacity={0.8} onPress={onPress} onLongPress={onLongPress}>
|
|
27
|
-
<
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
)}
|
|
33
|
-
|
|
34
|
-
{(loading || thumbnail !== null) && (
|
|
35
|
-
<Box style={styles.iconContainer} alignItems={'center'} justifyContent={'center'}>
|
|
36
|
-
<Icon
|
|
37
|
-
icon={'play'}
|
|
38
|
-
size={28}
|
|
39
|
-
color={palette.onBackgroundLight02}
|
|
40
|
-
containerStyle={[styles.playIcon, { backgroundColor: palette.onBackgroundDark01 }]}
|
|
41
|
-
/>
|
|
42
|
-
</Box>
|
|
43
|
-
)}
|
|
44
|
-
</Box>
|
|
23
|
+
<VideoThumbnail
|
|
24
|
+
style={styles.container}
|
|
25
|
+
source={uri}
|
|
26
|
+
fetchThumbnailFromVideoSource={props.fetchThumbnailFromVideoSource}
|
|
27
|
+
/>
|
|
45
28
|
</PressBox>
|
|
46
29
|
</MessageContainer>
|
|
47
30
|
);
|
|
48
31
|
};
|
|
49
|
-
const useRetry = (fetch: () => Promise<{ path: string } | null>, retryCount = 5) => {
|
|
50
|
-
const [state, setState] = useState({ thumbnail: null as null | string, loading: true });
|
|
51
|
-
const retryCountRef = useRef(0);
|
|
52
|
-
const retryTimeoutRef = useRef<NodeJS.Timeout>();
|
|
53
|
-
const fetchThumbnail = useRef(fetch);
|
|
54
|
-
fetchThumbnail.current = fetch;
|
|
55
|
-
|
|
56
|
-
useEffect(() => {
|
|
57
|
-
if (!state.thumbnail) {
|
|
58
|
-
const reloadReservation = () => {
|
|
59
|
-
if (retryCountRef.current < retryCount) {
|
|
60
|
-
retryTimeoutRef.current = setTimeout(() => {
|
|
61
|
-
retryCountRef.current++;
|
|
62
|
-
reloadReservation();
|
|
63
|
-
fetchThumbnail.current().then((result) => {
|
|
64
|
-
setState({ loading: false, thumbnail: result?.path ?? null });
|
|
65
|
-
});
|
|
66
|
-
}, retryCountRef.current * 5000);
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
32
|
|
|
70
|
-
return reloadReservation();
|
|
71
|
-
} else {
|
|
72
|
-
return clearTimeout(retryTimeoutRef.current);
|
|
73
|
-
}
|
|
74
|
-
}, [state.thumbnail]);
|
|
75
|
-
|
|
76
|
-
return state;
|
|
77
|
-
};
|
|
78
33
|
const styles = createStyleSheet({
|
|
79
34
|
container: {
|
|
80
35
|
maxWidth: 296,
|
|
81
36
|
height: 196,
|
|
37
|
+
borderRadius: 8,
|
|
38
|
+
overflow: 'hidden',
|
|
82
39
|
},
|
|
83
40
|
iconContainer: {
|
|
84
41
|
position: 'absolute',
|
|
@@ -88,7 +88,7 @@ const OpenGraphUserMessage = (props: OpenChannelMessageProps<SendbirdUserMessage
|
|
|
88
88
|
</Text>
|
|
89
89
|
)}
|
|
90
90
|
|
|
91
|
-
{
|
|
91
|
+
{!!props.message.ogMetaData.defaultImage && (
|
|
92
92
|
<ImageWithPlaceholder
|
|
93
93
|
style={styles.ogImage}
|
|
94
94
|
source={{ uri: props.message.ogMetaData.defaultImage.url }}
|