From 439222f9512a62a277dd030894f4f8f569fc2932 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Tue, 27 Dec 2022 02:46:13 +0100 Subject: [PATCH] Attachment Modal: Fix caption length calculation (#2226) --- src/components/middle/composer/AttachmentModal.tsx | 11 ++++++++--- src/components/middle/composer/MessageInput.tsx | 2 +- .../middle/composer/helpers/getHtmlTextLength.ts | 12 ++++++++++++ src/components/middle/message/MessageMeta.scss | 5 +++++ .../middle/message/helpers/calculateAuthorWidth.ts | 2 +- src/styles/_forms.scss | 1 + src/util/parseMessageInput.ts | 2 +- 7 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 src/components/middle/composer/helpers/getHtmlTextLength.ts diff --git a/src/components/middle/composer/AttachmentModal.tsx b/src/components/middle/composer/AttachmentModal.tsx index 864511393..70f04f4bc 100644 --- a/src/components/middle/composer/AttachmentModal.tsx +++ b/src/components/middle/composer/AttachmentModal.tsx @@ -1,5 +1,5 @@ import React, { - memo, useCallback, useEffect, useRef, + memo, useCallback, useEffect, useMemo, useRef, } from '../../../lib/teact/teact'; import { getActions } from '../../../global'; @@ -16,6 +16,7 @@ import { getFileExtension } from '../../common/helpers/documentInfo'; import captureEscKeyListener from '../../../util/captureEscKeyListener'; import getFilesFromDataTransferItems from './helpers/getFilesFromDataTransferItems'; import { hasPreview } from '../../../util/files'; +import { getHtmlTextLength } from './helpers/getHtmlTextLength'; import usePrevious from '../../../hooks/usePrevious'; import useMentionTooltip from './hooks/useMentionTooltip'; @@ -63,6 +64,7 @@ export type OwnProps = { }; const DROP_LEAVE_TIMEOUT_MS = 150; +const CAPTION_SYMBOLS_LEFT_THRESHOLD = 100; const AttachmentModal: FC = ({ chatId, @@ -200,6 +202,11 @@ const AttachmentModal: FC = ({ } } + const leftChars = useMemo(() => { + const captionLeftBeforeLimit = captionLimit - getHtmlTextLength(caption); + return captionLeftBeforeLimit <= CAPTION_SYMBOLS_LEFT_THRESHOLD ? captionLeftBeforeLimit : undefined; + }, [caption, captionLimit]); + if (!renderingAttachments) { return undefined; } @@ -257,8 +264,6 @@ const AttachmentModal: FC = ({ ); } - const leftChars = (captionLimit - caption.length) <= 100 ? captionLimit - caption.length : undefined; - return ( = ({
- {captionLimit && ( + {captionLimit !== undefined && (
{captionLimit}
diff --git a/src/components/middle/composer/helpers/getHtmlTextLength.ts b/src/components/middle/composer/helpers/getHtmlTextLength.ts new file mode 100644 index 000000000..9985c4a1a --- /dev/null +++ b/src/components/middle/composer/helpers/getHtmlTextLength.ts @@ -0,0 +1,12 @@ +import { fixImageContent } from '../../../../util/parseMessageInput'; + +const div = document.createElement('div'); + +export function getHtmlTextLength(html: string) { + div.innerHTML = html; + fixImageContent(div); + div.querySelectorAll('br').forEach((br) => { + br.replaceWith('\n'); + }); + return div.textContent?.trim().length || 0; +} diff --git a/src/components/middle/message/MessageMeta.scss b/src/components/middle/message/MessageMeta.scss index c401888cc..095dce514 100644 --- a/src/components/middle/message/MessageMeta.scss +++ b/src/components/middle/message/MessageMeta.scss @@ -40,6 +40,11 @@ overflow: hidden; text-overflow: ellipsis; margin-right: 0.375rem; + + .emoji-small { + width: 1rem !important; + height: 1rem !important; + } } .icon-channelviews { diff --git a/src/components/middle/message/helpers/calculateAuthorWidth.ts b/src/components/middle/message/helpers/calculateAuthorWidth.ts index f70af85c9..125728a4b 100644 --- a/src/components/middle/message/helpers/calculateAuthorWidth.ts +++ b/src/components/middle/message/helpers/calculateAuthorWidth.ts @@ -16,7 +16,7 @@ export default function calculateAuthorWidth(text: string) { document.body.appendChild(element); } - element.innerHTML = text; + element.textContent = text; return element.offsetWidth; } diff --git a/src/styles/_forms.scss b/src/styles/_forms.scss index c0fe3e802..817b306a2 100644 --- a/src/styles/_forms.scss +++ b/src/styles/_forms.scss @@ -3,6 +3,7 @@ right: 0.75rem; bottom: -0.5625rem; padding: 0 0.25rem; + border-radius: 0.25rem; color: var(--color-text-secondary); font-size: 0.75rem; background: var(--color-background); diff --git a/src/util/parseMessageInput.ts b/src/util/parseMessageInput.ts index 7245e9b44..667db4788 100644 --- a/src/util/parseMessageInput.ts +++ b/src/util/parseMessageInput.ts @@ -63,7 +63,7 @@ export default function parseMessageInput( }; } -function fixImageContent(fragment: HTMLDivElement) { +export function fixImageContent(fragment: HTMLDivElement) { fragment.querySelectorAll('img').forEach((node) => { if (node.dataset.documentId) { // Custom Emoji node.textContent = (node as HTMLImageElement).alt || '';