diff --git a/src/i18n/en.json b/src/i18n/en.json index 732286e3d..4ff40a169 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -370,5 +370,7 @@ "editChatMembersModal.confirm.title": "Leave without finishing?", "editChatMembersModal.confirm.content": "Your progress won’t be saved. Are you sure to leave this page now?", "editChatMembersModal.confirm.cancelText": "Continue editing", - "editChatMembersModal.confirm.okText": "Leave" + "editChatMembersModal.confirm.okText": "Leave", + + "notification.error.blockedWord": "Amity SDK (400308): Text contain blocked word" } diff --git a/src/social/components/Comment/index.tsx b/src/social/components/Comment/index.tsx index 250c7c803..f7e7b0e32 100644 --- a/src/social/components/Comment/index.tsx +++ b/src/social/components/Comment/index.tsx @@ -33,11 +33,11 @@ import useSDK from '~/core/hooks/useSDK'; import useUser from '~/core/hooks/useUser'; import useFile from '~/core/hooks/useFile'; import { CommentRepository } from '@amityco/ts-sdk'; -import useCommunity from '~/social/hooks/useCommunity'; import { useCustomComponent } from '~/core/providers/CustomComponentsProvider'; import useCommentFlaggedByMe from '~/social/hooks/useCommentFlaggedByMe'; import useCommentPermission from '~/social/hooks/useCommentPermission'; import useCommentSubscription from '~/social/hooks/useCommentSubscription'; +import { ERROR_RESPONSE } from '~/social/constants'; const REPLIES_PER_PAGE = 5; @@ -138,18 +138,30 @@ const Comment = ({ commentId, readonly }: CommentProps) => { ) => { if (!comment?.referenceType || !comment?.referenceId) return; - const { referenceType, referenceId } = comment; - - await CommentRepository.createComment({ - referenceType, - referenceId, - data: { - text: replyCommentText, - }, - parentId: commentId, - metadata, - mentionees, - }); + try { + const { referenceType, referenceId } = comment; + + await CommentRepository.createComment({ + referenceType, + referenceId, + data: { + text: replyCommentText, + }, + parentId: commentId, + metadata, + mentionees, + }); + setIsReplying(false); + setExpanded(true); + } catch (error: unknown) { + if (error instanceof Error) { + if (error.message === ERROR_RESPONSE.CONTAIN_BLOCKED_WORD) { + notification.error({ + content: , + }); + } + } + } }; const handleEditComment = async (text: string, mentionees: Mentionees, metadata: Metadata) => @@ -288,8 +300,6 @@ const Comment = ({ commentId, readonly }: CommentProps) => { userToReply={commentAuthor?.displayName} onSubmit={(replyText, mentionees, metadata) => { handleReplyToComment(replyText, mentionees, metadata); - setIsReplying(false); - setExpanded(true); }} /> )} diff --git a/src/social/components/CommentComposeBar/index.tsx b/src/social/components/CommentComposeBar/index.tsx index 1774944fd..b4352e691 100644 --- a/src/social/components/CommentComposeBar/index.tsx +++ b/src/social/components/CommentComposeBar/index.tsx @@ -42,7 +42,7 @@ const CommentComposeBar = ({ const { currentUserId } = useSDK(); const user = useUser(currentUserId); const avatarFileUrl = useImage({ fileId: user?.avatarFileId, imageSize: 'small' }); - const { text, markup, mentions, mentionees, metadata, onChange, clearAll, queryMentionees } = + const { text, markup, mentions, mentionees, metadata, onChange, queryMentionees } = useSocialMention({ targetId: post?.targetId, targetType: post?.targetType, @@ -76,7 +76,6 @@ const CommentComposeBar = ({ } onSubmit?.(text, mentionees, metadata); - clearAll?.(); }; const isEmpty = text === ''; diff --git a/src/social/components/EngagementBar/index.tsx b/src/social/components/EngagementBar/index.tsx index 684013de2..d3d60446a 100644 --- a/src/social/components/EngagementBar/index.tsx +++ b/src/social/components/EngagementBar/index.tsx @@ -7,6 +7,10 @@ import { Mentionees, Metadata } from '~/helpers/utils'; import { useCustomComponent } from '~/core/providers/CustomComponentsProvider'; import useReactionSubscription from '~/social/hooks/useReactionSubscription'; import usePostSubscription from '~/social/hooks/usePostSubscription'; +import { notification } from '~/core/components/Notification'; +import { FormattedMessage } from 'react-intl'; +import useSocialMention from '~/social/hooks/useSocialMention'; +import { ERROR_RESPONSE } from '~/social/constants'; interface EngagementBarProps { postId: string; @@ -20,6 +24,10 @@ const EngagementBar = ({ postId, readonly = false }: EngagementBarProps) => { const hideComposeBar = () => setComposeBarDisplayed(false); const post = usePost(postId); + const { clearAll } = useSocialMention({ + targetType: post?.targetType, + targetId: post?.targetId, + }); usePostSubscription({ postId, @@ -39,17 +47,27 @@ const EngagementBar = ({ postId, readonly = false }: EngagementBarProps) => { mentionees: Mentionees, metadata: Metadata, ) => { - await CommentRepository.createComment({ - referenceType: 'post', - referenceId: postId, - data: { - text: commentText, - }, - mentionees, - metadata, - }); - - hideComposeBar(); + try { + await CommentRepository.createComment({ + referenceType: 'post', + referenceId: postId, + data: { + text: commentText, + }, + mentionees, + metadata, + }); + clearAll?.(); + hideComposeBar(); + } catch (error: unknown) { + if (error instanceof Error) { + if (error.message === ERROR_RESPONSE.CONTAIN_BLOCKED_WORD) { + notification.error({ + content: , + }); + } + } + } }; return ( diff --git a/src/social/components/post/Creator/index.tsx b/src/social/components/post/Creator/index.tsx index b2e83c768..e006c9aab 100644 --- a/src/social/components/post/Creator/index.tsx +++ b/src/social/components/post/Creator/index.tsx @@ -44,6 +44,7 @@ import { MAXIMUM_POST_CHARACTERS, MAXIMUM_POST_MENTIONEES } from './constants'; import useSDK from '~/core/hooks/useSDK'; import useSocialMention from '~/social/hooks/useSocialMention'; import useCommunityModeratorsCollection from '~/social/hooks/collections/useCommunityModeratorsCollection'; +import { ERROR_RESPONSE } from '~/social/constants'; const useTargetData = ({ targetId, @@ -227,6 +228,14 @@ const PostCreatorBar = ({ }); } } + } catch (error: unknown) { + if (error instanceof Error) { + if (error.message === ERROR_RESPONSE.CONTAIN_BLOCKED_WORD) { + notification.error({ + content: , + }); + } + } } finally { setIsCreating(false); } diff --git a/src/social/components/post/PollComposer/PollModal.tsx b/src/social/components/post/PollComposer/PollModal.tsx index ec9e2d620..819e61627 100644 --- a/src/social/components/post/PollComposer/PollModal.tsx +++ b/src/social/components/post/PollComposer/PollModal.tsx @@ -1,10 +1,12 @@ import React, { useState } from 'react'; -import { useIntl } from 'react-intl'; +import { FormattedMessage, useIntl } from 'react-intl'; import { PollRepository } from '@amityco/ts-sdk'; import Modal from '~/core/components/Modal'; import { confirm } from '~/core/components/Confirm'; import PollComposer from '~/social/components/post/PollComposer'; +import { notification } from '~/core/components/Notification'; +import { ERROR_RESPONSE } from '~/social/constants'; interface PollModalProps { targetId?: string | null; @@ -27,9 +29,19 @@ const PollModal = ({ targetId, targetType, onClose, onCreatePoll }: PollModalPro mentionees: Amity.UserMention[], metadata: Record, ) => { - const createdPoll = await PollRepository.createPoll(data); - await onCreatePoll(createdPoll.data.pollId, data.question, mentionees, metadata); - onClose(); + try { + const createdPoll = await PollRepository.createPoll(data); + await onCreatePoll(createdPoll.data.pollId, data.question, mentionees, metadata); + onClose(); + } catch (error: unknown) { + if (error instanceof Error) { + if (error.message === ERROR_RESPONSE.CONTAIN_BLOCKED_WORD) { + notification.error({ + content: , + }); + } + } + } }; const closeConfirm = () => diff --git a/src/social/constants.ts b/src/social/constants.ts index 7737ee1a5..408b8f4d0 100644 --- a/src/social/constants.ts +++ b/src/social/constants.ts @@ -74,3 +74,7 @@ export const VideoQuality = Object.freeze({ }); export const MP4MimeType = 'video/mp4'; + +export const ERROR_RESPONSE = Object.freeze({ + CONTAIN_BLOCKED_WORD: 'Amity SDK (400308): Text contain blocked word', +}); diff --git a/src/social/hooks/useStory.ts b/src/social/hooks/useStory.ts new file mode 100644 index 000000000..84210ccae --- /dev/null +++ b/src/social/hooks/useStory.ts @@ -0,0 +1,15 @@ +import { StoryRepository } from '@amityco/ts-sdk'; + +import useLiveObject from '~/core/hooks/useLiveObject'; + +const useStory = (storyId: string | undefined) => { + const story = useLiveObject({ + fetcher: StoryRepository.getStoryByStoryId, + params: storyId, + shouldCall: () => !!storyId, + }); + + return story; +}; + +export default useStory;