diff --git a/src/pages/common/components/ChatComponent/ChatComponent.module.scss b/src/pages/common/components/ChatComponent/ChatComponent.module.scss index f072d86ded..bfd974ed8a 100644 --- a/src/pages/common/components/ChatComponent/ChatComponent.module.scss +++ b/src/pages/common/components/ChatComponent/ChatComponent.module.scss @@ -96,8 +96,12 @@ display: flex; flex-direction: column; justify-content: center; - padding: 0.125rem 1.5rem 0.125rem 0.25rem; word-break: break-word; + padding: 0.125rem 1.75rem 0.125rem 0.25rem; +} + +.messageInputRtl { + padding: 0.125rem 0.25rem 0.125rem 1.75rem; } .messageInputEmpty { diff --git a/src/pages/common/components/ChatComponent/ChatComponent.tsx b/src/pages/common/components/ChatComponent/ChatComponent.tsx index 8cdade8355..ef31be0348 100644 --- a/src/pages/common/components/ChatComponent/ChatComponent.tsx +++ b/src/pages/common/components/ChatComponent/ChatComponent.tsx @@ -658,6 +658,7 @@ export default function ChatComponent({ [styles.messageInputEmpty]: checkIsTextEditorValueEmpty(message), })} + classNameRtl={styles.messageInputRtl} elementStyles={{ emoji: classNames({ [styles.singleEmojiText]: emojiCount.isSingleEmoji, diff --git a/src/shared/components/Chat/ChatMessage/ChatMessage.module.scss b/src/shared/components/Chat/ChatMessage/ChatMessage.module.scss index ee1bf0d5cf..9da9e2e916 100644 --- a/src/shared/components/Chat/ChatMessage/ChatMessage.module.scss +++ b/src/shared/components/Chat/ChatMessage/ChatMessage.module.scss @@ -111,6 +111,11 @@ word-break: break-word; } +.messageContentRtl { + direction: rtl; + text-align: right; +} + .messageContentCurrentUser { color: $white; margin-right: 2.5rem; diff --git a/src/shared/components/Chat/ChatMessage/ChatMessage.tsx b/src/shared/components/Chat/ChatMessage/ChatMessage.tsx index 7cf8c2cd0e..343a2e74c9 100644 --- a/src/shared/components/Chat/ChatMessage/ChatMessage.tsx +++ b/src/shared/components/Chat/ChatMessage/ChatMessage.tsx @@ -40,8 +40,7 @@ import { parseStringToTextEditorValue, } from "@/shared/ui-kit"; import { ChatImageGallery } from "@/shared/ui-kit"; -import { StaticLinkType, isRTL } from "@/shared/utils"; -import { getUserName } from "@/shared/utils"; +import { StaticLinkType, isRtlText, getUserName } from "@/shared/utils"; import { convertBytes } from "@/shared/utils/convertBytes"; import { EditMessageInput } from "../EditMessageInput"; import { ChatMessageLinkify, InternalLinkData, Time } from "./components"; @@ -302,12 +301,14 @@ export default function ChatMessage({ className={classNames( styles.messageContent, styles.replyMessageContent, - { [styles.replyMessageContentCurrentUser]: !isNotCurrentUserMessage, [styles.replyMessageContentWithImage]: image, [styles.replyMessageContentWithFile]: file, + [styles.messageContentRtl]: isRtlText( + discussionMessage?.parentMessage?.text, + ), }, )} > @@ -378,7 +379,7 @@ export default function ChatMessage({ ref={messageRef} className={classNames(styles.messageText, { [styles.messageTextCurrentUser]: !isNotCurrentUserMessage, - [styles.messageTextRtl]: isRTL(discussionMessage.text), + [styles.messageTextRtl]: isRtlText(discussionMessage.text), [styles.messageTextWithReply]: !!discussionMessage.parentMessage?.id, [styles.systemMessage]: isSystemMessage, @@ -398,6 +399,7 @@ export default function ChatMessage({
{filePreview && ( diff --git a/src/shared/ui-kit/TextEditor/BaseTextEditor.tsx b/src/shared/ui-kit/TextEditor/BaseTextEditor.tsx index 734db6ff39..81a76765b8 100644 --- a/src/shared/ui-kit/TextEditor/BaseTextEditor.tsx +++ b/src/shared/ui-kit/TextEditor/BaseTextEditor.tsx @@ -8,6 +8,7 @@ import React, { useMemo, useState, } from "react"; +import classNames from "classnames"; import { isEqual } from "lodash"; import { createEditor, @@ -20,7 +21,7 @@ import { withHistory } from "slate-history"; import { ReactEditor, Slate, withReact } from "slate-react"; import { KeyboardKeys } from "@/shared/constants/keyboardKeys"; import { User } from "@/shared/models"; -import { getUserName, isMobile } from "@/shared/utils"; +import { getUserName, isMobile, isRtlText } from "@/shared/utils"; import { Editor, MentionDropdown, @@ -39,6 +40,7 @@ import styles from "./BaseTextEditor.module.scss"; export interface TextEditorProps { className?: string; + classNameRtl?: string; emojiContainerClassName?: string; emojiPickerContainerClassName?: string; inputContainerRef?: @@ -74,6 +76,7 @@ const INITIAL_SEARCH_VALUE = { const BaseTextEditor: FC = (props) => { const { className, + classNameRtl, emojiContainerClassName, emojiPickerContainerClassName, editorRef, @@ -106,6 +109,8 @@ const BaseTextEditor: FC = (props) => { const [target, setTarget] = useState(); const [shouldFocusTarget, setShouldFocusTarget] = useState(false); + + const [isRtlLanguage, setIsRtlLanguage] = useState(false); useEffect(() => { if (!shouldReinitializeEditor) { return; @@ -235,10 +240,17 @@ const BaseTextEditor: FC = (props) => { handleSearch(beforeText ?? "", beforeRange); } + + setIsRtlLanguage(isRtlText(EditorSlate.string(editor, []))); }} > = (props) => { elementStyles={elementStyles} /> void; isMessageSent?: boolean; onToggleIsMessageSent?: () => void; + isRtl: boolean; } const EmojiPicker: FC = (props) => { @@ -22,6 +23,7 @@ const EmojiPicker: FC = (props) => { onEmojiSelect, isMessageSent, onToggleIsMessageSent, + isRtl, } = props; const [isOpen, setIsOpen] = useState(false); const wrapperRef = useRef(null); @@ -48,14 +50,23 @@ const EmojiPicker: FC = (props) => { return (
{isOpen && ( -
+
)} diff --git a/src/shared/utils/shared.tsx b/src/shared/utils/shared.tsx index aa32f97fdc..f57ffd1c1f 100644 --- a/src/shared/utils/shared.tsx +++ b/src/shared/utils/shared.tsx @@ -200,6 +200,25 @@ export const isRTL = (text = ""): boolean => { return Boolean(text && rtlDirCheck.test(text)); }; +export const isRtlText = (text = ""): boolean => { + for (let i = 0; i < text.length; i++) { + const charCode = text.charCodeAt(i); + + // Hebrew Block + if (charCode >= 0x0590 && charCode <= 0x05ff) return true; + + // Arabic Block + if (charCode >= 0x0600 && charCode <= 0x06ff) return true; + + // Arabic Supplement Block + if (charCode >= 0x0750 && charCode <= 0x077f) return true; + + // Arabic Extended-A Block + if (charCode >= 0x08a0 && charCode <= 0x08ff) return true; + } + return false; +}; + /** * Validate credit card provider (Visa or MasterCard) * Currently only Visa is supported.