Show price in my/purchased paid media.

This commit is contained in:
John Preston 2024-06-24 22:21:52 +04:00
parent a39a8dbd2c
commit 7e704d9529
17 changed files with 133 additions and 5 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -285,7 +285,7 @@ void SendCreditsBox(
lt_count,
rpl::single(form->invoice.amount) | tr::to_count(),
lt_emoji,
rpl::single(CreditsEmoji(session)),
rpl::single(CreditsEmojiSmall(session)),
Ui::Text::RichLangValue);
const auto buttonLabel = Ui::CreateChild<Ui::FlatLabel>(
button,
@ -369,4 +369,13 @@ TextWithEntities CreditsEmoji(not_null<Main::Session*> session) {
QString(QChar(0x2B50)));
}
TextWithEntities CreditsEmojiSmall(not_null<Main::Session*> session) {
return Ui::Text::SingleCustomEmoji(
session->data().customEmojiManager().registerInternalEmoji(
st::starIconSmall,
st::starIconSmallPadding,
true),
QString(QChar(0x2B50)));
}
} // namespace Ui

View file

@ -29,4 +29,7 @@ void SendCreditsBox(
[[nodiscard]] TextWithEntities CreditsEmoji(
not_null<Main::Session*> session);
[[nodiscard]] TextWithEntities CreditsEmojiSmall(
not_null<Main::Session*> session);
} // namespace Ui

View file

