diff --git a/src/components/common/Audio.scss b/src/components/common/Audio.scss index ef4e4e01a..4f17e2d11 100644 --- a/src/components/common/Audio.scss +++ b/src/components/common/Audio.scss @@ -74,6 +74,7 @@ align-self: center; min-width: 0; flex-grow: 1; + text-align: initial; } .content-row { diff --git a/src/components/common/Audio.tsx b/src/components/common/Audio.tsx index 454cbce7c..1337c8d6f 100644 --- a/src/components/common/Audio.tsx +++ b/src/components/common/Audio.tsx @@ -237,7 +237,7 @@ const Audio: FC = ({ <>
-

{renderText(getFirstLine())}

+

{renderText(getFirstLine())}

{date && ( @@ -253,7 +253,7 @@ const Audio: FC = ({ {showSeekline && renderSeekline(playProgress, bufferedProgress, seekHandlers)} {!showSeekline && ( -

+

{playProgress > 0 ? `${formatMediaDuration(duration * playProgress)} / ` : undefined} {getSecondLine()}

@@ -318,10 +318,10 @@ function renderAudio( return (
-

{renderText(title || fileName)}

+

{renderText(title || fileName)}

{showSeekline && renderSeekline(playProgress, bufferedProgress, seekHandlers)} {!showSeekline && ( -
+
{renderText(performer || 'Unknown')} {date && ( <> @@ -333,7 +333,7 @@ function renderAudio( )}
)} -

+

{playProgress > 0 ? `${formatMediaDuration(duration * playProgress)} / ` : undefined} {formatMediaDuration(duration)}

@@ -345,7 +345,7 @@ function renderVoice(voice: ApiVoice, renderedWaveform: any, isMediaUnread?: boo return (
{renderedWaveform} -

+

{formatMediaDuration(voice.duration)} {isMediaUnread && }

diff --git a/src/components/common/EmbeddedMessage.tsx b/src/components/common/EmbeddedMessage.tsx index 64de95680..e423bd2ec 100644 --- a/src/components/common/EmbeddedMessage.tsx +++ b/src/components/common/EmbeddedMessage.tsx @@ -63,8 +63,8 @@ const EmbeddedMessage: FC = ({ > {mediaThumbnail && renderPictogram(pictogramId, mediaThumbnail, mediaBlobUrl, isRoundVideo)}
-
{renderText(senderTitle || title || NBSP)}
-

+

{renderText(senderTitle || title || NBSP)}
+

{!message ? ( customText || NBSP ) : isActionMessage(message) ? ( diff --git a/src/components/common/File.tsx b/src/components/common/File.tsx index 005a1c458..7abaa4f94 100644 --- a/src/components/common/File.tsx +++ b/src/components/common/File.tsx @@ -113,7 +113,7 @@ const File: FC = ({ ) : (

{extension.length <= 4 && ( - {extension} + {extension} )}
)} @@ -129,8 +129,8 @@ const File: FC = ({ {onClick && }
-
{renderText(name)}
-
+
{renderText(name)}
+
{isTransferring && transferProgress ? `${Math.round(transferProgress * 100)}%` : sizeString} diff --git a/src/components/common/GroupChatInfo.tsx b/src/components/common/GroupChatInfo.tsx index 87daea218..bc862762e 100644 --- a/src/components/common/GroupChatInfo.tsx +++ b/src/components/common/GroupChatInfo.tsx @@ -84,7 +84,7 @@ const GroupChatInfo: FC = ({ function renderStatusOrTyping() { if (withUpdatingStatus && !areMessagesLoaded && !isRestricted) { return ( - {lang('Updating')} + {lang('Updating')} ); } @@ -98,7 +98,7 @@ const GroupChatInfo: FC = ({ if (withChatType) { return ( -
{lang(getChatTypeString(chat))}
+
{lang(getChatTypeString(chat))}
); } @@ -125,7 +125,7 @@ const GroupChatInfo: FC = ({ />
-

{renderText(getChatTitle(lang, chat))}

+

{renderText(getChatTitle(lang, chat))}

{chat.isVerified && }
{renderStatusOrTyping()} diff --git a/src/components/common/PickerSelectedItem.tsx b/src/components/common/PickerSelectedItem.tsx index c7bc5cece..5d9dbd561 100644 --- a/src/components/common/PickerSelectedItem.tsx +++ b/src/components/common/PickerSelectedItem.tsx @@ -85,7 +85,7 @@ const PickerSelectedItem: FC = ({ > {iconElement} {!isMinimized && ( -
+
{titleText}
)} diff --git a/src/components/common/PrivateChatInfo.tsx b/src/components/common/PrivateChatInfo.tsx index 4d7838eaf..a0febe639 100644 --- a/src/components/common/PrivateChatInfo.tsx +++ b/src/components/common/PrivateChatInfo.tsx @@ -83,13 +83,13 @@ const PrivateChatInfo: FC = ({ function renderStatusOrTyping() { if (status) { return ( - {status} + {status} ); } if (withUpdatingStatus && !areMessagesLoaded) { return ( - {lang('Updating')} + {lang('Updating')} ); } @@ -104,7 +104,7 @@ const PrivateChatInfo: FC = ({ return (
{withUsername && user.username && {user.username}} - {getUserStatus(lang, user)} + {getUserStatus(lang, user)}
); } @@ -125,7 +125,7 @@ const PrivateChatInfo: FC = ({
) : (
-

{fullName && renderText(fullName)}

+

{fullName && renderText(fullName)}

{user && user.isVerified && }
)} diff --git a/src/components/common/TypingStatus.tsx b/src/components/common/TypingStatus.tsx index a7f99ffcd..a2d31bc2a 100644 --- a/src/components/common/TypingStatus.tsx +++ b/src/components/common/TypingStatus.tsx @@ -23,7 +23,7 @@ const TypingStatus: FC = ({ typingStatus, typingUser }) = return (

{typingUserName && ( - {renderText(typingUserName)} + {renderText(typingUserName)} )} {typingStatus.action} diff --git a/src/components/common/helpers/renderMessageText.tsx b/src/components/common/helpers/renderMessageText.tsx index 2f638ca0c..4923ed5d9 100644 --- a/src/components/common/helpers/renderMessageText.tsx +++ b/src/components/common/helpers/renderMessageText.tsx @@ -229,6 +229,7 @@ function processEntity( {renderMessagePart(renderedContent)} @@ -238,6 +239,7 @@ function processEntity( {renderMessagePart(renderedContent)} @@ -247,6 +249,7 @@ function processEntity( {renderMessagePart(renderedContent)} @@ -260,6 +263,7 @@ function processEntity( target="_blank" rel="noopener noreferrer" className="text-entity-link" + dir="auto" > {renderMessagePart(renderedContent)} @@ -385,6 +389,7 @@ function processEntityAsHtml( data-entity-type="${ApiMessageEntityTypes.MentionName}" data-user-id="${entity.userId}" contenteditable="false" + dir="auto" >${renderedContent}`; case ApiMessageEntityTypes.Url: case ApiMessageEntityTypes.TextUrl: @@ -392,6 +397,7 @@ function processEntityAsHtml( class="text-entity-link" href=${getLinkUrl(rawEntityText, entity)} data-entity-type="${entity.type}" + dir="auto" >${renderedContent}`; default: return renderedContent; diff --git a/src/components/left/main/Chat.scss b/src/components/left/main/Chat.scss index 50a07bf38..cc622197e 100644 --- a/src/components/left/main/Chat.scss +++ b/src/components/left/main/Chat.scss @@ -82,6 +82,7 @@ padding-right: 0.25rem; flex-grow: 1; color: var(--color-text-secondary); + unicode-bidi: plaintext; .sender-name { color: var(--color-text); diff --git a/src/components/left/main/Chat.tsx b/src/components/left/main/Chat.tsx index 0c7bcfb0c..d7d46dd31 100644 --- a/src/components/left/main/Chat.tsx +++ b/src/components/left/main/Chat.tsx @@ -193,7 +193,7 @@ const Chat: FC = ({ if (draft && draft.text.length) { return ( -

+

{lang('Draft')} {renderText(draft.text)}

@@ -210,7 +210,7 @@ const Chat: FC = ({ : lastMessageSender; return ( -

+

{renderText(renderActionMessageText( lang, lastMessage, @@ -227,7 +227,7 @@ const Chat: FC = ({ const senderName = getMessageSenderName(lang, chatId, lastMessageSender); return ( -

+

{senderName && ( {renderText(senderName)} )} diff --git a/src/components/left/main/ContactList.tsx b/src/components/left/main/ContactList.tsx index 1dab6c367..55be93e8c 100644 --- a/src/components/left/main/ContactList.tsx +++ b/src/components/left/main/ContactList.tsx @@ -82,7 +82,7 @@ const ContactList: FC = ({ )) ) : viewportIds && !viewportIds.length ? ( -

+

{filter.length ? 'No contacts matched your search.' : 'Contact list is empty.'}

) : ( diff --git a/src/components/left/search/ChatMessage.tsx b/src/components/left/search/ChatMessage.tsx index 867b68b93..1bbdc049b 100644 --- a/src/components/left/search/ChatMessage.tsx +++ b/src/components/left/search/ChatMessage.tsx @@ -86,7 +86,7 @@ const ChatMessage: FC = ({
-

{renderText(getChatTitle(lang, chat, privateChatUser))}

+

{renderText(getChatTitle(lang, chat, privateChatUser))}

{chat.isVerified && }
@@ -97,7 +97,7 @@ const ChatMessage: FC = ({
-
+
{renderMessageSummary(lang, message, mediaBlobUrl || mediaThumbnail, searchQuery, isRoundVideo)}
diff --git a/src/components/left/search/LeftSearch.scss b/src/components/left/search/LeftSearch.scss index 5747a21c7..fcaadf99e 100644 --- a/src/components/left/search/LeftSearch.scss +++ b/src/components/left/search/LeftSearch.scss @@ -95,15 +95,24 @@ .ListItem.search-result { .ChatInfo { .handle { + unicode-bidi: plaintext; color: var(--color-primary); &::before { content: '@'; + html[lang=ar] & { + content: ' ،@'; + margin-inline-end: .25rem; + } } &::after { content: ', '; color: var(--color-text-secondary); + + html[lang=ar] & { + content: ''; + } } } } diff --git a/src/components/left/settings/SettingsPrivacy.tsx b/src/components/left/settings/SettingsPrivacy.tsx index d9e75f12d..3fd1aa627 100644 --- a/src/components/left/settings/SettingsPrivacy.tsx +++ b/src/components/left/settings/SettingsPrivacy.tsx @@ -74,7 +74,7 @@ const SettingsPrivacy: FC = ({
{lang('BlockedUsers')} {blockedCount > 0 && ( - + {lang('Users', blockedCount)} )} @@ -89,7 +89,9 @@ const SettingsPrivacy: FC = ({ >
{lang('TwoStepVerification')} - {lang(hasPassword ? 'PasswordOn' : 'PasswordOff')} + + {lang(hasPassword ? 'PasswordOn' : 'PasswordOff')} +
= ({
{lang('SessionsTitle')} {sessionsCount > 0 && ( - + {sessionsCount === 1 ? '1 session' : `${sessionsCount} sessions`} )} @@ -117,7 +119,9 @@ const SettingsPrivacy: FC = ({ >
{lang('PrivacyPhoneTitle')} - {getVisibilityValue(visibilityPrivacyPhoneNumber)} + + {getVisibilityValue(visibilityPrivacyPhoneNumber)} +
= ({ >
{lang('LastSeenTitle')} - {getVisibilityValue(visibilityPrivacyLastSeen)} + + {getVisibilityValue(visibilityPrivacyLastSeen)} +
= ({ >
{lang('PrivacyProfilePhotoTitle')} - {getVisibilityValue(visibilityPrivacyProfilePhoto)} + + {getVisibilityValue(visibilityPrivacyProfilePhoto)} +
= ({ >
{lang('PrivacyForwardsTitle')} - {getVisibilityValue(visibilityPrivacyForwarding)} + + {getVisibilityValue(visibilityPrivacyForwarding)} +
= ({ >
{lang('WhoCanAddMe')} - {getVisibilityValue(visibilityPrivacyGroupChats)} + + {getVisibilityValue(visibilityPrivacyGroupChats)} +
diff --git a/src/components/left/settings/SettingsPrivacyBlockedUsers.tsx b/src/components/left/settings/SettingsPrivacyBlockedUsers.tsx index ae85c7211..b0a657410 100644 --- a/src/components/left/settings/SettingsPrivacyBlockedUsers.tsx +++ b/src/components/left/settings/SettingsPrivacyBlockedUsers.tsx @@ -67,13 +67,13 @@ const SettingsPrivacyBlockedUsers: FC = ({ style={`top: ${(viewportOffset + i) * CHAT_HEIGHT_PX}px;`} > -
-

{renderText((isPrivate ? getUserFullName(user) : getChatTitle(lang, chat!)) || '')}

+
+

{renderText((isPrivate ? getUserFullName(user) : getChatTitle(lang, chat!)) || '')}

{user && user.phoneNumber && ( -
{formatPhoneNumberWithCode(user.phoneNumber)}
+
{formatPhoneNumberWithCode(user.phoneNumber)}
)} {user && !user.phoneNumber && user.username && ( -
@{user.username}
+
@{user.username}
)}
diff --git a/src/components/left/settings/folders/SettingsFoldersChatsPicker.tsx b/src/components/left/settings/folders/SettingsFoldersChatsPicker.tsx index 197844939..b9b3be122 100644 --- a/src/components/left/settings/folders/SettingsFoldersChatsPicker.tsx +++ b/src/components/left/settings/folders/SettingsFoldersChatsPicker.tsx @@ -121,7 +121,7 @@ const SettingsFoldersChatsPicker: FC = ({ ripple > -

{lang(type.title)}

+

{lang(type.title)}

= ({ placeholder={lang('Search')} /> ) : ( -

{`Sorry, you can't add more than ${MAX_CHATS} chats.`}

+

+ {`Sorry, you can't add more than ${MAX_CHATS} chats.`} +

)}
= ({ )}
-

+

{lang('CreateNewFilterInfo')}

diff --git a/src/components/left/settings/twoFa/SettingsTwoFaCongratulations.tsx b/src/components/left/settings/twoFa/SettingsTwoFaCongratulations.tsx index 1c73fdcef..c7059fe1a 100644 --- a/src/components/left/settings/twoFa/SettingsTwoFaCongratulations.tsx +++ b/src/components/left/settings/twoFa/SettingsTwoFaCongratulations.tsx @@ -32,7 +32,7 @@ const SettingsTwoFaCongratulations: FC = ({
-

+

{lang('TwoStepVerificationPasswordSetInfo')}

diff --git a/src/components/left/settings/twoFa/SettingsTwoFaEnabled.tsx b/src/components/left/settings/twoFa/SettingsTwoFaEnabled.tsx index d9965b8f9..08c3c6823 100644 --- a/src/components/left/settings/twoFa/SettingsTwoFaEnabled.tsx +++ b/src/components/left/settings/twoFa/SettingsTwoFaEnabled.tsx @@ -29,7 +29,7 @@ const SettingsTwoFaEnabled: FC = ({
-

+

{renderText(lang('EnabledPasswordText'), ['br'])}

diff --git a/src/components/left/settings/twoFa/SettingsTwoFaStart.tsx b/src/components/left/settings/twoFa/SettingsTwoFaStart.tsx index ec0b66154..f2a8112d6 100644 --- a/src/components/left/settings/twoFa/SettingsTwoFaStart.tsx +++ b/src/components/left/settings/twoFa/SettingsTwoFaStart.tsx @@ -25,7 +25,7 @@ const SettingsTwoFaStart: FC = ({ animatedEmoji, onStart
-

+

{lang('SetAdditionalPasswordInfo')}

diff --git a/src/components/main/ForwardPicker.scss b/src/components/main/ForwardPicker.scss index e5195a88c..81189c554 100644 --- a/src/components/main/ForwardPicker.scss +++ b/src/components/main/ForwardPicker.scss @@ -31,6 +31,7 @@ padding: 0.5rem; font-size: 1.25rem; line-height: 1.75rem; + unicode-bidi: plaintext; } } diff --git a/src/components/mediaViewer/MediaViewerFooter.tsx b/src/components/mediaViewer/MediaViewerFooter.tsx index 6f4a017b1..fb0373636 100644 --- a/src/components/mediaViewer/MediaViewerFooter.tsx +++ b/src/components/mediaViewer/MediaViewerFooter.tsx @@ -46,7 +46,7 @@ const MediaViewerFooter: FC = ({ text = '', isHideable, onClick }) =>
{text && (
-

{text}

+

{text}

)}
diff --git a/src/components/mediaViewer/SenderInfo.tsx b/src/components/mediaViewer/SenderInfo.tsx index 3c312f61b..53e9d9975 100644 --- a/src/components/mediaViewer/SenderInfo.tsx +++ b/src/components/mediaViewer/SenderInfo.tsx @@ -58,10 +58,10 @@ const SenderInfo: FC = ({ )}
-
+
{senderTitle && renderText(senderTitle)}
-
+
{isAvatar ? lang('lng_mediaview_profile_photo') : formatMediaDateTime(lang, message!.date * 1000)}
diff --git a/src/components/middle/AudioPlayer.tsx b/src/components/middle/AudioPlayer.tsx index bd886d189..a3a2a024a 100644 --- a/src/components/middle/AudioPlayer.tsx +++ b/src/components/middle/AudioPlayer.tsx @@ -102,9 +102,9 @@ function renderAudio(audio: ApiAudio) { return ( <> -
{renderText(title || fileName)}
+
{renderText(title || fileName)}
{performer && ( -
{renderText(performer)}
+
{renderText(performer)}
)} ); @@ -113,8 +113,8 @@ function renderAudio(audio: ApiAudio) { function renderVoice(subtitle: string, senderName?: string) { return ( <> -
{senderName && renderText(senderName)}
-
{subtitle}
+
{senderName && renderText(senderName)}
+
{subtitle}
); } diff --git a/src/components/middle/HeaderPinnedMessage.tsx b/src/components/middle/HeaderPinnedMessage.tsx index e9c4f3c5d..c56f16103 100644 --- a/src/components/middle/HeaderPinnedMessage.tsx +++ b/src/components/middle/HeaderPinnedMessage.tsx @@ -86,10 +86,10 @@ const HeaderPinnedMessage: FC = ({ /> {mediaThumbnail && renderPictogram(mediaThumbnail, mediaBlobUrl)}
-
+
{customTitle || `${lang('PinnedMessage')} ${index > 0 ? `#${count - index}` : ''}`}
-

{renderText(text)}

+

{renderText(text)}

diff --git a/src/components/middle/MessageList.tsx b/src/components/middle/MessageList.tsx index c16a4da0f..3a6afcef5 100644 --- a/src/components/middle/MessageList.tsx +++ b/src/components/middle/MessageList.tsx @@ -702,7 +702,7 @@ function renderMessages( teactFastList >
- + {isSchedule && dateGroup.originalDate === SCHEDULED_WHEN_ONLINE && ( lang('MessageScheduledUntilOnline') )} diff --git a/src/components/middle/MiddleHeader.scss b/src/components/middle/MiddleHeader.scss index 565135309..24acb45ee 100644 --- a/src/components/middle/MiddleHeader.scss +++ b/src/components/middle/MiddleHeader.scss @@ -226,6 +226,7 @@ margin: 0; overflow: hidden; text-overflow: ellipsis; + unicode-bidi: plaintext; @media (max-width: 600px) { display: block; @@ -264,6 +265,10 @@ margin-top: 0.05rem; } } + + .user-status, .status { + unicode-bidi: plaintext; + } } .Avatar { diff --git a/src/components/middle/composer/Composer.scss b/src/components/middle/composer/Composer.scss index 3dcec5c9f..ac19bb15b 100644 --- a/src/components/middle/composer/Composer.scss +++ b/src/components/middle/composer/Composer.scss @@ -256,6 +256,8 @@ overflow: hidden; line-height: 1.375rem; font-family: Roboto, -apple-system, "Apple Color Emoji", "Helvetica Neue", sans-serif; + unicode-bidi: plaintext; + text-align: initial; &.overflown { overflow-y: auto; @@ -278,6 +280,8 @@ bottom: .9375rem; color: var(--color-placeholders); pointer-events: none; + unicode-bidi: plaintext; + text-align: initial; @media (max-width: 600px) { bottom: 0.6875rem; @@ -301,6 +305,8 @@ opacity: 0; pointer-events: none; z-index: -10; + unicode-bidi: plaintext; + text-align: initial; } } diff --git a/src/components/middle/composer/EmojiCategory.tsx b/src/components/middle/composer/EmojiCategory.tsx index 6eeb7e0d7..dd3126dbb 100644 --- a/src/components/middle/composer/EmojiCategory.tsx +++ b/src/components/middle/composer/EmojiCategory.tsx @@ -47,7 +47,9 @@ const EmojiCategory: FC = ({ id={`emoji-category-${index}`} className="symbol-set" > -

{lang(category.id === 'recent' ? 'RecentStickers' : `Emoji${index}`)}

+

+ {lang(category.id === 'recent' ? 'RecentStickers' : `Emoji${index}`)} +

= ({ ref={inputRef} id={editableInputId || EDITABLE_INPUT_ID} className={className} + dir="auto" contentEditable onClick={focusInput} onChange={handleChange} @@ -364,8 +365,8 @@ const MessageInput: FC = ({ onContextMenu={stopEvent} onTouchCancel={handleTouchSelection} /> -
- {placeholder} +
+ {placeholder} = ({ isOpen, onSend, onClear }) => { ref={solutionRef} className="form-control" contentEditable + dir="auto" onChange={(e) => setSolution(e.currentTarget.innerHTML)} />
{lang('CreatePoll.ExplanationInfo')}
diff --git a/src/components/middle/composer/SymbolMenu.scss b/src/components/middle/composer/SymbolMenu.scss index 6b0c8df20..777bca6f1 100644 --- a/src/components/middle/composer/SymbolMenu.scss +++ b/src/components/middle/composer/SymbolMenu.scss @@ -122,6 +122,12 @@ overflow: hidden; white-space: nowrap; text-overflow: ellipsis; + text-align: initial; + unicode-bidi: plaintext; + } + + &-container { + text-align: initial; } &-button { diff --git a/src/components/middle/composer/TextFormatter.tsx b/src/components/middle/composer/TextFormatter.tsx index a67c99fb1..e269f3644 100644 --- a/src/components/middle/composer/TextFormatter.tsx +++ b/src/components/middle/composer/TextFormatter.tsx @@ -258,7 +258,7 @@ const TextFormatter: FC = ({ } const text = getSelectedText(); - document.execCommand('insertHTML', false, `${text}`); + document.execCommand('insertHTML', false, `${text}`); onClose(); }, [ getSelectedElement, getSelectedText, onClose, @@ -282,7 +282,11 @@ const TextFormatter: FC = ({ const text = getSelectedText(); restoreSelection(); - document.execCommand('insertHTML', false, `${text}`); + document.execCommand( + 'insertHTML', + false, + `${text}`, + ); onClose(); } @@ -424,6 +428,7 @@ const TextFormatter: FC = ({ placeholder="Enter URL..." autoComplete="off" inputMode="url" + dir="auto" onChange={handleLinkUrlChange} onScroll={updateInputStyles} /> diff --git a/src/components/middle/composer/hooks/useMentionTooltip.ts b/src/components/middle/composer/hooks/useMentionTooltip.ts index 7da685e25..d6d11adb3 100644 --- a/src/components/middle/composer/hooks/useMentionTooltip.ts +++ b/src/components/middle/composer/hooks/useMentionTooltip.ts @@ -73,6 +73,7 @@ export default function useMentionTooltip( data-entity-type="${ApiMessageEntityTypes.MentionName}" data-user-id="${user.id}" contenteditable="false" + dir="auto" >${getUserFirstOrLastName(user)}`; const atIndex = html.lastIndexOf('@'); diff --git a/src/components/middle/message/CommentButton.tsx b/src/components/middle/message/CommentButton.tsx index ed07f7a97..3a544834c 100644 --- a/src/components/middle/message/CommentButton.tsx +++ b/src/components/middle/message/CommentButton.tsx @@ -78,7 +78,7 @@ const CommentButton: FC = ({ {(!recentRepliers || recentRepliers.length === 0) && } {renderRecentRepliers()} -
+
{messagesCount ? lang('Comments', messagesCount, 'i') : lang('LeaveAComment')}
diff --git a/src/components/middle/message/MentionLink.tsx b/src/components/middle/message/MentionLink.tsx index 76cd96676..be1d45e10 100644 --- a/src/components/middle/message/MentionLink.tsx +++ b/src/components/middle/message/MentionLink.tsx @@ -35,7 +35,7 @@ const MentionLink: FC = ({ }; return ( - + {children} ); diff --git a/src/components/middle/message/Message.tsx b/src/components/middle/message/Message.tsx index 4ab9d9001..f42ac034f 100644 --- a/src/components/middle/message/Message.tsx +++ b/src/components/middle/message/Message.tsx @@ -503,9 +503,10 @@ const Message: FC = ({ noMediaCorners && 'no-media-corners', ); const hasCustomAppendix = isLastInGroup && !textParts && !asForwarded && !hasThread; + const shouldInlineMeta = !webPage && !animatedEmoji && textParts; return ( -
+
{renderSenderName()} {hasReply && ( = ({ {poll && ( )} - {!animatedEmoji && textParts &&

{textParts}

} + {!animatedEmoji && textParts && ( +

+ {textParts} + {shouldInlineMeta && ( + + )} +

+ )} {webPage && ( = ({ className={contentClassName} // @ts-ignore style={style} + dir="auto" > {withAppendix && (
)} {asForwarded && !customShape && (!isInDocumentGroup || isFirstInDocumentGroup) && (
{lang('ForwardedMessage')}
)} {renderContent()} - {(!isInDocumentGroup || isLastInDocumentGroup) && ( + {(!isInDocumentGroup || isLastInDocumentGroup) && !(!webPage && !animatedEmoji && textParts) && ( = ({ } return ( -
+
{renderSolution()}
{renderText(summary.question)}
diff --git a/src/components/middle/message/WebPage.tsx b/src/components/middle/message/WebPage.tsx index 5ceebdd85..e8704762b 100644 --- a/src/components/middle/message/WebPage.tsx +++ b/src/components/middle/message/WebPage.tsx @@ -72,6 +72,7 @@ const WebPage: FC = ({
{photo && ( .MessageMeta { + position: relative; + top: .4375rem; + bottom: auto !important; + float: right; + line-height: 1; + margin-left: .4375rem; + margin-right: -.5rem; + } + + &:dir(rtl) { + & > .MessageMeta { + float: left; + margin-left: -.25rem; + margin-right: .4375rem; + } + } } .theme-dark .Message.own & { @@ -24,6 +52,10 @@ &:not(.custom-shape) { font-size: var(--message-text-size, 1rem); + + & > .content-inner { + min-width: 0; + } } .matching-text-highlight { @@ -40,6 +72,7 @@ font-weight: 500; line-height: 1.25rem; color: var(--accent-color); + unicode-bidi: plaintext; display: flex; & > .interactive { @@ -94,8 +127,8 @@ .admin-title { flex: 1; - margin-left: 1rem; - text-align: right; + margin-inline-start: 1rem; + text-align: end; font-weight: 400; font-size: 0.75rem; margin-top: -0.1rem; @@ -118,7 +151,7 @@ &.has-solid-background { padding: .3125rem .5rem .375rem; - .text-content:last-child::after { + .forwarded-message > .text-content:not(.with-meta):last-child::after { content: ''; display: inline-block; width: var(--meta-safe-area-size); @@ -210,7 +243,7 @@ width: 1.25rem; background-size: 1.25rem; color: transparent; - margin-right: 1px; + margin-inline-end: 1px; vertical-align: text-bottom; &::selection { @@ -531,8 +564,9 @@ .text-entity-link { color: var(--color-links) !important; text-decoration: none; - word-break: none; + word-break: break-word; cursor: pointer; + unicode-bidi: initial; &:hover, &:active, &:visited { color: var(--color-links-hover) !important; diff --git a/src/components/right/ChatExtra.tsx b/src/components/right/ChatExtra.tsx index e174c97bb..f525d249f 100644 --- a/src/components/right/ChatExtra.tsx +++ b/src/components/right/ChatExtra.tsx @@ -86,7 +86,7 @@ const ChatExtra: FC = ({
{formattedNumber && !!formattedNumber.length && ( copy(formattedNumber, lang('Phone'))}> - {formattedNumber} + {formattedNumber} {lang('Phone')} )} @@ -98,7 +98,7 @@ const ChatExtra: FC = ({ ripple onClick={() => copy(`@${printedUsername}`, lang('Username'))} > - {renderText(printedUsername)} + {renderText(printedUsername)} {lang('Username')} )} @@ -109,7 +109,9 @@ const ChatExtra: FC = ({ narrow isStatic > - {renderText(description, ['br', 'links', 'emoji'])} + + {renderText(description, ['br', 'links', 'emoji'])} + {lang(userId ? 'UserBio' : 'Info')} )} diff --git a/src/components/right/GifSearch.tsx b/src/components/right/GifSearch.tsx index e047419c4..0ec01ee74 100644 --- a/src/components/right/GifSearch.tsx +++ b/src/components/right/GifSearch.tsx @@ -80,7 +80,7 @@ const GifSearch: FC = ({ if (!results.length) { return ( -

{lang('NoGIFsFound')}

+

{lang('NoGIFsFound')}

); } diff --git a/src/components/right/PollAnswerResults.tsx b/src/components/right/PollAnswerResults.tsx index 29fef2e7d..5e96370b9 100644 --- a/src/components/right/PollAnswerResults.tsx +++ b/src/components/right/PollAnswerResults.tsx @@ -116,7 +116,7 @@ const PollAnswerResults: FC = ({ {voters && renderViewMoreButton()}
- {text} + {text} {getPercentage(answerVote.votersCount, totalVoters)}%
diff --git a/src/components/right/PollResults.tsx b/src/components/right/PollResults.tsx index b747b4f62..c41130aff 100644 --- a/src/components/right/PollResults.tsx +++ b/src/components/right/PollResults.tsx @@ -35,7 +35,7 @@ const PollResults: FC = ({ return (
-

{summary.question}

+

{summary.question}

{lastSyncTime && summary.answers.map((answer) => ( = ({ if (user) { return (
- {getUserStatus(lang, user)} + {getUserStatus(lang, user)}
); } return ( - { + { isChatChannel(chat!) ? lang('Subscribers', chat!.membersCount, 'i') : lang('Members', chat!.membersCount, 'i') @@ -203,11 +203,11 @@ const PrivateChatInfo: FC = ({
{isSavedMessages ? (
-

{lang('SavedMessages')}

+

{lang('SavedMessages')}

) : (
-

{fullName && renderText(fullName)}

+

{fullName && renderText(fullName)}

{isVerifiedIconShown && }
)} diff --git a/src/components/right/RightSearch.scss b/src/components/right/RightSearch.scss index 176bcee60..df0b507dc 100644 --- a/src/components/right/RightSearch.scss +++ b/src/components/right/RightSearch.scss @@ -8,5 +8,7 @@ margin-bottom: 0.125rem; font-weight: 500; color: var(--color-text-secondary); + unicode-bidi: plaintext; + text-align: initial; } } diff --git a/src/components/right/RightSearch.tsx b/src/components/right/RightSearch.tsx index b90634215..4cd727613 100644 --- a/src/components/right/RightSearch.tsx +++ b/src/components/right/RightSearch.tsx @@ -108,10 +108,10 @@ const RightSearch: FC = ({
-

{title && renderText(title)}

+

{title && renderText(title)}

-
+
{renderText(text, ['emoji', 'highlight'], { highlight: query })}
@@ -127,13 +127,15 @@ const RightSearch: FC = ({ onLoadMore={searchTextMessagesLocal} noFastList > -

+

{!query ? ( - 'Search messages' + lang('lng_dlg_search_for_messages') + ) : (totalCount === 0 || !foundResults.length) ? ( + lang('lng_search_no_results') ) : totalCount === 1 ? ( '1 message found' ) : ( - `${(foundResults.length && (totalCount || foundResults.length)) || 'No'} messages found` + `${(foundResults.length && (totalCount || foundResults.length))} messages found` )}

{foundResults.map(renderSearchResult)} diff --git a/src/components/right/StickerSetResult.tsx b/src/components/right/StickerSetResult.tsx index eccd9157d..fe70bce5a 100644 --- a/src/components/right/StickerSetResult.tsx +++ b/src/components/right/StickerSetResult.tsx @@ -80,8 +80,8 @@ const StickerSetResult: FC = ({
-

{set.title}

-

{lang('Stickers', set.count, 'i')}

+

{set.title}

+

{lang('Stickers', set.count, 'i')}

- {lang('ChannelSubscribers')} - {lang('Subscribers', chat.membersCount!, 'i')} + {lang('ChannelSubscribers')} + {lang('Subscribers', chat.membersCount!, 'i')}
diff --git a/src/components/right/management/ManageChatAdministrators.tsx b/src/components/right/management/ManageChatAdministrators.tsx index 3a84623c3..0fd205305 100644 --- a/src/components/right/management/ManageChatAdministrators.tsx +++ b/src/components/right/management/ManageChatAdministrators.tsx @@ -86,7 +86,7 @@ const ManageChatAdministrators: FC = ({
-

+

{isChannel ? 'You can add administrators to help you manage your channel.' : 'You can add administrators to help you manage your group.'} diff --git a/src/components/right/management/ManageChatPrivacyType.tsx b/src/components/right/management/ManageChatPrivacyType.tsx index 34fdcb9c1..9f2e31232 100644 --- a/src/components/right/management/ManageChatPrivacyType.tsx +++ b/src/components/right/management/ManageChatPrivacyType.tsx @@ -135,7 +135,7 @@ const ManageChatPrivacyType: FC = ({ checkUsername={checkPublicLink} onChange={setUsername} /> -

+

{lang(`${langPrefix2}.Username.CreatePublicLinkHelp`)}

diff --git a/src/components/right/management/ManageDiscussion.tsx b/src/components/right/management/ManageDiscussion.tsx index 053a820e2..110ba0379 100644 --- a/src/components/right/management/ManageDiscussion.tsx +++ b/src/components/right/management/ManageDiscussion.tsx @@ -185,7 +185,7 @@ const ManageDiscussion: FC = ({ function renderDiscussionGroups() { return (
-

{lang('DiscussionChannelHelp')}

+

{lang('DiscussionChannelHelp')}

= ({ )}
-

{lang('DiscussionChannelHelp2')}

+

{lang('DiscussionChannelHelp2')}

= ({ onChange={handleChange} />
- {label} - {subLabel && {subLabel}} + {label} + {subLabel && {subLabel}}
{isLoading && } diff --git a/src/components/ui/InputText.tsx b/src/components/ui/InputText.tsx index ba1939890..e36fc98fc 100644 --- a/src/components/ui/InputText.tsx +++ b/src/components/ui/InputText.tsx @@ -62,6 +62,7 @@ const InputText: FC = ({ className="form-control" type="text" id={id} + dir="auto" value={value || ''} placeholder={placeholder} maxLength={maxLength} diff --git a/src/components/ui/Link.tsx b/src/components/ui/Link.tsx index 1e582ccb5..e24afd0e0 100644 --- a/src/components/ui/Link.tsx +++ b/src/components/ui/Link.tsx @@ -20,6 +20,7 @@ const Link: FC = ({ children, className, onClick }) => { {children} diff --git a/src/components/ui/MenuItem.scss b/src/components/ui/MenuItem.scss index d00e70b91..37480a28a 100644 --- a/src/components/ui/MenuItem.scss +++ b/src/components/ui/MenuItem.scss @@ -13,6 +13,7 @@ color: var(--color-text); --ripple-color: rgba(0, 0, 0, .08); cursor: pointer; + unicode-bidi: plaintext; &:hover, &:focus { background-color: var(--color-chat-hover); diff --git a/src/components/ui/SearchInput.tsx b/src/components/ui/SearchInput.tsx index fed7279a8..543dbc9fd 100644 --- a/src/components/ui/SearchInput.tsx +++ b/src/components/ui/SearchInput.tsx @@ -93,6 +93,7 @@ const SearchInput: FC = ({ ref={inputRef} id={inputId} type="text" + dir="auto" placeholder={placeholder || lang('Search')} className="form-control" value={value} diff --git a/src/lib/teact/teact-dom.ts b/src/lib/teact/teact-dom.ts index 22cf76818..05f6fd24a 100644 --- a/src/lib/teact/teact-dom.ts +++ b/src/lib/teact/teact-dom.ts @@ -22,6 +22,7 @@ type VirtualDomHead = { }; const FILTERED_ATTRIBUTES = new Set(['key', 'ref', 'teactFastList', 'teactOrderKey']); +const HTML_ATTRIBUTES = new Set(['dir']); const MAPPED_ATTRIBUTES: { [k: string]: string } = { autoPlay: 'autoplay', autoComplete: 'autocomplete', @@ -428,7 +429,7 @@ function addAttribute(element: HTMLElement, key: string, value: any) { element.style.cssText = value; } else if (key.startsWith('on')) { addEventListener(element, key, value); - } else if (key.startsWith('data-')) { + } else if (key.startsWith('data-') || HTML_ATTRIBUTES.has(key)) { element.setAttribute(key, value); } else if (!FILTERED_ATTRIBUTES.has(key)) { (element as any)[MAPPED_ATTRIBUTES[key] || key] = value; @@ -444,7 +445,7 @@ function removeAttribute(element: HTMLElement, key: string, value: any) { element.style.cssText = ''; } else if (key.startsWith('on')) { removeEventListener(element, key, value); - } else if (key.startsWith('data-')) { + } else if (key.startsWith('data-') || HTML_ATTRIBUTES.has(key)) { element.removeAttribute(key); } else if (!FILTERED_ATTRIBUTES.has(key)) { delete (element as any)[MAPPED_ATTRIBUTES[key] || key]; diff --git a/src/modules/actions/api/initial.ts b/src/modules/actions/api/initial.ts index e5b2cb5db..294137f7b 100644 --- a/src/modules/actions/api/initial.ts +++ b/src/modules/actions/api/initial.ts @@ -120,6 +120,12 @@ addReducer('reset', () => { cacheApi.clear(CUSTOM_BG_CACHE_NAME); cacheApi.clear(LANG_CACHE_NAME); + const langChachePrefix = LANG_CACHE_NAME.replace(/\d+$/, ''); + const langCacheVersion = (LANG_CACHE_NAME.match(/\d+$/) || [0])[0]; + for (let i = 0; i < langCacheVersion; i++) { + cacheApi.clear(`${langChachePrefix}${i === 0 ? '' : i}`); + } + getDispatch().init(); });