mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Show price in my/purchased paid media.
This commit is contained in:
parent
a39a8dbd2c
commit
7e704d9529
17 changed files with 133 additions and 5 deletions
BIN
Telegram/Resources/icons/payments/small_star.png
Normal file
BIN
Telegram/Resources/icons/payments/small_star.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 484 B |
BIN
Telegram/Resources/icons/payments/small_star@2x.png
Normal file
BIN
Telegram/Resources/icons/payments/small_star@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 860 B |
BIN
Telegram/Resources/icons/payments/small_star@3x.png
Normal file
BIN
Telegram/Resources/icons/payments/small_star@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -285,7 +285,7 @@ void SendCreditsBox(
|
||||||
lt_count,
|
lt_count,
|
||||||
rpl::single(form->invoice.amount) | tr::to_count(),
|
rpl::single(form->invoice.amount) | tr::to_count(),
|
||||||
lt_emoji,
|
lt_emoji,
|
||||||
rpl::single(CreditsEmoji(session)),
|
rpl::single(CreditsEmojiSmall(session)),
|
||||||
Ui::Text::RichLangValue);
|
Ui::Text::RichLangValue);
|
||||||
const auto buttonLabel = Ui::CreateChild<Ui::FlatLabel>(
|
const auto buttonLabel = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
button,
|
button,
|
||||||
|
@ -369,4 +369,13 @@ TextWithEntities CreditsEmoji(not_null<Main::Session*> session) {
|
||||||
QString(QChar(0x2B50)));
|
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
|
} // namespace Ui
|
||||||
|
|
|
@ -29,4 +29,7 @@ void SendCreditsBox(
|
||||||
[[nodiscard]] TextWithEntities CreditsEmoji(
|
[[nodiscard]] TextWithEntities CreditsEmoji(
|
||||||
not_null<Main::Session*> session);
|
not_null<Main::Session*> session);
|
||||||
|
|
||||||
|
[[nodiscard]] TextWithEntities CreditsEmojiSmall(
|
||||||
|
not_null<Main::Session*> session);
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -2068,7 +2068,7 @@ ItemPreview MediaInvoice::toPreview(ToPreviewOptions options) const {
|
||||||
: parent()->originalText();
|
: parent()->originalText();
|
||||||
const auto hasMiniImages = !images.empty();
|
const auto hasMiniImages = !images.empty();
|
||||||
auto nice = Ui::Text::Colorized(
|
auto nice = Ui::Text::Colorized(
|
||||||
Ui::CreditsEmoji(&parent()->history()->session()));
|
Ui::CreditsEmojiSmall(&parent()->history()->session()));
|
||||||
nice.append(WithCaptionNotificationText(type, caption, hasMiniImages));
|
nice.append(WithCaptionNotificationText(type, caption, hasMiniImages));
|
||||||
return {
|
return {
|
||||||
.text = std::move(nice),
|
.text = std::move(nice),
|
||||||
|
|
|
@ -721,6 +721,14 @@ void Element::overrideMedia(std::unique_ptr<Media> media) {
|
||||||
_flags |= Flag::MediaOverriden;
|
_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) {
|
void Element::refreshMedia(Element *replacing) {
|
||||||
if (_flags & Flag::MediaOverriden) {
|
if (_flags & Flag::MediaOverriden) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -278,6 +278,10 @@ struct FakeBotAboutTop : public RuntimeComponent<FakeBotAboutTop, Element> {
|
||||||
int height = 0;
|
int height = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PurchasedTag : public RuntimeComponent<PurchasedTag, Element> {
|
||||||
|
Ui::Text::String text;
|
||||||
|
};
|
||||||
|
|
||||||
struct TopicButton {
|
struct TopicButton {
|
||||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
ClickHandlerPtr link;
|
ClickHandlerPtr link;
|
||||||
|
@ -564,6 +568,8 @@ public:
|
||||||
|
|
||||||
void overrideMedia(std::unique_ptr<Media> media);
|
void overrideMedia(std::unique_ptr<Media> media);
|
||||||
|
|
||||||
|
[[nodiscard]] not_null<PurchasedTag*> enforcePurchasedTag();
|
||||||
|
|
||||||
virtual bool consumeHorizontalScroll(QPoint position, int delta) {
|
virtual bool consumeHorizontalScroll(QPoint position, int delta) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,6 +191,8 @@ Gif::Gif(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ensureTranscribeButton();
|
ensureTranscribeButton();
|
||||||
|
|
||||||
|
_purchasedPriceTag = hasPurchasedTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
Gif::~Gif() {
|
Gif::~Gif() {
|
||||||
|
@ -663,6 +665,10 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
||||||
const auto skipDrawingSurrounding = context.skipDrawingParts
|
const auto skipDrawingSurrounding = context.skipDrawingParts
|
||||||
== PaintContext::SkipDrawingParts::Surrounding;
|
== PaintContext::SkipDrawingParts::Surrounding;
|
||||||
|
|
||||||
|
if (!skipDrawingSurrounding && _purchasedPriceTag) {
|
||||||
|
drawPurchasedTag(p, rthumb, context);
|
||||||
|
}
|
||||||
|
|
||||||
if (!unwrapped && !skipDrawingSurrounding) {
|
if (!unwrapped && !skipDrawingSurrounding) {
|
||||||
if (!isRound || !inWebPage) {
|
if (!isRound || !inWebPage) {
|
||||||
drawCornerStatus(p, context, QPoint());
|
drawCornerStatus(p, context, QPoint());
|
||||||
|
|
|
@ -213,6 +213,7 @@ private:
|
||||||
mutable bool _thumbCacheBlurred : 1 = false;
|
mutable bool _thumbCacheBlurred : 1 = false;
|
||||||
mutable bool _thumbIsEllipse : 1 = false;
|
mutable bool _thumbIsEllipse : 1 = false;
|
||||||
mutable bool _pollingStory : 1 = false;
|
mutable bool _pollingStory : 1 = false;
|
||||||
|
mutable bool _purchasedPriceTag : 1 = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "history/view/media/history_view_media.h"
|
#include "history/view/media/history_view_media.h"
|
||||||
|
|
||||||
|
#include "boxes/send_credits_box.h" // CreditsEmoji.
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "history/view/history_view_element.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_document.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_web_page.h"
|
#include "data/data_web_page.h"
|
||||||
|
#include "lang/lang_tag.h" // FormatCountDecimal.
|
||||||
#include "ui/item_text_options.h"
|
#include "ui/item_text_options.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"
|
||||||
#include "ui/effects/spoiler_mess.h"
|
#include "ui/effects/spoiler_mess.h"
|
||||||
#include "ui/image/image_prepare.h"
|
#include "ui/image/image_prepare.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
|
#include "ui/painter.h"
|
||||||
#include "ui/power_saving.h"
|
#include "ui/power_saving.h"
|
||||||
|
#include "ui/text/text_utilities.h"
|
||||||
#include "core/ui_integration.h"
|
#include "core/ui_integration.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
|
@ -202,6 +207,72 @@ QSize Media::countCurrentSize(int newWidth) {
|
||||||
return QSize(qMin(newWidth, maxWidth()), minHeight());
|
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(
|
void Media::fillImageShadow(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
QRect rect,
|
QRect rect,
|
||||||
|
|
|
@ -357,6 +357,12 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool hasPurchasedTag() const;
|
||||||
|
void drawPurchasedTag(
|
||||||
|
Painter &p,
|
||||||
|
QRect outer,
|
||||||
|
const PaintContext &context) const;
|
||||||
|
|
||||||
virtual ~Media() = default;
|
virtual ~Media() = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -133,6 +133,8 @@ GroupedMedia::Mode GroupedMedia::DetectMode(not_null<Data::Media*> media) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize GroupedMedia::countOptimalSize() {
|
QSize GroupedMedia::countOptimalSize() {
|
||||||
|
_purchasedPriceTag = hasPurchasedTag();
|
||||||
|
|
||||||
std::vector<QSize> sizes;
|
std::vector<QSize> sizes;
|
||||||
const auto partsCount = _parts.size();
|
const auto partsCount = _parts.size();
|
||||||
sizes.reserve(partsCount);
|
sizes.reserve(partsCount);
|
||||||
|
@ -433,7 +435,7 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
|
||||||
if (!part.cache.isNull()) {
|
if (!part.cache.isNull()) {
|
||||||
nowCache = true;
|
nowCache = true;
|
||||||
}
|
}
|
||||||
if (unpaid) {
|
if (unpaid || _purchasedPriceTag) {
|
||||||
fullRect = fullRect.united(part.geometry);
|
fullRect = fullRect.united(part.geometry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,6 +447,8 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
|
||||||
unpaid->drawPriceTag(p, fullRect, context, [&] {
|
unpaid->drawPriceTag(p, fullRect, context, [&] {
|
||||||
return generatePriceTagBackground(fullRect);
|
return generatePriceTagBackground(fullRect);
|
||||||
});
|
});
|
||||||
|
} else if (_purchasedPriceTag) {
|
||||||
|
drawPurchasedTag(p, fullRect, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
// date
|
// date
|
||||||
|
|
|
@ -155,7 +155,8 @@ private:
|
||||||
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;
|
||||||
bool _needBubble = false;
|
bool _needBubble : 1 = false;
|
||||||
|
bool _purchasedPriceTag : 1 = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -139,6 +139,7 @@ void Photo::create(FullMsgId contextId, PeerData *chat) {
|
||||||
if (_spoiler) {
|
if (_spoiler) {
|
||||||
createSpoilerLink(_spoiler.get());
|
createSpoilerLink(_spoiler.get());
|
||||||
}
|
}
|
||||||
|
_purchasedPriceTag = hasPurchasedTag() ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Photo::ensureDataMediaCreated() const {
|
void Photo::ensureDataMediaCreated() const {
|
||||||
|
@ -393,6 +394,14 @@ void Photo::draw(Painter &p, const PaintContext &context) const {
|
||||||
p.drawRoundedRect(rect, radius, radius);
|
p.drawRoundedRect(rect, radius, radius);
|
||||||
sti->historyPageEnlarge.paintInCenter(p, rect);
|
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
|
// date
|
||||||
if (!inWebPage && (!bubble || isBubbleBottom())) {
|
if (!inWebPage && (!bubble || isBubbleBottom())) {
|
||||||
|
|
|
@ -167,7 +167,8 @@ private:
|
||||||
const std::unique_ptr<MediaSpoiler> _spoiler;
|
const std::unique_ptr<MediaSpoiler> _spoiler;
|
||||||
mutable QImage _imageCache;
|
mutable QImage _imageCache;
|
||||||
mutable std::optional<Ui::BubbleRounding> _imageCacheRounding;
|
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 _imageCacheForum : 1 = 0;
|
||||||
mutable uint32 _imageCacheBlurred : 1 = 0;
|
mutable uint32 _imageCacheBlurred : 1 = 0;
|
||||||
mutable uint32 _pollingStory : 1 = 0;
|
mutable uint32 _pollingStory : 1 = 0;
|
||||||
|
|
|
@ -44,3 +44,6 @@ creditsBoxAboutDivider: FlatLabel(boxDividerLabel) {
|
||||||
creditsBoxButtonLabel: FlatLabel(defaultFlatLabel) {
|
creditsBoxButtonLabel: FlatLabel(defaultFlatLabel) {
|
||||||
style: semiboldTextStyle;
|
style: semiboldTextStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
starIconSmall: icon{{ "payments/small_star", windowFg }};
|
||||||
|
starIconSmallPadding: margins(0px, -3px, 0px, 0px);
|
||||||
|
|
Loading…
Add table
Reference in a new issue