Message List: Fix exception due to dot in ID (#1742)

This commit is contained in:
Alexander Zinchuk 2022-03-04 16:21:31 +03:00
parent 4c33acddf0
commit d65e9937b5
9 changed files with 28 additions and 22 deletions

View File

@ -49,7 +49,6 @@ const EmbeddedMessage: FC<OwnProps> = ({
const isIntersecting = useIsIntersecting(ref, observeIntersection); const isIntersecting = useIsIntersecting(ref, observeIntersection);
const mediaBlobUrl = useMedia(message && getMessageMediaHash(message, 'pictogram'), !isIntersecting); const mediaBlobUrl = useMedia(message && getMessageMediaHash(message, 'pictogram'), !isIntersecting);
const pictogramId = message && `sticker-reply-thumb${message.id}`;
const mediaThumbnail = useWebpThumbnail(message); const mediaThumbnail = useWebpThumbnail(message);
const isRoundVideo = Boolean(message && getMessageRoundVideo(message)); const isRoundVideo = Boolean(message && getMessageRoundVideo(message));
@ -63,7 +62,7 @@ const EmbeddedMessage: FC<OwnProps> = ({
className={buildClassName('EmbeddedMessage', className)} className={buildClassName('EmbeddedMessage', className)}
onClick={message ? onClick : undefined} onClick={message ? onClick : undefined}
> >
{mediaThumbnail && renderPictogram(pictogramId, mediaThumbnail, mediaBlobUrl, isRoundVideo, isProtected)} {mediaThumbnail && renderPictogram(mediaThumbnail, mediaBlobUrl, isRoundVideo, isProtected)}
<div className="message-text"> <div className="message-text">
<p dir="auto"> <p dir="auto">
{!message ? ( {!message ? (
@ -81,7 +80,6 @@ const EmbeddedMessage: FC<OwnProps> = ({
}; };
function renderPictogram( function renderPictogram(
id: string | undefined,
thumbDataUri: string, thumbDataUri: string,
blobUrl?: string, blobUrl?: string,
isRoundVideo?: boolean, isRoundVideo?: boolean,
@ -92,7 +90,6 @@ function renderPictogram(
return ( return (
<> <>
<img <img
id={id}
src={blobUrl || thumbDataUri} src={blobUrl || thumbDataUri}
width={width} width={width}
height={height} height={height}

View File

@ -5,6 +5,7 @@ import { ApiMessage } from '../../api/types';
import { formatMediaDuration } from '../../util/dateFormat'; import { formatMediaDuration } from '../../util/dateFormat';
import stopEvent from '../../util/stopEvent'; import stopEvent from '../../util/stopEvent';
import { import {
getMessageHtmlId,
getMessageMediaHash, getMessageMediaHash,
getMessageMediaThumbDataUri, getMessageMediaThumbDataUri,
getMessageVideo, getMessageVideo,
@ -48,7 +49,7 @@ const Media: FC<OwnProps> = ({
return ( return (
<div <div
ref={ref} ref={ref}
id={`${idPrefix}${message.id}`} id={`${idPrefix}${getMessageHtmlId(message.id)}`}
className="Media scroll-item" className="Media scroll-item"
onClick={onClick ? handleClick : undefined} onClick={onClick ? handleClick : undefined}
> >

View File

@ -12,6 +12,7 @@ import {
import windowSize from '../../../util/windowSize'; import windowSize from '../../../util/windowSize';
import stopEvent from '../../../util/stopEvent'; import stopEvent from '../../../util/stopEvent';
import { IS_TOUCH_ENV } from '../../../util/environment'; import { IS_TOUCH_ENV } from '../../../util/environment';
import { getMessageHtmlId } from '../../../modules/helpers';
const ANIMATION_DURATION = 200; const ANIMATION_DURATION = 200;
@ -306,17 +307,17 @@ function getNodes(origin: MediaViewerOrigin, message?: ApiMessage) {
switch (origin) { switch (origin) {
case MediaViewerOrigin.Album: case MediaViewerOrigin.Album:
case MediaViewerOrigin.ScheduledAlbum: case MediaViewerOrigin.ScheduledAlbum:
containerSelector = `.Transition__slide--active > .MessageList #album-media-${message!.id}`; containerSelector = `.Transition__slide--active > .MessageList #album-media-${getMessageHtmlId(message!.id)}`;
mediaSelector = '.full-media'; mediaSelector = '.full-media';
break; break;
case MediaViewerOrigin.SharedMedia: case MediaViewerOrigin.SharedMedia:
containerSelector = `#shared-media${message!.id}`; containerSelector = `#shared-media${getMessageHtmlId(message!.id)}`;
mediaSelector = 'img'; mediaSelector = 'img';
break; break;
case MediaViewerOrigin.SearchResult: case MediaViewerOrigin.SearchResult:
containerSelector = `#search-media${message!.id}`; containerSelector = `#search-media${getMessageHtmlId(message!.id)}`;
mediaSelector = 'img'; mediaSelector = 'img';
break; break;
@ -338,7 +339,7 @@ function getNodes(origin: MediaViewerOrigin, message?: ApiMessage) {
case MediaViewerOrigin.ScheduledInline: case MediaViewerOrigin.ScheduledInline:
case MediaViewerOrigin.Inline: case MediaViewerOrigin.Inline:
default: default:
containerSelector = `.Transition__slide--active > .MessageList #message${message!.id}`; containerSelector = `.Transition__slide--active > .MessageList #${getMessageHtmlId(message!.id)}`;
mediaSelector = '.message-content .full-media, .message-content .thumbnail'; mediaSelector = '.message-content .full-media, .message-content .thumbnail';
} }

View File

@ -12,7 +12,7 @@ import {
selectIsMessageFocused, selectIsMessageFocused,
selectChat, selectChat,
} from '../../modules/selectors'; } from '../../modules/selectors';
import { isChatChannel } from '../../modules/helpers'; import { getMessageHtmlId, isChatChannel } from '../../modules/helpers';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import { renderActionMessageText } from '../common/helpers/renderActionMessageText'; import { renderActionMessageText } from '../common/helpers/renderActionMessageText';
import useEnsureMessage from '../../hooks/useEnsureMessage'; import useEnsureMessage from '../../hooks/useEnsureMessage';
@ -127,7 +127,7 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
return ( return (
<div <div
ref={ref} ref={ref}
id={`message${message.id}`} id={getMessageHtmlId(message.id)}
className={className} className={className}
data-message-id={message.id} data-message-id={message.id}
onMouseDown={handleMouseDown} onMouseDown={handleMouseDown}

View File

@ -7,7 +7,9 @@ import { SCHEDULED_WHEN_ONLINE } from '../../config';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import { compact, flatten } from '../../util/iteratees'; import { compact, flatten } from '../../util/iteratees';
import { formatHumanDate } from '../../util/dateFormat'; import { formatHumanDate } from '../../util/dateFormat';
import { getMessageOriginalId, isActionMessage, isOwnMessage } from '../../modules/helpers'; import {
getMessageHtmlId, getMessageOriginalId, isActionMessage, isOwnMessage,
} from '../../modules/helpers';
import useLang from '../../hooks/useLang'; import useLang from '../../hooks/useLang';
import { isAlbum, MessageDateGroup } from './helpers/groupMessages'; import { isAlbum, MessageDateGroup } from './helpers/groupMessages';
import { preventMessageInputBlur } from './helpers/preventMessageInputBlur'; import { preventMessageInputBlur } from './helpers/preventMessageInputBlur';
@ -151,8 +153,8 @@ const MessageListContent: FC<OwnProps> = ({
const isMessageAlbum = isAlbum(messageOrAlbum); const isMessageAlbum = isAlbum(messageOrAlbum);
const nextMessage = senderGroup[messageIndex + 1]; const nextMessage = senderGroup[messageIndex + 1];
if (message.previousLocalId && anchorIdRef.current === `message${message.previousLocalId}`) { if (message.previousLocalId && anchorIdRef.current === getMessageHtmlId(message.previousLocalId)) {
anchorIdRef.current = `message${message.id}`; anchorIdRef.current = getMessageHtmlId(message.id);
} }
const documentGroupId = !isMessageAlbum && message.groupedId ? message.groupedId : undefined; const documentGroupId = !isMessageAlbum && message.groupedId ? message.groupedId : undefined;

View File

@ -5,7 +5,7 @@ import { ApiMessage } from '../../../api/types';
import { IAlbum, ISettings } from '../../../types'; import { IAlbum, ISettings } from '../../../types';
import { AlbumRectPart, IAlbumLayout } from './helpers/calculateAlbumLayout'; import { AlbumRectPart, IAlbumLayout } from './helpers/calculateAlbumLayout';
import { getMessageContent } from '../../../modules/helpers'; import { getMessageContent, getMessageHtmlId } from '../../../modules/helpers';
import { getDispatch, getGlobal, withGlobal } from '../../../lib/teact/teactn'; import { getDispatch, getGlobal, withGlobal } from '../../../lib/teact/teactn';
import withSelectControl from './hocs/withSelectControl'; import withSelectControl from './hocs/withSelectControl';
import { ObserveFn } from '../../../hooks/useIntersectionObserver'; import { ObserveFn } from '../../../hooks/useIntersectionObserver';
@ -80,7 +80,7 @@ const Album: FC<OwnProps & StateProps> = ({
return ( return (
<PhotoWithSelect <PhotoWithSelect
id={`album-media-${message.id}`} id={`album-media-${getMessageHtmlId(message.id)}`}
message={message} message={message}
observeIntersection={observeIntersection} observeIntersection={observeIntersection}
canAutoLoad={canAutoLoad} canAutoLoad={canAutoLoad}
@ -97,7 +97,7 @@ const Album: FC<OwnProps & StateProps> = ({
} else if (video) { } else if (video) {
return ( return (
<VideoWithSelect <VideoWithSelect
id={`album-media-${message.id}`} id={`album-media-${getMessageHtmlId(message.id)}`}
message={message} message={message}
observeIntersection={observeIntersection} observeIntersection={observeIntersection}
canAutoLoad={canAutoLoad} canAutoLoad={canAutoLoad}

View File

@ -68,6 +68,7 @@ import {
getSenderTitle, getSenderTitle,
getUserColorKey, getUserColorKey,
areReactionsEmpty, areReactionsEmpty,
getMessageHtmlId,
isGeoLiveExpired, isGeoLiveExpired,
} from '../../../modules/helpers'; } from '../../../modules/helpers';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
@ -848,7 +849,7 @@ const Message: FC<OwnProps & StateProps> = ({
return ( return (
<div <div
ref={ref} ref={ref}
id={`message${messageId}`} id={getMessageHtmlId(message.id)}
className={containerClassName} className={containerClassName}
style={metaSafeAuthorWidth ? `--meta-safe-author-width: ${metaSafeAuthorWidth}px` : undefined} style={metaSafeAuthorWidth ? `--meta-safe-author-width: ${metaSafeAuthorWidth}px` : undefined}
data-message-id={messageId} data-message-id={messageId}

View File

@ -4,7 +4,7 @@ import { ApiMessage } from '../../../api/types';
import { NO_STICKER_SET_ID } from '../../../config'; import { NO_STICKER_SET_ID } from '../../../config';
import { getStickerDimensions } from '../../common/helpers/mediaDimensions'; import { getStickerDimensions } from '../../common/helpers/mediaDimensions';
import { getMessageMediaFormat, getMessageMediaHash } from '../../../modules/helpers'; import { getMessageHtmlId, getMessageMediaFormat, getMessageMediaHash } from '../../../modules/helpers';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import { ObserveFn, useIsIntersecting } from '../../../hooks/useIntersectionObserver'; import { ObserveFn, useIsIntersecting } from '../../../hooks/useIntersectionObserver';
import useMedia from '../../../hooks/useMedia'; import useMedia from '../../../hooks/useMedia';
@ -85,7 +85,7 @@ const Sticker: FC<OwnProps> = ({
<div ref={ref} className={stickerClassName} onClick={!isMemojiSticker ? openModal : undefined}> <div ref={ref} className={stickerClassName} onClick={!isMemojiSticker ? openModal : undefined}>
{(!isMediaReady || (isVideo && !canDisplayVideo)) && ( {(!isMediaReady || (isVideo && !canDisplayVideo)) && (
<img <img
id={`sticker-thumb-${message.id}`} id={`sticker-thumb-${getMessageHtmlId(message.id)}`}
src={previewUrl} src={previewUrl}
width={width} width={width}
height={height} height={height}
@ -95,7 +95,7 @@ const Sticker: FC<OwnProps> = ({
)} )}
{!isLottie && !isVideo && ( {!isLottie && !isVideo && (
<img <img
id={`sticker-${message.id}`} id={`sticker-${getMessageHtmlId(message.id)}`}
src={mediaData as string} src={mediaData as string}
width={width} width={width}
height={height} height={height}
@ -105,7 +105,7 @@ const Sticker: FC<OwnProps> = ({
)} )}
{isVideo && canDisplayVideo && isMediaReady && ( {isVideo && canDisplayVideo && isMediaReady && (
<video <video
id={`sticker-${message.id}`} id={`sticker-${getMessageHtmlId(message.id)}`}
src={mediaData as string} src={mediaData as string}
width={width} width={width}
height={height} height={height}

View File

@ -18,6 +18,10 @@ const RE_LINK = new RegExp(RE_LINK_TEMPLATE, 'i');
export type MessageKey = `msg${string}-${number}`; export type MessageKey = `msg${string}-${number}`;
export function getMessageHtmlId(messageId: number) {
return `message${messageId.toString().replace('.', '-')}`;
}
export function getMessageKey(message: ApiMessage): MessageKey { export function getMessageKey(message: ApiMessage): MessageKey {
const { chatId, id } = message; const { chatId, id } = message;