Show extended preview inline keyboard button.

This commit is contained in:
John Preston 2022-09-12 16:40:19 +04:00
parent d2234d88b6
commit 379736a7d1
3 changed files with 71 additions and 23 deletions

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item.h" #include "history/history_item.h"
#include "history/history.h" #include "history/history.h"
#include "history/history_item_components.h"
#include "history/view/history_view_element.h" #include "history/view/history_view_element.h"
#include "history/view/history_view_cursor_state.h" #include "history/view/history_view_cursor_state.h"
#include "history/view/media/history_view_media_common.h" #include "history/view/media/history_view_media_common.h"
@ -53,6 +54,22 @@ ExtendedPreview::ExtendedPreview(
const auto item = parent->data(); const auto item = parent->data();
_caption = createCaption(item); _caption = createCaption(item);
_link = MakeInvoiceLink(item); _link = MakeInvoiceLink(item);
resolveButtonText();
}
void ExtendedPreview::resolveButtonText() {
if (const auto markup = _parent->data()->inlineReplyMarkup()) {
for (const auto &row : markup->data.rows) {
for (const auto &button : row) {
if (button.type == HistoryMessageMarkupButton::Type::Buy) {
_buttonText.setText(
st::semiboldTextStyle,
TextUtilities::SingleLine(button.text));
return;
}
}
}
}
} }
ExtendedPreview::~ExtendedPreview() { ExtendedPreview::~ExtendedPreview() {
@ -101,11 +118,14 @@ QSize ExtendedPreview::countOptimalSize() {
} }
const auto &preview = _invoice->extendedPreview; const auto &preview = _invoice->extendedPreview;
const auto dimensions = preview.dimensions; const auto dimensions = preview.dimensions;
const auto minWidth = std::clamp( const auto minWidth = std::min(
_parent->minWidthForMedia(), std::max({
(_parent->hasBubble() _parent->minWidthForMedia(),
? st::historyPhotoBubbleMinWidth (_parent->hasBubble()
: st::minPhotoSize), ? st::historyPhotoBubbleMinWidth
: st::minPhotoSize),
minWidthForButton(),
}),
st::maxMediaSize); st::maxMediaSize);
const auto scaled = CountDesiredMediaSize(dimensions); const auto scaled = CountDesiredMediaSize(dimensions);
auto maxWidth = qMax(scaled.width(), minWidth); auto maxWidth = qMax(scaled.width(), minWidth);
@ -129,11 +149,14 @@ QSize ExtendedPreview::countCurrentSize(int newWidth) {
const auto &preview = _invoice->extendedPreview; const auto &preview = _invoice->extendedPreview;
const auto dimensions = preview.dimensions; const auto dimensions = preview.dimensions;
const auto thumbMaxWidth = std::min(newWidth, st::maxMediaSize); const auto thumbMaxWidth = std::min(newWidth, st::maxMediaSize);
const auto minWidth = std::clamp( const auto minWidth = std::min(
_parent->minWidthForMedia(), std::max({
(_parent->hasBubble() _parent->minWidthForMedia(),
? st::historyPhotoBubbleMinWidth (_parent->hasBubble()
: st::minPhotoSize), ? st::historyPhotoBubbleMinWidth
: st::minPhotoSize),
minWidthForButton(),
}),
thumbMaxWidth); thumbMaxWidth);
const auto scaled = (preview.videoDuration >= 0) const auto scaled = (preview.videoDuration >= 0)
? CountMediaSize( ? CountMediaSize(
@ -163,6 +186,11 @@ QSize ExtendedPreview::countCurrentSize(int newWidth) {
return { newWidth, newHeight }; return { newWidth, newHeight };
} }
int ExtendedPreview::minWidthForButton() const {
return (st::msgBotKbButton.margin + st::msgBotKbButton.padding) * 2
+ _buttonText.maxWidth();
}
void ExtendedPreview::draw(Painter &p, const PaintContext &context) const { void ExtendedPreview::draw(Painter &p, const PaintContext &context) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return; if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
@ -193,7 +221,7 @@ void ExtendedPreview::draw(Painter &p, const PaintContext &context) const {
validateImageCache(rthumb.size(), roundRadius, roundCorners); validateImageCache(rthumb.size(), roundRadius, roundCorners);
p.drawImage(rthumb.topLeft(), _imageCache); p.drawImage(rthumb.topLeft(), _imageCache);
fillSpoilerMess(p, rthumb, roundRadius, roundCorners, context); fillSpoilerMess(p, rthumb, roundRadius, roundCorners, context);
paintButtonBackground(p, rthumb, context); paintButton(p, rthumb, context);
if (context.selected()) { if (context.selected()) {
Ui::FillComplexOverlayRect(p, st, rthumb, roundRadius, roundCorners); Ui::FillComplexOverlayRect(p, st, rthumb, roundRadius, roundCorners);
} }
@ -276,16 +304,24 @@ void ExtendedPreview::fillSpoilerMess(
_cornerCache); _cornerCache);
} }
void ExtendedPreview::paintButtonBackground( void ExtendedPreview::paintButton(
QPainter &p, Painter &p,
QRect outer, QRect outer,
const PaintContext &context) const { const PaintContext &context) const {
const auto st = context.st; const auto st = context.st;
const auto height = st::msgFileLayout.thumbSize; const auto &padding = st::extendedPreviewButtonPadding;
const auto width = height * 4; const auto margin = st::extendedPreviewButtonMargin;
const auto width = std::min(
_buttonText.maxWidth() + padding.left() + padding.right(),
outer.width() - 2 * margin);
const auto height = padding.top()
+ st::semiboldFont->height
+ padding.bottom();
const auto overlay = st->msgDateImgBg()->c; const auto overlay = st->msgDateImgBg()->c;
if (_buttonBackground.isNull() || _buttonBackgroundOverlay != overlay) { const auto ratio = style::DevicePixelRatio();
const auto ratio = style::DevicePixelRatio(); const auto size = QSize(width, height);
if (_buttonBackground.size() != size * ratio
|| _buttonBackgroundOverlay != overlay) {
if (_imageCache.width() < width * ratio if (_imageCache.width() < width * ratio
|| _imageCache.height() < height * ratio) { || _imageCache.height() < height * ratio) {
return; return;
@ -303,10 +339,16 @@ void ExtendedPreview::paintButtonBackground(
std::move(_buttonBackground), std::move(_buttonBackground),
Images::CornersMask(height / 2)); Images::CornersMask(height / 2));
} }
p.drawImage( const auto left = outer.x() + (outer.width() - width) / 2;
outer.x() + (outer.width() - width) / 2, const auto top = outer.y() + (outer.height() - height) / 2;
outer.y() + (outer.height() - height) / 2, p.drawImage(left, top, _buttonBackground);
_buttonBackground); p.setPen(st->msgDateImgFg()->c);
_buttonText.drawLeftElided(
p,
left + padding.left(),
top + padding.top(),
width - padding.left() - padding.right(),
outer.width());
} }
TextState ExtendedPreview::textState(QPoint point, StateRequest request) const { TextState ExtendedPreview::textState(QPoint point, StateRequest request) const {

View file

@ -70,6 +70,8 @@ public:
void unloadHeavyPart() override; void unloadHeavyPart() override;
private: private:
int minWidthForButton() const;
void resolveButtonText();
void ensureThumbnailRead() const; void ensureThumbnailRead() const;
QSize countOptimalSize() override; QSize countOptimalSize() override;
@ -85,8 +87,8 @@ private:
ImageRoundRadius radius, ImageRoundRadius radius,
RectParts corners) const; RectParts corners) const;
[[nodiscard]] QImage prepareImageCache(QSize outer) const; [[nodiscard]] QImage prepareImageCache(QSize outer) const;
void paintButtonBackground( void paintButton(
QPainter &p, Painter &p,
QRect outer, QRect outer,
const PaintContext &context) const; const PaintContext &context) const;
@ -106,6 +108,7 @@ private:
mutable QImage _cornerCache; mutable QImage _cornerCache;
mutable QImage _buttonBackground; mutable QImage _buttonBackground;
mutable QColor _buttonBackgroundOverlay; mutable QColor _buttonBackgroundOverlay;
mutable Ui::Text::String _buttonText;
mutable int _imageCacheRoundRadius : 4 = 0; mutable int _imageCacheRoundRadius : 4 = 0;
mutable int _imageCacheRoundCorners : 12 = 0; mutable int _imageCacheRoundCorners : 12 = 0;
mutable int _imageCacheInvalid : 1 = 0; mutable int _imageCacheInvalid : 1 = 0;

View file

@ -47,6 +47,9 @@ maxWallPaperWidth: 160px;
maxWallPaperHeight: 240px; maxWallPaperHeight: 240px;
historyThemeSize: size(272px, 176px); historyThemeSize: size(272px, 176px);
extendedPreviewButtonPadding: margins(20px, 10px, 20px, 10px);
extendedPreviewButtonMargin: 20px;
historyMinimalWidth: 380px; historyMinimalWidth: 380px;
reactionMenu: PopupMenu(defaultPopupMenu) { reactionMenu: PopupMenu(defaultPopupMenu) {