Skip to content

Commit 512a5c3

Browse files
HoonBaekAhyoungRyu
andauthored
feat: Apply the uikitUploadSizeLimit to the Open Channel Message Input (#885)
[CLNP-1699](https://sendbird.atlassian.net/browse/CLNP-1699) ### Customer Request Apply the uikitUploadSizeLimit into the Message Input of the Open Channel ### ChangeLog * Check the file size limit when sending file messages from Open Channel * Display the modal alert when the file size over the limit [CLNP-1699]: https://sendbird.atlassian.net/browse/CLNP-1699?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --------- Co-authored-by: Irene Ryu <[email protected]>
1 parent d5ad8f3 commit 512a5c3

File tree

9 files changed

+159
-205
lines changed

9 files changed

+159
-205
lines changed

rollup.module-exports.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export default {
6060
Channel: 'src/modules/Channel/index.tsx',
6161
'Channel/context': 'src/modules/Channel/context/ChannelProvider.tsx',
6262
'Channel/hooks/useInitialMessagesFetch': 'src/modules/Channel/context/hooks/useInitialMessagesFetch.ts',
63-
'Channel/hooks/useHandleUploadFiles': 'src/modules/Channel/components/MessageInput/useHandleUploadFiles.tsx',
63+
'Channel/hooks/useHandleUploadFiles': 'src/modules/Channel/context/hooks/useHandleUploadFiles.tsx',
6464
'Channel/utils/getMessagePartsInfo': 'src/modules/Channel/components/MessageList/getMessagePartsInfo.ts',
6565
'Channel/utils/compareMessagesForGrouping': 'src/modules/Channel/context/compareMessagesForGrouping.ts',
6666
'Channel/components/ChannelHeader': 'src/modules/Channel/components/ChannelHeader/index.tsx',

src/modules/Channel/components/MessageInput/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { MessageInputKeys } from '../../../../ui/MessageInput/const';
1414
import VoiceMessageInputWrapper from './VoiceMessageInputWrapper';
1515
import { useDirtyGetMentions } from '../../../Message/hooks/useDirtyGetMentions';
1616
import { useMediaQueryContext } from '../../../../lib/MediaQueryContext';
17-
import { useHandleUploadFiles } from './useHandleUploadFiles';
17+
import { useHandleUploadFiles } from '../../context/hooks/useHandleUploadFiles';
1818

1919
export type MessageInputWrapperProps = {
2020
value?: string;

src/modules/Channel/components/MessageInput/useHandleUploadFiles.tsx renamed to src/modules/Channel/context/hooks/useHandleUploadFiles.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useCallback } from 'react';
22

33
import { Logger } from '../../../../lib/SendbirdState';
4-
import { SendMFMFunctionType } from '../../context/hooks/useSendMultipleFilesMessage';
4+
import { SendMFMFunctionType } from './useSendMultipleFilesMessage';
55
import useSendbirdStateContext from '../../../../hooks/useSendbirdStateContext';
66
import { SendableMessageType, isImage } from '../../../../utils';
77
// TODO: get SendFileMessageFunctionType from Channel
@@ -12,6 +12,7 @@ import { useLocalization } from '../../../../lib/LocalizationContext';
1212
import { ModalFooter } from '../../../../ui/Modal';
1313
import { FileMessage, MultipleFilesMessage } from '@sendbird/chat/message';
1414
import { compressImages } from '../../../../utils/compressImages';
15+
import { ONE_MiB } from '../../../../utils/consts';
1516

1617
/**
1718
* The handleUploadFiles is a function sending a FileMessage and MultipleFilesMessage
@@ -70,11 +71,13 @@ export const useHandleUploadFiles = ({
7071
});
7172
return;
7273
}
73-
// Validate file sizes
74+
75+
/**
76+
* Validate file sizes
77+
* The default value of uikitUploadSizeLimit is 25MiB
78+
*/
7479
if (files.some((file: File) => file.size > uikitUploadSizeLimit)) {
75-
// The default value of uikitUploadSizeLimit is 26MB
7680
logger.info(`Channel|useHandleUploadFiles: Cannot upload file size exceeding ${uikitUploadSizeLimit}`);
77-
const ONE_MiB = 1024 * 1024;
7881
openModal({
7982
modalProps: {
8083
titleText: stringSet.FILE_UPLOAD_NOTIFICATION__SIZE_LIMIT.replace('%d', `${Math.floor(uikitUploadSizeLimit / ONE_MiB)}`),

src/modules/OpenChannel/context/hooks/useFileUploadCallback.ts

Lines changed: 0 additions & 196 deletions
This file was deleted.
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import React, { useCallback } from 'react';
2+
import type { OpenChannel } from '@sendbird/chat/openChannel';
3+
import type { FileMessageCreateParams } from '@sendbird/chat/message';
4+
5+
import type { Logger } from '../../../../lib/SendbirdState';
6+
import * as messageActionTypes from '../dux/actionTypes';
7+
import * as utils from '../utils';
8+
import { SdkStore } from '../../../../lib/types';
9+
import { compressImages } from '../../../../utils/compressImages';
10+
import useSendbirdStateContext from '../../../../hooks/useSendbirdStateContext';
11+
import { useGlobalModalContext } from '../../../../hooks/useModal';
12+
import { useLocalization } from '../../../../lib/LocalizationContext';
13+
import { ONE_MiB } from '../../../../utils/consts';
14+
import { ModalFooter } from '../../../../ui/Modal';
15+
import { ButtonTypes } from '../../../../ui/Button';
16+
17+
interface DynamicParams {
18+
currentOpenChannel: OpenChannel;
19+
onBeforeSendFileMessage: (file: File) => FileMessageCreateParams;
20+
checkScrollBottom: () => boolean;
21+
imageCompression?: {
22+
compressionRate?: number,
23+
resizingWidth?: number | string,
24+
resizingHeight?: number | string,
25+
};
26+
}
27+
interface StaticParams {
28+
sdk: SdkStore['sdk'];
29+
logger: Logger;
30+
messagesDispatcher: (props: { type: string, payload: any }) => void;
31+
scrollRef: React.MutableRefObject<HTMLElement>;
32+
}
33+
34+
type CallbackReturn = (files: Array<File> | File) => void;
35+
36+
function useFileUploadCallback({
37+
currentOpenChannel,
38+
checkScrollBottom,
39+
imageCompression = {},
40+
onBeforeSendFileMessage,
41+
}: DynamicParams,
42+
{ sdk, logger, messagesDispatcher, scrollRef }: StaticParams,
43+
): CallbackReturn {
44+
const { stringSet } = useLocalization();
45+
const { openModal } = useGlobalModalContext();
46+
const { config } = useSendbirdStateContext();
47+
const { uikitUploadSizeLimit } = config;
48+
49+
return useCallback(async (files) => {
50+
if (sdk) {
51+
/**
52+
* OpenChannel does not currently support file lists.
53+
* However, this change is made to maintain interface consistency with group channels.
54+
*/
55+
const file = Array.isArray(files) ? files[0] : files;
56+
const createCustomParams = onBeforeSendFileMessage && typeof onBeforeSendFileMessage === 'function';
57+
58+
const createParamsDefault = (file_): FileMessageCreateParams => {
59+
const params: FileMessageCreateParams = {};
60+
params.file = file_;
61+
return params;
62+
};
63+
64+
/**
65+
* Validate file sizes
66+
* The default value of uikitUploadSizeLimit is 25MiB
67+
*/
68+
if (file.size > uikitUploadSizeLimit) {
69+
logger.info(`OpenChannel | useFileUploadCallback: Cannot upload file size exceeding ${uikitUploadSizeLimit}`);
70+
openModal({
71+
modalProps: {
72+
titleText: stringSet.FILE_UPLOAD_NOTIFICATION__SIZE_LIMIT.replace('%d', `${Math.floor(uikitUploadSizeLimit / ONE_MiB)}`),
73+
hideFooter: true,
74+
},
75+
childElement: ({ closeModal }) => (
76+
<ModalFooter
77+
type={ButtonTypes.PRIMARY}
78+
submitText={stringSet.BUTTON__OK}
79+
hideCancelButton
80+
onCancel={closeModal}
81+
onSubmit={closeModal}
82+
/>
83+
),
84+
});
85+
return;
86+
}
87+
88+
// Image compression
89+
const { compressedFiles } = await compressImages({
90+
files: [file],
91+
imageCompression,
92+
logger,
93+
});
94+
const [compressedFile] = compressedFiles;
95+
96+
// Send FileMessage
97+
if (createCustomParams) {
98+
logger.info('OpenChannel | useFileUploadCallback: Creating params using onBeforeSendFileMessage', onBeforeSendFileMessage);
99+
}
100+
const params = onBeforeSendFileMessage ? onBeforeSendFileMessage(compressedFile) : createParamsDefault(compressedFile);
101+
logger.info('OpenChannel | useFileUploadCallback: Uploading file message start', params);
102+
103+
const isBottom = checkScrollBottom();
104+
currentOpenChannel.sendFileMessage(params)
105+
.onPending((pendingMessage) => {
106+
messagesDispatcher({
107+
type: messageActionTypes.SENDING_MESSAGE_START,
108+
payload: {
109+
message: {
110+
...pendingMessage,
111+
url: URL.createObjectURL(file),
112+
// pending thumbnail message seems to be failed
113+
requestState: 'pending',
114+
},
115+
channel: currentOpenChannel,
116+
},
117+
});
118+
})
119+
.onSucceeded((message) => {
120+
logger.info('OpenChannel | useFileUploadCallback: Sending message succeeded', message);
121+
messagesDispatcher({
122+
type: messageActionTypes.SENDING_MESSAGE_SUCCEEDED,
123+
payload: message,
124+
});
125+
if (isBottom) {
126+
setTimeout(() => {
127+
utils.scrollIntoLast(0, scrollRef);
128+
});
129+
}
130+
})
131+
.onFailed((error, message) => {
132+
logger.error('OpenChannel | useFileUploadCallback: Sending file message failed', { message, error });
133+
// @ts-ignore
134+
message.localUrl = URL.createObjectURL(file);
135+
// @ts-ignore
136+
message.file = file;
137+
messagesDispatcher({
138+
type: messageActionTypes.SENDING_MESSAGE_FAILED,
139+
payload: message,
140+
});
141+
});
142+
}
143+
}, [currentOpenChannel, onBeforeSendFileMessage, checkScrollBottom, imageCompression]);
144+
}
145+
146+
export default useFileUploadCallback;

0 commit comments

Comments
 (0)