WebPage: Render document in the web page message (#4329)

This commit is contained in:
Alexander Zinchuk 2024-03-01 14:02:49 -05:00
parent 511dbd13ae
commit 3c7b07d07f
9 changed files with 45 additions and 10 deletions

View File

@ -365,7 +365,6 @@ export function isMessageWithMedia(message: GramJs.Message | GramJs.UpdateServic
&& ( && (
media.webpage.photo instanceof GramJs.Photo || ( media.webpage.photo instanceof GramJs.Photo || (
media.webpage.document instanceof GramJs.Document media.webpage.document instanceof GramJs.Document
&& media.webpage.document.mimeType.startsWith('video')
) )
) )
) || ( ) || (

View File

@ -13,6 +13,7 @@ import {
getMessageMediaFormat, getMessageMediaFormat,
getMessageMediaHash, getMessageMediaHash,
getMessageMediaThumbDataUri, getMessageMediaThumbDataUri,
getMessageWebPageDocument,
isMessageDocumentVideo, isMessageDocumentVideo,
} from '../../global/helpers'; } from '../../global/helpers';
import { getDocumentExtension, getDocumentHasPreview } from './helpers/documentInfo'; import { getDocumentExtension, getDocumentHasPreview } from './helpers/documentInfo';
@ -79,7 +80,8 @@ const Document: FC<OwnProps> = ({
const [isSvgDialogOpen, openSvgDialog, closeSvgDialog] = useFlag(); const [isSvgDialogOpen, openSvgDialog, closeSvgDialog] = useFlag();
const [shouldNotWarnAboutSvg, setShouldNotWarnAboutSvg] = useState(false); const [shouldNotWarnAboutSvg, setShouldNotWarnAboutSvg] = useState(false);
const document = message.content.document!; const document = message.content.document! || getMessageWebPageDocument(message);
const { fileName, size, timestamp } = document; const { fileName, size, timestamp } = document;
const extension = getDocumentExtension(document) || ''; const extension = getDocumentExtension(document) || '';

View File

@ -59,7 +59,7 @@
right: 0; right: 0;
border-bottom-left-radius: 0.25rem; border-bottom-left-radius: 0.25rem;
background: rgba(black, 0.25); background: rgba(black, 0.25);
border-color: transparent var(--background-color) transparent var(--background-color); border-color: transparent var(--file-icon-border-color, var(--background-color)) transparent var(--file-icon-border-color, var(--background-color));
border-width: 0 1.125rem 1.125rem 0; border-width: 0 1.125rem 1.125rem 0;
border-style: solid; border-style: solid;
/* stylelint-disable-next-line plugin/no-low-performance-animation-properties */ /* stylelint-disable-next-line plugin/no-low-performance-animation-properties */

View File

@ -1226,6 +1226,8 @@ const Message: FC<OwnProps & StateProps> = ({
story={webPageStory} story={webPageStory}
isConnected={isConnected} isConnected={isConnected}
backgroundEmojiId={sender?.color?.backgroundEmojiId} backgroundEmojiId={sender?.color?.backgroundEmojiId}
shouldWarnAboutSvg={shouldWarnAboutSvg}
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}
onMediaClick={handleMediaClick} onMediaClick={handleMediaClick}
onCancelMediaTransfer={handleCancelUpload} onCancelMediaTransfer={handleCancelUpload}
/> />

View File

@ -10,6 +10,10 @@
position: relative; position: relative;
overflow: hidden; overflow: hidden;
&.with-document {
--file-icon-border-color: var(--accent-background-color);
}
&--background-icons { &--background-icons {
margin: -0.375rem; margin: -0.375rem;
} }

View File

@ -18,6 +18,7 @@ import useEnsureStory from '../../../hooks/useEnsureStory';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import Document from '../../common/Document';
import EmojiIconBackground from '../../common/embedded/EmojiIconBackground'; import EmojiIconBackground from '../../common/embedded/EmojiIconBackground';
import SafeLink from '../../common/SafeLink'; import SafeLink from '../../common/SafeLink';
import Button from '../../ui/Button'; import Button from '../../ui/Button';
@ -44,6 +45,8 @@ type OwnProps = {
backgroundEmojiId?: string; backgroundEmojiId?: string;
theme: ISettings['theme']; theme: ISettings['theme'];
story?: ApiTypeStory; story?: ApiTypeStory;
shouldWarnAboutSvg?: boolean;
autoLoadFileMaxSizeMb?: number;
onMediaClick?: () => void; onMediaClick?: () => void;
onCancelMediaTransfer?: () => void; onCancelMediaTransfer?: () => void;
}; };
@ -62,6 +65,8 @@ const WebPage: FC<OwnProps> = ({
story, story,
theme, theme,
backgroundEmojiId, backgroundEmojiId,
shouldWarnAboutSvg,
autoLoadFileMaxSizeMb,
onMediaClick, onMediaClick,
onCancelMediaTransfer, onCancelMediaTransfer,
}) => { }) => {
@ -99,6 +104,7 @@ const WebPage: FC<OwnProps> = ({
photo, photo,
video, video,
type, type,
document,
} = webPage; } = webPage;
const isStory = type === WEBPAGE_STORY_TYPE; const isStory = type === WEBPAGE_STORY_TYPE;
const isExpiredStory = story && 'isDeleted' in story; const isExpiredStory = story && 'isDeleted' in story;
@ -119,6 +125,7 @@ const WebPage: FC<OwnProps> = ({
!photo && !video && !inPreview && 'without-media', !photo && !video && !inPreview && 'without-media',
video && 'with-video', video && 'with-video',
!isArticle && 'no-article', !isArticle && 'no-article',
document && 'with-document',
quickButtonLangKey && 'with-quick-button', quickButtonLangKey && 'with-quick-button',
); );
@ -193,6 +200,17 @@ const WebPage: FC<OwnProps> = ({
onCancelUpload={onCancelMediaTransfer} onCancelUpload={onCancelMediaTransfer}
/> />
)} )}
{!inPreview && document && (
<Document
message={message}
observeIntersection={observeIntersection}
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}
onMediaClick={handleMediaClick}
onCancelUpload={onCancelMediaTransfer}
isDownloading={isDownloading}
shouldWarnAboutSvg={shouldWarnAboutSvg}
/>
)}
</div> </div>
{quickButtonLangKey && renderQuickButton(quickButtonLangKey)} {quickButtonLangKey && renderQuickButton(quickButtonLangKey)}
</div> </div>

