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_giveaway_name" = "Received Prize";
"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_in_about" = "Use Stars to unlock content and services on Telegram. {link}";
"lng_credits_box_history_entry_gift_about_link" = "See Examples {emoji}";

View file

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

View file

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

View file

@ -730,15 +730,16 @@ void ReceiptCreditsBox(
const auto item = controller->session().data().message(
PeerId(e.barePeerId), MsgId(e.bareMsgId));
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)
? item->history()->peer->asUser()
: (isStarGift && e.in)
? controller->session().data().peer(PeerId(e.barePeerId))->asUser()
: nullptr;
const auto canConvert = myStarGift
&& !e.converted
&& starGiftSender;
const auto canConvert = gotStarGift && !e.converted && starGiftSender;
box->setStyle(canConvert ? st::starGiftBox : st::giveawayGiftCodeBox);
box->setNoContentMargin(true);
@ -815,11 +816,17 @@ void ReceiptCreditsBox(
) | rpl::start_with_next([=] {
auto p = Painter(icon);
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())
? lottie->frameInfo({ .box = icon->size() })
? lottie->frameInfo(request)
: Lottie::Animation::FrameInfo();
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) {
lottie->markFrameShown();
}
@ -862,7 +869,11 @@ void ReceiptCreditsBox(
? tr::lng_credits_box_history_entry_subscription(tr::now)
: !e.title.isEmpty()
? 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)
: e.gift
? tr::lng_credits_box_history_entry_gift_name(tr::now)
@ -912,9 +923,9 @@ void ReceiptCreditsBox(
context);
} else {
auto t = TextWithEntities()
.append((e.in && !isStarGift)
.append((e.in && (creditsHistoryStarGift || !isStarGift))
? u"+"_q
: e.gift
: (e.gift && !creditsHistoryStarGift)
? QString()
: QString(kMinus))
.append(Lang::FormatCountDecimal(std::abs(int64(e.credits))))
@ -942,9 +953,9 @@ void ReceiptCreditsBox(
? st::windowSubTextFg
: e.pending
? st::creditsStroke
: (e.in || isStarGift)
: (e.in || (isStarGift && !creditsHistoryStarGift))
? st::boxTextFgGood
: e.gift
: (e.gift && !creditsHistoryStarGift)
? st::windowBoldFg
: st::menuIconAttentionColor);
const auto x = (amount->width() - fullWidth) / 2;
@ -997,7 +1008,7 @@ void ReceiptCreditsBox(
rpl::single(e.description),
st::creditsBoxAbout)));
}
if (myStarGift) {
if (gotStarGift) {
Ui::AddSkip(content);
const auto about = box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
@ -1061,7 +1072,7 @@ void ReceiptCreditsBox(
Ui::AddSkip(content);
Ui::AddSkip(content);
if (isStarGift) {
if (isStarGift && e.id.isEmpty()) {
AddStarGiftTable(controller, content, e);
} else {
AddCreditsHistoryEntryTable(controller, content, e);
@ -1082,7 +1093,7 @@ void ReceiptCreditsBox(
tr::lng_credits_box_out_about_link(tr::now)),
Ui::Text::WithEntities),
st::creditsBoxAboutDivider)));
} else if (myStarGift && e.fromGiftsList) {
} else if (gotStarGift && e.fromGiftsList) {
box->addRow(object_ptr<Ui::CenterWrap<>>(
box,
object_ptr<Ui::FlatLabel>(
@ -1091,7 +1102,7 @@ void ReceiptCreditsBox(
? tr::lng_gift_visible_hint()
: tr::lng_gift_hidden_hint()),
st::creditsBoxAboutDivider)));
} else if (myStarGift && e.anonymous) {
} else if (gotStarGift && e.anonymous) {
box->addRow(object_ptr<Ui::CenterWrap<>>(
box,
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_media.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 "main/main_session.h"
#include "ui/effects/premium_graphics.h"
@ -436,6 +438,32 @@ PaintRoundImageCallback GeneratePaidMediaPaintCallback(
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(
not_null<Main::Session*> session,
const Data::CreditsHistoryEntry &entry) {
@ -463,6 +491,10 @@ TextWithEntities GenerateEntryName(const Data::CreditsHistoryEntry &entry) {
? tr::lng_credits_box_history_entry_reaction_name
: entry.bareGiveawayMsgId
? 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
? tr::lng_credits_box_history_entry_gift_name
: (entry.peerType == Data::CreditsHistoryEntry::PeerType::Fragment)

View file

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