@sendbird/uikit-react-native-foundation 2.5.0 → 3.0.0-rc.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/README.md +4 -0
- package/lib/commonjs/components/Image/FastImageInternal.js +13 -0
- package/lib/commonjs/components/Image/FastImageInternal.js.map +1 -0
- package/lib/commonjs/components/Image/Image.fastimage.js +2 -5
- package/lib/commonjs/components/Image/Image.fastimage.js.map +1 -1
- package/lib/commonjs/components/ImageWithPlaceholder/index.js +7 -1
- package/lib/commonjs/components/ImageWithPlaceholder/index.js.map +1 -1
- package/lib/commonjs/components/RegexText/index.js.map +1 -1
- package/lib/commonjs/index.js +8 -8
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/ui/Avatar/AvatarGroup.js +1 -1
- package/lib/commonjs/ui/Avatar/AvatarGroup.js.map +1 -1
- package/lib/commonjs/ui/GroupChannelMessage/Message.admin.js +37 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.admin.js.map +1 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.file.image.js +54 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.file.image.js.map +1 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.file.js +80 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.file.js.map +1 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.file.video.js +120 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.file.video.js.map +1 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.unknown.js +54 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.unknown.js.map +1 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.user.js +44 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.user.js.map +1 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.user.og.js +59 -0
- package/lib/commonjs/ui/GroupChannelMessage/Message.user.og.js.map +1 -0
- package/lib/commonjs/ui/GroupChannelMessage/MessageBubbleWithText.js +74 -0
- package/lib/commonjs/ui/GroupChannelMessage/MessageBubbleWithText.js.map +1 -0
- package/lib/commonjs/ui/GroupChannelMessage/MessageContainer.js +110 -0
- package/lib/commonjs/ui/GroupChannelMessage/MessageContainer.js.map +1 -0
- package/lib/commonjs/ui/GroupChannelMessage/MessageOpenGraph.js +91 -0
- package/lib/commonjs/ui/GroupChannelMessage/MessageOpenGraph.js.map +1 -0
- package/lib/commonjs/ui/GroupChannelMessage/index.js +26 -0
- package/lib/commonjs/ui/GroupChannelMessage/index.js.map +1 -0
- package/lib/commonjs/ui/OpenChannelMessage/Message.user.js +1 -1
- package/lib/commonjs/ui/OpenChannelMessage/Message.user.js.map +1 -1
- package/lib/commonjs/ui/OpenChannelMessage/Message.user.og.js +5 -2
- package/lib/commonjs/ui/OpenChannelMessage/Message.user.og.js.map +1 -1
- package/lib/commonjs/ui/OpenChannelMessage/index.js.map +1 -1
- package/lib/module/components/Image/FastImageInternal.js +6 -0
- package/lib/module/components/Image/FastImageInternal.js.map +1 -0
- package/lib/module/components/Image/Image.fastimage.js +2 -5
- package/lib/module/components/Image/Image.fastimage.js.map +1 -1
- package/lib/module/components/ImageWithPlaceholder/index.js +7 -1
- package/lib/module/components/ImageWithPlaceholder/index.js.map +1 -1
- package/lib/module/components/RegexText/index.js.map +1 -1
- package/lib/module/index.js +2 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/ui/Avatar/AvatarGroup.js +1 -1
- package/lib/module/ui/Avatar/AvatarGroup.js.map +1 -1
- package/lib/module/ui/GroupChannelMessage/Message.admin.js +29 -0
- package/lib/module/ui/GroupChannelMessage/Message.admin.js.map +1 -0
- package/lib/module/ui/GroupChannelMessage/Message.file.image.js +46 -0
- package/lib/module/ui/GroupChannelMessage/Message.file.image.js.map +1 -0
- package/lib/module/ui/GroupChannelMessage/Message.file.js +72 -0
- package/lib/module/ui/GroupChannelMessage/Message.file.js.map +1 -0
- package/lib/module/ui/GroupChannelMessage/Message.file.video.js +110 -0
- package/lib/module/ui/GroupChannelMessage/Message.file.video.js.map +1 -0
- package/lib/module/ui/GroupChannelMessage/Message.unknown.js +46 -0
- package/lib/module/ui/GroupChannelMessage/Message.unknown.js.map +1 -0
- package/lib/module/ui/GroupChannelMessage/Message.user.js +36 -0
- package/lib/module/ui/GroupChannelMessage/Message.user.js.map +1 -0
- package/lib/module/ui/GroupChannelMessage/Message.user.og.js +51 -0
- package/lib/module/ui/GroupChannelMessage/Message.user.og.js.map +1 -0
- package/lib/module/ui/GroupChannelMessage/MessageBubbleWithText.js +66 -0
- package/lib/module/ui/GroupChannelMessage/MessageBubbleWithText.js.map +1 -0
- package/lib/module/ui/GroupChannelMessage/MessageContainer.js +102 -0
- package/lib/module/ui/GroupChannelMessage/MessageContainer.js.map +1 -0
- package/lib/module/ui/GroupChannelMessage/MessageOpenGraph.js +83 -0
- package/lib/module/ui/GroupChannelMessage/MessageOpenGraph.js.map +1 -0
- package/lib/module/ui/GroupChannelMessage/index.js +18 -0
- package/lib/module/ui/GroupChannelMessage/index.js.map +1 -0
- package/lib/module/ui/OpenChannelMessage/Message.user.js +1 -1
- package/lib/module/ui/OpenChannelMessage/Message.user.js.map +1 -1
- package/lib/module/ui/OpenChannelMessage/Message.user.og.js +5 -2
- package/lib/module/ui/OpenChannelMessage/Message.user.og.js.map +1 -1
- package/lib/module/ui/OpenChannelMessage/index.js.map +1 -1
- package/lib/typescript/src/components/Image/FastImageInternal.d.ts +3 -0
- package/lib/typescript/src/components/RegexText/index.d.ts +2 -2
- package/lib/typescript/src/index.d.ts +4 -2
- package/lib/typescript/src/types.d.ts +1 -9
- package/lib/typescript/src/ui/GroupChannelMessage/Message.admin.d.ts +4 -0
- package/lib/typescript/src/ui/GroupChannelMessage/Message.file.d.ts +5 -0
- package/lib/typescript/src/ui/GroupChannelMessage/Message.file.image.d.ts +4 -0
- package/lib/typescript/src/ui/GroupChannelMessage/Message.file.video.d.ts +9 -0
- package/lib/typescript/src/ui/GroupChannelMessage/Message.unknown.d.ts +4 -0
- package/lib/typescript/src/ui/GroupChannelMessage/Message.user.d.ts +9 -0
- package/lib/typescript/src/ui/GroupChannelMessage/Message.user.og.d.ts +9 -0
- package/lib/typescript/src/ui/GroupChannelMessage/MessageBubbleWithText.d.ts +10 -0
- package/lib/typescript/src/ui/GroupChannelMessage/MessageContainer.d.ts +9 -0
- package/lib/typescript/src/ui/GroupChannelMessage/MessageOpenGraph.d.ts +8 -0
- package/lib/typescript/src/ui/GroupChannelMessage/index.d.ts +191 -0
- package/lib/typescript/src/ui/OpenChannelMessage/index.d.ts +7 -7
- package/package.json +6 -6
- package/src/components/Image/FastImageInternal.tsx +9 -0
- package/src/components/Image/Image.fastimage.tsx +2 -7
- package/src/components/ImageWithPlaceholder/index.tsx +3 -2
- package/src/components/RegexText/index.tsx +2 -2
- package/src/index.ts +5 -2
- package/src/types.ts +1 -11
- package/src/ui/Avatar/AvatarGroup.tsx +1 -1
- package/src/ui/GroupChannelMessage/Message.admin.tsx +34 -0
- package/src/ui/GroupChannelMessage/Message.file.image.tsx +45 -0
- package/src/ui/GroupChannelMessage/Message.file.tsx +70 -0
- package/src/ui/GroupChannelMessage/Message.file.video.tsx +106 -0
- package/src/ui/GroupChannelMessage/Message.unknown.tsx +47 -0
- package/src/ui/GroupChannelMessage/Message.user.og.tsx +62 -0
- package/src/ui/GroupChannelMessage/Message.user.tsx +49 -0
- package/src/ui/GroupChannelMessage/MessageBubbleWithText.tsx +80 -0
- package/src/ui/GroupChannelMessage/MessageContainer.tsx +106 -0
- package/src/ui/GroupChannelMessage/MessageOpenGraph.tsx +84 -0
- package/src/ui/GroupChannelMessage/index.ts +48 -0
- package/src/ui/OpenChannelMessage/Message.user.og.tsx +6 -2
- package/src/ui/OpenChannelMessage/Message.user.tsx +1 -1
- package/src/ui/OpenChannelMessage/index.ts +1 -1
- package/lib/commonjs/components/URLParsedText/index.js +0 -46
- package/lib/commonjs/components/URLParsedText/index.js.map +0 -1
- package/lib/module/components/URLParsedText/index.js +0 -38
- package/lib/module/components/URLParsedText/index.js.map +0 -1
- package/lib/typescript/src/components/URLParsedText/index.d.ts +0 -8
- package/src/components/URLParsedText/index.tsx +0 -50
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { StyleSheet } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import type { SendbirdFileMessage } from '@sendbird/uikit-utils';
|
|
5
|
+
import { getAvailableUriFromFileMessage } from '@sendbird/uikit-utils';
|
|
6
|
+
|
|
7
|
+
import Box from '../../components/Box';
|
|
8
|
+
import Icon from '../../components/Icon';
|
|
9
|
+
import ImageWithPlaceholder from '../../components/ImageWithPlaceholder';
|
|
10
|
+
import PressBox from '../../components/PressBox';
|
|
11
|
+
import createStyleSheet from '../../styles/createStyleSheet';
|
|
12
|
+
import useUIKitTheme from '../../theme/useUIKitTheme';
|
|
13
|
+
import MessageContainer from './MessageContainer';
|
|
14
|
+
import type { GroupChannelMessageProps } from './index';
|
|
15
|
+
|
|
16
|
+
type Props = GroupChannelMessageProps<
|
|
17
|
+
SendbirdFileMessage,
|
|
18
|
+
{
|
|
19
|
+
fetchThumbnailFromVideoSource: (uri: string) => Promise<{ path: string } | null>;
|
|
20
|
+
}
|
|
21
|
+
>;
|
|
22
|
+
|
|
23
|
+
const VideoFileMessage = (props: Props) => {
|
|
24
|
+
const { onPress, onLongPress, variant = 'incoming' } = props;
|
|
25
|
+
|
|
26
|
+
const { colors, palette, select } = useUIKitTheme();
|
|
27
|
+
const uri = getAvailableUriFromFileMessage(props.message);
|
|
28
|
+
const { thumbnail, loading } = useRetry(() => props.fetchThumbnailFromVideoSource(uri));
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<MessageContainer {...props}>
|
|
32
|
+
<Box style={styles.container} backgroundColor={colors.ui.groupChannelMessage[variant].enabled.background}>
|
|
33
|
+
<PressBox activeOpacity={0.8} onPress={onPress} onLongPress={onLongPress} style={styles.image}>
|
|
34
|
+
{loading ? (
|
|
35
|
+
<Box
|
|
36
|
+
style={StyleSheet.absoluteFill}
|
|
37
|
+
backgroundColor={select({ dark: palette.background400, light: palette.background100 })}
|
|
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
|
+
)}
|
|
53
|
+
</PressBox>
|
|
54
|
+
{props.children}
|
|
55
|
+
</Box>
|
|
56
|
+
</MessageContainer>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
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
|
+
const styles = createStyleSheet({
|
|
90
|
+
container: {
|
|
91
|
+
borderRadius: 16,
|
|
92
|
+
overflow: 'hidden',
|
|
93
|
+
},
|
|
94
|
+
image: {
|
|
95
|
+
maxWidth: 240,
|
|
96
|
+
width: 240,
|
|
97
|
+
height: 160,
|
|
98
|
+
borderRadius: 16,
|
|
99
|
+
overflow: 'hidden',
|
|
100
|
+
},
|
|
101
|
+
playIcon: {
|
|
102
|
+
padding: 10,
|
|
103
|
+
borderRadius: 50,
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
export default VideoFileMessage;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { SendbirdMessage } from '@sendbird/uikit-utils';
|
|
4
|
+
|
|
5
|
+
import Box from '../../components/Box';
|
|
6
|
+
import PressBox from '../../components/PressBox';
|
|
7
|
+
import Text from '../../components/Text';
|
|
8
|
+
import createStyleSheet from '../../styles/createStyleSheet';
|
|
9
|
+
import useUIKitTheme from '../../theme/useUIKitTheme';
|
|
10
|
+
import MessageContainer from './MessageContainer';
|
|
11
|
+
import type { GroupChannelMessageProps } from './index';
|
|
12
|
+
|
|
13
|
+
const UnknownMessage = (props: GroupChannelMessageProps<SendbirdMessage>) => {
|
|
14
|
+
const { variant = 'incoming' } = props;
|
|
15
|
+
|
|
16
|
+
const { colors } = useUIKitTheme();
|
|
17
|
+
const color = colors.ui.groupChannelMessage['incoming'];
|
|
18
|
+
const titleColor = variant === 'incoming' ? colors.onBackground01 : colors.onBackgroundReverse01;
|
|
19
|
+
const descColor = variant === 'incoming' ? colors.onBackground02 : colors.onBackgroundReverse02;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<MessageContainer {...props}>
|
|
23
|
+
<PressBox onPress={props.onPress} onLongPress={props.onLongPress}>
|
|
24
|
+
{({ pressed }) => (
|
|
25
|
+
<Box style={styles.bubble} backgroundColor={pressed ? color.pressed.background : color.enabled.background}>
|
|
26
|
+
<Text body3 color={titleColor}>
|
|
27
|
+
{props.strings?.unknownTitle ?? '(Unknown message type)'}
|
|
28
|
+
</Text>
|
|
29
|
+
<Text body3 color={descColor}>
|
|
30
|
+
{props.strings?.unknownDescription ?? 'Cannot read this message.'}
|
|
31
|
+
</Text>
|
|
32
|
+
</Box>
|
|
33
|
+
)}
|
|
34
|
+
</PressBox>
|
|
35
|
+
</MessageContainer>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const styles = createStyleSheet({
|
|
40
|
+
bubble: {
|
|
41
|
+
paddingVertical: 6,
|
|
42
|
+
paddingHorizontal: 12,
|
|
43
|
+
borderRadius: 16,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export default UnknownMessage;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { SendbirdUserMessage } from '@sendbird/uikit-utils';
|
|
4
|
+
|
|
5
|
+
import Box from '../../components/Box';
|
|
6
|
+
import PressBox from '../../components/PressBox';
|
|
7
|
+
import type { RegexTextPattern } from '../../components/RegexText';
|
|
8
|
+
import createStyleSheet from '../../styles/createStyleSheet';
|
|
9
|
+
import useUIKitTheme from '../../theme/useUIKitTheme';
|
|
10
|
+
import MessageBubbleWithText from './MessageBubbleWithText';
|
|
11
|
+
import MessageContainer from './MessageContainer';
|
|
12
|
+
import MessageOpenGraph from './MessageOpenGraph';
|
|
13
|
+
import type { GroupChannelMessageProps } from './index';
|
|
14
|
+
|
|
15
|
+
type Props = GroupChannelMessageProps<
|
|
16
|
+
SendbirdUserMessage,
|
|
17
|
+
{
|
|
18
|
+
regexTextPatterns?: RegexTextPattern[];
|
|
19
|
+
renderRegexTextChildren?: (message: SendbirdUserMessage) => string;
|
|
20
|
+
}
|
|
21
|
+
>;
|
|
22
|
+
|
|
23
|
+
const OpenGraphUserMessage = (props: Props) => {
|
|
24
|
+
const { variant = 'incoming' } = props;
|
|
25
|
+
|
|
26
|
+
const { palette, select, colors } = useUIKitTheme();
|
|
27
|
+
const color = colors.ui.groupChannelMessage[variant];
|
|
28
|
+
const containerBackgroundColor = select({ dark: palette.background400, light: palette.background100 });
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<MessageContainer {...props}>
|
|
32
|
+
<PressBox onPress={props.onPress} onLongPress={props.onLongPress}>
|
|
33
|
+
{({ pressed }) => (
|
|
34
|
+
<Box backgroundColor={containerBackgroundColor} style={styles.container}>
|
|
35
|
+
<MessageBubbleWithText
|
|
36
|
+
backgroundColor={pressed ? color.pressed.background : color.enabled.background}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
{props.message.ogMetaData && (
|
|
40
|
+
<MessageOpenGraph
|
|
41
|
+
variant={variant}
|
|
42
|
+
ogMetaData={props.message.ogMetaData}
|
|
43
|
+
onLongPress={props.onLongPress}
|
|
44
|
+
onPressURL={props.onPressURL}
|
|
45
|
+
/>
|
|
46
|
+
)}
|
|
47
|
+
{props.children}
|
|
48
|
+
</Box>
|
|
49
|
+
)}
|
|
50
|
+
</PressBox>
|
|
51
|
+
</MessageContainer>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const styles = createStyleSheet({
|
|
56
|
+
container: {
|
|
57
|
+
borderRadius: 16,
|
|
58
|
+
overflow: 'hidden',
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
export default OpenGraphUserMessage;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { SendbirdUserMessage } from '@sendbird/uikit-utils';
|
|
4
|
+
|
|
5
|
+
import Box from '../../components/Box';
|
|
6
|
+
import PressBox from '../../components/PressBox';
|
|
7
|
+
import type { RegexTextPattern } from '../../components/RegexText';
|
|
8
|
+
import createStyleSheet from '../../styles/createStyleSheet';
|
|
9
|
+
import useUIKitTheme from '../../theme/useUIKitTheme';
|
|
10
|
+
import MessageBubbleWithText from './MessageBubbleWithText';
|
|
11
|
+
import MessageContainer from './MessageContainer';
|
|
12
|
+
import type { GroupChannelMessageProps } from './index';
|
|
13
|
+
|
|
14
|
+
type Props = GroupChannelMessageProps<
|
|
15
|
+
SendbirdUserMessage,
|
|
16
|
+
{
|
|
17
|
+
regexTextPatterns?: RegexTextPattern[];
|
|
18
|
+
renderRegexTextChildren?: (message: SendbirdUserMessage) => string;
|
|
19
|
+
}
|
|
20
|
+
>;
|
|
21
|
+
|
|
22
|
+
const UserMessage = (props: Props) => {
|
|
23
|
+
const { variant = 'incoming' } = props;
|
|
24
|
+
|
|
25
|
+
const { colors } = useUIKitTheme();
|
|
26
|
+
const color = colors.ui.groupChannelMessage[variant];
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<MessageContainer {...props}>
|
|
30
|
+
<PressBox onPress={props.onPress} onLongPress={props.onLongPress}>
|
|
31
|
+
{({ pressed }) => (
|
|
32
|
+
<Box backgroundColor={pressed ? color.pressed.background : color.enabled.background} style={styles.container}>
|
|
33
|
+
<MessageBubbleWithText {...props} />
|
|
34
|
+
{props.children}
|
|
35
|
+
</Box>
|
|
36
|
+
)}
|
|
37
|
+
</PressBox>
|
|
38
|
+
</MessageContainer>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const styles = createStyleSheet({
|
|
43
|
+
container: {
|
|
44
|
+
overflow: 'hidden',
|
|
45
|
+
borderRadius: 16,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export default UserMessage;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { SendbirdUserMessage, urlRegexStrict } from '@sendbird/uikit-utils';
|
|
4
|
+
|
|
5
|
+
import Box from '../../components/Box';
|
|
6
|
+
import RegexText, { RegexTextPattern } from '../../components/RegexText';
|
|
7
|
+
import Text from '../../components/Text';
|
|
8
|
+
import createStyleSheet from '../../styles/createStyleSheet';
|
|
9
|
+
import useUIKitTheme from '../../theme/useUIKitTheme';
|
|
10
|
+
import type { GroupChannelMessageProps } from './index';
|
|
11
|
+
|
|
12
|
+
type Props = GroupChannelMessageProps<
|
|
13
|
+
SendbirdUserMessage,
|
|
14
|
+
{
|
|
15
|
+
backgroundColor?: string;
|
|
16
|
+
regexTextPatterns?: RegexTextPattern[];
|
|
17
|
+
renderRegexTextChildren?: (message: SendbirdUserMessage) => string;
|
|
18
|
+
}
|
|
19
|
+
>;
|
|
20
|
+
|
|
21
|
+
const MessageBubbleWithText = ({
|
|
22
|
+
backgroundColor,
|
|
23
|
+
message,
|
|
24
|
+
onPressURL,
|
|
25
|
+
onLongPress,
|
|
26
|
+
strings,
|
|
27
|
+
variant = 'incoming',
|
|
28
|
+
regexTextPatterns = [],
|
|
29
|
+
renderRegexTextChildren = (msg) => msg.message,
|
|
30
|
+
}: Props) => {
|
|
31
|
+
const { colors } = useUIKitTheme();
|
|
32
|
+
const color = colors.ui.groupChannelMessage[variant];
|
|
33
|
+
return (
|
|
34
|
+
<Box backgroundColor={backgroundColor} style={styles.bubble}>
|
|
35
|
+
<Text body3 color={color.enabled.textMsg} suppressHighlighting>
|
|
36
|
+
<RegexText
|
|
37
|
+
body3
|
|
38
|
+
color={color.enabled.textMsg}
|
|
39
|
+
patterns={[
|
|
40
|
+
...regexTextPatterns,
|
|
41
|
+
{
|
|
42
|
+
regex: urlRegexStrict,
|
|
43
|
+
replacer({ match, parentProps, keyPrefix, index }) {
|
|
44
|
+
return (
|
|
45
|
+
<Text
|
|
46
|
+
{...parentProps}
|
|
47
|
+
key={`${keyPrefix}-${index}`}
|
|
48
|
+
onPress={() => onPressURL?.(match)}
|
|
49
|
+
onLongPress={onLongPress}
|
|
50
|
+
style={[parentProps?.style, styles.urlText]}
|
|
51
|
+
>
|
|
52
|
+
{match}
|
|
53
|
+
</Text>
|
|
54
|
+
);
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
]}
|
|
58
|
+
>
|
|
59
|
+
{renderRegexTextChildren(message)}
|
|
60
|
+
</RegexText>
|
|
61
|
+
{Boolean(message.updatedAt) && (
|
|
62
|
+
<Text body3 color={color.enabled.textEdited}>
|
|
63
|
+
{strings?.edited ?? ' (edited)'}
|
|
64
|
+
</Text>
|
|
65
|
+
)}
|
|
66
|
+
</Text>
|
|
67
|
+
</Box>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const styles = createStyleSheet({
|
|
72
|
+
bubble: {
|
|
73
|
+
paddingHorizontal: 12,
|
|
74
|
+
paddingVertical: 6,
|
|
75
|
+
},
|
|
76
|
+
urlText: {
|
|
77
|
+
textDecorationLine: 'underline',
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
export default MessageBubbleWithText;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Pressable } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import type { SendbirdMessage } from '@sendbird/uikit-utils';
|
|
5
|
+
import { getMessageTimeFormat } from '@sendbird/uikit-utils';
|
|
6
|
+
|
|
7
|
+
import Box from '../../components/Box';
|
|
8
|
+
import Text from '../../components/Text';
|
|
9
|
+
import createStyleSheet from '../../styles/createStyleSheet';
|
|
10
|
+
import useUIKitTheme from '../../theme/useUIKitTheme';
|
|
11
|
+
import Avatar from '../Avatar';
|
|
12
|
+
import type { GroupChannelMessageProps } from './index';
|
|
13
|
+
|
|
14
|
+
type Props = GroupChannelMessageProps<SendbirdMessage>;
|
|
15
|
+
|
|
16
|
+
const MessageContainer = (props: Props) => {
|
|
17
|
+
if (props.variant === 'incoming') {
|
|
18
|
+
return <MessageContainer.Incoming {...props} />;
|
|
19
|
+
} else {
|
|
20
|
+
return <MessageContainer.Outgoing {...props} />;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
MessageContainer.Incoming = function MessageContainerIncoming({
|
|
25
|
+
children,
|
|
26
|
+
groupedWithNext,
|
|
27
|
+
groupedWithPrev,
|
|
28
|
+
message,
|
|
29
|
+
onPressAvatar,
|
|
30
|
+
strings,
|
|
31
|
+
}: Props) {
|
|
32
|
+
const { colors } = useUIKitTheme();
|
|
33
|
+
const color = colors.ui.groupChannelMessage.incoming;
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Box flexDirection={'row'} justifyContent={'flex-start'} alignItems={'flex-end'}>
|
|
37
|
+
<Box width={26} marginRight={12}>
|
|
38
|
+
{(message.isFileMessage() || message.isUserMessage()) && !groupedWithNext && (
|
|
39
|
+
<Pressable onPress={onPressAvatar}>
|
|
40
|
+
<Avatar size={26} uri={message.sender?.profileUrl} />
|
|
41
|
+
</Pressable>
|
|
42
|
+
)}
|
|
43
|
+
</Box>
|
|
44
|
+
<Box flexShrink={1}>
|
|
45
|
+
{!groupedWithPrev && (
|
|
46
|
+
<Box marginLeft={12} marginBottom={4}>
|
|
47
|
+
{(message.isFileMessage() || message.isUserMessage()) && (
|
|
48
|
+
<Text caption1 color={color.enabled.textSenderName} numberOfLines={1}>
|
|
49
|
+
{strings?.senderName ?? message.sender.nickname}
|
|
50
|
+
</Text>
|
|
51
|
+
)}
|
|
52
|
+
</Box>
|
|
53
|
+
)}
|
|
54
|
+
|
|
55
|
+
<Box flexDirection={'row'} alignItems={'flex-end'}>
|
|
56
|
+
<Box style={styles.bubble}>{children}</Box>
|
|
57
|
+
{!groupedWithNext && (
|
|
58
|
+
<Box marginLeft={4}>
|
|
59
|
+
<Text caption4 color={color.enabled.textTime}>
|
|
60
|
+
{strings?.sentDate ?? getMessageTimeFormat(new Date(message.createdAt))}
|
|
61
|
+
</Text>
|
|
62
|
+
</Box>
|
|
63
|
+
)}
|
|
64
|
+
</Box>
|
|
65
|
+
</Box>
|
|
66
|
+
</Box>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
MessageContainer.Outgoing = function MessageContainerOutgoing({
|
|
71
|
+
children,
|
|
72
|
+
message,
|
|
73
|
+
groupedWithNext,
|
|
74
|
+
strings,
|
|
75
|
+
sendingStatus,
|
|
76
|
+
}: Props) {
|
|
77
|
+
const { colors } = useUIKitTheme();
|
|
78
|
+
const color = colors.ui.groupChannelMessage.outgoing;
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<Box flexDirection={'row'} justifyContent={'flex-end'} alignItems={'flex-end'}>
|
|
82
|
+
<Box flexDirection={'row'} alignItems={'flex-end'} justifyContent={'center'}>
|
|
83
|
+
{sendingStatus && <Box marginRight={4}>{sendingStatus}</Box>}
|
|
84
|
+
|
|
85
|
+
{!groupedWithNext && (
|
|
86
|
+
<Box marginRight={4}>
|
|
87
|
+
<Text caption4 color={color.enabled.textTime}>
|
|
88
|
+
{strings?.sentDate ?? getMessageTimeFormat(new Date(message.createdAt))}
|
|
89
|
+
</Text>
|
|
90
|
+
</Box>
|
|
91
|
+
)}
|
|
92
|
+
</Box>
|
|
93
|
+
<Box style={styles.bubble}>{children}</Box>
|
|
94
|
+
</Box>
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const styles = createStyleSheet({
|
|
99
|
+
bubble: {
|
|
100
|
+
maxWidth: 240,
|
|
101
|
+
overflow: 'hidden',
|
|
102
|
+
flexShrink: 1,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
export default MessageContainer;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { SendbirdUserMessage } from '@sendbird/uikit-utils';
|
|
4
|
+
|
|
5
|
+
import Box from '../../components/Box';
|
|
6
|
+
import ImageWithPlaceholder from '../../components/ImageWithPlaceholder';
|
|
7
|
+
import PressBox from '../../components/PressBox';
|
|
8
|
+
import Text from '../../components/Text';
|
|
9
|
+
import createStyleSheet from '../../styles/createStyleSheet';
|
|
10
|
+
import useUIKitTheme from '../../theme/useUIKitTheme';
|
|
11
|
+
|
|
12
|
+
const MessageOpenGraph = ({
|
|
13
|
+
onPressURL,
|
|
14
|
+
onLongPress,
|
|
15
|
+
ogMetaData,
|
|
16
|
+
variant,
|
|
17
|
+
}: {
|
|
18
|
+
ogMetaData: Required<SendbirdUserMessage>['ogMetaData'];
|
|
19
|
+
variant: 'outgoing' | 'incoming';
|
|
20
|
+
onPressURL?: (url: string) => void;
|
|
21
|
+
onLongPress?: () => void;
|
|
22
|
+
}) => {
|
|
23
|
+
const { palette, select, colors } = useUIKitTheme();
|
|
24
|
+
const color = colors.ui.groupChannelMessage[variant];
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<PressBox
|
|
28
|
+
activeOpacity={0.85}
|
|
29
|
+
onPress={() => typeof ogMetaData?.url === 'string' && onPressURL?.(ogMetaData.url)}
|
|
30
|
+
onLongPress={onLongPress}
|
|
31
|
+
>
|
|
32
|
+
{({ pressed }) => (
|
|
33
|
+
<Box backgroundColor={pressed ? color.pressed.background : color.enabled.background}>
|
|
34
|
+
{Boolean(ogMetaData.defaultImage) && (
|
|
35
|
+
<ImageWithPlaceholder style={styles.ogImage} source={{ uri: ogMetaData.defaultImage.url }} />
|
|
36
|
+
)}
|
|
37
|
+
|
|
38
|
+
<Box
|
|
39
|
+
style={styles.ogContainer}
|
|
40
|
+
backgroundColor={select({ dark: palette.background400, light: palette.background100 })}
|
|
41
|
+
>
|
|
42
|
+
<Text numberOfLines={3} body2 color={colors.onBackground01} style={styles.ogTitle}>
|
|
43
|
+
{ogMetaData.title}
|
|
44
|
+
</Text>
|
|
45
|
+
{Boolean(ogMetaData.description) && (
|
|
46
|
+
<Text numberOfLines={1} caption2 color={colors.onBackground01} style={styles.ogDesc}>
|
|
47
|
+
{ogMetaData.description}
|
|
48
|
+
</Text>
|
|
49
|
+
)}
|
|
50
|
+
<Text numberOfLines={1} caption2 color={colors.onBackground02}>
|
|
51
|
+
{ogMetaData.url}
|
|
52
|
+
</Text>
|
|
53
|
+
</Box>
|
|
54
|
+
</Box>
|
|
55
|
+
)}
|
|
56
|
+
</PressBox>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const styles = createStyleSheet({
|
|
61
|
+
ogContainer: {
|
|
62
|
+
overflow: 'hidden',
|
|
63
|
+
paddingHorizontal: 12,
|
|
64
|
+
paddingTop: 8,
|
|
65
|
+
paddingBottom: 12,
|
|
66
|
+
},
|
|
67
|
+
ogImage: {
|
|
68
|
+
maxWidth: 240,
|
|
69
|
+
width: 240,
|
|
70
|
+
height: 136,
|
|
71
|
+
},
|
|
72
|
+
ogUrl: {
|
|
73
|
+
marginBottom: 4,
|
|
74
|
+
},
|
|
75
|
+
ogTitle: {
|
|
76
|
+
marginBottom: 4,
|
|
77
|
+
},
|
|
78
|
+
ogDesc: {
|
|
79
|
+
lineHeight: 14,
|
|
80
|
+
marginBottom: 8,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export default MessageOpenGraph;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { SendbirdGroupChannel, SendbirdMessage, SendbirdUser } from '@sendbird/uikit-utils';
|
|
4
|
+
|
|
5
|
+
import AdminMessage from './Message.admin';
|
|
6
|
+
import FileMessage from './Message.file';
|
|
7
|
+
import ImageFileMessage from './Message.file.image';
|
|
8
|
+
import VideoFileMessage from './Message.file.video';
|
|
9
|
+
import UnknownMessage from './Message.unknown';
|
|
10
|
+
import UserMessage from './Message.user';
|
|
11
|
+
import OpenGraphUser from './Message.user.og';
|
|
12
|
+
|
|
13
|
+
export type GroupChannelMessageProps<T extends SendbirdMessage, AdditionalProps = unknown> = {
|
|
14
|
+
channel: SendbirdGroupChannel;
|
|
15
|
+
message: T;
|
|
16
|
+
variant?: 'outgoing' | 'incoming';
|
|
17
|
+
strings?: {
|
|
18
|
+
senderName?: string;
|
|
19
|
+
sentDate?: string;
|
|
20
|
+
edited?: string;
|
|
21
|
+
fileName?: string;
|
|
22
|
+
unknownTitle?: string;
|
|
23
|
+
unknownDescription?: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
children?: React.ReactNode;
|
|
27
|
+
sendingStatus?: React.ReactNode;
|
|
28
|
+
|
|
29
|
+
groupedWithPrev: boolean;
|
|
30
|
+
groupedWithNext: boolean;
|
|
31
|
+
onPress?: () => void;
|
|
32
|
+
onLongPress?: () => void;
|
|
33
|
+
onPressAvatar?: () => void;
|
|
34
|
+
onPressURL?: (url: string) => void;
|
|
35
|
+
onPressMentionedUser?: (mentionedUser?: SendbirdUser) => void;
|
|
36
|
+
} & AdditionalProps;
|
|
37
|
+
|
|
38
|
+
const GroupChannelMessage = {
|
|
39
|
+
User: UserMessage,
|
|
40
|
+
OpenGraphUser: OpenGraphUser,
|
|
41
|
+
File: FileMessage,
|
|
42
|
+
ImageFile: ImageFileMessage,
|
|
43
|
+
VideoFile: VideoFileMessage,
|
|
44
|
+
Admin: AdminMessage,
|
|
45
|
+
Unknown: UnknownMessage,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export default GroupChannelMessage;
|
|
@@ -36,7 +36,7 @@ const OpenGraphUserMessage = (props: OpenChannelMessageProps<SendbirdUserMessage
|
|
|
36
36
|
<Text
|
|
37
37
|
{...parentProps}
|
|
38
38
|
key={`${keyPrefix}-${index}`}
|
|
39
|
-
onPress={onPressURL}
|
|
39
|
+
onPress={() => onPressURL?.(match)}
|
|
40
40
|
onLongPress={onLongPress}
|
|
41
41
|
color={colors.primary}
|
|
42
42
|
style={parentProps?.style}
|
|
@@ -61,7 +61,11 @@ const OpenGraphUserMessage = (props: OpenChannelMessageProps<SendbirdUserMessage
|
|
|
61
61
|
</PressBox>
|
|
62
62
|
{props.message.ogMetaData && (
|
|
63
63
|
<MessageContainer {...rest} grouped>
|
|
64
|
-
<PressBox
|
|
64
|
+
<PressBox
|
|
65
|
+
style={styles.ogContainer}
|
|
66
|
+
onPress={() => props.message.ogMetaData?.url && onPressURL?.(props.message.ogMetaData.url)}
|
|
67
|
+
onLongPress={onLongPress}
|
|
68
|
+
>
|
|
65
69
|
{({ pressed }) =>
|
|
66
70
|
props.message.ogMetaData && (
|
|
67
71
|
<Box
|
|
@@ -32,7 +32,7 @@ const UserMessage = (props: OpenChannelMessageProps<SendbirdUserMessage, Props>)
|
|
|
32
32
|
<Text
|
|
33
33
|
{...parentProps}
|
|
34
34
|
key={`${keyPrefix}-${index}`}
|
|
35
|
-
onPress={onPressURL}
|
|
35
|
+
onPress={() => onPressURL?.(match)}
|
|
36
36
|
onLongPress={onLongPress}
|
|
37
37
|
color={colors.primary}
|
|
38
38
|
style={parentProps?.style}
|
|
@@ -26,7 +26,7 @@ export type OpenChannelMessageProps<T extends SendbirdMessage, AdditionalProps =
|
|
|
26
26
|
onPress?: () => void;
|
|
27
27
|
onLongPress?: () => void;
|
|
28
28
|
onPressAvatar?: () => void;
|
|
29
|
-
onPressURL?: () => void;
|
|
29
|
+
onPressURL?: (url: string) => void;
|
|
30
30
|
} & AdditionalProps;
|
|
31
31
|
|
|
32
32
|
const OpenChannelMessage = {
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
var _react = _interopRequireDefault(require("react"));
|
|
8
|
-
var _reactNative = require("react-native");
|
|
9
|
-
var _uikitUtils = require("@sendbird/uikit-utils");
|
|
10
|
-
var _createStyleSheet = _interopRequireDefault(require("../../styles/createStyleSheet"));
|
|
11
|
-
var _Text = _interopRequireDefault(require("../Text"));
|
|
12
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
14
|
-
const openUrl = (url, httpProtocol) => {
|
|
15
|
-
const targetUrl = httpProtocol ? url : 'https://' + url;
|
|
16
|
-
_reactNative.Linking.openURL(targetUrl).catch(err => _uikitUtils.Logger.warn('[URLParsedText]', 'Cannot open url', err));
|
|
17
|
-
};
|
|
18
|
-
const URLParsedText = _ref => {
|
|
19
|
-
let {
|
|
20
|
-
children,
|
|
21
|
-
onPressUrl = openUrl,
|
|
22
|
-
strict,
|
|
23
|
-
...props
|
|
24
|
-
} = _ref;
|
|
25
|
-
const parsedChildren = _react.default.Children.map(_react.default.Children.toArray(children), child => {
|
|
26
|
-
if (typeof child === 'string') {
|
|
27
|
-
return (0, _uikitUtils.replaceUrlAsComponents)(child, url => {
|
|
28
|
-
return /*#__PURE__*/_react.default.createElement(_Text.default, _extends({}, props, {
|
|
29
|
-
suppressHighlighting: true,
|
|
30
|
-
onPress: () => onPressUrl === null || onPressUrl === void 0 ? void 0 : onPressUrl(url, url.startsWith('http')),
|
|
31
|
-
style: [props.style, styles.url]
|
|
32
|
-
}), url);
|
|
33
|
-
}, strict);
|
|
34
|
-
}
|
|
35
|
-
return child;
|
|
36
|
-
});
|
|
37
|
-
return /*#__PURE__*/_react.default.createElement(_Text.default, props, parsedChildren);
|
|
38
|
-
};
|
|
39
|
-
const styles = (0, _createStyleSheet.default)({
|
|
40
|
-
url: {
|
|
41
|
-
textDecorationLine: 'underline'
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
var _default = URLParsedText;
|
|
45
|
-
exports.default = _default;
|
|
46
|
-
//# sourceMappingURL=index.js.map
|