View File

@ -113,7 +113,7 @@
&.with-voice-transcription, &.with-voice-transcription,
&:not(.custom-shape) .text-content, &:not(.custom-shape) .text-content,
&.document { &:not(.web-page).document {
& > .MessageMeta { & > .MessageMeta {
position: relative; position: relative;
top: 0.375rem; top: 0.375rem;
@ -538,7 +538,7 @@
} }
.message-content.media, .message-content.media,
.WebPage { .WebPage:not(.with-document) {
.media-inner { .media-inner {
display: flex; display: flex;
justify-content: center; justify-content: center;

View File

@ -96,6 +96,10 @@ export function buildContentClassName(
if (webPage.photo || webPage.video) { if (webPage.photo || webPage.video) {
classNames.push('media'); classNames.push('media');
} }
if (webPage.document) {
classNames.push('document');
}
} }
if (invoice && !invoice.extendedMedia) { if (invoice && !invoice.extendedMedia) {

View File

@ -104,6 +104,10 @@ export function getMessageDocument(message: MediaContainer) {
return message.content.document; return message.content.document;
} }
export function getMessageWebPageDocument(message: MediaContainer) {
return getMessageWebPage(message)?.document;
}
export function isMessageDocumentPhoto(message: MediaContainer) { export function isMessageDocumentPhoto(message: MediaContainer) {
const document = getMessageDocument(message); const document = getMessageDocument(message);
return document ? document.mediaType === 'photo' : undefined; return document ? document.mediaType === 'photo' : undefined;
@ -213,8 +217,9 @@ export function getMessageMediaHash(
const messagePhoto = getMessagePhoto(message) || getMessageWebPagePhoto(message) || getMessageDocumentPhoto(message); const messagePhoto = getMessagePhoto(message) || getMessageWebPagePhoto(message) || getMessageDocumentPhoto(message);
const actionPhoto = getMessageActionPhoto(message); const actionPhoto = getMessageActionPhoto(message);
const messageVideo = video || getMessageWebPageVideo(message) || getMessageDocumentVideo(message); const messageVideo = video || getMessageWebPageVideo(message) || getMessageDocumentVideo(message);
const messageDocument = document || getMessageWebPageDocument(message);
const content = actionPhoto || messagePhoto || messageVideo || sticker || audio || voice || document; const content = actionPhoto || messagePhoto || messageVideo || sticker || audio || voice || messageDocument;
if (!content) { if (!content) {
return undefined; return undefined;
} }
@ -249,17 +254,17 @@ export function getMessageMediaHash(
return `${base}?size=${actionPhoto ? 'b' : 'x'}`; return `${base}?size=${actionPhoto ? 'b' : 'x'}`;
case 'full': case 'full':
case 'download': case 'download':
return document ? base : `${base}?size=${actionPhoto ? 'c' : 'z'}`; return messageDocument ? base : `${base}?size=${actionPhoto ? 'c' : 'z'}`;
} }
} }
if (document) { if (messageDocument) {
switch (target) { switch (target) {
case 'micro': case 'micro':
case 'pictogram': case 'pictogram':
case 'inline': case 'inline':
case 'preview': case 'preview':
if (!getDocumentHasPreview(document) || hasMessageLocalBlobUrl(message)) { if (!getDocumentHasPreview(messageDocument) || hasMessageLocalBlobUrl(message)) {
return undefined; return undefined;
} }
@ -353,8 +358,9 @@ export function getMessageMediaFormat(
const { const {
video, audio, voice, document, video, audio, voice, document,
} = message.content; } = message.content;
const messageDocument = document || getMessageWebPageDocument(message);
const isVideo = Boolean(video || getMessageWebPageVideo(message) || isMessageDocumentVideo(message)); const isVideo = Boolean(video || getMessageWebPageVideo(message) || isMessageDocumentVideo(message));
const size = (video || audio || document)?.size!; const size = (video || audio || messageDocument)?.size!;
if (target === 'download') { if (target === 'download') {
if (IS_PROGRESSIVE_SUPPORTED && size > MAX_BUFFER_SIZE && !IS_OPFS_SUPPORTED) { if (IS_PROGRESSIVE_SUPPORTED && size > MAX_BUFFER_SIZE && !IS_OPFS_SUPPORTED) {
return ApiMediaFormat.DownloadUrl; return ApiMediaFormat.DownloadUrl;