Added initial support of personal earn currency history.

This commit is contained in:
23rd 2025-06-28 13:51:30 +03:00
parent a3b76fed4c
commit 9d7aab4326
7 changed files with 121 additions and 23 deletions

View file

@ -318,13 +318,18 @@ void CreditsStatus::request(
}).send();
}
CreditsHistory::CreditsHistory(not_null<PeerData*> peer, bool in, bool out)
CreditsHistory::CreditsHistory(
not_null<PeerData*> peer,
bool in,
bool out,
bool currency)
: _peer(peer)
, _flags((in == out)
, _flags(((in == out)
? HistoryTL::Flags(0)
: HistoryTL::Flags(0)
| (in ? HistoryTL::Flag::f_inbound : HistoryTL::Flags(0))
| (out ? HistoryTL::Flag::f_outbound : HistoryTL::Flags(0)))
| (currency ? HistoryTL::Flag::f_ton : HistoryTL::Flags(0)))
, _api(&peer->session().api().instance()) {
}

View file

@ -75,7 +75,11 @@ private:
class CreditsHistory final {
public:
CreditsHistory(not_null<PeerData*> peer, bool in, bool out);
CreditsHistory(
not_null<PeerData*> peer,
bool in,
bool out,
bool currency = false);
void request(
const Data::CreditsStatusSlice::OffsetToken &token,

View file

@ -1729,7 +1729,7 @@ void AddCreditsHistoryEntryTable(
(entry.gift
? tr::lng_credits_box_history_entry_peer_in
: tr::lng_credits_box_history_entry_via)(),
(entry.gift
((entry.gift && entry.credits.stars())
? tr::lng_credits_box_history_entry_anonymous
: tr::lng_credits_box_history_entry_fragment)(
Ui::Text::RichLangValue));

View file

@ -12,6 +12,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/peer_list_controllers.h"
#include "boxes/peer_list_widgets.h"
#include "info/channel_statistics/earn/earn_format.h"
#include "info/channel_statistics/earn/earn_icons.h"
#include "info/channel_statistics/earn/earn_format.h"
#include "chat_helpers/stickers_gift_box_pack.h"
#include "core/ui_integration.h" // TextContext
#include "data/data_channel.h"
@ -42,6 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/vertical_layout.h"
#include "styles/style_boxes.h"
#include "styles/style_color_indices.h"
#include "styles/style_channel_earn.h"
#include "styles/style_credits.h"
#include "styles/style_dialogs.h" // dialogsStoriesFull.
#include "styles/style_layers.h" // boxRowPadding.
@ -49,6 +52,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_settings.h"
#include "styles/style_statistics.h"
#include "styles/style_window.h"
#include "styles/style_chat.h"
namespace Info::Statistics {
namespace {
@ -830,6 +834,7 @@ private:
Ui::Text::String _description;
Ui::Text::String _rightText;
Ui::Text::String _rightMinorText;
std::shared_ptr<Ui::DynamicImage> _descriptionThumbnail;
QImage _descriptionThumbnailCache;
@ -910,6 +915,8 @@ void CreditsRow::init() {
: (_entry.peerType
== Data::CreditsHistoryEntry::PeerType::PremiumBot)
? tr::lng_credits_box_history_entry_via_premium_bot(tr::now)
: (_entry.peerType == Data::CreditsHistoryEntry::PeerType::Fragment)
? tr::lng_credits_box_history_entry_fragment(tr::now)
: (_entry.gift && isSpecial)
? tr::lng_credits_box_history_entry_anonymous(tr::now)
: (_name == name)
@ -960,15 +967,35 @@ void CreditsRow::init() {
}
if (_entry) {
constexpr auto kMinus = QChar(0x2212);
const auto isCurrency = _entry.credits.ton();
_rightText.setMarkedText(
st::creditsHistoryRowRightStyle,
isCurrency
? st::channelEarnHistoryMajorLabel.style
: st::creditsHistoryRowRightStyle,
TextWithEntities()
.append(_entry.in ? QChar('+') : kMinus)
.append(Lang::FormatCreditsAmountDecimal(_entry.credits.abs()))
.append(isCurrency
? Info::ChannelEarn::MajorPart(_entry.credits)
: Lang::FormatCreditsAmountDecimal(_entry.credits.abs()))
.append(QChar(' '))
.append(Ui::MakeCreditsIconEntity()),
.append(isCurrency
? TextWithEntities()
: Ui::MakeCreditsIconEntity()),
kMarkupTextOptions,
_context);
if (isCurrency) {
_rightMinorText.setMarkedText(
st::channelEarnHistoryMinorLabel.style,
TextWithEntities()
.append(Info::ChannelEarn::MinorPart(_entry.credits))
.append(QChar(' '))
.append(
Ui::Text::SingleCustomEmoji(_entry.in
? u"ton:in"_q
: u"ton:out"_q)),
kMarkupTextOptions,
_context);
}
}
if (!_paintUserpicCallback) {
_paintUserpicCallback = /*_entry.stargift
@ -1023,7 +1050,9 @@ QSize CreditsRow::rightActionSize() const {
return QSize(maxWidth + st::boxRowPadding.right(), _rowHeight);
} else if (_subscription || _entry) {
return QSize(
_rightText.maxWidth() + st::boxRowPadding.right() / 2,
_rightText.maxWidth()
+ _rightMinorText.maxWidth()
+ st::boxRowPadding.right() / 2,
_rowHeight);
} else if (!_entry && !_subscription) {
return QSize();
@ -1046,7 +1075,6 @@ void CreditsRow::rightActionPaint(
int outerWidth,
bool selected,
bool actionSelected) {
const auto &font = _rightText.style()->font;
const auto rightSkip = st::boxRowPadding.right();
if (_rightLabel) {
return _rightLabel->draw(p, x, y, _rowHeight);
@ -1082,9 +1110,15 @@ void CreditsRow::rightActionPaint(
: _entry.in
? st::boxTextFgGood
: st::menuIconAttentionColor);
const auto xMinor = outerWidth - _rightMinorText.maxWidth() - rightSkip;
_rightMinorText.draw(p, Ui::Text::PaintContext{
.position = QPoint(xMinor, y + st::creditsHistoryRowRightMinorTop),
.outerWidth = outerWidth,
.availableWidth = outerWidth,
});
_rightText.draw(p, Ui::Text::PaintContext{
.position = QPoint(
outerWidth - _rightText.maxWidth() - rightSkip,
xMinor - _rightText.maxWidth(),
y + st::creditsHistoryRowRightTop),
.outerWidth = outerWidth,
.availableWidth = outerWidth,
@ -1179,6 +1213,18 @@ CreditsController::CreditsController(CreditsDescriptor d)
Ui::MakeCreditsIconEmoji(height, 1),
QPoint(-st::lineWidth, st::lineWidth));
}
if (data.startsWith(u"ton"_q)) {
const auto in = data.split(u":"_q)[1].startsWith(u"in"_q);
return std::make_unique<Ui::Text::ShiftedEmoji>(
std::make_unique<Ui::Text::StaticCustomEmoji>(
Ui::Earn::IconCurrencyColored(
st::tonFieldIconSize,
in
? st::boxTextFgGood->c
: st::menuIconAttentionColor->c),
data.toString()),
QPoint(0, st::lineWidth));
}
const auto desc = DeserializeCreditsRowDescriptionData(
data.toString());
if (!desc.rowId || !desc.bareGiftStickerId) {

View file

@ -380,9 +380,10 @@ void Credits::setupHistory(not_null<Ui::VerticalLayout*> container) {
const auto apiLifetime = content->lifetime().make_state<rpl::lifetime>();
{
using Api = Api::CreditsHistory;
const auto apiFull = apiLifetime->make_state<Api>(self, true, true);
const auto apiIn = apiLifetime->make_state<Api>(self, true, false);
const auto apiOut = apiLifetime->make_state<Api>(self, false, true);
const auto c = (_creditsType == CreditsType::Ton);
const auto apiFull = apiLifetime->make_state<Api>(self, true, true, c);
const auto apiIn = apiLifetime->make_state<Api>(self, true, false, c);
const auto apiOut = apiLifetime->make_state<Api>(self, false, true, c);
apiFull->request({}, [=](Data::CreditsStatusSlice fullSlice) {
apiIn->request({}, [=](Data::CreditsStatusSlice inSlice) {
apiOut->request({}, [=](Data::CreditsStatusSlice outSlice) {

View file

@ -43,6 +43,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "info/bot/starref/info_bot_starref_common.h"
#include "info/channel_statistics/boosts/giveaway/boost_badge.h" // InfiniteRadialAnimationWidget.
#include "info/channel_statistics/earn/info_channel_earn_widget.h" // Info::ChannelEarn::Make.
#include "info/channel_statistics/earn/earn_format.h"
#include "info/channel_statistics/earn/earn_icons.h"
#include "info/peer_gifts/info_peer_gifts_common.h"
#include "info/settings/info_settings_widget.h" // SectionCustomTopBarData.
@ -1429,6 +1430,7 @@ void GenericCreditsEntryBox(
constexpr auto kMinus = QChar(0x2212);
auto &lifetime = content->lifetime();
const auto text = lifetime.make_state<Ui::Text::String>();
auto minorText = (Ui::Text::String*)(nullptr);
const auto roundedText = e.refunded
? tr::lng_channel_earn_history_return(tr::now)
: e.pending
@ -1466,13 +1468,13 @@ void GenericCreditsEntryBox(
Ui::Text::WithEntities),
kMarkupTextOptions,
context);
} else {
} else if (e.credits.stars()) {
auto t = TextWithEntities()
.append((e.in && (creditsHistoryStarGift || !isStarGift))
? u"+"_q
? QChar('+')
: (e.gift && !creditsHistoryStarGift)
? QString()
: QString(kMinus))
? QChar()
: kMinus)
.append(Lang::FormatCreditsAmountDecimal(e.credits.abs()))
.append(QChar(' '))
.append(owner->customEmojiManager().creditsEmoji());
@ -1481,6 +1483,35 @@ void GenericCreditsEntryBox(
std::move(t),
kMarkupTextOptions,
context);
} else if (e.credits.ton()) {
auto t = TextWithEntities()
.append((e.in ? QChar('+') : kMinus))
.append(Info::ChannelEarn::MajorPart(e.credits.abs()));
text->setMarkedText(
st::channelEarnHistoryMajorLabel.style,
std::move(t),
kMarkupTextOptions,
context);
auto minor = TextWithEntities()
.append(Info::ChannelEarn::MinorPart(e.credits.abs()))
.append(QChar(' '))
.append(
Ui::Text::SingleCustomEmoji(
owner->customEmojiManager().registerInternalEmoji(
Ui::Earn::IconCurrencyColored(
st::tonFieldIconSize,
(e.in
? st::boxTextFgGood->c
: st::menuIconAttentionColor->c)),
QMargins(0, st::lineWidth * 1, 0, 0),
false)));
minorText = lifetime.make_state<Ui::Text::String>();
minorText->setMarkedText(
st::channelEarnHistoryMinorLabel.style,
std::move(minor),
kMarkupTextOptions,
context);
}
const auto font = text->style()->font;
const auto roundedFont = st::defaultTextStyle.font;
@ -1490,7 +1521,9 @@ void GenericCreditsEntryBox(
+ roundedSkip
+ roundedFont->height
: 0;
const auto fullWidth = text->maxWidth() + roundedWidth;
const auto fullWidth = text->maxWidth()
+ roundedWidth
+ (minorText ? minorText->maxWidth() : 0);
amount->paintRequest(
) | rpl::start_with_next([=] {
auto p = Painter(amount);
@ -1506,13 +1539,21 @@ void GenericCreditsEntryBox(
? st::windowBoldFg
: st::menuIconAttentionColor);
const auto x = (amount->width() - fullWidth) / 2;
const auto y = (amount->height() - font->height) / 2;
text->draw(p, Ui::Text::PaintContext{
.position = QPoint(
x,
(amount->height() - font->height) / 2),
.position = QPoint(x, y),
.outerWidth = amount->width(),
.availableWidth = amount->width(),
});
if (minorText) {
minorText->draw(p, Ui::Text::PaintContext{
.position = QPoint(
x + text->maxWidth(),
y + st::lineWidth * 2),
.outerWidth = amount->width(),
.availableWidth = amount->width(),
});
}
if (rounded) {
const auto roundedLeft = fullWidth
@ -1620,7 +1661,7 @@ void GenericCreditsEntryBox(
about->setTextColorOverride(st::menuIconAttentionColor->c);
}
} else if (isStarGift) {
} else if (e.gift || isPrize) {
} else if ((e.gift || isPrize) && e.credits.stars()) {
Ui::AddSkip(content);
auto link = tr::lng_credits_box_history_entry_gift_about_link(
lt_emoji,
@ -1805,7 +1846,7 @@ void GenericCreditsEntryBox(
Ui::AddSkip(content);
if (!isStarGift) {
if (!isStarGift && e.credits.stars()) {
box->addRow(object_ptr<Ui::CenterWrap<>>(
box,
object_ptr<Ui::FlatLabel>(

View file

@ -309,6 +309,7 @@ creditsHistoryTabsSlider: SettingsSlider(defaultTabsSlider) {
creditsHistoryTabsSliderPadding: margins(14px, 0px, 24px, 0px);
creditsHistoryRowDescriptionSkip: 20px;
creditsHistoryRowRightTop: 16px;
creditsHistoryRowRightMinorTop: 18px;
creditsHistoryRowRightStyle: TextStyle(defaultTextStyle) {
font: font(fsize);
}