init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
using "ui/basic.style";
|
||||
using "boxes/boxes.style";
|
||||
using "statistics/statistics.style";
|
||||
|
||||
channelEarnLearnArrowMargins: margins(-2px, 5px, 0px, 0px);
|
||||
|
||||
channelEarnOverviewTitleSkip: 11px;
|
||||
channelEarnOverviewMajorLabel: FlatLabel(defaultFlatLabel) {
|
||||
maxHeight: 30px;
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(15px semibold);
|
||||
}
|
||||
}
|
||||
channelEarnOverviewMinorLabel: FlatLabel(channelEarnOverviewMajorLabel) {
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(12px semibold);
|
||||
}
|
||||
}
|
||||
channelEarnOverviewMinorLabelSkip: 3px;
|
||||
channelEarnOverviewSubMinorLabel: FlatLabel(channelEarnOverviewMinorLabel) {
|
||||
textFg: windowSubTextFg;
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(13px);
|
||||
}
|
||||
}
|
||||
channelEarnOverviewSubMinorLabelPos: point(4px, 2px);
|
||||
channelEarnSemiboldLabel: FlatLabel(channelEarnOverviewMajorLabel) {
|
||||
style: semiboldTextStyle;
|
||||
}
|
||||
channelEarnHeaderLabel: FlatLabel(channelEarnOverviewMajorLabel) {
|
||||
style: TextStyle(statisticsHeaderTitleTextStyle) {
|
||||
}
|
||||
textFg: windowActiveTextFg;
|
||||
}
|
||||
channelEarnHistorySubLabel: FlatLabel(channelEarnOverviewSubMinorLabel) {
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(12px);
|
||||
}
|
||||
}
|
||||
channelEarnHistoryRecipientLabel: FlatLabel(channelEarnOverviewSubMinorLabel) {
|
||||
maxHeight: 0px;
|
||||
minWidth: 100px;
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(12px);
|
||||
}
|
||||
}
|
||||
channelEarnHistoryMajorLabel: FlatLabel(channelEarnOverviewMajorLabel) {
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(14px semibold);
|
||||
}
|
||||
}
|
||||
channelEarnHistoryMinorLabel: FlatLabel(channelEarnOverviewMinorLabel) {
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(12px semibold);
|
||||
}
|
||||
}
|
||||
channelEarnHistoryDescriptionLabel: FlatLabel(channelEarnHistoryMajorLabel) {
|
||||
// boxWidth - boxRowPadding = 320 - 24 * 2
|
||||
minWidth: 272px;
|
||||
maxHeight: 0px;
|
||||
align: align(center);
|
||||
}
|
||||
channelEarnHistoryMinorLabelSkip: 2px;
|
||||
channelEarnHistoryOuter: margins(0px, 6px, 0px, 6px);
|
||||
channelEarnHistoryTwoSkip: 5px;
|
||||
channelEarnHistoryThreeSkip: 3px;
|
||||
|
||||
channelEarnHistoryRecipientButton: RoundButton {
|
||||
textFg: transparent;
|
||||
textFgOver: transparent;
|
||||
numbersTextFg: transparent;
|
||||
numbersTextFgOver: transparent;
|
||||
textBg: windowBgOver;
|
||||
textBgOver: windowBgOver;
|
||||
|
||||
numbersSkip: 7px;
|
||||
|
||||
width: 190px;
|
||||
height: 34px;
|
||||
padding: margins(0px, 0px, 0px, 0px);
|
||||
|
||||
textTop: 8px;
|
||||
radius: 8px;
|
||||
|
||||
iconPosition: point(0px, 0px);
|
||||
|
||||
style: semiboldTextStyle;
|
||||
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: windowBgRipple;
|
||||
}
|
||||
}
|
||||
channelEarnHistoryRecipientButtonLabel: FlatLabel(channelEarnHistoryRecipientLabel) {
|
||||
align: align(center);
|
||||
}
|
||||
|
||||
channelEarnBalanceMajorLabel: FlatLabel(channelEarnOverviewMajorLabel) {
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(22px semibold);
|
||||
}
|
||||
}
|
||||
channelEarnBalanceMinorLabel: FlatLabel(channelEarnOverviewMinorLabel) {
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(16px semibold);
|
||||
}
|
||||
}
|
||||
channelEarnBalanceMinorLabelSkip: 6px;
|
||||
channelEarnFadeDuration: 60;
|
||||
|
||||
channelEarnLearnDescription: FlatLabel(defaultFlatLabel) {
|
||||
maxHeight: 0px;
|
||||
minWidth: 264px;
|
||||
align: align(top);
|
||||
}
|
||||
|
||||
channelEarnCurrencyCommonMargins: margins(0px, 3px, 1px, 0px);
|
||||
channelEarnCurrencyLearnMargins: margins(0px, 2px, 0px, 0px);
|
||||
|
||||
sponsoredAboutTitleIcon: icon {{ "sponsored/large_about", activeButtonFg }};
|
||||
sponsoredAboutPrivacyIcon: icon {{ "sponsored/privacy_about", boxTextFg }};
|
||||
sponsoredAboutRemoveIcon: icon {{ "sponsored/remove_about", boxTextFg }};
|
||||
sponsoredAboutSplitIcon: icon {{ "sponsored/revenue_split", boxTextFg }};
|
||||
|
||||
channelEarnLearnTitleIcon: icon {{ "sponsored/large_earn", activeButtonFg }};
|
||||
channelEarnLearnChannelIcon: icon {{ "sponsored/channel", boxTextFg }};
|
||||
channelEarnLearnWithdrawalsIcon: icon {{ "sponsored/withdrawals", boxTextFg }};
|
||||
|
||||
sponsoredReportLabel: FlatLabel(defaultFlatLabel) {
|
||||
style: boxTextStyle;
|
||||
minWidth: 150px;
|
||||
}
|
||||
|
||||
botEarnInputField: InputField(defaultInputField) {
|
||||
textMargins: margins(23px, 28px, 0px, 4px);
|
||||
placeholderMargins: margins(-23px, 0px, 0px, 0px);
|
||||
width: 100px;
|
||||
heightMax: 55px;
|
||||
}
|
||||
botEarnLockedButtonLabel: FlatLabel(channelEarnOverviewMajorLabel) {
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(10px semibold);
|
||||
}
|
||||
}
|
||||
botEarnButtonLock: IconEmoji {
|
||||
icon: icon{{ "chat/mini_lock", premiumButtonFg }};
|
||||
padding: margins(-2px, 4px, 0px, 0px);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "info/channel_statistics/earn/earn_format.h"
|
||||
|
||||
#include <QtCore/QLocale>
|
||||
|
||||
namespace Info::ChannelEarn {
|
||||
namespace {
|
||||
|
||||
constexpr auto kMinorPartLength = 9;
|
||||
constexpr auto kMaxChoppedZero = kMinorPartLength - 2;
|
||||
constexpr auto kZero = QChar('0');
|
||||
const auto DecimalPoint = QString() + QLocale().decimalPoint();
|
||||
|
||||
using EarnInt = Data::EarnInt;
|
||||
|
||||
} // namespace
|
||||
|
||||
QString MajorPart(EarnInt value) {
|
||||
const auto string = QString::number(value);
|
||||
const auto diff = int(string.size()) - kMinorPartLength;
|
||||
return (diff <= 0) ? QString(kZero) : string.mid(0, diff);
|
||||
}
|
||||
|
||||
QString MajorPart(CreditsAmount value) {
|
||||
return QString::number(int64(value.value()));
|
||||
}
|
||||
|
||||
QString MinorPart(EarnInt value) {
|
||||
if (!value) {
|
||||
return DecimalPoint + kZero + kZero;
|
||||
}
|
||||
const auto string = QString::number(value);
|
||||
const auto diff = int(string.size()) - kMinorPartLength;
|
||||
const auto result = (diff < 0)
|
||||
? DecimalPoint + u"%1"_q.arg(0, std::abs(diff), 10, kZero) + string
|
||||
: DecimalPoint + string.mid(diff);
|
||||
const auto begin = (result.constData());
|
||||
const auto end = (begin + result.size());
|
||||
auto ch = end - 1;
|
||||
auto zeroCount = 0;
|
||||
while (ch != begin) {
|
||||
if (((*ch) == kZero) && (zeroCount < kMaxChoppedZero)) {
|
||||
zeroCount++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
ch--;
|
||||
}
|
||||
return result.chopped(zeroCount);
|
||||
}
|
||||
|
||||
QString MinorPart(CreditsAmount value) {
|
||||
static const int DecimalPointLength = DecimalPoint.length();
|
||||
|
||||
const auto fractional = std::abs(int(value.value() * 100)) % 100;
|
||||
auto result = QString(DecimalPointLength + 2, Qt::Uninitialized);
|
||||
|
||||
for (int i = 0; i < DecimalPointLength; ++i) {
|
||||
result[i] = DecimalPoint[i];
|
||||
}
|
||||
|
||||
result[DecimalPointLength] = QChar('0' + fractional / 10);
|
||||
result[DecimalPointLength + 1] = QChar('0' + fractional % 10);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString ToUsd(
|
||||
Data::EarnInt value,
|
||||
float64 rate,
|
||||
int afterFloat) {
|
||||
return ToUsd(CreditsAmount(value), rate, afterFloat);
|
||||
}
|
||||
|
||||
QString ToUsd(
|
||||
CreditsAmount value,
|
||||
float64 rate,
|
||||
int afterFloat) {
|
||||
constexpr auto kApproximately = QChar(0x2248);
|
||||
|
||||
return QString(kApproximately)
|
||||
+ QChar('$')
|
||||
+ QLocale().toString(
|
||||
value.value() * rate,
|
||||
'f',
|
||||
afterFloat ? afterFloat : 2);
|
||||
}
|
||||
|
||||
} // namespace Info::ChannelEarn
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "data/data_channel_earn.h"
|
||||
|
||||
namespace Info::ChannelEarn {
|
||||
|
||||
[[nodiscard]] QString MajorPart(Data::EarnInt value);
|
||||
[[nodiscard]] QString MajorPart(CreditsAmount value);
|
||||
[[nodiscard]] QString MinorPart(Data::EarnInt value);
|
||||
[[nodiscard]] QString MinorPart(CreditsAmount value);
|
||||
[[nodiscard]] QString ToUsd(
|
||||
Data::EarnInt value,
|
||||
float64 rate,
|
||||
int afterFloat);
|
||||
[[nodiscard]] QString ToUsd(
|
||||
CreditsAmount value,
|
||||
float64 rate,
|
||||
int afterFloat);
|
||||
|
||||
} // namespace Info::ChannelEarn
|
||||
186
Telegram/SourceFiles/info/channel_statistics/earn/earn_icons.cpp
Normal file
186
Telegram/SourceFiles/info/channel_statistics/earn/earn_icons.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "info/channel_statistics/earn/earn_icons.h"
|
||||
|
||||
#include "ui/effects/credits_graphics.h"
|
||||
#include "ui/effects/premium_graphics.h"
|
||||
#include "ui/text/custom_emoji_instance.h"
|
||||
#include "ui/rect.h"
|
||||
#include "styles/style_credits.h"
|
||||
#include "styles/style_menu_icons.h"
|
||||
#include "styles/style_widgets.h"
|
||||
#include "styles/style_info.h" // infoIconReport.
|
||||
|
||||
#include <QFile>
|
||||
#include <QtSvg/QSvgRenderer>
|
||||
|
||||
namespace Ui::Earn {
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] QByteArray CurrencySvg(const QColor &c) {
|
||||
const auto color = u"rgb(%1,%2,%3)"_q
|
||||
.arg(c.red())
|
||||
.arg(c.green())
|
||||
.arg(c.blue())
|
||||
.toUtf8();
|
||||
return R"(
|
||||
<svg width="72px" height="72px" viewBox="0 0 72 72">
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(9.000000, 14.000000)
|
||||
" stroke-width="7.2" stroke=")" + color + R"(">
|
||||
<path d="M2.96014341,0 L50.9898193,0 C51.9732032,-7.06402744e-15
|
||||
52.7703933,0.797190129 52.7703933,1.78057399 C52.7703933,2.08038611
|
||||
52.6946886,2.3753442 52.5502994,2.63809702 L29.699977,44.2200383
|
||||
C28.7527832,45.9436969 26.5876295,46.5731461 24.8639708,45.6259523
|
||||
C24.2556953,45.2916896 23.7583564,44.7869606 23.4331014,44.1738213
|
||||
L1.38718565,2.61498853 C0.926351231,1.74626794 1.25700829,0.668450654
|
||||
2.12572888,0.20761623 C2.38272962,0.0712838007 2.6692209,4.97530809e-16
|
||||
2.96014341,0 Z"></path>
|
||||
<line x1="27" y1="44.4532875" x2="27" y2="0"></line>
|
||||
</g>
|
||||
</g>
|
||||
</svg>)";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
QImage IconCurrencyColored(int size, const QColor &c) {
|
||||
const auto s = Size(size);
|
||||
auto svg = QSvgRenderer(CurrencySvg(c));
|
||||
auto image = QImage(
|
||||
s * style::DevicePixelRatio(),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
image.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
image.fill(Qt::transparent);
|
||||
{
|
||||
auto p = QPainter(&image);
|
||||
svg.render(&p, Rect(s));
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
QImage IconCurrencyColored(
|
||||
const style::font &font,
|
||||
const QColor &c) {
|
||||
return IconCurrencyColored(font->ascent, c);
|
||||
}
|
||||
|
||||
QByteArray CurrencySvgColored(const QColor &c) {
|
||||
return CurrencySvg(c);
|
||||
}
|
||||
|
||||
QImage MenuIconCurrency(const QSize &size) {
|
||||
auto image = QImage(
|
||||
size * style::DevicePixelRatio(),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
image.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
image.fill(Qt::transparent);
|
||||
auto p = QPainter(&image);
|
||||
st::infoIconReport.paintInCenter(
|
||||
p,
|
||||
Rect(size),
|
||||
st::infoIconFg->c);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Clear);
|
||||
const auto w = st::lineWidth * 6;
|
||||
p.fillRect(
|
||||
QRect(
|
||||
rect::center(Rect(size)).x() - w / 2,
|
||||
rect::center(Rect(size)).y() - w,
|
||||
w,
|
||||
w * 2),
|
||||
Qt::white);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
|
||||
const auto s = Size(st::inviteLinkSubscribeBoxTerms.style.font->ascent);
|
||||
auto svg = QSvgRenderer(CurrencySvg(st::infoIconFg->c));
|
||||
svg.render(
|
||||
&p,
|
||||
QRectF(
|
||||
(size.width() - s.width()) / 2.,
|
||||
(size.height() - s.height()) / 2.,
|
||||
s.width(),
|
||||
s.height()));
|
||||
return image;
|
||||
}
|
||||
|
||||
QImage MenuIconCredits() {
|
||||
constexpr auto kStrokeWidth = 5;
|
||||
const auto sizeShift = st::lineWidth * 1.5;
|
||||
|
||||
auto colorized = [&] {
|
||||
auto f = QFile(Ui::Premium::Svg());
|
||||
if (!f.open(QIODevice::ReadOnly)) {
|
||||
return QString();
|
||||
}
|
||||
return QString::fromUtf8(f.readAll()).replace(
|
||||
u"#fff"_q,
|
||||
u"#ffffff00"_q);
|
||||
}();
|
||||
colorized.replace(
|
||||
u"stroke=\"none\""_q,
|
||||
u"stroke=\"%1\""_q.arg(st::menuIconColor->c.name()));
|
||||
colorized.replace(
|
||||
u"stroke-width=\"1\""_q,
|
||||
u"stroke-width=\"%1\""_q.arg(kStrokeWidth));
|
||||
auto svg = QSvgRenderer(colorized.toUtf8());
|
||||
svg.setViewBox(svg.viewBox()
|
||||
+ Margins(style::ConvertScale(kStrokeWidth)));
|
||||
|
||||
auto image = QImage(
|
||||
st::menuIconLinks.size() * style::DevicePixelRatio(),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
image.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
image.fill(Qt::transparent);
|
||||
{
|
||||
auto p = QPainter(&image);
|
||||
svg.render(&p, Rect(st::menuIconLinks.size()) - Margins(sizeShift));
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
std::unique_ptr<Ui::Text::CustomEmoji> MakeCurrencyIconEmoji(
|
||||
const style::font &font,
|
||||
const QColor &c) {
|
||||
return std::make_unique<Ui::CustomEmoji::Internal>(
|
||||
u"currency_icon:%1:%2"_q.arg(font->height).arg(c.name()),
|
||||
IconCurrencyColored(font, c));
|
||||
}
|
||||
|
||||
Ui::Text::PaletteDependentEmoji IconCreditsEmoji(
|
||||
IconDescriptor descriptor) {
|
||||
return { .factory = [=] {
|
||||
return Ui::GenerateStars(
|
||||
(descriptor.size
|
||||
? descriptor.size
|
||||
: st::defaultTableLabel.style.font->height),
|
||||
1);
|
||||
}, .margin = descriptor.margin.value_or(
|
||||
QMargins{ 0, st::giftBoxByStarsSkip, 0, 0 }) };
|
||||
}
|
||||
|
||||
Ui::Text::PaletteDependentEmoji IconCurrencyEmoji(
|
||||
IconDescriptor descriptor) {
|
||||
return { .factory = [=] {
|
||||
return IconCurrencyColored(
|
||||
descriptor.size ? descriptor.size : st::earnTonIconSize,
|
||||
st::currencyFg->c);
|
||||
}, .margin = descriptor.margin.value_or(st::earnTonIconMargin) };
|
||||
}
|
||||
|
||||
Ui::Text::PaletteDependentEmoji IconCreditsEmojiSmall() {
|
||||
return IconCreditsEmoji({
|
||||
.size = st::giftBoxByStarsStyle.font->height,
|
||||
.margin = QMargins{ 0, st::giftBoxByStarsStarTop, 0, 0 },
|
||||
});
|
||||
}
|
||||
|
||||
Ui::Text::PaletteDependentEmoji IconCurrencyEmojiSmall() {
|
||||
return IconCreditsEmoji({});
|
||||
}
|
||||
|
||||
} // namespace Ui::Earn
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/text/custom_emoji_helper.h"
|
||||
|
||||
namespace Ui::Text {
|
||||
class CustomEmoji;
|
||||
} // namespace Ui::Text
|
||||
|
||||
namespace Ui::Earn {
|
||||
|
||||
[[nodiscard]] QImage IconCurrencyColored(int size, const QColor &c);
|
||||
[[nodiscard]] QImage IconCurrencyColored(
|
||||
const style::font &font,
|
||||
const QColor &c);
|
||||
[[nodiscard]] QByteArray CurrencySvgColored(const QColor &c);
|
||||
|
||||
[[nodiscard]] QImage MenuIconCurrency(const QSize &size);
|
||||
[[nodiscard]] QImage MenuIconCredits();
|
||||
|
||||
std::unique_ptr<Ui::Text::CustomEmoji> MakeCurrencyIconEmoji(
|
||||
const style::font &font,
|
||||
const QColor &c);
|
||||
|
||||
struct IconDescriptor {
|
||||
int size = 0;
|
||||
std::optional<QMargins> margin;
|
||||
};
|
||||
[[nodiscard]] Ui::Text::PaletteDependentEmoji IconCreditsEmoji(
|
||||
IconDescriptor descriptor = {});
|
||||
[[nodiscard]] Ui::Text::PaletteDependentEmoji IconCurrencyEmoji(
|
||||
IconDescriptor descriptor = {});
|
||||
|
||||
[[nodiscard]] Ui::Text::PaletteDependentEmoji IconCreditsEmojiSmall();
|
||||
[[nodiscard]] Ui::Text::PaletteDependentEmoji IconCurrencyEmojiSmall();
|
||||
|
||||
} // namespace Ui::Earn
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "info/channel_statistics/earn/info_channel_earn_widget.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
|
||||
namespace Ui {
|
||||
class Show;
|
||||
class FlatLabel;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Info {
|
||||
class Controller;
|
||||
} // namespace Info
|
||||
|
||||
namespace Info::ChannelEarn {
|
||||
|
||||
class Memento;
|
||||
|
||||
class InnerWidget final : public Ui::VerticalLayout {
|
||||
public:
|
||||
struct ShowRequest final {
|
||||
};
|
||||
|
||||
InnerWidget(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller,
|
||||
not_null<PeerData*> peer);
|
||||
|
||||
[[nodiscard]] not_null<PeerData*> peer() const;
|
||||
|
||||
[[nodiscard]] rpl::producer<Ui::ScrollToRequest> scrollToRequests() const;
|
||||
[[nodiscard]] rpl::producer<ShowRequest> showRequests() const;
|
||||
|
||||
void showFinished();
|
||||
void setInnerFocus();
|
||||
|
||||
void saveState(not_null<Memento*> memento);
|
||||
void restoreState(not_null<Memento*> memento);
|
||||
|
||||
private:
|
||||
void load();
|
||||
void fill();
|
||||
|
||||
not_null<Controller*> _controller;
|
||||
not_null<PeerData*> _peer;
|
||||
std::shared_ptr<Ui::Show> _show;
|
||||
|
||||
Memento::SavedState _state;
|
||||
|
||||
rpl::event_stream<Ui::ScrollToRequest> _scrollToRequests;
|
||||
rpl::event_stream<ShowRequest> _showRequests;
|
||||
rpl::event_stream<> _showFinished;
|
||||
rpl::event_stream<> _focusRequested;
|
||||
rpl::event_stream<bool> _loaded;
|
||||
rpl::event_stream<> _stateUpdated;
|
||||
|
||||
};
|
||||
|
||||
void AddEmojiToMajor(
|
||||
not_null<Ui::FlatLabel*> label,
|
||||
rpl::producer<CreditsAmount> value,
|
||||
std::optional<bool> isIn,
|
||||
std::optional<QMargins> margins);
|
||||
|
||||
} // namespace Info::ChannelEarn
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "info/channel_statistics/earn/info_channel_earn_widget.h"
|
||||
|
||||
#include "info/channel_statistics/earn/info_channel_earn_list.h"
|
||||
#include "info/info_controller.h"
|
||||
#include "info/info_memento.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/ui_utility.h"
|
||||
|
||||
namespace Info::ChannelEarn {
|
||||
|
||||
Memento::Memento(not_null<Controller*> controller)
|
||||
: ContentMemento(controller->statisticsTag()) {
|
||||
}
|
||||
|
||||
Memento::Memento(not_null<PeerData*> peer)
|
||||
: ContentMemento(Info::Statistics::Tag{ peer, {}, {} }) {
|
||||
}
|
||||
|
||||
Memento::~Memento() = default;
|
||||
|
||||
Section Memento::section() const {
|
||||
return Section(Section::Type::ChannelEarn);
|
||||
}
|
||||
|
||||
void Memento::setState(SavedState state) {
|
||||
_state = std::move(state);
|
||||
}
|
||||
|
||||
Memento::SavedState Memento::state() {
|
||||
return base::take(_state);
|
||||
}
|
||||
|
||||
object_ptr<ContentWidget> Memento::createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller,
|
||||
const QRect &geometry) {
|
||||
auto result = object_ptr<Widget>(parent, controller);
|
||||
result->setInternalState(geometry, this);
|
||||
return result;
|
||||
}
|
||||
|
||||
Widget::Widget(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller)
|
||||
: ContentWidget(parent, controller)
|
||||
, _inner(setInnerWidget(
|
||||
object_ptr<InnerWidget>(
|
||||
this,
|
||||
controller,
|
||||
controller->statisticsTag().peer))) {
|
||||
_inner->showRequests(
|
||||
) | rpl::on_next([=](InnerWidget::ShowRequest request) {
|
||||
}, _inner->lifetime());
|
||||
_inner->scrollToRequests(
|
||||
) | rpl::on_next([=](const Ui::ScrollToRequest &request) {
|
||||
scrollTo(request);
|
||||
}, _inner->lifetime());
|
||||
}
|
||||
|
||||
not_null<PeerData*> Widget::peer() const {
|
||||
return _inner->peer();
|
||||
}
|
||||
|
||||
bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
||||
return (memento->statisticsTag().peer == peer());
|
||||
}
|
||||
|
||||
rpl::producer<QString> Widget::title() {
|
||||
return tr::lng_channel_earn_title();
|
||||
}
|
||||
|
||||
void Widget::setInternalState(
|
||||
const QRect &geometry,
|
||||
not_null<Memento*> memento) {
|
||||
setGeometry(geometry);
|
||||
Ui::SendPendingMoveResizeEvents(this);
|
||||
restoreState(memento);
|
||||
}
|
||||
|
||||
rpl::producer<bool> Widget::desiredShadowVisibility() const {
|
||||
return rpl::single<bool>(true);
|
||||
}
|
||||
|
||||
void Widget::showFinished() {
|
||||
_inner->showFinished();
|
||||
}
|
||||
|
||||
void Widget::setInnerFocus() {
|
||||
_inner->setInnerFocus();
|
||||
}
|
||||
|
||||
std::shared_ptr<ContentMemento> Widget::doCreateMemento() {
|
||||
auto result = std::make_shared<Memento>(controller());
|
||||
saveState(result.get());
|
||||
return result;
|
||||
}
|
||||
|
||||
void Widget::saveState(not_null<Memento*> memento) {
|
||||
memento->setScrollTop(scrollTopSave());
|
||||
_inner->saveState(memento);
|
||||
}
|
||||
|
||||
void Widget::restoreState(not_null<Memento*> memento) {
|
||||
_inner->restoreState(memento);
|
||||
scrollTopRestore(memento->scrollTop());
|
||||
}
|
||||
|
||||
std::shared_ptr<Info::Memento> Make(not_null<PeerData*> peer) {
|
||||
return std::make_shared<Info::Memento>(
|
||||
std::vector<std::shared_ptr<ContentMemento>>(
|
||||
1,
|
||||
std::make_shared<Memento>(peer)));
|
||||
}
|
||||
|
||||
} // namespace Info::ChannelEarn
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "data/data_channel_earn.h"
|
||||
#include "data/data_credits.h"
|
||||
#include "data/data_credits_earn.h"
|
||||
#include "info/info_content_widget.h"
|
||||
|
||||
namespace Info::ChannelEarn {
|
||||
|
||||
class InnerWidget;
|
||||
|
||||
class Memento final : public ContentMemento {
|
||||
public:
|
||||
Memento(not_null<Controller*> controller);
|
||||
Memento(not_null<PeerData*> peer);
|
||||
~Memento();
|
||||
|
||||
object_ptr<ContentWidget> createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller,
|
||||
const QRect &geometry) override;
|
||||
|
||||
Section section() const override;
|
||||
|
||||
struct SavedState final {
|
||||
Data::EarnStatistics currencyEarn;
|
||||
Data::CreditsEarnStatistics creditsEarn;
|
||||
Data::CreditsStatusSlice creditsStatusSlice;
|
||||
PeerId premiumBotId = PeerId(0);
|
||||
bool canViewCurrencyMegagroupEarn = true;
|
||||
};
|
||||
|
||||
void setState(SavedState states);
|
||||
[[nodiscard]] SavedState state();
|
||||
|
||||
private:
|
||||
SavedState _state;
|
||||
|
||||
};
|
||||
|
||||
class Widget final : public ContentWidget {
|
||||
public:
|
||||
Widget(QWidget *parent, not_null<Controller*> controller);
|
||||
|
||||
bool showInternal(not_null<ContentMemento*> memento) override;
|
||||
rpl::producer<QString> title() override;
|
||||
rpl::producer<bool> desiredShadowVisibility() const override;
|
||||
void showFinished() override;
|
||||
void setInnerFocus() override;
|
||||
|
||||
[[nodiscard]] not_null<PeerData*> peer() const;
|
||||
|
||||
void setInternalState(
|
||||
const QRect &geometry,
|
||||
not_null<Memento*> memento);
|
||||
|
||||
private:
|
||||
void saveState(not_null<Memento*> memento);
|
||||
void restoreState(not_null<Memento*> memento);
|
||||
|
||||
std::shared_ptr<ContentMemento> doCreateMemento() override;
|
||||
|
||||
const not_null<InnerWidget*> _inner;
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]] std::shared_ptr<Info::Memento> Make(not_null<PeerData*> peer);
|
||||
|
||||
} // namespace Info::ChannelEarn
|
||||
Reference in New Issue
Block a user