Message / Invoice: Better layout (#1834)

This commit is contained in:
Alexander Zinchuk 2022-04-19 15:12:33 +02:00
parent 733d84c781
commit 0198f5f4d8
9 changed files with 80 additions and 13 deletions

View File

@ -712,10 +712,22 @@ export function buildInvoice(media: GramJs.MessageMediaInvoice): ApiInvoice {
description: text, title, photo, test, totalAmount, currency, receiptMsgId, description: text, title, photo, test, totalAmount, currency, receiptMsgId,
} = media; } = media;
const imageAttribute = photo?.attributes
.find((a: any): a is GramJs.DocumentAttributeImageSize => a instanceof GramJs.DocumentAttributeImageSize);
let photoWidth: number | undefined;
let photoHeight: number | undefined;
if (imageAttribute) {
photoWidth = imageAttribute.w;
photoHeight = imageAttribute.h;
}
return { return {
text, text,
title, title,
photoUrl: photo?.url, photoUrl: photo?.url,
photoWidth,
photoHeight,
receiptMsgId, receiptMsgId,
amount: Number(totalAmount), amount: Number(totalAmount),
currency, currency,

View File

@ -137,6 +137,8 @@ export interface ApiInvoice {
text: string; text: string;
title: string; title: string;
photoUrl?: string; photoUrl?: string;
photoWidth?: number;
photoHeight?: number;
amount: number; amount: number;
currency: string; currency: string;
receiptMsgId?: number; receiptMsgId?: number;

View File

@ -8,13 +8,14 @@
position: relative; position: relative;
&.has-image { &.has-image {
.invoice-image { margin: 1rem -0.5rem -0.375rem;
max-width: 100%;
height: 20rem;
@media (max-width: 600px) { .invoice-image {
height: 10rem; width: 100%;
} max-height: 30rem;
object-fit: cover;
border-bottom-left-radius: var(--border-bottom-left-radius);
border-bottom-right-radius: var(--border-bottom-right-radius);
} }
.description-text { .description-text {
@ -22,9 +23,9 @@
top: 0; top: 0;
padding: 0.25rem 0.5rem; padding: 0.25rem 0.5rem;
margin: 0.25rem; margin: 0.25rem;
background-color: rgba(90, 110, 70, 0.6); background-color: rgba(0, 0, 0, 0.2);
border-radius: var(--border-radius-messages-small); border-radius: var(--border-radius-messages-small);
color: var(--color-text); color: var(--color-white);
font-weight: 500; font-weight: 500;
span { span {

View File

@ -1,21 +1,37 @@
import React, { FC, memo } from '../../../lib/teact/teact'; import React, {
FC, memo, useLayoutEffect, useRef,
} from '../../../lib/teact/teact';
import { ApiMessage } from '../../../api/types'; import { ApiMessage } from '../../../api/types';
import { ISettings } from '../../../types';
import { CUSTOM_APPENDIX_ATTRIBUTE } from '../../../config';
import { getMessageInvoice } from '../../../global/helpers'; import { getMessageInvoice } from '../../../global/helpers';
import { formatCurrency } from '../../../util/formatCurrency'; import { formatCurrency } from '../../../util/formatCurrency';
import renderText from '../../common/helpers/renderText'; import renderText from '../../common/helpers/renderText';
import getCustomAppendixBg from './helpers/getCustomAppendixBg';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import './Invoice.scss'; import './Invoice.scss';
type OwnProps = { type OwnProps = {
message: ApiMessage; message: ApiMessage;
shouldAffectAppendix?: boolean;
isInSelectMode?: boolean;
isSelected?: boolean;
theme: ISettings['theme'];
}; };
const Invoice: FC<OwnProps> = ({ const Invoice: FC<OwnProps> = ({
message, message,
shouldAffectAppendix,
isInSelectMode,
isSelected,
theme,
}) => { }) => {
// eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLDivElement>(null);
const lang = useLang(); const lang = useLang();
const invoice = getMessageInvoice(message); const invoice = getMessageInvoice(message);
@ -26,10 +42,30 @@ const Invoice: FC<OwnProps> = ({
currency, currency,
isTest, isTest,
photoUrl, photoUrl,
photoWidth,
photoHeight,
} = invoice!; } = invoice!;
useLayoutEffect(() => {
if (!shouldAffectAppendix) {
return;
}
const contentEl = ref.current!.closest<HTMLDivElement>('.message-content')!;
if (photoUrl) {
getCustomAppendixBg(photoUrl, false, isInSelectMode, isSelected, theme).then((appendixBg) => {
contentEl.style.setProperty('--appendix-bg', appendixBg);
contentEl.setAttribute(CUSTOM_APPENDIX_ATTRIBUTE, '');
});
}
}, [shouldAffectAppendix, photoUrl, isInSelectMode, isSelected, theme]);
const photoStyle = photoHeight && photoWidth ? `aspect-ratio: ${photoWidth / photoHeight};` : undefined;
return ( return (
<div <div
ref={ref}
className="Invoice" className="Invoice"
> >
{title && ( {title && (
@ -44,6 +80,8 @@ const Invoice: FC<OwnProps> = ({
className="invoice-image" className="invoice-image"
src={photoUrl} src={photoUrl}
alt="" alt=""
style={photoStyle}
crossOrigin="anonymous"
/> />
)} )}
<p className="description-text"> <p className="description-text">

View File

@ -133,7 +133,7 @@
&.has-inline-buttons { &.has-inline-buttons {
.message-content { .message-content {
border-bottom-right-radius: var(--border-radius-messages-small); --border-bottom-right-radius: var(--border-radius-messages-small);
} }
} }

View File

@ -797,7 +797,15 @@ const Message: FC<OwnProps & StateProps> = ({
theme={theme} theme={theme}
/> />
)} )}
{invoice && <Invoice message={message} />} {invoice && (
<Invoice
message={message}
shouldAffectAppendix={hasCustomAppendix}
isInSelectMode={isInSelectMode}
isSelected={isSelected}
theme={theme}
/>
)}
{location && ( {location && (
<Location <Location
message={message} message={message}

View File

@ -60,7 +60,8 @@
} }
.media:not(.text) &, .media:not(.text) &,
.Message .custom-shape & { .Message .custom-shape &,
.Message .invoice & {
background: rgba(0, 0, 0, 0.2); background: rgba(0, 0, 0, 0.2);
--color-accent-own: white; --color-accent-own: white;
--color-accent: white; --color-accent: white;

View File

@ -33,7 +33,7 @@ export function buildContentClassName(
} = {}, } = {},
) { ) {
const { const {
text, photo, video, audio, voice, document, poll, webPage, contact, location, text, photo, video, audio, voice, document, poll, webPage, contact, location, invoice,
} = getMessageContent(message); } = getMessageContent(message);
const classNames = ['message-content']; const classNames = ['message-content'];
@ -82,6 +82,10 @@ export function buildContentClassName(
} }
} }
if (invoice) {
classNames.push('invoice');
}
if (asForwarded) { if (asForwarded) {
classNames.push('is-forwarded'); classNames.push('is-forwarded');
} }

View File

@ -23,6 +23,7 @@ export default function getCustomAppendixBg(
async function getAppendixColorFromImage(src: string, isOwn: boolean) { async function getAppendixColorFromImage(src: string, isOwn: boolean) {
const img = new Image(); const img = new Image();
img.src = src; img.src = src;
img.crossOrigin = 'anonymous';
if (!img.width) { if (!img.width) {
await new Promise((resolve) => { await new Promise((resolve) => {