Show nice star gift transactions in history.

This commit is contained in:
John Preston 2024-09-26 16:38:10 +04:00
parent 05fb0f81f9
commit 8b11d2d5e7
6 changed files with 85 additions and 20 deletions

View file

@ -2430,6 +2430,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_credits_box_history_entry_gift_name" = "Received Gift"; "lng_credits_box_history_entry_gift_name" = "Received Gift";
"lng_credits_box_history_entry_giveaway_name" = "Received Prize"; "lng_credits_box_history_entry_giveaway_name" = "Received Prize";
"lng_credits_box_history_entry_gift_sent" = "Sent Gift"; "lng_credits_box_history_entry_gift_sent" = "Sent Gift";
"lng_credits_box_history_entry_gift_converted" = "Converted Gift";
"lng_credits_box_history_entry_gift_out_about" = "With Stars, **{user}** will be able to unlock content and services on Telegram.\n{link}"; "lng_credits_box_history_entry_gift_out_about" = "With Stars, **{user}** will be able to unlock content and services on Telegram.\n{link}";
"lng_credits_box_history_entry_gift_in_about" = "Use Stars to unlock content and services on Telegram. {link}"; "lng_credits_box_history_entry_gift_in_about" = "Use Stars to unlock content and services on Telegram. {link}";
"lng_credits_box_history_entry_gift_about_link" = "See Examples {emoji}"; "lng_credits_box_history_entry_gift_about_link" = "See Examples {emoji}";

View file