@ -2068,7 +2068,7 @@ ItemPreview MediaInvoice::toPreview(ToPreviewOptions options) const {
: parent()->originalText();
const auto hasMiniImages = !images.empty();
auto nice = Ui::Text::Colorized(
Ui::CreditsEmoji(&parent()->history()->session()));
Ui::CreditsEmojiSmall(&parent()->history()->session()));
nice.append(WithCaptionNotificationText(type, caption, hasMiniImages));
return {
.text = std::move(nice),

View file

@ -721,6 +721,14 @@ void Element::overrideMedia(std::unique_ptr<Media> media) {
_flags |= Flag::MediaOverriden;
}
not_null<PurchasedTag*> Element::enforcePurchasedTag() {
if (const auto purchased = Get<PurchasedTag>()) {
return purchased;
}
AddComponents(PurchasedTag::Bit());
return Get<PurchasedTag>();
}
void Element::refreshMedia(Element *replacing) {
if (_flags & Flag::MediaOverriden) {
return;

View file

@ -278,6 +278,10 @@ struct FakeBotAboutTop : public RuntimeComponent<FakeBotAboutTop, Element> {
int height = 0;
};
struct PurchasedTag : public RuntimeComponent<PurchasedTag, Element> {
Ui::Text::String text;
};
struct TopicButton {
std::unique_ptr<Ui::RippleAnimation> ripple;
ClickHandlerPtr link;
@ -564,6 +568,8 @@ public:
void overrideMedia(std::unique_ptr<Media> media);
[[nodiscard]] not_null<PurchasedTag*> enforcePurchasedTag();
virtual bool consumeHorizontalScroll(QPoint position, int delta) {
return false;
}

View file

@ -191,6 +191,8 @@ Gif::Gif(
}
}
ensureTranscribeButton();
_purchasedPriceTag = hasPurchasedTag();
}
Gif::~Gif() {
@ -663,6 +665,10 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
const auto skipDrawingSurrounding = context.skipDrawingParts
== PaintContext::SkipDrawingParts::Surrounding;
if (!skipDrawingSurrounding && _purchasedPriceTag) {
drawPurchasedTag(p, rthumb, context);
}
if (!unwrapped && !skipDrawingSurrounding) {
if (!isRound || !inWebPage) {
drawCornerStatus(p, context, QPoint());

View file

@ -213,6 +213,7 @@ private:
mutable bool _thumbCacheBlurred : 1 = false;
mutable bool _thumbIsEllipse : 1 = false;
mutable bool _pollingStory : 1 = false;
mutable bool _purchasedPriceTag : 1 = false;
};

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/media/history_view_media.h"
#include "boxes/send_credits_box.h" // CreditsEmoji.
#include "history/history.h"
#include "history/history_item.h"
#include "history/view/history_view_element.h"
@ -18,12 +19,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h"
#include "data/data_session.h"
#include "data/data_web_page.h"
#include "lang/lang_tag.h" // FormatCountDecimal.
#include "ui/item_text_options.h"
#include "ui/chat/chat_style.h"
#include "ui/chat/message_bubble.h"
#include "ui/effects/spoiler_mess.h"
#include "ui/image/image_prepare.h"
#include "ui/cached_round_corners.h"
#include "ui/painter.h"
#include "ui/power_saving.h"
#include "ui/text/text_utilities.h"
#include "core/ui_integration.h"
#include "styles/style_chat.h"
@ -202,6 +207,72 @@ QSize Media::countCurrentSize(int newWidth) {
return QSize(qMin(newWidth, maxWidth()), minHeight());
}
bool Media::hasPurchasedTag() const {
if (const auto media = parent()->data()->media()) {
if (const auto invoice = media->invoice()) {
if (invoice->isPaidMedia && !invoice->extendedMedia.empty()) {
const auto photo = invoice->extendedMedia.front()->photo();
return !photo || !photo->extendedMediaPreview();
}
}
}
return false;
}
void Media::drawPurchasedTag(
Painter &p,
QRect outer,
const PaintContext &context) const {
const auto purchased = parent()->enforcePurchasedTag();
if (purchased->text.isEmpty()) {
const auto item = parent()->data();
const auto media = item->media();
const auto invoice = media ? media->invoice() : nullptr;
const auto amount = invoice ? invoice->amount : 0;
if (!amount) {
return;
}
const auto session = &item->history()->session();
auto text = Ui::Text::Colorized(Ui::CreditsEmojiSmall(session));
text.append(Lang::FormatCountDecimal(amount));
purchased->text.setMarkedText(st::defaultTextStyle, text, kMarkupTextOptions, Core::MarkedTextContext{
.session = session,
.customEmojiRepaint = [] {},
});
}
const auto st = context.st;
const auto sti = context.imageStyle();
auto right = outer.x() + outer.width();
auto top = outer.y();
right -= st::msgDateImgDelta + st::msgDateImgPadding.x();
top += st::msgDateImgDelta + st::msgDateImgPadding.y();
const auto size = QSize(
purchased->text.maxWidth(),
st::normalFont->height);
const auto tagX = right - size.width();
const auto tagY = top;
const auto tagW = size.width() + 2 * st::msgDateImgPadding.x();
const auto tagH = size.height() + 2 * st::msgDateImgPadding.y();
Ui::FillRoundRect(
p,
tagX - st::msgDateImgPadding.x(),
tagY - st::msgDateImgPadding.y(),
tagW,
tagH,
sti->msgDateImgBg,
sti->msgDateImgBgCorners);
p.setPen(st->msgDateImgFg());
purchased->text.draw(p, {
.position = { tagX, tagY },
.outerWidth = width(),
.availableWidth = tagW - 2 * st::msgDateImgPadding.x(),
.palette = &st->priceTagTextPalette(),
});
}
void Media::fillImageShadow(
QPainter &p,
QRect rect,

View file

@ -357,6 +357,12 @@ public:
return false;
}
[[nodiscard]] bool hasPurchasedTag() const;
void drawPurchasedTag(
Painter &p,
QRect outer,
const PaintContext &context) const;
virtual ~Media() = default;
protected:

View file

@ -133,6 +133,8 @@ GroupedMedia::Mode GroupedMedia::DetectMode(not_null<Data::Media*> media) {
}
QSize GroupedMedia::countOptimalSize() {
_purchasedPriceTag = hasPurchasedTag();
std::vector<QSize> sizes;
const auto partsCount = _parts.size();
sizes.reserve(partsCount);
@ -433,7 +435,7 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
if (!part.cache.isNull()) {
nowCache = true;
}
if (unpaid) {
if (unpaid || _purchasedPriceTag) {
fullRect = fullRect.united(part.geometry);
}
}
@ -445,6 +447,8 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
unpaid->drawPriceTag(p, fullRect, context, [&] {
return generatePriceTagBackground(fullRect);
});
} else if (_purchasedPriceTag) {
drawPurchasedTag(p, fullRect, context);
}
// date

View file

@ -155,7 +155,8 @@ private:
mutable std::optional<HistoryItem*> _captionItem;
std::vector<Part> _parts;
Mode _mode = Mode::Grid;
bool _needBubble = false;
bool _needBubble : 1 = false;
bool _purchasedPriceTag : 1 = false;
};

View file

@ -139,6 +139,7 @@ void Photo::create(FullMsgId contextId, PeerData *chat) {
if (_spoiler) {
createSpoilerLink(_spoiler.get());
}
_purchasedPriceTag = hasPurchasedTag() ? 1 : 0;
}
void Photo::ensureDataMediaCreated() const {
@ -393,6 +394,14 @@ void Photo::draw(Painter &p, const PaintContext &context) const {
p.drawRoundedRect(rect, radius, radius);
sti->historyPageEnlarge.paintInCenter(p, rect);
}
if (_purchasedPriceTag) {
auto geometry = rthumb;
if (showEnlarge) {
const auto rect = enlargeRect();
geometry.setY(rect.y() + rect.height());
}
drawPurchasedTag(p, geometry, context);
}
// date
if (!inWebPage && (!bubble || isBubbleBottom())) {

View file

@ -167,7 +167,8 @@ private:
const std::unique_ptr<MediaSpoiler> _spoiler;
mutable QImage _imageCache;
mutable std::optional<Ui::BubbleRounding> _imageCacheRounding;
uint32 _serviceWidth : 28 = 0;
uint32 _serviceWidth : 27 = 0;
uint32 _purchasedPriceTag : 1 = 0;
mutable uint32 _imageCacheForum : 1 = 0;
mutable uint32 _imageCacheBlurred : 1 = 0;
mutable uint32 _pollingStory : 1 = 0;

View file

@ -44,3 +44,6 @@ creditsBoxAboutDivider: FlatLabel(boxDividerLabel) {
creditsBoxButtonLabel: FlatLabel(defaultFlatLabel) {
style: semiboldTextStyle;
}
starIconSmall: icon{{ "payments/small_star", windowFg }};
starIconSmallPadding: margins(0px, -3px, 0px, 0px);