From 61222706a51d809f2b65f48119a1008aa6108822 Mon Sep 17 00:00:00 2001 From: Liam Hongman Cho Date: Thu, 2 May 2024 14:34:55 +0900 Subject: [PATCH] feat: Horizontal scroll support for suggested replies (#1061) Fixes: [AC-1727](https://sendbird.atlassian.net/browse/AC-1727) ### Docs https://sendbird.atlassian.net/wiki/spaces/SDK/pages/2336523995/Meeting+note+-+Horizontal+Suggested+Replies+-+240422 ### Figma https://www.figma.com/file/SVbXU00FhjztekD8AiVukK/UIKit_Work-file_React?node-id=2440%3A6306&mode=dev ## Changelogs ### Features * Added `suggestedRepliesDirection` global option which serves as vertical/horizontal scroll option for `SuggestedReplies` * How to use? ```tsx ``` [AC-1727]: https://sendbird.atlassian.net/browse/AC-1727?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --------- Co-authored-by: Hyungu Kang | Airen --- package.json | 4 +- src/lib/Sendbird.tsx | 1 + src/lib/types.ts | 1 + src/lib/utils/uikitConfigMapper.ts | 1 + .../components/Message/MessageView.tsx | 15 +++++-- .../components/MessageList/index.scss | 4 +- .../components/SuggestedReplies/index.scss | 44 +++++++++++++++---- .../components/SuggestedReplies/index.tsx | 34 +++++++------- src/styles/_variables.scss | 3 ++ yarn.lock | 24 +++++----- 10 files changed, 86 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index 91adb1996..0a4c536b6 100644 --- a/package.json +++ b/package.json @@ -68,8 +68,8 @@ }, "dependencies": { "@sendbird/chat": "^4.12.3", - "@sendbird/react-uikit-message-template-view": "0.0.1-alpha.72", - "@sendbird/uikit-tools": "0.0.1-alpha.72", + "@sendbird/react-uikit-message-template-view": "0.0.1-alpha.73", + "@sendbird/uikit-tools": "0.0.1-alpha.73", "css-vars-ponyfill": "^2.3.2", "date-fns": "^2.16.1", "dompurify": "^3.0.1" diff --git a/src/lib/Sendbird.tsx b/src/lib/Sendbird.tsx index 0b6e994bf..386f3cc26 100644 --- a/src/lib/Sendbird.tsx +++ b/src/lib/Sendbird.tsx @@ -392,6 +392,7 @@ const SendbirdSDK = ({ enableFeedback: configs.groupChannel.channel.enableFeedback, enableSuggestedReplies: configs.groupChannel.channel.enableSuggestedReplies, showSuggestedRepliesFor: configs.groupChannel.channel.showSuggestedRepliesFor, + suggestedRepliesDirection: configs.groupChannel.channel.suggestedRepliesDirection, }, groupChannelList: { enableTypingIndicator: configs.groupChannel.channelList.enableTypingIndicator, diff --git a/src/lib/types.ts b/src/lib/types.ts index 35e97b1ce..2fdc9bb24 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -107,6 +107,7 @@ export interface SendBirdStateConfig { enableFeedback: SBUConfig['groupChannel']['channel']['enableFeedback']; enableSuggestedReplies: SBUConfig['groupChannel']['channel']['enableSuggestedReplies']; showSuggestedRepliesFor: SBUConfig['groupChannel']['channel']['showSuggestedRepliesFor']; + suggestedRepliesDirection: SBUConfig['groupChannel']['channel']['suggestedRepliesDirection']; }, groupChannelList: { enableTypingIndicator: SBUConfig['groupChannel']['channelList']['enableTypingIndicator']; diff --git a/src/lib/utils/uikitConfigMapper.ts b/src/lib/utils/uikitConfigMapper.ts index 953d9726a..d98f8766c 100644 --- a/src/lib/utils/uikitConfigMapper.ts +++ b/src/lib/utils/uikitConfigMapper.ts @@ -37,6 +37,7 @@ export function uikitConfigMapper({ enableFeedback: uikitOptions.groupChannel?.enableFeedback, enableSuggestedReplies: uikitOptions.groupChannel?.enableSuggestedReplies, showSuggestedRepliesFor: uikitOptions.groupChannel?.showSuggestedRepliesFor, + suggestedRepliesDirection: uikitOptions.groupChannel?.suggestedRepliesDirection, }, groupChannelList: { enableTypingIndicator: uikitOptions.groupChannelList?.enableTypingIndicator ?? isTypingIndicatorEnabledOnChannelList, diff --git a/src/modules/GroupChannel/components/Message/MessageView.tsx b/src/modules/GroupChannel/components/Message/MessageView.tsx index aa58aeb97..8b77cc777 100644 --- a/src/modules/GroupChannel/components/Message/MessageView.tsx +++ b/src/modules/GroupChannel/components/Message/MessageView.tsx @@ -152,7 +152,13 @@ const MessageView = (props: MessageViewProps) => { const { dateLocale, stringSet } = useLocalization(); const globalStore = useSendbirdStateContext(); - const { userId, isOnline, userMention, logger, groupChannel } = globalStore.config; + const { + userId, + isOnline, + userMention, + logger, + groupChannel, + } = globalStore.config; const maxUserMentionCount = userMention?.maxMentionCount || MAX_USER_MENTION_COUNT; const maxUserSuggestionCount = userMention?.maxSuggestionCount || MAX_USER_SUGGESTION_COUNT; @@ -168,8 +174,10 @@ const MessageView = (props: MessageViewProps) => { const [mentionSuggestedUsers, setMentionSuggestedUsers] = useState([]); const editMessageInputRef = useRef(null); const messageScrollRef = useRef(null); - - const displaySuggestedMentionList = isOnline && groupChannel.enableMention && mentionNickname.length > 0 && !isDisabledBecauseFrozen(channel) && !isDisabledBecauseMuted(channel); + const displaySuggestedMentionList = isOnline + && groupChannel.enableMention && mentionNickname.length > 0 + && !isDisabledBecauseFrozen(channel) + && !isDisabledBecauseMuted(channel); const mentionNodes = useDirtyGetMentions({ ref: editMessageInputRef }, { logger }); const ableMention = mentionNodes?.length < maxUserMentionCount; @@ -276,6 +284,7 @@ const MessageView = (props: MessageViewProps) => { replyOptions: getSuggestedReplies(message), onSendMessage: sendUserMessage, message, + type: groupChannel?.suggestedRepliesDirection, }) } {/* Modal */} diff --git a/src/modules/GroupChannel/components/MessageList/index.scss b/src/modules/GroupChannel/components/MessageList/index.scss index 8c0008867..add69076f 100644 --- a/src/modules/GroupChannel/components/MessageList/index.scss +++ b/src/modules/GroupChannel/components/MessageList/index.scss @@ -10,9 +10,9 @@ position: relative; height: 100%; overflow-x: hidden; - padding: 0px 24px; + padding: 0 $messages-padding; @include mobile() { - padding: 0px 12px; + padding: 0 $messages-padding-mobile; } } .sendbird-separator, diff --git a/src/modules/GroupChannel/components/SuggestedReplies/index.scss b/src/modules/GroupChannel/components/SuggestedReplies/index.scss index 1304b4ee1..791e5e2c4 100644 --- a/src/modules/GroupChannel/components/SuggestedReplies/index.scss +++ b/src/modules/GroupChannel/components/SuggestedReplies/index.scss @@ -5,18 +5,44 @@ @import '../../../../styles/variables'; .sendbird-suggested-replies { + position: relative; + display: flex; + margin-top: 8px; + &.vertical { + justify-content: flex-end; + align-items: flex-end; + flex-wrap: wrap; + flex-direction: column; + .sendbird-suggested-replies__option:not(:first-child) { + margin-top: 8px; + } + } + + &.horizontal { + display: flex; + flex-direction: row; + overflow-x: scroll; + + margin-left: -$messages-padding; + margin-right: -$messages-padding; + padding-left: $messages-padding; + padding-right: $messages-padding; + @include mobile() { + margin-left: -$messages-padding-mobile; + margin-right: -$messages-padding-mobile; + padding-left: calc(40px + $messages-padding-mobile); + padding-right: $messages-padding-mobile; + } + .sendbird-suggested-replies__option:not(:last-child) { + margin-right: 8px; + } + } + &::-webkit-scrollbar { + display: none; + } @include themed() { font-family: var(--sendbird-font-family-default); } - position: relative; - display: flex; - justify-content: flex-end; - align-items: flex-end; - flex-wrap: wrap; - column-gap: 10px; - row-gap: 8px; - margin-top: 16px; - flex-direction: column; } .sendbird-suggested-replies__option { diff --git a/src/modules/GroupChannel/components/SuggestedReplies/index.tsx b/src/modules/GroupChannel/components/SuggestedReplies/index.tsx index 6505bfc89..5373e7120 100644 --- a/src/modules/GroupChannel/components/SuggestedReplies/index.tsx +++ b/src/modules/GroupChannel/components/SuggestedReplies/index.tsx @@ -6,9 +6,11 @@ export interface SuggestedRepliesProps { replyOptions: string[]; onSendMessage: ({ message }: { message: string }) => void; message: BaseMessage; + type?: 'vertical' | 'horizontal'; + gap?: number; } -const SuggestedReplies = ({ replyOptions, onSendMessage }: SuggestedRepliesProps) => { +const SuggestedReplies = ({ replyOptions, onSendMessage, type = 'vertical' }: SuggestedRepliesProps) => { const [replied, setReplied] = useState(false); const onClickReply = ( @@ -24,22 +26,20 @@ const SuggestedReplies = ({ replyOptions, onSendMessage }: SuggestedRepliesProps return null; } - return ( -
- {replyOptions.map((option: string, index: number) => { - return ( -
onClickReply(e, option)} - > - {option} -
- ); - })} -
- ); + const children = replyOptions.map((option: string, index: number) => { + return ( +
onClickReply(e, option)} + > + {option} +
+ ); + }); + + return
{children}
; }; export default SuggestedReplies; diff --git a/src/styles/_variables.scss b/src/styles/_variables.scss index 26b7ad28b..8e3394ed8 100644 --- a/src/styles/_variables.scss +++ b/src/styles/_variables.scss @@ -1,2 +1,5 @@ @import './color-themes'; @import './media-query'; + +$messages-padding: 24px; +$messages-padding-mobile: 12px; diff --git a/yarn.lock b/yarn.lock index 609e5dee5..b05ccf619 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2635,20 +2635,20 @@ __metadata: languageName: node linkType: hard -"@sendbird/react-uikit-message-template-view@npm:0.0.1-alpha.72": - version: 0.0.1-alpha.72 - resolution: "@sendbird/react-uikit-message-template-view@npm:0.0.1-alpha.72" +"@sendbird/react-uikit-message-template-view@npm:0.0.1-alpha.73": + version: 0.0.1-alpha.73 + resolution: "@sendbird/react-uikit-message-template-view@npm:0.0.1-alpha.73" dependencies: - "@sendbird/uikit-message-template": ^0.0.1-alpha.72 + "@sendbird/uikit-message-template": ^0.0.1-alpha.73 peerDependencies: "@sendbird/chat": ">=4.3.0 <5" react: ">=16.8.6" react-dom: ">=16.8.6" - checksum: f08023a2f679c942fbce73288a40752e7c1a8f03b487b4dffa2e76495f1078706cab3db41e0f02468569717dc9b84f26e8d0addbdc80bd5d9ae1184d3ec33c66 + checksum: 22cd8e83eda3e63f3463a07ae73678608087232719230fabc3ccbd5b6b9112bcd5c0ec2bd8a52e883230d91de9f2352d1e98b61afb4e400523cbd3c7f58a5f4f languageName: node linkType: hard -"@sendbird/uikit-message-template@npm:^0.0.1-alpha.72": +"@sendbird/uikit-message-template@npm:^0.0.1-alpha.73": version: 0.0.1-alpha.73 resolution: "@sendbird/uikit-message-template@npm:0.0.1-alpha.73" peerDependencies: @@ -2676,8 +2676,8 @@ __metadata: "@rollup/plugin-replace": ^5.0.4 "@rollup/plugin-typescript": ^11.1.5 "@sendbird/chat": ^4.12.3 - "@sendbird/react-uikit-message-template-view": 0.0.1-alpha.72 - "@sendbird/uikit-tools": 0.0.1-alpha.72 + "@sendbird/react-uikit-message-template-view": 0.0.1-alpha.73 + "@sendbird/uikit-tools": 0.0.1-alpha.73 "@storybook/addon-essentials": ^8.0.9 "@storybook/react-vite": ^8.0.9 "@svgr/rollup": ^8.1.0 @@ -2734,13 +2734,13 @@ __metadata: languageName: unknown linkType: soft -"@sendbird/uikit-tools@npm:0.0.1-alpha.72": - version: 0.0.1-alpha.72 - resolution: "@sendbird/uikit-tools@npm:0.0.1-alpha.72" +"@sendbird/uikit-tools@npm:0.0.1-alpha.73": + version: 0.0.1-alpha.73 + resolution: "@sendbird/uikit-tools@npm:0.0.1-alpha.73" peerDependencies: "@sendbird/chat": ">=4.10.5 <5" react: ">=16.8.6" - checksum: a209342267a8ddbbdd9d310a42def22d54a20ad30a54002de893480ed0bc26c0d3ebb7614ceb39340f3e6eb0d7bf5067769a0b73aca135b9e954580a8f5b08c0 + checksum: e75a6cde2a645d1fcc535fd65001337ba40ce68c87f30e5a0c8ab2c0ca9df69684988f9c9c0e147ceeb26efee4f157cd2e27d692de091cf320e12d9e70e9258b languageName: node linkType: hard