@sendbird/uikit-react-native 3.2.0 → 3.4.0

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.
Files changed (116) hide show
  1. package/lib/commonjs/components/ChannelInput/EditInput.js +2 -11
  2. package/lib/commonjs/components/ChannelInput/EditInput.js.map +1 -1
  3. package/lib/commonjs/components/ChannelInput/SendInput.js +2 -11
  4. package/lib/commonjs/components/ChannelInput/SendInput.js.map +1 -1
  5. package/lib/commonjs/components/ChannelInput/index.js +30 -3
  6. package/lib/commonjs/components/ChannelInput/index.js.map +1 -1
  7. package/lib/commonjs/components/ChannelMessageList/index.js +148 -116
  8. package/lib/commonjs/components/ChannelMessageList/index.js.map +1 -1
  9. package/lib/commonjs/components/FileViewer/FileViewerContent.js +140 -0
  10. package/lib/commonjs/components/FileViewer/FileViewerContent.js.map +1 -0
  11. package/lib/commonjs/components/FileViewer/FileViewerFooter.js +82 -0
  12. package/lib/commonjs/components/FileViewer/FileViewerFooter.js.map +1 -0
  13. package/lib/commonjs/components/FileViewer/FileViewerHeader.js +93 -0
  14. package/lib/commonjs/components/FileViewer/FileViewerHeader.js.map +1 -0
  15. package/lib/commonjs/components/FileViewer/index.js +133 -0
  16. package/lib/commonjs/components/FileViewer/index.js.map +1 -0
  17. package/lib/commonjs/components/GroupChannelMessageRenderer/index.js +34 -1
  18. package/lib/commonjs/components/GroupChannelMessageRenderer/index.js.map +1 -1
  19. package/lib/commonjs/components/ReactionAddons/BottomSheetReactionAddon.js.map +1 -1
  20. package/lib/commonjs/domain/groupChannel/component/GroupChannelHeader.js +14 -4
  21. package/lib/commonjs/domain/groupChannel/component/GroupChannelHeader.js.map +1 -1
  22. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js +11 -9
  23. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  24. package/lib/commonjs/domain/groupChannel/types.js.map +1 -1
  25. package/lib/commonjs/domain/messageSearch/component/MessageSearchHeader.js +4 -1
  26. package/lib/commonjs/domain/messageSearch/component/MessageSearchHeader.js.map +1 -1
  27. package/lib/commonjs/domain/openChannelCreate/component/OpenChannelCreateProfileInput.js +4 -2
  28. package/lib/commonjs/domain/openChannelCreate/component/OpenChannelCreateProfileInput.js.map +1 -1
  29. package/lib/commonjs/fragments/createGroupChannelFragment.js +18 -16
  30. package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
  31. package/lib/commonjs/index.js +4 -0
  32. package/lib/commonjs/index.js.map +1 -1
  33. package/lib/commonjs/types.js +7 -0
  34. package/lib/commonjs/types.js.map +1 -1
  35. package/lib/commonjs/utils/promise.js +138 -0
  36. package/lib/commonjs/utils/promise.js.map +1 -0
  37. package/lib/commonjs/version.js +1 -1
  38. package/lib/commonjs/version.js.map +1 -1
  39. package/lib/module/components/ChannelInput/EditInput.js +3 -12
  40. package/lib/module/components/ChannelInput/EditInput.js.map +1 -1
  41. package/lib/module/components/ChannelInput/SendInput.js +3 -12
  42. package/lib/module/components/ChannelInput/SendInput.js.map +1 -1
  43. package/lib/module/components/ChannelInput/index.js +32 -5
  44. package/lib/module/components/ChannelInput/index.js.map +1 -1
  45. package/lib/module/components/ChannelMessageList/index.js +148 -116
  46. package/lib/module/components/ChannelMessageList/index.js.map +1 -1
  47. package/lib/module/components/FileViewer/FileViewerContent.js +130 -0
  48. package/lib/module/components/FileViewer/FileViewerContent.js.map +1 -0
  49. package/lib/module/components/FileViewer/FileViewerFooter.js +74 -0
  50. package/lib/module/components/FileViewer/FileViewerFooter.js.map +1 -0
  51. package/lib/module/components/FileViewer/FileViewerHeader.js +85 -0
  52. package/lib/module/components/FileViewer/FileViewerHeader.js.map +1 -0
  53. package/lib/module/components/FileViewer/index.js +123 -0
  54. package/lib/module/components/FileViewer/index.js.map +1 -0
  55. package/lib/module/components/GroupChannelMessageRenderer/index.js +34 -2
  56. package/lib/module/components/GroupChannelMessageRenderer/index.js.map +1 -1
  57. package/lib/module/components/ReactionAddons/BottomSheetReactionAddon.js.map +1 -1
  58. package/lib/module/domain/groupChannel/component/GroupChannelHeader.js +15 -5
  59. package/lib/module/domain/groupChannel/component/GroupChannelHeader.js.map +1 -1
  60. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js +11 -9
  61. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  62. package/lib/module/domain/groupChannel/types.js.map +1 -1
  63. package/lib/module/domain/messageSearch/component/MessageSearchHeader.js +4 -1
  64. package/lib/module/domain/messageSearch/component/MessageSearchHeader.js.map +1 -1
  65. package/lib/module/domain/openChannelCreate/component/OpenChannelCreateProfileInput.js +4 -2
  66. package/lib/module/domain/openChannelCreate/component/OpenChannelCreateProfileInput.js.map +1 -1
  67. package/lib/module/fragments/createGroupChannelFragment.js +19 -17
  68. package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
  69. package/lib/module/index.js +4 -0
  70. package/lib/module/index.js.map +1 -1
  71. package/lib/module/types.js +5 -1
  72. package/lib/module/types.js.map +1 -1
  73. package/lib/module/utils/promise.js +132 -0
  74. package/lib/module/utils/promise.js.map +1 -0
  75. package/lib/module/version.js +1 -1
  76. package/lib/module/version.js.map +1 -1
  77. package/lib/typescript/src/components/ChannelInput/index.d.ts +2 -0
  78. package/lib/typescript/src/components/ChannelMessageList/index.d.ts +4 -1
  79. package/lib/typescript/src/components/FileViewer/FileViewerContent.d.ts +13 -0
  80. package/lib/typescript/src/components/FileViewer/FileViewerFooter.d.ts +9 -0
  81. package/lib/typescript/src/components/FileViewer/FileViewerHeader.d.ts +10 -0
  82. package/lib/typescript/src/components/{FileViewer.d.ts → FileViewer/index.d.ts} +5 -1
  83. package/lib/typescript/src/components/GroupChannelMessageRenderer/index.d.ts +3 -0
  84. package/lib/typescript/src/components/OpenChannelMessageRenderer/index.d.ts +2 -0
  85. package/lib/typescript/src/containers/SendbirdUIKitContainer.d.ts +1 -1
  86. package/lib/typescript/src/domain/groupChannel/component/GroupChannelMessageList.d.ts +2 -2
  87. package/lib/typescript/src/domain/groupChannel/types.d.ts +5 -2
  88. package/lib/typescript/src/types.d.ts +4 -0
  89. package/lib/typescript/src/utils/promise.d.ts +7 -0
  90. package/lib/typescript/src/version.d.ts +1 -1
  91. package/package.json +8 -7
  92. package/src/components/ChannelInput/EditInput.tsx +3 -15
  93. package/src/components/ChannelInput/SendInput.tsx +2 -9
  94. package/src/components/ChannelInput/index.tsx +27 -4
  95. package/src/components/ChannelMessageList/index.tsx +145 -115
  96. package/src/components/FileViewer/FileViewerContent.tsx +141 -0
  97. package/src/components/FileViewer/FileViewerFooter.tsx +73 -0
  98. package/src/components/FileViewer/FileViewerHeader.tsx +86 -0
  99. package/src/components/FileViewer/index.tsx +139 -0
  100. package/src/components/GroupChannelMessageRenderer/index.tsx +34 -2
  101. package/src/components/ReactionAddons/BottomSheetReactionAddon.tsx +3 -2
  102. package/src/domain/groupChannel/component/GroupChannelHeader.tsx +14 -3
  103. package/src/domain/groupChannel/component/GroupChannelMessageList.tsx +8 -6
  104. package/src/domain/groupChannel/types.ts +6 -2
  105. package/src/domain/messageSearch/component/MessageSearchHeader.tsx +4 -1
  106. package/src/domain/openChannelCreate/component/OpenChannelCreateProfileInput.tsx +4 -2
  107. package/src/fragments/createGroupChannelFragment.tsx +25 -15
  108. package/src/index.ts +5 -1
  109. package/src/types.ts +5 -0
  110. package/src/utils/promise.ts +139 -0
  111. package/src/version.ts +1 -1
  112. package/lib/commonjs/components/FileViewer.js +0 -300
  113. package/lib/commonjs/components/FileViewer.js.map +0 -1
  114. package/lib/module/components/FileViewer.js +0 -291
  115. package/lib/module/components/FileViewer.js.map +0 -1
  116. package/src/components/FileViewer.tsx +0 -288