@ -69,6 +69,8 @@ constexpr auto kTransactionsLimit = 100;
}, [](const auto &) { }, [](const auto &) {
return PeerId(0); return PeerId(0);
}).value; }).value;
const auto stargift = tl.data().vstargift();
const auto incoming = (int64(tl.data().vstars().v) >= 0);
return Data::CreditsHistoryEntry{ return Data::CreditsHistoryEntry{
.id = qs(tl.data().vid()), .id = qs(tl.data().vid()),
.title = qs(tl.data().vtitle().value_or_empty()), .title = qs(tl.data().vtitle().value_or_empty()),
@ -81,6 +83,9 @@ constexpr auto kTransactionsLimit = 100;
.barePeerId = barePeerId, .barePeerId = barePeerId,
.bareGiveawayMsgId = uint64( .bareGiveawayMsgId = uint64(
tl.data().vgiveaway_post_id().value_or_empty()), tl.data().vgiveaway_post_id().value_or_empty()),
.bareGiftStickerId = (stargift
? owner->processDocument(stargift->data().vsticker())->id
: 0),
.peerType = tl.data().vpeer().match([](const HistoryPeerTL &) { .peerType = tl.data().vpeer().match([](const HistoryPeerTL &) {
return Data::CreditsHistoryEntry::PeerType::Peer; return Data::CreditsHistoryEntry::PeerType::Peer;
}, [](const MTPDstarsTransactionPeerPlayMarket &) { }, [](const MTPDstarsTransactionPeerPlayMarket &) {
@ -104,12 +109,16 @@ constexpr auto kTransactionsLimit = 100;
? base::unixtime::parse(tl.data().vtransaction_date()->v) ? base::unixtime::parse(tl.data().vtransaction_date()->v)
: QDateTime(), : QDateTime(),
.successLink = qs(tl.data().vtransaction_url().value_or_empty()), .successLink = qs(tl.data().vtransaction_url().value_or_empty()),
.convertStars = int(stargift
? stargift->data().vconvert_stars().v
: 0),
.converted = stargift && incoming,
.reaction = tl.data().is_reaction(), .reaction = tl.data().is_reaction(),
.refunded = tl.data().is_refund(), .refunded = tl.data().is_refund(),
.pending = tl.data().is_pending(), .pending = tl.data().is_pending(),
.failed = tl.data().is_failed(), .failed = tl.data().is_failed(),
.in = (int64(tl.data().vstars().v) >= 0), .in = incoming,
.gift = tl.data().is_gift(), .gift = tl.data().is_gift() || stargift.has_value(),
}; };
} }

View file

@ -843,14 +843,16 @@ void CreditsRow::init() {
const auto name = !isSpecial const auto name = !isSpecial
? PeerListRow::generateName() ? PeerListRow::generateName()
: Ui::GenerateEntryName(_entry).text; : Ui::GenerateEntryName(_entry).text;
_name = (_entry.reaction || _entry.bareGiveawayMsgId) _name = (_entry.reaction
|| _entry.bareGiveawayMsgId
|| _entry.convertStars)
? Ui::GenerateEntryName(_entry).text ? Ui::GenerateEntryName(_entry).text
: _entry.title.isEmpty() : _entry.title.isEmpty()
? name ? name
: _entry.title; : _entry.title;
const auto joiner = QString(QChar(' ')) + QChar(8212) + QChar(' '); const auto joiner = QString(QChar(' ')) + QChar(8212) + QChar(' ');
PeerListRow::setCustomStatus( PeerListRow::setCustomStatus(
langDateTimeFull(_entry.date) langDateTime(_entry.date)
+ (_entry.refunded + (_entry.refunded
? (joiner + tr::lng_channel_earn_history_return(tr::now)) ? (joiner + tr::lng_channel_earn_history_return(tr::now))
: _entry.pending : _entry.pending
@ -889,7 +891,12 @@ void CreditsRow::init() {
_context); _context);
} }
if (!_paintUserpicCallback) { if (!_paintUserpicCallback) {
_paintUserpicCallback = !isSpecial _paintUserpicCallback = _entry.convertStars
? Ui::GenerateGiftStickerUserpicCallback(
_context.session,
_entry.bareGiftStickerId,
_context.customEmojiRepaint)
: !isSpecial
? PeerListRow::generatePaintUserpicCallback(false) ? PeerListRow::generatePaintUserpicCallback(false)
: Ui::GenerateCreditsPaintUserpicCallback(_entry); : Ui::GenerateCreditsPaintUserpicCallback(_entry);
} }

View file

@ -730,15 +730,16 @@ void ReceiptCreditsBox(
const auto item = controller->session().data().message( const auto item = controller->session().data().message(
PeerId(e.barePeerId), MsgId(e.bareMsgId)); PeerId(e.barePeerId), MsgId(e.bareMsgId));
const auto isStarGift = (e.convertStars > 0); const auto isStarGift = (e.convertStars > 0);
const auto myStarGift = isStarGift && e.in; const auto creditsHistoryStarGift = isStarGift && !e.id.isEmpty();
const auto sentStarGift = creditsHistoryStarGift && !e.in;
const auto convertedStarGift = creditsHistoryStarGift && e.converted;
const auto gotStarGift = isStarGift && !creditsHistoryStarGift && e.in;
const auto starGiftSender = (isStarGift && item) const auto starGiftSender = (isStarGift && item)
? item->history()->peer->asUser() ? item->history()->peer->asUser()
: (isStarGift && e.in) : (isStarGift && e.in)
? controller->session().data().peer(PeerId(e.barePeerId))->asUser() ? controller->session().data().peer(PeerId(e.barePeerId))->asUser()
: nullptr; : nullptr;
const auto canConvert = myStarGift const auto canConvert = gotStarGift && !e.converted && starGiftSender;
&& !e.converted
&& starGiftSender;
box->setStyle(canConvert ? st::starGiftBox : st::giveawayGiftCodeBox); box->setStyle(canConvert ? st::starGiftBox : st::giveawayGiftCodeBox);
box->setNoContentMargin(true); box->setNoContentMargin(true);
@ -815,11 +816,17 @@ void ReceiptCreditsBox(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
auto p = Painter(icon); auto p = Painter(icon);
const auto &lottie = state->lottie; const auto &lottie = state->lottie;
const auto factor = style::DevicePixelRatio();
const auto request = Lottie::FrameRequest{
.box = icon->size() * factor,
};
const auto frame = (lottie && lottie->ready()) const auto frame = (lottie && lottie->ready())
? lottie->frameInfo({ .box = icon->size() }) ? lottie->frameInfo(request)
: Lottie::Animation::FrameInfo(); : Lottie::Animation::FrameInfo();
if (!frame.image.isNull()) { if (!frame.image.isNull()) {
p.drawImage(0, 0, frame.image); p.drawImage(
QRect(QPoint(), frame.image.size() / factor),
frame.image);
if (lottie->frameIndex() < lottie->framesCount() - 1) { if (lottie->frameIndex() < lottie->framesCount() - 1) {
lottie->markFrameShown(); lottie->markFrameShown();
} }
@ -862,7 +869,11 @@ void ReceiptCreditsBox(
? tr::lng_credits_box_history_entry_subscription(tr::now) ? tr::lng_credits_box_history_entry_subscription(tr::now)
: !e.title.isEmpty() : !e.title.isEmpty()
? e.title ? e.title
: (isStarGift && !myStarGift) : sentStarGift
? tr::lng_credits_box_history_entry_gift_sent(tr::now)
: convertedStarGift
? tr::lng_credits_box_history_entry_gift_converted(tr::now)
: (isStarGift && !gotStarGift)
? tr::lng_gift_link_label_gift(tr::now) ? tr::lng_gift_link_label_gift(tr::now)
: e.gift : e.gift
? tr::lng_credits_box_history_entry_gift_name(tr::now) ? tr::lng_credits_box_history_entry_gift_name(tr::now)
@ -912,9 +923,9 @@ void ReceiptCreditsBox(
context); context);
} else { } else {
auto t = TextWithEntities() auto t = TextWithEntities()
.append((e.in && !isStarGift) .append((e.in && (creditsHistoryStarGift || !isStarGift))
? u"+"_q ? u"+"_q
: e.gift : (e.gift && !creditsHistoryStarGift)
? QString() ? QString()
: QString(kMinus)) : QString(kMinus))
.append(Lang::FormatCountDecimal(std::abs(int64(e.credits)))) .append(Lang::FormatCountDecimal(std::abs(int64(e.credits))))
@ -942,9 +953,9 @@ void ReceiptCreditsBox(
? st::windowSubTextFg ? st::windowSubTextFg
: e.pending : e.pending
? st::creditsStroke ? st::creditsStroke
: (e.in || isStarGift) : (e.in || (isStarGift && !creditsHistoryStarGift))
? st::boxTextFgGood ? st::boxTextFgGood
: e.gift : (e.gift && !creditsHistoryStarGift)
? st::windowBoldFg ? st::windowBoldFg
: st::menuIconAttentionColor); : st::menuIconAttentionColor);
const auto x = (amount->width() - fullWidth) / 2; const auto x = (amount->width() - fullWidth) / 2;
@ -997,7 +1008,7 @@ void ReceiptCreditsBox(
rpl::single(e.description), rpl::single(e.description),
st::creditsBoxAbout))); st::creditsBoxAbout)));
} }
if (myStarGift) { if (gotStarGift) {
Ui::AddSkip(content); Ui::AddSkip(content);
const auto about = box->addRow( const auto about = box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>( object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
@ -1061,7 +1072,7 @@ void ReceiptCreditsBox(
Ui::AddSkip(content); Ui::AddSkip(content);
Ui::AddSkip(content); Ui::AddSkip(content);
if (isStarGift) { if (isStarGift && e.id.isEmpty()) {
AddStarGiftTable(controller, content, e); AddStarGiftTable(controller, content, e);
} else { } else {
AddCreditsHistoryEntryTable(controller, content, e); AddCreditsHistoryEntryTable(controller, content, e);
@ -1082,7 +1093,7 @@ void ReceiptCreditsBox(
tr::lng_credits_box_out_about_link(tr::now)), tr::lng_credits_box_out_about_link(tr::now)),
Ui::Text::WithEntities), Ui::Text::WithEntities),
st::creditsBoxAboutDivider))); st::creditsBoxAboutDivider)));
} else if (myStarGift && e.fromGiftsList) { } else if (gotStarGift && e.fromGiftsList) {
box->addRow(object_ptr<Ui::CenterWrap<>>( box->addRow(object_ptr<Ui::CenterWrap<>>(
box, box,
object_ptr<Ui::FlatLabel>( object_ptr<Ui::FlatLabel>(
@ -1091,7 +1102,7 @@ void ReceiptCreditsBox(
? tr::lng_gift_visible_hint() ? tr::lng_gift_visible_hint()
: tr::lng_gift_hidden_hint()), : tr::lng_gift_hidden_hint()),
st::creditsBoxAboutDivider))); st::creditsBoxAboutDivider)));
} else if (myStarGift && e.anonymous) { } else if (gotStarGift && e.anonymous) {
box->addRow(object_ptr<Ui::CenterWrap<>>( box->addRow(object_ptr<Ui::CenterWrap<>>(
box, box,
object_ptr<Ui::FlatLabel>( object_ptr<Ui::FlatLabel>(

View file

@ -16,6 +16,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_photo.h" #include "data/data_photo.h"
#include "data/data_photo_media.h" #include "data/data_photo_media.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "history/view/media/history_view_sticker_player.h"
#include "info/userpic/info_userpic_emoji_builder_preview.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "ui/effects/premium_graphics.h" #include "ui/effects/premium_graphics.h"
@ -436,6 +438,32 @@ PaintRoundImageCallback GeneratePaidMediaPaintCallback(
totalCount); totalCount);
} }
PaintRoundImageCallback GenerateGiftStickerUserpicCallback(
not_null<Main::Session*> session,
uint64 stickerId,
Fn<void()> update) {
struct State {
std::optional<UserpicBuilder::PreviewPainter> painter;
int size = 0;
};
const auto state = std::make_shared<State>();
//const auto document = session->data().document(stickerId);
return [=](Painter &p, int x, int y, int outerWidth, int size) {
if (state->size != size || !state->painter) {
state->size = size;
state->painter.emplace(size * M_SQRT2);
state->painter->setDocument(
session->data().document(stickerId),
update);
}
const auto skip = int(base::SafeRound((size * (M_SQRT2 - 1.)) / 2.));
auto hq = PainterHighQualityEnabler(p);
p.translate(x - skip, y - skip);
state->painter->paintForeground(p);
p.translate(skip - x, skip - y);
};
}
Fn<PaintRoundImageCallback(Fn<void()>)> PaintPreviewCallback( Fn<PaintRoundImageCallback(Fn<void()>)> PaintPreviewCallback(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const Data::CreditsHistoryEntry &entry) { const Data::CreditsHistoryEntry &entry) {
@ -463,6 +491,10 @@ TextWithEntities GenerateEntryName(const Data::CreditsHistoryEntry &entry) {
? tr::lng_credits_box_history_entry_reaction_name ? tr::lng_credits_box_history_entry_reaction_name
: entry.bareGiveawayMsgId : entry.bareGiveawayMsgId
? tr::lng_credits_box_history_entry_giveaway_name ? tr::lng_credits_box_history_entry_giveaway_name
: entry.converted
? tr::lng_credits_box_history_entry_gift_converted
: entry.convertStars
? tr::lng_credits_box_history_entry_gift_sent
: entry.gift : entry.gift
? tr::lng_credits_box_history_entry_gift_name ? tr::lng_credits_box_history_entry_gift_name
: (entry.peerType == Data::CreditsHistoryEntry::PeerType::Fragment) : (entry.peerType == Data::CreditsHistoryEntry::PeerType::Fragment)

View file

@ -64,6 +64,11 @@ PaintRoundImageCallback GeneratePaidMediaPaintCallback(
int totalCount, int totalCount,
Fn<void()> update); Fn<void()> update);
PaintRoundImageCallback GenerateGiftStickerUserpicCallback(
not_null<Main::Session*> session,
uint64 stickerId,
Fn<void()> update);
Fn<PaintRoundImageCallback(Fn<void()>)> PaintPreviewCallback( Fn<PaintRoundImageCallback(Fn<void()>)> PaintPreviewCallback(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const Data::CreditsHistoryEntry &entry); const Data::CreditsHistoryEntry &entry);