WebPage: Render preview and audio document (#4345)
This commit is contained in:
parent
70dfa2e160
commit
f8bcd32865
@ -216,6 +216,39 @@ export function buildVideoFromDocument(document: GramJs.Document, isSpoiler?: bo
|
||||
};
|
||||
}
|
||||
|
||||
export function buildAudioFromDocument(document: GramJs.Document): ApiAudio | undefined {
|
||||
if (document instanceof GramJs.DocumentEmpty) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const {
|
||||
id, mimeType, size, attributes,
|
||||
} = document;
|
||||
|
||||
const audioAttributes = attributes
|
||||
.find((a: any): a is GramJs.DocumentAttributeAudio => a instanceof GramJs.DocumentAttributeAudio);
|
||||
|
||||
if (!audioAttributes) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const {
|
||||
duration,
|
||||
title,
|
||||
performer,
|
||||
} = audioAttributes;
|
||||
|
||||
return {
|
||||
id: String(id),
|
||||
mimeType,
|
||||
duration,
|
||||
fileName: getFilenameFromDocument(document, 'audio'),
|
||||
title,
|
||||
performer,
|
||||
size: size.toJSNumber(),
|
||||
};
|
||||
}
|
||||
|
||||
function buildVideo(media: GramJs.TypeMessageMedia): ApiVideo | undefined {
|
||||
if (
|
||||
!(media instanceof GramJs.MessageMediaDocument)
|
||||
@ -653,9 +686,13 @@ export function buildWebPage(media: GramJs.TypeMessageMedia): ApiWebPage | undef
|
||||
} = media.webpage;
|
||||
|
||||
let video;
|
||||
let audio;
|
||||
if (document instanceof GramJs.Document && document.mimeType.startsWith('video/')) {
|
||||
video = buildVideoFromDocument(document);
|
||||
}
|
||||
if (document instanceof GramJs.Document && document.mimeType.startsWith('audio/')) {
|
||||
audio = buildAudioFromDocument(document);
|
||||
}
|
||||
let story: ApiWebPageStoryData | undefined;
|
||||
const attributeStory = attributes
|
||||
?.find((a: any): a is GramJs.WebPageAttributeStory => a instanceof GramJs.WebPageAttributeStory);
|
||||
@ -683,8 +720,9 @@ export function buildWebPage(media: GramJs.TypeMessageMedia): ApiWebPage | undef
|
||||
'duration',
|
||||
]),
|
||||
photo: photo instanceof GramJs.Photo ? buildApiPhoto(photo) : undefined,
|
||||
document: !video && document ? buildApiDocument(document) : undefined,
|
||||
document: !video && !audio && document ? buildApiDocument(document) : undefined,
|
||||
video,
|
||||
audio,
|
||||
story,
|
||||
};
|
||||
}
|
||||
|
||||
@ -329,6 +329,7 @@ export interface ApiWebPage {
|
||||
title?: string;
|
||||
description?: string;
|
||||
photo?: ApiPhoto;
|
||||
audio?: ApiAudio;
|
||||
duration?: number;
|
||||
document?: ApiDocument;
|
||||
video?: ApiVideo;
|
||||
|
||||
@ -16,6 +16,7 @@ import {
|
||||
getMediaTransferState,
|
||||
getMessageMediaFormat,
|
||||
getMessageMediaHash,
|
||||
getMessageWebPageAudio,
|
||||
hasMessageTtl,
|
||||
isMessageLocal,
|
||||
isOwnMessage,
|
||||
@ -67,7 +68,7 @@ type OwnProps = {
|
||||
isTranscriptionError?: boolean;
|
||||
autoPlay?: boolean;
|
||||
onHideTranscription?: (isHidden: boolean) => void;
|
||||
onPlay: (messageId: number, chatId: string) => void;
|
||||
onPlay?: (messageId: number, chatId: string) => void;
|
||||
onPause?: NoneToVoidFunction;
|
||||
onReadMedia?: () => void;
|
||||
onCancelUpload?: () => void;
|
||||
@ -112,9 +113,10 @@ const Audio: FC<OwnProps> = ({
|
||||
|
||||
const {
|
||||
content: {
|
||||
audio, voice, video,
|
||||
audio: contentAudio, voice, video,
|
||||
}, isMediaUnread,
|
||||
} = message;
|
||||
const audio = contentAudio || getMessageWebPageAudio(message);
|
||||
const isVoice = Boolean(voice || video);
|
||||
const isSeeking = useRef<boolean>(false);
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
@ -145,7 +147,7 @@ const Audio: FC<OwnProps> = ({
|
||||
|
||||
const handleForcePlay = useLastCallback(() => {
|
||||
setIsActivated(true);
|
||||
onPlay(message.id, message.chatId);
|
||||
onPlay?.(message.id, message.chatId);
|
||||
});
|
||||
|
||||
const handleTrackChange = useLastCallback(() => {
|
||||
@ -228,7 +230,7 @@ const Audio: FC<OwnProps> = ({
|
||||
}
|
||||
|
||||
if (!isPlaying) {
|
||||
onPlay(message.id, message.chatId);
|
||||
onPlay?.(message.id, message.chatId);
|
||||
}
|
||||
|
||||
getActions().setAudioPlayerOrigin({ origin });
|
||||
|
||||
@ -642,7 +642,7 @@
|
||||
}
|
||||
|
||||
&.has-replies:not(.custom-shape),
|
||||
&.text {
|
||||
&.text:not(.web-page) {
|
||||
.media-inner,
|
||||
.Album {
|
||||
--border-bottom-left-radius: 0;
|
||||
|
||||
@ -1228,6 +1228,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
backgroundEmojiId={sender?.color?.backgroundEmojiId}
|
||||
shouldWarnAboutSvg={shouldWarnAboutSvg}
|
||||
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}
|
||||
onAudioPlay={handleAudioPlay}
|
||||
onMediaClick={handleMediaClick}
|
||||
onCancelMediaTransfer={handleCancelUpload}
|
||||
/>
|
||||
|
||||
@ -9,6 +9,10 @@
|
||||
border-radius: 0.25rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&.with-video {
|
||||
padding: 0.1875rem 0.375rem;
|
||||
}
|
||||
|
||||
&.with-document {
|
||||
--file-icon-border-color: var(--accent-background-color);
|
||||
@ -77,13 +81,15 @@
|
||||
|
||||
.media-inner {
|
||||
margin: 0 !important;
|
||||
margin-bottom: 0.375rem !important;
|
||||
|
||||
&,
|
||||
& img,
|
||||
& canvas,
|
||||
&.small-image img {
|
||||
border-radius: var(--border-radius-messages-small) !important;
|
||||
--border-top-left-radius: var(--border-radius-messages-small);
|
||||
--border-top-right-radius: var(--border-radius-messages-small);
|
||||
--border-bottom-left-radius: var(--border-radius-messages-small);
|
||||
--border-bottom-right-radius: var(--border-radius-messages-small);
|
||||
}
|
||||
|
||||
&.square-image {
|
||||
@ -100,11 +106,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.with-video .media-inner {
|
||||
margin-top: 0.5rem !important;
|
||||
margin-bottom: 1rem !important;
|
||||
}
|
||||
|
||||
.message-content:not(.has-reactions) & {
|
||||
margin-bottom: calc(var(--message-meta-height)) !important;
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import { getActions } from '../../../global';
|
||||
|
||||
import type { ApiMessage, ApiTypeStory } from '../../../api/types';
|
||||
import type { ObserveFn } from '../../../hooks/useIntersectionObserver';
|
||||
import type { ISettings } from '../../../types';
|
||||
import { AudioOrigin, type ISettings } from '../../../types';
|
||||
|
||||
import { getMessageWebPage } from '../../../global/helpers';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
@ -18,6 +18,7 @@ import useEnsureStory from '../../../hooks/useEnsureStory';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
|
||||
import Audio from '../../common/Audio';
|
||||
import Document from '../../common/Document';
|
||||
import EmojiIconBackground from '../../common/embedded/EmojiIconBackground';
|
||||
import SafeLink from '../../common/SafeLink';
|
||||
@ -47,8 +48,9 @@ type OwnProps = {
|
||||
story?: ApiTypeStory;
|
||||
shouldWarnAboutSvg?: boolean;
|
||||
autoLoadFileMaxSizeMb?: number;
|
||||
onMediaClick?: () => void;
|
||||
onCancelMediaTransfer?: () => void;
|
||||
onAudioPlay?: NoneToVoidFunction;
|
||||
onMediaClick?: NoneToVoidFunction;
|
||||
onCancelMediaTransfer?: NoneToVoidFunction;
|
||||
};
|
||||
|
||||
const WebPage: FC<OwnProps> = ({
|
||||
@ -68,6 +70,7 @@ const WebPage: FC<OwnProps> = ({
|
||||
shouldWarnAboutSvg,
|
||||
autoLoadFileMaxSizeMb,
|
||||
onMediaClick,
|
||||
onAudioPlay,
|
||||
onCancelMediaTransfer,
|
||||
}) => {
|
||||
const { openTelegramLink } = getActions();
|
||||
@ -103,6 +106,7 @@ const WebPage: FC<OwnProps> = ({
|
||||
description,
|
||||
photo,
|
||||
video,
|
||||
audio,
|
||||
type,
|
||||
document,
|
||||
} = webPage;
|
||||
@ -200,6 +204,17 @@ const WebPage: FC<OwnProps> = ({
|
||||
onCancelUpload={onCancelMediaTransfer}
|
||||
/>
|
||||
)}
|
||||
{!inPreview && audio && (
|
||||
<Audio
|
||||
theme={theme}
|
||||
message={message}
|
||||
origin={AudioOrigin.Inline}
|
||||
noAvatars={noAvatars}
|
||||
isDownloading={isDownloading}
|
||||
onPlay={onAudioPlay}
|
||||
onCancelUpload={onCancelMediaTransfer}
|
||||
/>
|
||||
)}
|
||||
{!inPreview && document && (
|
||||
<Document
|
||||
message={message}
|
||||
@ -211,6 +226,18 @@ const WebPage: FC<OwnProps> = ({
|
||||
shouldWarnAboutSvg={shouldWarnAboutSvg}
|
||||
/>
|
||||
)}
|
||||
{inPreview && displayUrl && !isArticle && (
|
||||
<div className="WebPage-text">
|
||||
{backgroundEmojiId && (
|
||||
<EmojiIconBackground
|
||||
emojiDocumentId={backgroundEmojiId}
|
||||
className="WebPage--background-icons"
|
||||
/>
|
||||
)}
|
||||
<p className="site-name">{displayUrl}</p>
|
||||
<p className="site-description">{lang('Chat.Empty.LinkPreview')}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{quickButtonLangKey && renderQuickButton(quickButtonLangKey)}
|
||||
</div>
|
||||
|
||||
@ -155,6 +155,10 @@ export function getMessageWebPageVideo(message: MediaContainer) {
|
||||
return getMessageWebPage(message)?.video;
|
||||
}
|
||||
|
||||
export function getMessageWebPageAudio(message: MediaContainer) {
|
||||
return getMessageWebPage(message)?.audio;
|
||||
}
|
||||
|
||||
export function getMessageDocumentVideo(message: MediaContainer) {
|
||||
return isMessageDocumentVideo(message) ? getMessageDocument(message) : undefined;
|
||||
}
|
||||
@ -218,8 +222,9 @@ export function getMessageMediaHash(
|
||||
const actionPhoto = getMessageActionPhoto(message);
|
||||
const messageVideo = video || getMessageWebPageVideo(message) || getMessageDocumentVideo(message);
|
||||
const messageDocument = document || getMessageWebPageDocument(message);
|
||||
const messageAudio = audio || getMessageWebPageAudio(message);
|
||||
|
||||
const content = actionPhoto || messagePhoto || messageVideo || sticker || audio || voice || messageDocument;
|
||||
const content = actionPhoto || messagePhoto || messageVideo || sticker || messageAudio || voice || messageDocument;
|
||||
if (!content) {
|
||||
return undefined;
|
||||
}
|
||||
@ -288,13 +293,13 @@ export function getMessageMediaHash(
|
||||
}
|
||||
}
|
||||
|
||||
if (audio) {
|
||||
if (messageAudio) {
|
||||
switch (target) {
|
||||
case 'micro':
|
||||
case 'pictogram':
|
||||
return getAudioHasCover(audio) ? `${base}?size=m` : undefined;
|
||||
return getAudioHasCover(messageAudio) ? `${base}?size=m` : undefined;
|
||||
case 'inline':
|
||||
return getVideoOrAudioBaseHash(audio, base);
|
||||
return getVideoOrAudioBaseHash(messageAudio, base);
|
||||
case 'download':
|
||||
return `${base}?download`;
|
||||
}
|
||||
@ -517,7 +522,7 @@ export function getMessageContentIds(
|
||||
|
||||
export function getMediaDuration(message: ApiMessage) {
|
||||
const { audio, voice, video } = getMessageContent(message);
|
||||
const media = audio || voice || video || getMessageWebPageVideo(message);
|
||||
const media = audio || voice || video || getMessageWebPageVideo(message) || getMessageWebPageAudio(message);
|
||||
if (!media) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user