mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Display nice price tag, handle pay in albums.
This commit is contained in:
parent
a9bd7803e6
commit
5f8da27c86
9 changed files with 288 additions and 46 deletions
|
@ -4212,6 +4212,67 @@ void ApiWrap::sendMediaWithRandomId(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiWrap::sendMultiPaidMedia(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
const QVector<MTPInputMedia> &medias,
|
||||||
|
Api::SendOptions options,
|
||||||
|
uint64 randomId,
|
||||||
|
Fn<void(bool)> done) {
|
||||||
|
Expects(options.price > 0);
|
||||||
|
|
||||||
|
const auto history = item->history();
|
||||||
|
const auto replyTo = item->replyTo();
|
||||||
|
|
||||||
|
auto caption = item->originalText();
|
||||||
|
TextUtilities::Trim(caption);
|
||||||
|
auto sentEntities = Api::EntitiesToMTP(
|
||||||
|
_session,
|
||||||
|
caption.entities,
|
||||||
|
Api::ConvertOption::SkipLocal);
|
||||||
|
|
||||||
|
using Flag = MTPmessages_SendMedia::Flag;
|
||||||
|
const auto flags = Flag(0)
|
||||||
|
| (replyTo ? Flag::f_reply_to : Flag(0))
|
||||||
|
| (ShouldSendSilent(history->peer, options)
|
||||||
|
? Flag::f_silent
|
||||||
|
: Flag(0))
|
||||||
|
| (!sentEntities.v.isEmpty() ? Flag::f_entities : Flag(0))
|
||||||
|
| (options.scheduled ? Flag::f_schedule_date : Flag(0))
|
||||||
|
| (options.sendAs ? Flag::f_send_as : Flag(0))
|
||||||
|
| (options.shortcutId ? Flag::f_quick_reply_shortcut : Flag(0))
|
||||||
|
| (options.effectId ? Flag::f_effect : Flag(0))
|
||||||
|
| (options.invertCaption ? Flag::f_invert_media : Flag(0));
|
||||||
|
|
||||||
|
auto &histories = history->owner().histories();
|
||||||
|
const auto peer = history->peer;
|
||||||
|
const auto itemId = item->fullId();
|
||||||
|
histories.sendPreparedMessage(
|
||||||
|
history,
|
||||||
|
replyTo,
|
||||||
|
randomId,
|
||||||
|
Data::Histories::PrepareMessage<MTPmessages_SendMedia>(
|
||||||
|
MTP_flags(flags),
|
||||||
|
peer->input,
|
||||||
|
Data::Histories::ReplyToPlaceholder(),
|
||||||
|
MTP_inputMediaPaidMedia(
|
||||||
|
MTP_long(options.price),
|
||||||
|
MTP_vector<MTPInputMedia>(medias)),
|
||||||
|
MTP_string(caption.text),
|
||||||
|
MTP_long(randomId),
|
||||||
|
MTPReplyMarkup(),
|
||||||
|
sentEntities,
|
||||||
|
MTP_int(options.scheduled),
|
||||||
|
(options.sendAs ? options.sendAs->input : MTP_inputPeerEmpty()),
|
||||||
|
Data::ShortcutIdToMTP(_session, options.shortcutId),
|
||||||
|
MTP_long(options.effectId)
|
||||||
|
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||||
|
if (done) done(true);
|
||||||
|
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
||||||
|
if (done) done(false);
|
||||||
|
sendMessageFail(error, peer, randomId, itemId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ApiWrap::sendAlbumWithUploaded(
|
void ApiWrap::sendAlbumWithUploaded(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
const MessageGroupId &groupId,
|
const MessageGroupId &groupId,
|
||||||
|
@ -4266,7 +4327,7 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
|
||||||
_sendingAlbums.remove(groupId);
|
_sendingAlbums.remove(groupId);
|
||||||
return;
|
return;
|
||||||
} else if (medias.size() < 2) {
|
} else if (medias.size() < 2) {
|
||||||
const auto &single = medias.front().c_inputSingleMedia();
|
const auto &single = medias.front().data();
|
||||||
sendMediaWithRandomId(
|
sendMediaWithRandomId(
|
||||||
sample,
|
sample,
|
||||||
single.vmedia(),
|
single.vmedia(),
|
||||||
|
@ -4274,6 +4335,19 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
|
||||||
single.vrandom_id().v);
|
single.vrandom_id().v);
|
||||||
_sendingAlbums.remove(groupId);
|
_sendingAlbums.remove(groupId);
|
||||||
return;
|
return;
|
||||||
|
} else if (album->options.price > 0) {
|
||||||
|
const auto &single = medias.front().data();
|
||||||
|
auto list = medias | ranges::view::transform([](
|
||||||
|
const MTPInputSingleMedia &media) {
|
||||||
|
return MTPInputMedia(media.data().vmedia());
|
||||||
|
}) | ranges::to<QVector<MTPInputMedia>>();
|
||||||
|
sendMultiPaidMedia(
|
||||||
|
sample,
|
||||||
|
std::move(list),
|
||||||
|
album->options,
|
||||||
|
single.vrandom_id().v);
|
||||||
|
_sendingAlbums.remove(groupId);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
const auto history = sample->history();
|
const auto history = sample->history();
|
||||||
const auto replyTo = sample->replyTo();
|
const auto replyTo = sample->replyTo();
|
||||||
|
|
|
@ -545,6 +545,12 @@ private:
|
||||||
Api::SendOptions options,
|
Api::SendOptions options,
|
||||||
uint64 randomId,
|
uint64 randomId,
|
||||||
Fn<void(bool)> done = nullptr);
|
Fn<void(bool)> done = nullptr);
|
||||||
|
void sendMultiPaidMedia(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
const QVector<MTPInputMedia> &medias,
|
||||||
|
Api::SendOptions options,
|
||||||
|
uint64 randomId,
|
||||||
|
Fn<void(bool)> done = nullptr);
|
||||||
|
|
||||||
void getTopPromotionDelayed(TimeId now, TimeId next);
|
void getTopPromotionDelayed(TimeId now, TimeId next);
|
||||||
void topPromotionDone(const MTPhelp_PromoData &proxy);
|
void topPromotionDone(const MTPhelp_PromoData &proxy);
|
||||||
|
|
|
@ -680,9 +680,11 @@ bool SendFilesBox::hasSpoilerMenu() const {
|
||||||
|
|
||||||
bool SendFilesBox::canChangePrice() const {
|
bool SendFilesBox::canChangePrice() const {
|
||||||
const auto way = _sendWay.current();
|
const auto way = _sendWay.current();
|
||||||
return _list.canChangePrice(
|
return _captionToPeer
|
||||||
way.groupFiles() && way.sendImagesAsPhotos(),
|
&& _captionToPeer->isBroadcast()
|
||||||
way.sendImagesAsPhotos());
|
&& _list.canChangePrice(
|
||||||
|
way.groupFiles() && way.sendImagesAsPhotos(),
|
||||||
|
way.sendImagesAsPhotos());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendFilesBox::applyBlockChanges() {
|
void SendFilesBox::applyBlockChanges() {
|
||||||
|
@ -754,6 +756,7 @@ void SendFilesBox::refreshPriceTag() {
|
||||||
raw,
|
raw,
|
||||||
tr::lng_paid_price(lt_price, std::move(price)),
|
tr::lng_paid_price(lt_price, std::move(price)),
|
||||||
st::paidTagLabel);
|
st::paidTagLabel);
|
||||||
|
label->show();
|
||||||
label->sizeValue() | rpl::start_with_next([=](QSize size) {
|
label->sizeValue() | rpl::start_with_next([=](QSize size) {
|
||||||
const auto inner = QRect(QPoint(), size);
|
const auto inner = QRect(QPoint(), size);
|
||||||
const auto rect = inner.marginsAdded(st::paidTagPadding);
|
const auto rect = inner.marginsAdded(st::paidTagPadding);
|
||||||
|
@ -833,6 +836,7 @@ void SendFilesBox::initSendWay() {
|
||||||
block.setSendWay(value);
|
block.setSendWay(value);
|
||||||
}
|
}
|
||||||
refreshButtons();
|
refreshButtons();
|
||||||
|
refreshPriceTag();
|
||||||
if (was != hidden()) {
|
if (was != hidden()) {
|
||||||
updateBoxSize();
|
updateBoxSize();
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
|
|
@ -1186,7 +1186,9 @@ base::unique_qptr<Ui::RpWidget> PremiumRequiredSendRestriction(
|
||||||
const auto margins = (st.textMargins + st.placeholderMargins);
|
const auto margins = (st.textMargins + st.placeholderMargins);
|
||||||
const auto available = width - margins.left() - margins.right();
|
const auto available = width - margins.left() - margins.right();
|
||||||
label->resizeToWidth(available);
|
label->resizeToWidth(available);
|
||||||
label->moveToLeft(margins.left(), margins.top(), width);
|
const auto height = label->height() + link->height();
|
||||||
|
const auto top = (raw->height() - height) / 2;
|
||||||
|
label->moveToLeft(margins.left(), top, width);
|
||||||
link->move(
|
link->move(
|
||||||
(width - link->width()) / 2,
|
(width - link->width()) / 2,
|
||||||
label->y() + label->height());
|
label->y() + label->height());
|
||||||
|
|
|
@ -223,6 +223,20 @@ public:
|
||||||
QPoint point,
|
QPoint point,
|
||||||
StateRequest request) const;
|
StateRequest request) const;
|
||||||
|
|
||||||
|
virtual void drawPriceTag(
|
||||||
|
Painter &p,
|
||||||
|
QRect rthumb,
|
||||||
|
const PaintContext &context,
|
||||||
|
Fn<QImage()> generateBackground) const {
|
||||||
|
Unexpected("Price tag method call.");
|
||||||
|
}
|
||||||
|
[[nodiscard]] virtual ClickHandlerPtr priceTagLink() const {
|
||||||
|
Unexpected("Price tag method call.");
|
||||||
|
}
|
||||||
|
[[nodiscard]] virtual QImage priceTagBackground() const {
|
||||||
|
Unexpected("Price tag method call.");
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] virtual bool animating() const {
|
[[nodiscard]] virtual bool animating() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "storage/storage_shared_media.h"
|
#include "storage/storage_shared_media.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
#include "media/streaming/media_streaming_utility.h"
|
||||||
#include "ui/grouped_layout.h"
|
#include "ui/grouped_layout.h"
|
||||||
#include "ui/chat/chat_style.h"
|
#include "ui/chat/chat_style.h"
|
||||||
#include "ui/chat/message_bubble.h"
|
#include "ui/chat/message_bubble.h"
|
||||||
|
@ -290,6 +291,42 @@ QMargins GroupedMedia::groupedPadding() const {
|
||||||
(normal.bottom() - grouped.bottom()) + addToBottom);
|
(normal.bottom() - grouped.bottom()) + addToBottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Media *GroupedMedia::lookupUnpaidMedia() const {
|
||||||
|
if (_parts.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const auto media = _parts.front().content.get();
|
||||||
|
const auto photo = media ? media->getPhoto() : nullptr;
|
||||||
|
return (photo && photo->extendedMediaPreview()) ? media : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage GroupedMedia::generatePriceTagBackground(QRect full) const {
|
||||||
|
const auto ratio = style::DevicePixelRatio();
|
||||||
|
auto result = QImage(
|
||||||
|
full.size() * ratio,
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
result.setDevicePixelRatio(ratio);
|
||||||
|
auto p = QPainter(&result);
|
||||||
|
const auto shift = -full.topLeft();
|
||||||
|
const auto skip1 = st::historyGroupSkip / 2;
|
||||||
|
const auto skip2 = st::historyGroupSkip - skip1;
|
||||||
|
for (const auto &part : _parts) {
|
||||||
|
auto background = part.content->priceTagBackground();
|
||||||
|
const auto extended = part.geometry.translated(shift).marginsAdded(
|
||||||
|
{ skip1, skip1, skip2, skip2 });
|
||||||
|
if (background.isNull()) {
|
||||||
|
p.fillRect(extended, Qt::black);
|
||||||
|
} else {
|
||||||
|
p.drawImage(extended, background);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.end();
|
||||||
|
|
||||||
|
return ::Media::Streaming::PrepareBlurredBackground(
|
||||||
|
full.size(),
|
||||||
|
std::move(result));
|
||||||
|
}
|
||||||
|
|
||||||
void GroupedMedia::drawHighlight(
|
void GroupedMedia::drawHighlight(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
const PaintContext &context,
|
const PaintContext &context,
|
||||||
|
@ -351,6 +388,8 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
|
||||||
? Ui::BubbleRounding{ kSmall, kSmall, kSmall, kSmall }
|
? Ui::BubbleRounding{ kSmall, kSmall, kSmall, kSmall }
|
||||||
: adjustedBubbleRounding();
|
: adjustedBubbleRounding();
|
||||||
auto highlight = context.highlight.range;
|
auto highlight = context.highlight.range;
|
||||||
|
const auto unpaid = lookupUnpaidMedia();
|
||||||
|
auto fullRect = QRect();
|
||||||
const auto subpartHighlight = IsSubGroupSelection(highlight);
|
const auto subpartHighlight = IsSubGroupSelection(highlight);
|
||||||
for (auto i = 0, count = int(_parts.size()); i != count; ++i) {
|
for (auto i = 0, count = int(_parts.size()); i != count; ++i) {
|
||||||
const auto &part = _parts[i];
|
const auto &part = _parts[i];
|
||||||
|
@ -390,11 +429,20 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
|
||||||
if (!part.cache.isNull()) {
|
if (!part.cache.isNull()) {
|
||||||
nowCache = true;
|
nowCache = true;
|
||||||
}
|
}
|
||||||
|
if (unpaid) {
|
||||||
|
fullRect = fullRect.united(part.geometry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (nowCache && !wasCache) {
|
if (nowCache && !wasCache) {
|
||||||
history()->owner().registerHeavyViewPart(_parent);
|
history()->owner().registerHeavyViewPart(_parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unpaid) {
|
||||||
|
unpaid->drawPriceTag(p, fullRect, context, [&] {
|
||||||
|
return generatePriceTagBackground(fullRect);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// date
|
// date
|
||||||
if (_parent->media() == this && (!_parent->hasBubble() || isBubbleBottom())) {
|
if (_parent->media() == this && (!_parent->hasBubble() || isBubbleBottom())) {
|
||||||
auto fullRight = width();
|
auto fullRight = width();
|
||||||
|
@ -455,6 +503,11 @@ PointState GroupedMedia::pointState(QPoint point) const {
|
||||||
TextState GroupedMedia::textState(QPoint point, StateRequest request) const {
|
TextState GroupedMedia::textState(QPoint point, StateRequest request) const {
|
||||||
const auto groupPadding = groupedPadding();
|
const auto groupPadding = groupedPadding();
|
||||||
auto result = getPartState(point - QPoint(0, groupPadding.top()), request);
|
auto result = getPartState(point - QPoint(0, groupPadding.top()), request);
|
||||||
|
if (const auto unpaid = lookupUnpaidMedia()) {
|
||||||
|
if (QRect(0, 0, width(), height()).contains(point)) {
|
||||||
|
result.link = unpaid->priceTagLink();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (_parent->media() == this && (!_parent->hasBubble() || isBubbleBottom())) {
|
if (_parent->media() == this && (!_parent->hasBubble() || isBubbleBottom())) {
|
||||||
auto fullRight = width();
|
auto fullRight = width();
|
||||||
auto fullBottom = height();
|
auto fullBottom = height();
|
||||||
|
|
|
@ -149,6 +149,9 @@ private:
|
||||||
RectParts sides) const;
|
RectParts sides) const;
|
||||||
[[nodiscard]] QMargins groupedPadding() const;
|
[[nodiscard]] QMargins groupedPadding() const;
|
||||||
|
|
||||||
|
[[nodiscard]] Media *lookupUnpaidMedia() const;
|
||||||
|
[[nodiscard]] QImage generatePriceTagBackground(QRect full) const;
|
||||||
|
|
||||||
mutable std::optional<HistoryItem*> _captionItem;
|
mutable std::optional<HistoryItem*> _captionItem;
|
||||||
std::vector<Part> _parts;
|
std::vector<Part> _parts;
|
||||||
Mode _mode = Mode::Grid;
|
Mode _mode = Mode::Grid;
|
||||||
|
|
|
@ -60,6 +60,14 @@ struct Photo::Streamed {
|
||||||
QImage roundingMask;
|
QImage roundingMask;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Photo::PriceTag {
|
||||||
|
uint64 price = 0;
|
||||||
|
QImage cache;
|
||||||
|
QColor darken;
|
||||||
|
QColor fg;
|
||||||
|
ClickHandlerPtr link;
|
||||||
|
};
|
||||||
|
|
||||||
Photo::Streamed::Streamed(
|
Photo::Streamed::Streamed(
|
||||||
std::shared_ptr<::Media::Streaming::Document> shared)
|
std::shared_ptr<::Media::Streaming::Document> shared)
|
||||||
: instance(std::move(shared), nullptr) {
|
: instance(std::move(shared), nullptr) {
|
||||||
|
@ -281,8 +289,8 @@ void Photo::draw(Painter &p, const PaintContext &context) const {
|
||||||
const auto st = context.st;
|
const auto st = context.st;
|
||||||
const auto sti = context.imageStyle();
|
const auto sti = context.imageStyle();
|
||||||
const auto preview = _data->extendedMediaPreview();
|
const auto preview = _data->extendedMediaPreview();
|
||||||
auto loaded = preview || _dataMedia->loaded();
|
const auto loaded = preview || _dataMedia->loaded();
|
||||||
auto displayLoading = !preview && _data->displayLoading();
|
const auto displayLoading = !preview && _data->displayLoading();
|
||||||
|
|
||||||
auto inWebPage = (_parent->media() != this);
|
auto inWebPage = (_parent->media() != this);
|
||||||
auto paintx = 0, painty = 0, paintw = width(), painth = height();
|
auto paintx = 0, painty = 0, paintw = width(), painth = height();
|
||||||
|
@ -370,7 +378,9 @@ void Photo::draw(Painter &p, const PaintContext &context) const {
|
||||||
_animation->radial.draw(p, rinner, st::msgFileRadialLine, sti->historyFileThumbRadialFg);
|
_animation->radial.draw(p, rinner, st::msgFileRadialLine, sti->historyFileThumbRadialFg);
|
||||||
}
|
}
|
||||||
} else if (preview) {
|
} else if (preview) {
|
||||||
paintPriceTag(p, rthumb);
|
drawPriceTag(p, rthumb, context, [&] {
|
||||||
|
return _spoiler ? _spoiler->background : QImage();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (showEnlarge) {
|
if (showEnlarge) {
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
@ -403,41 +413,93 @@ void Photo::draw(Painter &p, const PaintContext &context) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Photo::paintPriceTag(Painter &p, QRect rthumb) const {
|
void Photo::setupPriceTag() const {
|
||||||
const auto media = parent()->data()->media();
|
const auto media = parent()->data()->media();
|
||||||
const auto invoice = media ? media->invoice() : nullptr;
|
const auto invoice = media ? media->invoice() : nullptr;
|
||||||
const auto price = invoice->isPaidMedia ? invoice->amount : 0;
|
const auto price = invoice->isPaidMedia ? invoice->amount : 0;
|
||||||
if (!price) {
|
if (!price) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_priceTag = std::make_unique<PriceTag>();
|
||||||
|
_priceTag->price = price;
|
||||||
|
}
|
||||||
|
|
||||||
auto text = Ui::Text::String();
|
void Photo::drawPriceTag(
|
||||||
text.setText(
|
Painter &p,
|
||||||
st::semiboldTextStyle,
|
QRect rthumb,
|
||||||
tr::lng_paid_price(
|
const PaintContext &context,
|
||||||
tr::now,
|
Fn<QImage()> generateBackground) const {
|
||||||
lt_price,
|
if (!_priceTag) {
|
||||||
QChar(0x2B50) + Lang::FormatCountDecimal(invoice->amount)));
|
setupPriceTag();
|
||||||
const auto width = text.maxWidth();
|
if (!_priceTag) {
|
||||||
const auto inner = QRect(0, 0, width, text.minHeight());
|
return;
|
||||||
const auto outer = inner.marginsAdded(st::paidTagPadding);
|
}
|
||||||
const auto size = outer.size();
|
}
|
||||||
|
const auto st = context.st;
|
||||||
|
const auto darken = st->msgDateImgBg()->c;
|
||||||
|
const auto fg = st->msgDateImgFg()->c;
|
||||||
|
if (_priceTag->cache.isNull()
|
||||||
|
|| _priceTag->darken != darken
|
||||||
|
|| _priceTag->fg != fg) {
|
||||||
|
auto bg = generateBackground();
|
||||||
|
if (bg.isNull()) {
|
||||||
|
bg = QImage(2, 2, QImage::Format_ARGB32_Premultiplied);
|
||||||
|
bg.fill(Qt::black);
|
||||||
|
}
|
||||||
|
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
auto text = Ui::Text::String();
|
||||||
p.setBrush(st::toastBg);
|
text.setText(
|
||||||
p.setPen(Qt::NoPen);
|
st::semiboldTextStyle,
|
||||||
|
tr::lng_paid_price(
|
||||||
|
tr::now,
|
||||||
|
lt_price,
|
||||||
|
QChar(0x2B50) + Lang::FormatCountDecimal(_priceTag->price)));
|
||||||
|
const auto width = text.maxWidth();
|
||||||
|
const auto inner = QRect(0, 0, width, text.minHeight());
|
||||||
|
const auto outer = inner.marginsAdded(st::paidTagPadding);
|
||||||
|
const auto size = outer.size();
|
||||||
|
const auto radius = std::min(size.width(), size.height()) / 2;
|
||||||
|
const auto ratio = style::DevicePixelRatio();
|
||||||
|
auto cache = QImage(
|
||||||
|
size * ratio,
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
cache.setDevicePixelRatio(ratio);
|
||||||
|
cache.fill(Qt::black);
|
||||||
|
auto p = Painter(&cache);
|
||||||
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
p.drawImage(
|
||||||
|
QRect(
|
||||||
|
(size.width() - rthumb.width()) / 2,
|
||||||
|
(size.height() - rthumb.height()) / 2,
|
||||||
|
rthumb.width(),
|
||||||
|
rthumb.height()),
|
||||||
|
bg);
|
||||||
|
p.fillRect(QRect(QPoint(), size), darken);
|
||||||
|
p.setPen(fg);
|
||||||
|
text.draw(p, -outer.x(), -outer.y(), width);
|
||||||
|
p.end();
|
||||||
|
|
||||||
const auto radius = std::min(size.width(), size.height()) / 2.;
|
_priceTag->darken = darken;
|
||||||
const auto rect = QRect(
|
_priceTag->fg = fg;
|
||||||
rthumb.x() + (rthumb.width() - size.width()) / 2,
|
_priceTag->cache = Images::Round(
|
||||||
rthumb.y() + (rthumb.height() - size.height()) / 2,
|
std::move(cache),
|
||||||
size.width(),
|
Images::CornersMask(radius));
|
||||||
size.height());
|
}
|
||||||
|
const auto &cache = _priceTag->cache;
|
||||||
p.drawRoundedRect(rect, radius, radius);
|
const auto size = cache.size() / cache.devicePixelRatio();
|
||||||
p.setPen(st::toastFg);
|
const auto left = rthumb.x() + (rthumb.width() - size.width()) / 2;
|
||||||
|
const auto top = rthumb.y() + (rthumb.height() - size.height()) / 2;
|
||||||
text.draw(p, rect.x() - outer.x(), rect.y() - outer.y(), width);
|
p.drawImage(left, top, cache);
|
||||||
|
if (context.selected()) {
|
||||||
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
const auto radius = std::min(size.width(), size.height()) / 2;
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(st->msgSelectOverlay());
|
||||||
|
p.drawRoundedRect(
|
||||||
|
QRect(left, top, size.width(), size.height()),
|
||||||
|
radius,
|
||||||
|
radius);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Photo::validateUserpicImageCache(QSize size, bool forum) const {
|
void Photo::validateUserpicImageCache(QSize size, bool forum) const {
|
||||||
|
@ -647,12 +709,24 @@ QRect Photo::enlargeRect() const {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ClickHandlerPtr Photo::ensureExtendedMediaLink() const {
|
ClickHandlerPtr Photo::priceTagLink() const {
|
||||||
const auto item = parent()->data();
|
const auto item = parent()->data();
|
||||||
if (!_extendedMediaLink && item->isRegular()) {
|
if (!item->isRegular()) {
|
||||||
_extendedMediaLink = MakePaidMediaLink(item);
|
return nullptr;
|
||||||
|
} else if (!_priceTag) {
|
||||||
|
setupPriceTag();
|
||||||
|
if (!_priceTag) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return _extendedMediaLink;
|
if (!_priceTag->link) {
|
||||||
|
_priceTag->link = MakePaidMediaLink(item);
|
||||||
|
}
|
||||||
|
return _priceTag->link;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage Photo::priceTagBackground() const {
|
||||||
|
return _spoiler ? _spoiler->background : QImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
TextState Photo::textState(QPoint point, StateRequest request) const {
|
TextState Photo::textState(QPoint point, StateRequest request) const {
|
||||||
|
@ -669,7 +743,7 @@ TextState Photo::textState(QPoint point, StateRequest request) const {
|
||||||
if (QRect(paintx, painty, paintw, painth).contains(point)) {
|
if (QRect(paintx, painty, paintw, painth).contains(point)) {
|
||||||
ensureDataMediaCreated();
|
ensureDataMediaCreated();
|
||||||
result.link = _data->extendedMediaPreview()
|
result.link = _data->extendedMediaPreview()
|
||||||
? ensureExtendedMediaLink()
|
? priceTagLink()
|
||||||
: (_spoiler && !_spoiler->revealed)
|
: (_spoiler && !_spoiler->revealed)
|
||||||
? _spoiler->link
|
? _spoiler->link
|
||||||
: _data->uploading()
|
: _data->uploading()
|
||||||
|
@ -735,8 +809,9 @@ void Photo::drawGrouped(
|
||||||
|
|
||||||
const auto st = context.st;
|
const auto st = context.st;
|
||||||
const auto sti = context.imageStyle();
|
const auto sti = context.imageStyle();
|
||||||
const auto loaded = _dataMedia->loaded();
|
const auto preview = _data->extendedMediaPreview();
|
||||||
const auto displayLoading = _data->displayLoading();
|
const auto loaded = preview || _dataMedia->loaded();
|
||||||
|
const auto displayLoading = !preview && _data->displayLoading();
|
||||||
|
|
||||||
if (displayLoading) {
|
if (displayLoading) {
|
||||||
ensureAnimation();
|
ensureAnimation();
|
||||||
|
@ -841,7 +916,9 @@ TextState Photo::getStateGrouped(
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
ensureDataMediaCreated();
|
ensureDataMediaCreated();
|
||||||
return TextState(_parent, (_spoiler && !_spoiler->revealed)
|
return TextState(_parent, _data->extendedMediaPreview()
|
||||||
|
? priceTagLink()
|
||||||
|
: (_spoiler && !_spoiler->revealed)
|
||||||
? _spoiler->link
|
? _spoiler->link
|
||||||
: _data->uploading()
|
: _data->uploading()
|
||||||
? _cancell
|
? _cancell
|
||||||
|
@ -887,7 +964,8 @@ void Photo::validateGroupedCache(
|
||||||
|
|
||||||
ensureDataMediaCreated();
|
ensureDataMediaCreated();
|
||||||
|
|
||||||
const auto loaded = _dataMedia->loaded();
|
const auto preview = _data->extendedMediaPreview();
|
||||||
|
const auto loaded = preview || _dataMedia->loaded();
|
||||||
const auto loadLevel = loaded
|
const auto loadLevel = loaded
|
||||||
? 2
|
? 2
|
||||||
: (_dataMedia->thumbnailInline()
|
: (_dataMedia->thumbnailInline()
|
||||||
|
|
|
@ -75,6 +75,14 @@ public:
|
||||||
QPoint point,
|
QPoint point,
|
||||||
StateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
|
void drawPriceTag(
|
||||||
|
Painter &p,
|
||||||
|
QRect rthumb,
|
||||||
|
const PaintContext &context,
|
||||||
|
Fn<QImage()> generateBackground) const override;
|
||||||
|
ClickHandlerPtr priceTagLink() const override;
|
||||||
|
QImage priceTagBackground() const override;
|
||||||
|
|
||||||
void hideSpoilers() override;
|
void hideSpoilers() override;
|
||||||
bool needsBubble() const override;
|
bool needsBubble() const override;
|
||||||
bool customInfoLayout() const override {
|
bool customInfoLayout() const override {
|
||||||
|
@ -97,6 +105,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Streamed;
|
struct Streamed;
|
||||||
|
struct PriceTag;
|
||||||
|
|
||||||
void create(FullMsgId contextId, PeerData *chat = nullptr);
|
void create(FullMsgId contextId, PeerData *chat = nullptr);
|
||||||
|
|
||||||
|
@ -106,6 +115,7 @@ private:
|
||||||
|
|
||||||
void ensureDataMediaCreated() const;
|
void ensureDataMediaCreated() const;
|
||||||
void dataMediaCreated() const;
|
void dataMediaCreated() const;
|
||||||
|
void setupPriceTag() const;
|
||||||
|
|
||||||
QSize countOptimalSize() override;
|
QSize countOptimalSize() override;
|
||||||
QSize countCurrentSize(int newWidth) override;
|
QSize countCurrentSize(int newWidth) override;
|
||||||
|
@ -147,13 +157,11 @@ private:
|
||||||
[[nodiscard]] QSize photoSize() const;
|
[[nodiscard]] QSize photoSize() const;
|
||||||
[[nodiscard]] QRect enlargeRect() const;
|
[[nodiscard]] QRect enlargeRect() const;
|
||||||
|
|
||||||
void paintPriceTag(Painter &p, QRect rthumb) const;
|
|
||||||
[[nodiscard]] ClickHandlerPtr ensureExtendedMediaLink() const;
|
|
||||||
void togglePollingStory(bool enabled) const;
|
void togglePollingStory(bool enabled) const;
|
||||||
|
|
||||||
const not_null<PhotoData*> _data;
|
const not_null<PhotoData*> _data;
|
||||||
const FullStoryId _storyId;
|
const FullStoryId _storyId;
|
||||||
mutable ClickHandlerPtr _extendedMediaLink;
|
mutable std::unique_ptr<PriceTag> _priceTag;
|
||||||
mutable std::shared_ptr<Data::PhotoMedia> _dataMedia;
|
mutable std::shared_ptr<Data::PhotoMedia> _dataMedia;
|
||||||
mutable std::unique_ptr<Streamed> _streamed;
|
mutable std::unique_ptr<Streamed> _streamed;
|
||||||
const std::unique_ptr<MediaSpoiler> _spoiler;
|
const std::unique_ptr<MediaSpoiler> _spoiler;
|
||||||
|
|
Loading…
Add table
Reference in a new issue