Web Page: Support media size (#5083)

This commit is contained in:
Alexander Zinchuk 2024-11-02 21:10:53 +04:00
parent 0eb0784165
commit 63ce255f4c
12 changed files with 56 additions and 5 deletions

View File

@ -761,6 +761,8 @@ export function buildWebPage(media: GramJs.TypeMessageMedia): ApiWebPage | undef
};
}
const mediaSize = media.forceSmallMedia ? 'small' : media.forceLargeMedia ? 'large' : undefined;
return {
mediaType: 'webpage',
id: Number(id),
@ -772,6 +774,7 @@ export function buildWebPage(media: GramJs.TypeMessageMedia): ApiWebPage | undef
'title',
'description',
'duration',
'hasLargeMedia',
]),
photo: photo instanceof GramJs.Photo ? buildApiPhoto(photo) : undefined,
document: !video && !audio && document ? buildApiDocument(document) : undefined,
@ -779,6 +782,7 @@ export function buildWebPage(media: GramJs.TypeMessageMedia): ApiWebPage | undef
audio,
story,
stickers,
mediaSize,
};
}

View File

@ -1,6 +1,7 @@
import BigInt from 'big-integer';
import { Api as GramJs } from '../../../lib/gramjs';
import type { WebPageMediaSize } from '../../../global/types';
import type { ThreadId } from '../../../types';
import type {
ApiAttachment,
@ -264,6 +265,8 @@ export function sendMessage(
wasDrafted,
isInvertedMedia,
effectId,
webPageMediaSize,
webPageUrl,
}: {
chat: ApiChat;
lastMessageId?: number;
@ -285,6 +288,8 @@ export function sendMessage(
wasDrafted?: boolean;
isInvertedMedia?: true;
effectId?: string;
webPageMediaSize?: WebPageMediaSize;
webPageUrl?: string;
},
onProgress?: ApiOnProgress,
) {
@ -366,6 +371,12 @@ export function sendMessage(
media = buildInputPoll(poll, randomId);
} else if (story) {
media = buildInputStory(story);
} else if (webPageUrl && webPageMediaSize) {
media = new GramJs.InputMediaWebPage({
url: webPageUrl,
forceLargeMedia: webPageMediaSize === 'large' ? true : undefined,
forceSmallMedia: webPageMediaSize === 'small' ? true : undefined,
});
} else if (contact) {
media = new GramJs.InputMediaContact({
phoneNumber: contact.phoneNumber,

View File

@ -1,3 +1,4 @@
import type { WebPageMediaSize } from '../../global/types';
import type { ThreadId } from '../../types';
import type { ApiWebDocument } from './bots';
import type { ApiGroupCall, PhoneCallAction } from './calls';
@ -476,6 +477,8 @@ export interface ApiWebPage {
video?: ApiVideo;
story?: ApiWebPageStoryData;
stickers?: ApiWebPageStickerData;
mediaSize?: WebPageMediaSize;
hasLargeMedia?: boolean;
}
export type ApiReplyInfo = ApiMessageReplyInfo | ApiStoryReplyInfo;

View File

@ -1063,6 +1063,8 @@ const Composer: FC<OwnProps & StateProps> = ({
shouldUpdateStickerSetOrder,
isInvertedMedia,
effectId,
webPageMediaSize: attachmentSettings.webPageMediaSize,
webPageUrl: hasWebPagePreview ? webPagePreview!.url : undefined,
});
}

View File

@ -5,7 +5,7 @@ import { getActions, withGlobal } from '../../../global';
import type {
ApiFormattedText, ApiMessage, ApiMessageEntityTextUrl, ApiWebPage,
} from '../../../api/types';
import type { GlobalState } from '../../../global/types';
import type { GlobalState, WebPageMediaSize } from '../../../global/types';
import type { ISettings, ThreadId } from '../../../types';
import type { Signal } from '../../../util/signals';
import { ApiMessageEntityTypes } from '../../../api/types';
@ -76,6 +76,7 @@ const WebPagePreview: FC<OwnProps & StateProps> = ({
const ref = useRef<HTMLDivElement>(null);
const isInvertedMedia = attachmentSettings.isInvertedMedia;
const isSmallerMedia = attachmentSettings.webPageMediaSize === 'small';
const detectLinkDebounced = useDebouncedResolver(() => {
const formattedText = parseHtmlAsFormattedText(getHtml());
@ -112,6 +113,8 @@ const WebPagePreview: FC<OwnProps & StateProps> = ({
}, [isDisabled, getHtml, noWebPage, webPagePreview]);
const { shouldRender, transitionClassNames } = useShowTransitionDeprecated(isShown);
const hasMediaSizeOptions = webPagePreview?.hasLargeMedia;
const renderingWebPage = useCurrentOrPrev(webPagePreview, true);
const handleClearWebpagePreview = useLastCallback(() => {
@ -144,6 +147,10 @@ const WebPagePreview: FC<OwnProps & StateProps> = ({
updateAttachmentSettings({ isInvertedMedia: value });
}
function updateIsLargerMedia(value?: WebPageMediaSize) {
updateAttachmentSettings({ webPageMediaSize: value });
}
if (!shouldRender || !renderingWebPage) {
return undefined;
}
@ -183,6 +190,19 @@ const WebPagePreview: FC<OwnProps & StateProps> = ({
</MenuItem>
)
}
{hasMediaSizeOptions && (
isSmallerMedia ? (
// eslint-disable-next-line react/jsx-no-bind
<MenuItem icon="expand" onClick={() => updateIsLargerMedia('large')}>
{lang('ChatInput.EditLink.LargerMedia')}
</MenuItem>
) : (
// eslint-disable-next-line react/jsx-no-bind
<MenuItem icon="collapse" onClick={() => updateIsLargerMedia('small')}>
{lang(('ChatInput.EditLink.SmallerMedia'))}
</MenuItem>
)
)}
<MenuItem
icon="delete"
// eslint-disable-next-line react/jsx-no-bind

View File

@ -205,7 +205,7 @@ const Photo = <T,>({
'media-inner',
!isUploading && !nonInteractive && 'interactive',
isSmall && 'small-image',
width === height && 'square-image',
(width === height || size === 'pictogram') && 'square-image',
height < MIN_MEDIA_HEIGHT && 'fix-min-height',
className,
);

View File

@ -157,6 +157,7 @@
margin-bottom: 0 !important;
img {
object-fit: cover;
width: 100%;
height: 100%;
}

View File

@ -129,6 +129,7 @@ const WebPage: FC<OwnProps> = ({
audio,
type,
document,
mediaSize,
} = webPage;
const isStory = type === WEBPAGE_STORY_TYPE;
const isExpiredStory = story && 'isDeleted' in story;
@ -145,7 +146,7 @@ const WebPage: FC<OwnProps> = ({
noAvatars,
isMobile,
});
isSquarePhoto = width === height;
isSquarePhoto = (width === height || mediaSize === 'small') && mediaSize !== 'large';
}
const isMediaInteractive = (photo || video) && onMediaClick && !isSquarePhoto;

View File

@ -19,7 +19,7 @@ import type {
import type { MessageKey } from '../../../util/keys/messageKey';
import type { RequiredGlobalActions } from '../../index';
import type {
ActionReturnType, ApiDraft, GlobalState, TabArgs,
ActionReturnType, ApiDraft, GlobalState, TabArgs, WebPageMediaSize,
} from '../../types';
import { MAIN_THREAD_ID, MESSAGE_DELETED } from '../../../api/types';
import { LoadMoreDirection, type ThreadId } from '../../../types';
@ -1455,6 +1455,7 @@ async function sendMessage<T extends GlobalState>(global: T, params: {
lastMessageId?: number;
isInvertedMedia?: true;
effectId?: string;
webPageMediaSize?: WebPageMediaSize;
}) {
let currentMessageKey: MessageKey | undefined;
const progressCallback = params.attachment ? (progress: number, messageKey: MessageKey) => {

View File

@ -491,7 +491,7 @@ addActionHandler('requestConfetti', (global, actions, payload): ActionReturnType
addActionHandler('updateAttachmentSettings', (global, actions, payload): ActionReturnType => {
const {
shouldCompress, shouldSendGrouped, isInvertedMedia,
shouldCompress, shouldSendGrouped, isInvertedMedia, webPageMediaSize,
} = payload;
return {
@ -500,6 +500,7 @@ addActionHandler('updateAttachmentSettings', (global, actions, payload): ActionR
shouldCompress: shouldCompress ?? global.attachmentSettings.shouldCompress,
shouldSendGrouped: shouldSendGrouped ?? global.attachmentSettings.shouldSendGrouped,
isInvertedMedia,
webPageMediaSize,
},
};
});

View File

@ -142,6 +142,7 @@ export const INITIAL_GLOBAL_STATE: GlobalState = {
shouldCompress: true,
shouldSendGrouped: true,
isInvertedMedia: undefined,
webPageMediaSize: undefined,
},
scheduledMessages: {

View File

@ -280,6 +280,8 @@ type ConfettiParams = OptionalCombine<{
height?: number;
}>;
export type WebPageMediaSize = 'large' | 'small';
export type TabState = {
id: number;
isBlurred?: boolean;
@ -920,6 +922,7 @@ export type GlobalState = {
shouldCompress: boolean;
shouldSendGrouped: boolean;
isInvertedMedia?: true;
webPageMediaSize?: WebPageMediaSize;
};
attachMenu: {
@ -1632,6 +1635,8 @@ export interface ActionPayloads {
isReaction?: true; // Reaction to the story are sent in the form of a message
isInvertedMedia?: true;
effectId?: string;
webPageMediaSize?: WebPageMediaSize;
webPageUrl?: string;
} & WithTabId;
sendInviteMessages: {
chatId: string;
@ -3189,6 +3194,7 @@ export interface ActionPayloads {
shouldCompress?: boolean;
shouldSendGrouped?: boolean;
isInvertedMedia?: true;
webPageMediaSize?: WebPageMediaSize;
};
saveEffectInDraft: {