@@ -1,291 +0,0 @@
1
- import React, { useEffect, useState } from 'react';
2
- import { StatusBar, StyleSheet, TouchableOpacity, View } from 'react-native';
3
- import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
- import { Icon, Image, LoadingSpinner, Text, createStyleSheet, useAlert, useHeaderStyle, useToast, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
5
- import { Logger, getFileExtension, getFileType, isMyMessage, toMegabyte, truncate, useIIFE } from '@sendbird/uikit-utils';
6
- import { useLocalization, usePlatformService, useSendbirdChat } from '../hooks/useContext';
7
- const FileViewer = _ref => {
8
- let {
9
- headerShown = true,
10
- deleteMessage,
11
- headerTopInset,
12
- fileMessage,
13
- onPressDownload,
14
- onPressDelete,
15
- onClose
16
- } = _ref;
17
- const [loading, setLoading] = useState(true);
18
- const {
19
- bottom
20
- } = useSafeAreaInsets();
21
- const {
22
- currentUser
23
- } = useSendbirdChat();
24
- const {
25
- palette
26
- } = useUIKitTheme();
27
- const {
28
- topInset,
29
- statusBarTranslucent,
30
- defaultHeight
31
- } = useHeaderStyle();
32
- const {
33
- STRINGS
34
- } = useLocalization();
35
- const {
36
- fileService,
37
- mediaService
38
- } = usePlatformService();
39
- const toast = useToast();
40
- const {
41
- alert
42
- } = useAlert();
43
- const basicTopInset = statusBarTranslucent ? topInset : 0;
44
- const canDelete = isMyMessage(fileMessage, currentUser === null || currentUser === void 0 ? void 0 : currentUser.userId);
45
- const fileType = getFileType(fileMessage.type || getFileExtension(fileMessage.url));
46
- useEffect(() => {
47
- if (fileType === 'file') onClose();
48
- }, []);
49
- const fileViewer = useIIFE(() => {
50
- switch (fileType) {
51
- case 'image':
52
- {
53
- return /*#__PURE__*/React.createElement(Image, {
54
- source: {
55
- uri: fileMessage.url
56
- },
57
- style: StyleSheet.absoluteFill,
58
- resizeMode: 'contain',
59
- onLoadEnd: () => setLoading(false)
60
- });
61
- }
62
- case 'video':
63
- case 'audio':
64
- {
65
- return /*#__PURE__*/React.createElement(mediaService.VideoComponent, {
66
- source: {
67
- uri: fileMessage.url
68
- },
69
- style: [StyleSheet.absoluteFill, {
70
- top: basicTopInset + defaultHeight,
71
- bottom: defaultHeight + bottom
72
- }],
73
- resizeMode: 'contain',
74
- onLoad: () => setLoading(false)
75
- });
76
- }
77
- default:
78
- {
79
- return null;
80
- }
81
- }
82
- });
83
- const _onPressDelete = () => {
84
- if (!canDelete) return;
85
- if (onPressDelete) {
86
- onPressDelete(fileMessage);
87
- } else {
88
- alert({
89
- title: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_TITLE,
90
- buttons: [{
91
- text: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_CANCEL
92
- }, {
93
- text: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_OK,
94
- style: 'destructive',
95
- onPress: () => {
96
- deleteMessage().then(() => {
97
- onClose();
98
- }).catch(() => {
99
- toast.show(STRINGS.TOAST.DELETE_MSG_ERROR, 'error');
100
- });
101
- }
102
- }]
103
- });
104
- }
105
- };
106
- const _onPressDownload = () => {
107
- if (onPressDownload) {
108
- onPressDownload(fileMessage);
109
- } else {
110
- if (toMegabyte(fileMessage.size) > 4) {
111
- toast.show(STRINGS.TOAST.DOWNLOAD_START, 'success');
112
- }
113
- fileService.save({
114
- fileUrl: fileMessage.url,
115
- fileName: fileMessage.name,
116
- fileType: fileMessage.type
117
- }).then(response => {
118
- toast.show(STRINGS.TOAST.DOWNLOAD_OK, 'success');
119
- Logger.log('File saved to', response);
120
- }).catch(err => {
121
- toast.show(STRINGS.TOAST.DOWNLOAD_ERROR, 'error');
122
- Logger.log('File save failure', err);
123
- });
124
- }
125
- };
126
- return /*#__PURE__*/React.createElement(View, {
127
- style: {
128
- flex: 1,
129
- backgroundColor: palette.background700
130
- }
131
- }, /*#__PURE__*/React.createElement(StatusBar, {
132
- barStyle: 'light-content',
133
- animated: true
134
- }), /*#__PURE__*/React.createElement(View, {
135
- style: {
136
- flex: 1,
137
- alignItems: 'center',
138
- justifyContent: 'center'
139
- }
140
- }, fileViewer, loading && /*#__PURE__*/React.createElement(LoadingSpinner, {
141
- style: {
142
- position: 'absolute'
143
- },
144
- size: 40,
145
- color: palette.primary300
146
- })), headerShown && /*#__PURE__*/React.createElement(FileViewerHeader, {
147
- title: STRINGS.FILE_VIEWER.TITLE(fileMessage),
148
- subtitle: STRINGS.FILE_VIEWER.SUBTITLE(fileMessage),
149
- topInset: headerTopInset ?? basicTopInset,
150
- onClose: onClose
151
- }), /*#__PURE__*/React.createElement(FileViewerFooter, {
152
- bottomInset: bottom,
153
- deleteShown: canDelete,
154
- onPressDelete: _onPressDelete,
155
- onPressDownload: _onPressDownload
156
- }));
157
- };
158
- const FileViewerHeader = _ref2 => {
159
- let {
160
- topInset,
161
- onClose,
162
- subtitle,
163
- title
164
- } = _ref2;
165
- const {
166
- palette
167
- } = useUIKitTheme();
168
- const {
169
- defaultHeight
170
- } = useHeaderStyle();
171
- const {
172
- left,
173
- right
174
- } = useSafeAreaInsets();
175
- return /*#__PURE__*/React.createElement(View, {
176
- style: [styles.headerContainer, {
177
- paddingLeft: styles.headerContainer.paddingHorizontal + left,
178
- paddingRight: styles.headerContainer.paddingHorizontal + right
179
- }, {
180
- paddingTop: topInset,
181
- height: defaultHeight + topInset,
182
- backgroundColor: palette.overlay01
183
- }]
184
- }, /*#__PURE__*/React.createElement(TouchableOpacity, {
185
- onPress: onClose,
186
- style: styles.barButton
187
- }, /*#__PURE__*/React.createElement(Icon, {
188
- icon: 'close',
189
- size: 24,
190
- color: palette.onBackgroundDark01
191
- })), /*#__PURE__*/React.createElement(View, {
192
- style: styles.barTitleContainer
193
- }, /*#__PURE__*/React.createElement(Text, {
194
- h2: true,
195
- color: palette.onBackgroundDark01,
196
- style: styles.headerTitle,
197
- numberOfLines: 1
198
- }, truncate(title, {
199
- mode: 'mid',
200
- maxLen: 18
201
- })), /*#__PURE__*/React.createElement(Text, {
202
- caption2: true,
203
- color: palette.onBackgroundDark01,
204
- numberOfLines: 1
205
- }, subtitle)), /*#__PURE__*/React.createElement(View, {
206
- style: styles.barButton
207
- }));
208
- };
209
- const FileViewerFooter = _ref3 => {
210
- let {
211
- bottomInset,
212
- deleteShown,
213
- onPressDelete,
214
- onPressDownload
215
- } = _ref3;
216
- const {
217
- palette
218
- } = useUIKitTheme();
219
- const {
220
- defaultHeight
221
- } = useHeaderStyle();
222
- const {
223
- left,
224
- right
225
- } = useSafeAreaInsets();
226
- return /*#__PURE__*/React.createElement(View, {
227
- style: [styles.footerContainer, {
228
- paddingLeft: styles.headerContainer.paddingHorizontal + left,
229
- paddingRight: styles.headerContainer.paddingHorizontal + right
230
- }, {
231
- paddingBottom: bottomInset,
232
- height: defaultHeight + bottomInset,
233
- backgroundColor: palette.overlay01
234
- }]
235
- }, /*#__PURE__*/React.createElement(TouchableOpacity, {
236
- onPress: onPressDownload,
237
- style: styles.barButton
238
- }, /*#__PURE__*/React.createElement(Icon, {
239
- icon: 'download',
240
- size: 24,
241
- color: palette.onBackgroundDark01
242
- })), /*#__PURE__*/React.createElement(View, {
243
- style: styles.barTitleContainer
244
- }), /*#__PURE__*/React.createElement(TouchableOpacity, {
245
- onPress: onPressDelete,
246
- style: styles.barButton,
247
- disabled: !deleteShown
248
- }, deleteShown && /*#__PURE__*/React.createElement(Icon, {
249
- icon: 'delete',
250
- size: 24,
251
- color: palette.onBackgroundDark01
252
- })));
253
- };
254
- const styles = createStyleSheet({
255
- headerContainer: {
256
- top: 0,
257
- left: 0,
258
- right: 0,
259
- position: 'absolute',
260
- flexDirection: 'row',
261
- alignItems: 'center',
262
- justifyContent: 'center',
263
- paddingHorizontal: 12
264
- },
265
- barButton: {
266
- width: 32,
267
- height: 32,
268
- alignItems: 'center',
269
- justifyContent: 'center'
270
- },
271
- barTitleContainer: {
272
- flex: 1,
273
- alignItems: 'center',
274
- justifyContent: 'center'
275
- },
276
- headerTitle: {
277
- marginBottom: 2
278
- },
279
- footerContainer: {
280
- position: 'absolute',
281
- left: 0,
282
- right: 0,
283
- bottom: 0,
284
- flexDirection: 'row',
285
- alignItems: 'center',
286
- justifyContent: 'center',
287
- paddingHorizontal: 12
288
- }
289
- });
290
- export default FileViewer;
291
- //# sourceMappingURL=FileViewer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","useEffect","useState","StatusBar","StyleSheet","TouchableOpacity","View","useSafeAreaInsets","Icon","Image","LoadingSpinner","Text","createStyleSheet","useAlert","useHeaderStyle","useToast","useUIKitTheme","Logger","getFileExtension","getFileType","isMyMessage","toMegabyte","truncate","useIIFE","useLocalization","usePlatformService","useSendbirdChat","FileViewer","_ref","headerShown","deleteMessage","headerTopInset","fileMessage","onPressDownload","onPressDelete","onClose","loading","setLoading","bottom","currentUser","palette","topInset","statusBarTranslucent","defaultHeight","STRINGS","fileService","mediaService","toast","alert","basicTopInset","canDelete","userId","fileType","type","url","fileViewer","createElement","source","uri","style","absoluteFill","resizeMode","onLoadEnd","VideoComponent","top","onLoad","_onPressDelete","title","LABELS","CHANNEL_MESSAGE_DELETE_CONFIRM_TITLE","buttons","text","CHANNEL_MESSAGE_DELETE_CONFIRM_CANCEL","CHANNEL_MESSAGE_DELETE_CONFIRM_OK","onPress","then","catch","show","TOAST","DELETE_MSG_ERROR","_onPressDownload","size","DOWNLOAD_START","save","fileUrl","fileName","name","response","DOWNLOAD_OK","log","err","DOWNLOAD_ERROR","flex","backgroundColor","background700","barStyle","animated","alignItems","justifyContent","position","color","primary300","FileViewerHeader","FILE_VIEWER","TITLE","subtitle","SUBTITLE","FileViewerFooter","bottomInset","deleteShown","_ref2","left","right","styles","headerContainer","paddingLeft","paddingHorizontal","paddingRight","paddingTop","height","overlay01","barButton","icon","onBackgroundDark01","barTitleContainer","h2","headerTitle","numberOfLines","mode","maxLen","caption2","_ref3","footerContainer","paddingBottom","disabled","flexDirection","width","marginBottom"],"sources":["FileViewer.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport { StatusBar, StyleSheet, TouchableOpacity, View } from 'react-native';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\n\nimport {\n Icon,\n Image,\n LoadingSpinner,\n Text,\n createStyleSheet,\n useAlert,\n useHeaderStyle,\n useToast,\n useUIKitTheme,\n} from '@sendbird/uikit-react-native-foundation';\nimport type { SendbirdFileMessage } from '@sendbird/uikit-utils';\nimport {\n Logger,\n getFileExtension,\n getFileType,\n isMyMessage,\n toMegabyte,\n truncate,\n useIIFE,\n} from '@sendbird/uikit-utils';\n\nimport { useLocalization, usePlatformService, useSendbirdChat } from '../hooks/useContext';\n\ntype Props = {\n fileMessage: SendbirdFileMessage;\n deleteMessage: () => Promise<void>;\n\n onClose: () => void;\n onPressDownload?: (message: SendbirdFileMessage) => void;\n onPressDelete?: (message: SendbirdFileMessage) => void;\n\n headerShown?: boolean;\n headerTopInset?: number;\n};\nconst FileViewer = ({\n headerShown = true,\n deleteMessage,\n headerTopInset,\n fileMessage,\n onPressDownload,\n onPressDelete,\n onClose,\n}: Props) => {\n const [loading, setLoading] = useState(true);\n\n const { bottom } = useSafeAreaInsets();\n\n const { currentUser } = useSendbirdChat();\n const { palette } = useUIKitTheme();\n const { topInset, statusBarTranslucent, defaultHeight } = useHeaderStyle();\n const { STRINGS } = useLocalization();\n const { fileService, mediaService } = usePlatformService();\n const toast = useToast();\n const { alert } = useAlert();\n\n const basicTopInset = statusBarTranslucent ? topInset : 0;\n const canDelete = isMyMessage(fileMessage, currentUser?.userId);\n const fileType = getFileType(fileMessage.type || getFileExtension(fileMessage.url));\n\n useEffect(() => {\n if (fileType === 'file') onClose();\n }, []);\n\n const fileViewer = useIIFE(() => {\n switch (fileType) {\n case 'image': {\n return (\n <Image\n source={{ uri: fileMessage.url }}\n style={StyleSheet.absoluteFill}\n resizeMode={'contain'}\n onLoadEnd={() => setLoading(false)}\n />\n );\n }\n\n case 'video':\n case 'audio': {\n return (\n <mediaService.VideoComponent\n source={{ uri: fileMessage.url }}\n style={[StyleSheet.absoluteFill, { top: basicTopInset + defaultHeight, bottom: defaultHeight + bottom }]}\n resizeMode={'contain'}\n onLoad={() => setLoading(false)}\n />\n );\n }\n\n default: {\n return null;\n }\n }\n });\n\n const _onPressDelete = () => {\n if (!canDelete) return;\n\n if (onPressDelete) {\n onPressDelete(fileMessage);\n } else {\n alert({\n title: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_TITLE,\n buttons: [\n {\n text: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_CANCEL,\n },\n {\n text: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_OK,\n style: 'destructive',\n onPress: () => {\n deleteMessage()\n .then(() => {\n onClose();\n })\n .catch(() => {\n toast.show(STRINGS.TOAST.DELETE_MSG_ERROR, 'error');\n });\n },\n },\n ],\n });\n }\n };\n\n const _onPressDownload = () => {\n if (onPressDownload) {\n onPressDownload(fileMessage);\n } else {\n if (toMegabyte(fileMessage.size) > 4) {\n toast.show(STRINGS.TOAST.DOWNLOAD_START, 'success');\n }\n\n fileService\n .save({ fileUrl: fileMessage.url, fileName: fileMessage.name, fileType: fileMessage.type })\n .then((response) => {\n toast.show(STRINGS.TOAST.DOWNLOAD_OK, 'success');\n Logger.log('File saved to', response);\n })\n .catch((err) => {\n toast.show(STRINGS.TOAST.DOWNLOAD_ERROR, 'error');\n Logger.log('File save failure', err);\n });\n }\n };\n\n return (\n <View style={{ flex: 1, backgroundColor: palette.background700 }}>\n <StatusBar barStyle={'light-content'} animated />\n <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>\n {fileViewer}\n {loading && <LoadingSpinner style={{ position: 'absolute' }} size={40} color={palette.primary300} />}\n </View>\n {headerShown && (\n <FileViewerHeader\n title={STRINGS.FILE_VIEWER.TITLE(fileMessage)}\n subtitle={STRINGS.FILE_VIEWER.SUBTITLE(fileMessage)}\n topInset={headerTopInset ?? basicTopInset}\n onClose={onClose}\n />\n )}\n <FileViewerFooter\n bottomInset={bottom}\n deleteShown={canDelete}\n onPressDelete={_onPressDelete}\n onPressDownload={_onPressDownload}\n />\n </View>\n );\n};\n\ntype HeaderProps = {\n topInset: number;\n onClose: () => void;\n title: string;\n subtitle: string;\n};\nconst FileViewerHeader = ({ topInset, onClose, subtitle, title }: HeaderProps) => {\n const { palette } = useUIKitTheme();\n const { defaultHeight } = useHeaderStyle();\n const { left, right } = useSafeAreaInsets();\n\n return (\n <View\n style={[\n styles.headerContainer,\n {\n paddingLeft: styles.headerContainer.paddingHorizontal + left,\n paddingRight: styles.headerContainer.paddingHorizontal + right,\n },\n { paddingTop: topInset, height: defaultHeight + topInset, backgroundColor: palette.overlay01 },\n ]}\n >\n <TouchableOpacity onPress={onClose} style={styles.barButton}>\n <Icon icon={'close'} size={24} color={palette.onBackgroundDark01} />\n </TouchableOpacity>\n <View style={styles.barTitleContainer}>\n <Text h2 color={palette.onBackgroundDark01} style={styles.headerTitle} numberOfLines={1}>\n {truncate(title, { mode: 'mid', maxLen: 18 })}\n </Text>\n <Text caption2 color={palette.onBackgroundDark01} numberOfLines={1}>\n {subtitle}\n </Text>\n </View>\n <View style={styles.barButton} />\n </View>\n );\n};\n\ntype FooterProps = {\n bottomInset: number;\n deleteShown: boolean;\n onPressDelete: () => void;\n onPressDownload: () => void;\n};\nconst FileViewerFooter = ({ bottomInset, deleteShown, onPressDelete, onPressDownload }: FooterProps) => {\n const { palette } = useUIKitTheme();\n const { defaultHeight } = useHeaderStyle();\n const { left, right } = useSafeAreaInsets();\n\n return (\n <View\n style={[\n styles.footerContainer,\n {\n paddingLeft: styles.headerContainer.paddingHorizontal + left,\n paddingRight: styles.headerContainer.paddingHorizontal + right,\n },\n {\n paddingBottom: bottomInset,\n height: defaultHeight + bottomInset,\n backgroundColor: palette.overlay01,\n },\n ]}\n >\n <TouchableOpacity onPress={onPressDownload} style={styles.barButton}>\n <Icon icon={'download'} size={24} color={palette.onBackgroundDark01} />\n </TouchableOpacity>\n <View style={styles.barTitleContainer} />\n <TouchableOpacity onPress={onPressDelete} style={styles.barButton} disabled={!deleteShown}>\n {deleteShown && <Icon icon={'delete'} size={24} color={palette.onBackgroundDark01} />}\n </TouchableOpacity>\n </View>\n );\n};\n\nconst styles = createStyleSheet({\n headerContainer: {\n top: 0,\n left: 0,\n right: 0,\n position: 'absolute',\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: 12,\n },\n barButton: {\n width: 32,\n height: 32,\n alignItems: 'center',\n justifyContent: 'center',\n },\n barTitleContainer: {\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n },\n headerTitle: {\n marginBottom: 2,\n },\n footerContainer: {\n position: 'absolute',\n left: 0,\n right: 0,\n bottom: 0,\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: 12,\n },\n});\n\nexport default FileViewer;\n"],"mappings":"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"}
@@ -1,288 +0,0 @@
1
- import React, { useEffect, useState } from 'react';
2
- import { StatusBar, StyleSheet, TouchableOpacity, View } from 'react-native';
3
- import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
-
5
- import {
6
- Icon,
7
- Image,
8
- LoadingSpinner,
9
- Text,
10
- createStyleSheet,
11
- useAlert,
12
- useHeaderStyle,
13
- useToast,
14
- useUIKitTheme,
15
- } from '@sendbird/uikit-react-native-foundation';
16
- import type { SendbirdFileMessage } from '@sendbird/uikit-utils';
17
- import {
18
- Logger,
19
- getFileExtension,
20
- getFileType,
21
- isMyMessage,
22
- toMegabyte,
23
- truncate,
24
- useIIFE,
25
- } from '@sendbird/uikit-utils';
26
-
27
- import { useLocalization, usePlatformService, useSendbirdChat } from '../hooks/useContext';
28
-
29
- type Props = {
30
- fileMessage: SendbirdFileMessage;
31
- deleteMessage: () => Promise<void>;
32
-
33
- onClose: () => void;
34
- onPressDownload?: (message: SendbirdFileMessage) => void;
35
- onPressDelete?: (message: SendbirdFileMessage) => void;
36
-
37
- headerShown?: boolean;
38
- headerTopInset?: number;
39
- };
40
- const FileViewer = ({
41
- headerShown = true,
42
- deleteMessage,
43
- headerTopInset,
44
- fileMessage,
45
- onPressDownload,
46
- onPressDelete,
47
- onClose,
48
- }: Props) => {
49
- const [loading, setLoading] = useState(true);
50
-
51
- const { bottom } = useSafeAreaInsets();
52
-
53
- const { currentUser } = useSendbirdChat();
54
- const { palette } = useUIKitTheme();
55
- const { topInset, statusBarTranslucent, defaultHeight } = useHeaderStyle();
56
- const { STRINGS } = useLocalization();
57
- const { fileService, mediaService } = usePlatformService();
58
- const toast = useToast();
59
- const { alert } = useAlert();
60
-
61
- const basicTopInset = statusBarTranslucent ? topInset : 0;
62
- const canDelete = isMyMessage(fileMessage, currentUser?.userId);
63
- const fileType = getFileType(fileMessage.type || getFileExtension(fileMessage.url));
64
-
65
- useEffect(() => {
66
- if (fileType === 'file') onClose();
67
- }, []);
68
-
69
- const fileViewer = useIIFE(() => {
70
- switch (fileType) {
71
- case 'image': {
72
- return (
73
- <Image
74
- source={{ uri: fileMessage.url }}
75
- style={StyleSheet.absoluteFill}
76
- resizeMode={'contain'}
77
- onLoadEnd={() => setLoading(false)}
78
- />
79
- );
80
- }
81
-
82
- case 'video':
83
- case 'audio': {
84
- return (
85
- <mediaService.VideoComponent
86
- source={{ uri: fileMessage.url }}
87
- style={[StyleSheet.absoluteFill, { top: basicTopInset + defaultHeight, bottom: defaultHeight + bottom }]}
88
- resizeMode={'contain'}
89
- onLoad={() => setLoading(false)}
90
- />
91
- );
92
- }
93
-
94
- default: {
95
- return null;
96
- }
97
- }
98
- });
99
-
100
- const _onPressDelete = () => {
101
- if (!canDelete) return;
102
-
103
- if (onPressDelete) {
104
- onPressDelete(fileMessage);
105
- } else {
106
- alert({
107
- title: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_TITLE,
108
- buttons: [
109
- {
110
- text: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_CANCEL,
111
- },
112
- {
113
- text: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_OK,
114
- style: 'destructive',
115
- onPress: () => {
116
- deleteMessage()
117
- .then(() => {
118
- onClose();
119
- })
120
- .catch(() => {
121
- toast.show(STRINGS.TOAST.DELETE_MSG_ERROR, 'error');
122
- });
123
- },
124
- },
125
- ],
126
- });
127
- }
128
- };
129
-
130
- const _onPressDownload = () => {
131
- if (onPressDownload) {
132
- onPressDownload(fileMessage);
133
- } else {
134
- if (toMegabyte(fileMessage.size) > 4) {
135
- toast.show(STRINGS.TOAST.DOWNLOAD_START, 'success');
136
- }
137
-
138
- fileService
139
- .save({ fileUrl: fileMessage.url, fileName: fileMessage.name, fileType: fileMessage.type })
140
- .then((response) => {
141
- toast.show(STRINGS.TOAST.DOWNLOAD_OK, 'success');
142
- Logger.log('File saved to', response);
143
- })
144
- .catch((err) => {
145
- toast.show(STRINGS.TOAST.DOWNLOAD_ERROR, 'error');
146
- Logger.log('File save failure', err);
147
- });
148
- }
149
- };
150
-
151
- return (
152
- <View style={{ flex: 1, backgroundColor: palette.background700 }}>
153
- <StatusBar barStyle={'light-content'} animated />
154
- <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
155
- {fileViewer}
156
- {loading && <LoadingSpinner style={{ position: 'absolute' }} size={40} color={palette.primary300} />}
157
- </View>
158
- {headerShown && (
159
- <FileViewerHeader
160
- title={STRINGS.FILE_VIEWER.TITLE(fileMessage)}
161
- subtitle={STRINGS.FILE_VIEWER.SUBTITLE(fileMessage)}
162
- topInset={headerTopInset ?? basicTopInset}
163
- onClose={onClose}
164
- />
165
- )}
166
- <FileViewerFooter
167
- bottomInset={bottom}
168
- deleteShown={canDelete}
169
- onPressDelete={_onPressDelete}
170
- onPressDownload={_onPressDownload}
171
- />
172
- </View>
173
- );
174
- };
175
-
176
- type HeaderProps = {
177
- topInset: number;
178
- onClose: () => void;
179
- title: string;
180
- subtitle: string;
181
- };
182
- const FileViewerHeader = ({ topInset, onClose, subtitle, title }: HeaderProps) => {
183
- const { palette } = useUIKitTheme();
184
- const { defaultHeight } = useHeaderStyle();
185
- const { left, right } = useSafeAreaInsets();
186
-
187
- return (
188
- <View
189
- style={[
190
- styles.headerContainer,
191
- {
192
- paddingLeft: styles.headerContainer.paddingHorizontal + left,
193
- paddingRight: styles.headerContainer.paddingHorizontal + right,
194
- },
195
- { paddingTop: topInset, height: defaultHeight + topInset, backgroundColor: palette.overlay01 },
196
- ]}
197
- >
198
- <TouchableOpacity onPress={onClose} style={styles.barButton}>
199
- <Icon icon={'close'} size={24} color={palette.onBackgroundDark01} />
200
- </TouchableOpacity>
201
- <View style={styles.barTitleContainer}>
202
- <Text h2 color={palette.onBackgroundDark01} style={styles.headerTitle} numberOfLines={1}>
203
- {truncate(title, { mode: 'mid', maxLen: 18 })}
204
- </Text>
205
- <Text caption2 color={palette.onBackgroundDark01} numberOfLines={1}>
206
- {subtitle}
207
- </Text>
208
- </View>
209
- <View style={styles.barButton} />
210
- </View>
211
- );
212
- };
213
-
214
- type FooterProps = {
215
- bottomInset: number;
216
- deleteShown: boolean;
217
- onPressDelete: () => void;
218
- onPressDownload: () => void;
219
- };
220
- const FileViewerFooter = ({ bottomInset, deleteShown, onPressDelete, onPressDownload }: FooterProps) => {
221
- const { palette } = useUIKitTheme();
222
- const { defaultHeight } = useHeaderStyle();
223
- const { left, right } = useSafeAreaInsets();
224
-
225
- return (
226
- <View
227
- style={[
228
- styles.footerContainer,
229
- {
230
- paddingLeft: styles.headerContainer.paddingHorizontal + left,
231
- paddingRight: styles.headerContainer.paddingHorizontal + right,
232
- },
233
- {
234
- paddingBottom: bottomInset,
235
- height: defaultHeight + bottomInset,
236
- backgroundColor: palette.overlay01,
237
- },
238
- ]}
239
- >
240
- <TouchableOpacity onPress={onPressDownload} style={styles.barButton}>
241
- <Icon icon={'download'} size={24} color={palette.onBackgroundDark01} />
242
- </TouchableOpacity>
243
- <View style={styles.barTitleContainer} />
244
- <TouchableOpacity onPress={onPressDelete} style={styles.barButton} disabled={!deleteShown}>
245
- {deleteShown && <Icon icon={'delete'} size={24} color={palette.onBackgroundDark01} />}
246
- </TouchableOpacity>
247
- </View>
248
- );
249
- };
250
-
251
- const styles = createStyleSheet({
252
- headerContainer: {
253
- top: 0,
254
- left: 0,
255
- right: 0,
256
- position: 'absolute',
257
- flexDirection: 'row',
258
- alignItems: 'center',
259
- justifyContent: 'center',
260
- paddingHorizontal: 12,
261
- },
262
- barButton: {
263
- width: 32,
264
- height: 32,
265
- alignItems: 'center',
266
- justifyContent: 'center',
267
- },
268
- barTitleContainer: {
269
- flex: 1,
270
- alignItems: 'center',
271
- justifyContent: 'center',
272
- },
273
- headerTitle: {
274
- marginBottom: 2,
275
- },
276
- footerContainer: {
277
- position: 'absolute',
278
- left: 0,
279
- right: 0,
280
- bottom: 0,
281
- flexDirection: 'row',
282
- alignItems: 'center',
283
- justifyContent: 'center',
284
- paddingHorizontal: 12,
285
- },
286
- });
287
-
288
- export default FileViewer;