Skip to content

Commit 634b94e

Browse files
chohongmLiam Chobang9
authored
feat: Support form message (#1168)
Fixes [AC-3068](https://sendbird.atlassian.net/browse/AC-3068) ### Test sheet https://docs.google.com/spreadsheets/d/1TBjj8SBnxdV0dy65PEshUUGq-2HShFFQmkS3184cVj4/edit?gid=0#gid=0 ### Changelogs UIKit now supports form message! `message` with `messageForm` will be displayed as form message. ### Features: * Added `enableFormTypeMessage` global option * How to use? ```tsx <App appId={appId} userId={userId} uikitOptions={{ groupChannel: { // Below turns on the form message feature. Default value is false. enableFormTypeMessage: true, } }} /> ``` * `MessageInput` is now being disabled if a channel has a form message that is not submitted and its `extendedMessagePayload['disable_chat_input']` value is true * Added `FormMessageItemBody`, and `FormInput` ### Sample https://deploy-preview-1168--sendbird-uikit-react.netlify.app/group_channel [AC-3068]: https://sendbird.atlassian.net/browse/AC-3068?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --------- Co-authored-by: Liam Cho <[email protected]> Co-authored-by: Hyungu Kang | Airen <[email protected]>
1 parent 7192bac commit 634b94e

File tree

27 files changed

+2743
-2734
lines changed

27 files changed

+2743
-2734
lines changed

apps/testing/src/utils/paramsBuilder.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ export interface InitialParams {
66
userId?: string;
77
nickname?: string;
88
accessToken?: string;
9+
customApiHost?: string;
10+
customWebSocketHost?: string;
911
}
1012

1113
interface ParamsAsProps {
@@ -26,6 +28,8 @@ export const useConfigParams = (initParams: InitialParams): ParamsAsProps => {
2628
userId: searchParams.get('userId') || initParams.userId,
2729
nickname: searchParams.get('nickname') || initParams.nickname || initParams.userId,
2830
accessToken: searchParams.get('accessToken') || initParams.accessToken,
31+
customApiHost: searchParams.get('customApiHost') || initParams.customApiHost,
32+
customWebSocketHost: searchParams.get('customWebSocketHost') || initParams.customWebSocketHost,
2933
allowProfileEdit: parseValue(searchParams.get('enableProfileEdit')) ?? true,
3034
isMultipleFilesMessageEnabled: parseValue(searchParams.get('enableMultipleFilesMessage')) ?? true,
3135
enableLegacyChannelModules: parseValue(searchParams.get('enableLegacyChannelModules')) ?? false,
@@ -97,6 +101,7 @@ export const paramKeys = [
97101
'groupChannel_enableSuggestedReplies',
98102
'groupChannel_showSuggestedRepliesFor',
99103
'groupChannel_enableMarkdownForUserMessage',
104+
'groupChannel_enableFormTypeMessage',
100105
'groupChannelList_enableTypingIndicator',
101106
'groupChannelList_enableMessageReceiptStatus',
102107
'groupChannelSettings_enableMessageSearch',

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@
6969
"react-dom": "^16.8.6 || ^17.0.0 || ^18.0.0"
7070
},
7171
"dependencies": {
72-
"@sendbird/chat": "^4.13.0",
73-
"@sendbird/react-uikit-message-template-view": "0.0.1-alpha.76",
74-
"@sendbird/uikit-tools": "0.0.1-alpha.76",
72+
"@sendbird/chat": "^4.14.2",
73+
"@sendbird/react-uikit-message-template-view": "0.0.1-alpha.79",
74+
"@sendbird/uikit-tools": "0.0.1-alpha.79",
7575
"css-vars-ponyfill": "^2.3.2",
7676
"date-fns": "^2.16.1",
7777
"dompurify": "^3.0.1"

src/lib/Sendbird.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ const SendbirdSDK = ({
387387
showSuggestedRepliesFor: configs.groupChannel.channel.showSuggestedRepliesFor,
388388
suggestedRepliesDirection: configs.groupChannel.channel.suggestedRepliesDirection,
389389
enableMarkdownForUserMessage: configs.groupChannel.channel.enableMarkdownForUserMessage,
390+
enableFormTypeMessage: configs.groupChannel.channel.enableFormTypeMessage,
390391
enableReactionsSupergroup: sdkInitialized && configsWithAppAttr(sdk).groupChannel.channel.enableReactionsSupergroup as never,
391392
},
392393
groupChannelList: {

src/lib/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export interface SendBirdStateConfig {
112112
showSuggestedRepliesFor: SBUConfig['groupChannel']['channel']['showSuggestedRepliesFor'];
113113
suggestedRepliesDirection: SBUConfig['groupChannel']['channel']['suggestedRepliesDirection'];
114114
enableMarkdownForUserMessage: SBUConfig['groupChannel']['channel']['enableMarkdownForUserMessage'];
115+
enableFormTypeMessage: SBUConfig['groupChannel']['channel']['enableFormTypeMessage'];
115116
/**
116117
* @deprecated Currently, this feature is turned off by default. If you wish to use this feature, contact us: {@link https://dashboard.sendbird.com/settings/contact_us?category=feedback_and_feature_requests&product=UIKit}
117118
*/

src/lib/utils/uikitConfigMapper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export function uikitConfigMapper({
4040
showSuggestedRepliesFor: uikitOptions.groupChannel?.showSuggestedRepliesFor,
4141
suggestedRepliesDirection: uikitOptions.groupChannel?.suggestedRepliesDirection,
4242
enableMarkdownForUserMessage: uikitOptions.groupChannel?.enableMarkdownForUserMessage,
43+
enableFormTypeMessage: uikitOptions.groupChannel?.enableFormTypeMessage,
4344
},
4445
groupChannelList: {
4546
enableTypingIndicator: uikitOptions.groupChannelList?.enableTypingIndicator ?? isTypingIndicatorEnabledOnChannelList,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const MessageInputWrapper = (props: MessageInputWrapperProps) => {
2121
{...props}
2222
{...context}
2323
currentChannel={currentGroupChannel}
24+
messages={context.allMessages}
2425
sendUserMessage={(params) => {
2526
return sendMessage({
2627
message: params.message,

src/modules/GroupChannel/components/MessageInputWrapper/MessageInputWrapperView.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React, { useState, useEffect } from 'react';
33
import type { User } from '@sendbird/chat';
44
import type { GroupChannel } from '@sendbird/chat/groupChannel';
55
import type {
6+
BaseMessage,
67
FileMessage,
78
FileMessageCreateParams,
89
MultipleFilesMessage,
@@ -15,6 +16,7 @@ import {
1516
isDisabledBecauseFrozen,
1617
isDisabledBecauseMuted,
1718
isDisabledBecauseSuggestedReplies,
19+
isDisabledBecauseMessageForm,
1820
} from '../../context/utils';
1921
import useSendbirdStateContext from '../../../../hooks/useSendbirdStateContext';
2022
import { useLocalization } from '../../../../lib/LocalizationContext';
@@ -34,6 +36,7 @@ export interface MessageInputWrapperViewProps {
3436
disabled?: boolean;
3537
// ChannelContext
3638
currentChannel: GroupChannel | null;
39+
messages: BaseMessage[];
3740
isMultipleFilesMessageEnabled?: boolean;
3841
loading: boolean;
3942
quoteMessage: SendableMessageType | null;
@@ -58,6 +61,7 @@ export const MessageInputWrapperView = React.forwardRef((
5861
// Props
5962
const {
6063
currentChannel,
64+
messages,
6165
loading,
6266
quoteMessage,
6367
setQuoteMessage,
@@ -103,6 +107,7 @@ export const MessageInputWrapperView = React.forwardRef((
103107
|| isDisabledBecauseFrozen(currentChannel)
104108
|| isDisabledBecauseMuted(currentChannel)
105109
|| isDisabledBecauseSuggestedReplies(currentChannel, config.groupChannel.enableSuggestedReplies)
110+
|| isDisabledBecauseMessageForm(messages, config.groupChannel.enableFormTypeMessage)
106111
|| disabled;
107112

108113
const showSuggestedMentionList = !isMessageInputDisabled
@@ -210,7 +215,14 @@ export const MessageInputWrapperView = React.forwardRef((
210215
placeholder={
211216
(quoteMessage && stringSet.MESSAGE_INPUT__QUOTE_REPLY__PLACE_HOLDER)
212217
|| (isDisabledBecauseFrozen(currentChannel) && stringSet.MESSAGE_INPUT__PLACE_HOLDER__FROZEN)
213-
|| (isDisabledBecauseMuted(currentChannel) && (isMobile ? stringSet.MESSAGE_INPUT__PLACE_HOLDER__MUTED_SHORT : stringSet.MESSAGE_INPUT__PLACE_HOLDER__MUTED))
218+
|| (isDisabledBecauseMuted(currentChannel)
219+
&& (isMobile
220+
? stringSet.MESSAGE_INPUT__PLACE_HOLDER__MUTED_SHORT
221+
: stringSet.MESSAGE_INPUT__PLACE_HOLDER__MUTED))
222+
|| (isDisabledBecauseSuggestedReplies(currentChannel, config.groupChannel.enableSuggestedReplies)
223+
&& stringSet.MESSAGE_INPUT__PLACE_HOLDER__SUGGESTED_REPLIES)
224+
|| (isDisabledBecauseMessageForm(messages, config.groupChannel.enableFormTypeMessage)
225+
&& stringSet.MESSAGE_INPUT__PLACE_HOLDER__MESSAGE_FORM)
214226
|| (disabled && stringSet.MESSAGE_INPUT__PLACE_HOLDER__DISABLED)
215227
|| undefined
216228
}

src/modules/GroupChannel/context/GroupChannelProvider.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,9 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
186186
onMessagesReceived: () => {
187187
// FIXME: onMessagesReceived called with onApiResult
188188
if (isScrollBottomReached && isContextMenuClosed()) {
189-
scrollPubSub.publish('scrollToBottom', {});
189+
setTimeout(() => {
190+
scrollPubSub.publish('scrollToBottom', {});
191+
}, 10);
190192
}
191193
},
192194
onChannelDeleted: () => {

src/modules/GroupChannel/context/const.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export const MAX_USER_MENTION_COUNT = 10;
22
export const MAX_USER_SUGGESTION_COUNT = 15;
33
export const USER_MENTION_TEMP_CHAR = '@';
4+
export const UIKIT_COMPATIBLE_FORM_VERSION = 1;
45

56
export enum ThreadReplySelectType {
67
PARENT = 'PARENT',

src/modules/GroupChannel/context/utils.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { GroupChannel } from '@sendbird/chat/groupChannel';
22
import type { BaseMessage } from '@sendbird/chat/message';
33
import type { SendableMessage } from '@sendbird/chat/lib/__definition';
4+
import { UIKIT_COMPATIBLE_FORM_VERSION } from './const';
45

56
export function getComponentKeyFromMessage(message: BaseMessage | SendableMessage): string {
67
if ('sendingStatus' in message) {
@@ -36,6 +37,28 @@ export const isDisabledBecauseMuted = (groupChannel?: GroupChannel | null) => {
3637
return groupChannel.myMutedState === 'muted';
3738
};
3839

39-
export const isDisabledBecauseSuggestedReplies = (channel: GroupChannel | null | undefined, enableSuggestedReplies: boolean) => {
40-
return enableSuggestedReplies && !!channel?.lastMessage?.extendedMessagePayload?.disable_chat_input;
40+
export const isDisabledBecauseSuggestedReplies = (
41+
channel: GroupChannel | null | undefined,
42+
enableSuggestedReplies: boolean,
43+
) => {
44+
return enableSuggestedReplies
45+
&& Array.isArray(channel?.lastMessage?.extendedMessagePayload?.suggested_replies)
46+
&& !!channel?.lastMessage?.extendedMessagePayload?.disable_chat_input;
47+
};
48+
49+
export const isFormVersionCompatible = (version: number) => {
50+
return version <= UIKIT_COMPATIBLE_FORM_VERSION;
51+
};
52+
53+
export const isDisabledBecauseMessageForm = (
54+
allMessages: BaseMessage[],
55+
enableFormTypeMessage: boolean,
56+
) => {
57+
return enableFormTypeMessage
58+
&& allMessages.some((message) => (
59+
!!message.messageForm
60+
&& !message.messageForm.isSubmitted
61+
&& !!message.extendedMessagePayload?.disable_chat_input
62+
&& isFormVersionCompatible(message.messageForm.version)
63+
));
4164
};

0 commit comments

Comments
 (0)