import type { FC } from '../../../lib/teact/teact'; import React, { memo, useRef } from '../../../lib/teact/teact'; import { getActions } from '../../../global'; import type { ApiMessage, ApiTypeStory } from '../../../api/types'; import type { ObserveFn } from '../../../hooks/useIntersectionObserver'; import { AudioOrigin, type ISettings } from '../../../types'; import { getMessageWebPage } from '../../../global/helpers'; import buildClassName from '../../../util/buildClassName'; import trimText from '../../../util/trimText'; import renderText from '../../common/helpers/renderText'; import { calculateMediaDimensions } from './helpers/mediaDimensions'; import { getWebpageButtonText } from './helpers/webpageType'; import useDynamicColorListener from '../../../hooks/stickers/useDynamicColorListener'; import useAppLayout from '../../../hooks/useAppLayout'; import useEnsureStory from '../../../hooks/useEnsureStory'; import useLastCallback from '../../../hooks/useLastCallback'; import useOldLang from '../../../hooks/useOldLang'; import Audio from '../../common/Audio'; import Document from '../../common/Document'; import EmojiIconBackground from '../../common/embedded/EmojiIconBackground'; import SafeLink from '../../common/SafeLink'; import StickerView from '../../common/StickerView'; import Button from '../../ui/Button'; import BaseStory from './BaseStory'; import Photo from './Photo'; import Video from './Video'; import './WebPage.scss'; const MAX_TEXT_LENGTH = 170; // symbols const WEBPAGE_STORY_TYPE = 'telegram_story'; const STICKER_SIZE = 80; const EMOJI_SIZE = 38; type OwnProps = { message: ApiMessage; observeIntersectionForLoading?: ObserveFn; observeIntersectionForPlaying?: ObserveFn; noAvatars?: boolean; canAutoLoad?: boolean; canAutoPlay?: boolean; inPreview?: boolean; asForwarded?: boolean; isDownloading?: boolean; isProtected?: boolean; isConnected?: boolean; backgroundEmojiId?: string; theme: ISettings['theme']; story?: ApiTypeStory; shouldWarnAboutSvg?: boolean; autoLoadFileMaxSizeMb?: number; onAudioPlay?: NoneToVoidFunction; onMediaClick?: NoneToVoidFunction; onCancelMediaTransfer?: NoneToVoidFunction; onContainerClick?: ((e: React.MouseEvent) => void); isEditing?: boolean; }; const WebPage: FC = ({ message, observeIntersectionForLoading, observeIntersectionForPlaying, noAvatars, canAutoLoad, canAutoPlay, inPreview, asForwarded, isDownloading = false, isProtected, isConnected, story, theme, backgroundEmojiId, shouldWarnAboutSvg, autoLoadFileMaxSizeMb, onMediaClick, onContainerClick, onAudioPlay, onCancelMediaTransfer, isEditing, }) => { const { openTelegramLink } = getActions(); const webPage = getMessageWebPage(message); const { isMobile } = useAppLayout(); // eslint-disable-next-line no-null/no-null const ref = useRef(null); // eslint-disable-next-line no-null/no-null const stickersRef = useRef(null); const lang = useOldLang(); const handleMediaClick = useLastCallback(() => { onMediaClick!(); }); const handleContainerClick = useLastCallback((e: React.MouseEvent) => { onContainerClick?.(e); }); const handleQuickButtonClick = useLastCallback(() => { if (!webPage) return; openTelegramLink({ url: webPage.url, }); }); const { story: storyData, stickers } = webPage || {}; useEnsureStory(storyData?.peerId, storyData?.id, story); const hasCustomColor = stickers?.isWithTextColor || stickers?.documents?.[0]?.shouldUseTextColor; const customColor = useDynamicColorListener(stickersRef, !hasCustomColor); if (!webPage) { return undefined; } const { siteName, url, displayUrl, title, description, photo, video, audio, type, document, } = webPage; const isStory = type === WEBPAGE_STORY_TYPE; const isExpiredStory = story && 'isDeleted' in story; const quickButtonLangKey = !inPreview && !isExpiredStory ? getWebpageButtonText(type) : undefined; const truncatedDescription = trimText(description, MAX_TEXT_LENGTH); const isArticle = Boolean(truncatedDescription || title || siteName); let isSquarePhoto = Boolean(stickers); if (isArticle && webPage?.photo && !webPage.video) { const { width, height } = calculateMediaDimensions({ media: webPage.photo, isOwn: message.isOutgoing, isInWebPage: true, asForwarded, noAvatars, isMobile, }); isSquarePhoto = width === height; } const isMediaInteractive = (photo || video) && onMediaClick && !isSquarePhoto; const className = buildClassName( 'WebPage', inPreview && 'in-preview', !isEditing && inPreview && 'interactive', isSquarePhoto && 'with-square-photo', !photo && !video && !inPreview && 'without-media', video && 'with-video', !isArticle && 'no-article', document && 'with-document', quickButtonLangKey && 'with-quick-button', ); function renderQuickButton(langKey: string) { return ( ); } return (
{backgroundEmojiId && ( )} {isStory && ( )} {photo && !video && ( )} {isArticle && (
{!inPreview && title && (

{renderText(title)}

)} {truncatedDescription && (

{renderText(truncatedDescription, ['emoji', 'br'])}

)}
)} {!inPreview && video && (
{quickButtonLangKey && renderQuickButton(quickButtonLangKey)}
); }; export default memo(WebPage);