mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added support of api update to history lists in section of channel earn.
This commit is contained in:
parent
b79c306bfe
commit
a84ac933dd
2 changed files with 426 additions and 372 deletions
|
@ -5214,6 +5214,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_channel_earn_chart_revenue" = "Ad revenue";
|
"lng_channel_earn_chart_revenue" = "Ad revenue";
|
||||||
"lng_channel_earn_chart_overriden_detail_currency" = "Revenue in TON";
|
"lng_channel_earn_chart_overriden_detail_currency" = "Revenue in TON";
|
||||||
"lng_channel_earn_chart_overriden_detail_usd" = "Revenue in USD";
|
"lng_channel_earn_chart_overriden_detail_usd" = "Revenue in USD";
|
||||||
|
"lng_channel_earn_currency_history" = "TON Transactions";
|
||||||
|
"lng_channel_earn_credits_history" = "Stars Transactions";
|
||||||
|
|
||||||
"lng_bot_earn_title" = "Stars Balance";
|
"lng_bot_earn_title" = "Stars Balance";
|
||||||
"lng_bot_earn_chart_revenue" = "Revenue";
|
"lng_bot_earn_chart_revenue" = "Revenue";
|
||||||
|
|
|
@ -697,7 +697,11 @@ void InnerWidget::fill() {
|
||||||
const auto majorLabel = Ui::CreateChild<Ui::FlatLabel>(
|
const auto majorLabel = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
line,
|
line,
|
||||||
st::channelEarnOverviewMajorLabel);
|
st::channelEarnOverviewMajorLabel);
|
||||||
addEmojiToMajor(majorLabel, rpl::duplicate(currencyValue), {}, {});
|
addEmojiToMajor(
|
||||||
|
majorLabel,
|
||||||
|
rpl::duplicate(currencyValue),
|
||||||
|
{},
|
||||||
|
{});
|
||||||
const auto minorLabel = Ui::CreateChild<Ui::FlatLabel>(
|
const auto minorLabel = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
line,
|
line,
|
||||||
rpl::duplicate(currencyValue) | rpl::map(MinorPart),
|
rpl::duplicate(currencyValue) | rpl::map(MinorPart),
|
||||||
|
@ -912,414 +916,462 @@ void InnerWidget::fill() {
|
||||||
Ui::AddSkip(container);
|
Ui::AddSkip(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto hasCurrencyTab = !data.firstHistorySlice.list.empty();
|
const auto sectionIndex = container->lifetime().make_state<int>(0);
|
||||||
const auto hasCreditsTab = !_state.creditsStatusSlice.list.empty()
|
const auto rebuildLists = [=](
|
||||||
&& _state.premiumBotId;
|
const Memento::SavedState &data,
|
||||||
const auto hasOneTab = (hasCurrencyTab || hasCreditsTab)
|
not_null<Ui::VerticalLayout*> listsContainer) {
|
||||||
&& (hasCurrencyTab != hasCreditsTab);
|
const auto hasCurrencyTab
|
||||||
|
= !data.currencyEarn.firstHistorySlice.list.empty();
|
||||||
|
const auto hasCreditsTab = !data.creditsStatusSlice.list.empty()
|
||||||
|
&& data.premiumBotId;
|
||||||
|
const auto hasOneTab = (hasCurrencyTab || hasCreditsTab)
|
||||||
|
&& (hasCurrencyTab != hasCreditsTab);
|
||||||
|
|
||||||
const auto currencyTabText = tr::lng_channel_earn_currency_history(
|
const auto currencyTabText = tr::lng_channel_earn_currency_history(
|
||||||
tr::now);
|
tr::now);
|
||||||
const auto creditsTabText = tr::lng_channel_earn_credits_history(tr::now);
|
const auto creditsTabText = tr::lng_channel_earn_credits_history(
|
||||||
|
tr::now);
|
||||||
|
|
||||||
const auto slider = container->add(
|
const auto slider = listsContainer->add(
|
||||||
object_ptr<Ui::SlideWrap<Ui::CustomWidthSlider>>(
|
object_ptr<Ui::SlideWrap<Ui::CustomWidthSlider>>(
|
||||||
container,
|
listsContainer,
|
||||||
object_ptr<Ui::CustomWidthSlider>(
|
object_ptr<Ui::CustomWidthSlider>(
|
||||||
container,
|
listsContainer,
|
||||||
st::defaultTabsSlider)),
|
st::defaultTabsSlider)),
|
||||||
st::boxRowPadding);
|
st::boxRowPadding);
|
||||||
slider->toggle(!hasOneTab, anim::type::instant);
|
slider->toggle(!hasOneTab, anim::type::instant);
|
||||||
|
|
||||||
if (hasCurrencyTab) {
|
|
||||||
slider->entity()->addSection(currencyTabText);
|
|
||||||
}
|
|
||||||
if (hasCreditsTab) {
|
|
||||||
slider->entity()->addSection(creditsTabText);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const auto &st = st::defaultTabsSlider;
|
|
||||||
slider->entity()->setNaturalWidth(0
|
|
||||||
+ (hasCurrencyTab
|
|
||||||
? st.labelStyle.font->width(currencyTabText)
|
|
||||||
: 0)
|
|
||||||
+ (hasCreditsTab
|
|
||||||
? st.labelStyle.font->width(creditsTabText)
|
|
||||||
: 0)
|
|
||||||
+ rect::m::sum::h(st::boxRowPadding));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasOneTab) {
|
|
||||||
if (hasCurrencyTab) {
|
if (hasCurrencyTab) {
|
||||||
AddHeader(container, tr::lng_channel_earn_history_title);
|
slider->entity()->addSection(currencyTabText);
|
||||||
} else if (hasCreditsTab) {
|
|
||||||
AddHeader(container, tr::lng_channel_earn_credits_history);
|
|
||||||
slider->entity()->setActiveSectionFast(1);
|
|
||||||
}
|
}
|
||||||
}
|
if (hasCreditsTab) {
|
||||||
|
slider->entity()->addSection(creditsTabText);
|
||||||
const auto historyCurrencyList = container->add(
|
|
||||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
|
||||||
container,
|
|
||||||
object_ptr<Ui::VerticalLayout>(container)));
|
|
||||||
const auto historyCreditsList = container->add(
|
|
||||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
|
||||||
container,
|
|
||||||
object_ptr<Ui::VerticalLayout>(container)));
|
|
||||||
|
|
||||||
rpl::single(slider->entity()->activeSection()) | rpl::then(
|
|
||||||
slider->entity()->sectionActivated()
|
|
||||||
) | rpl::start_with_next([=](int index) {
|
|
||||||
if (index == 0) {
|
|
||||||
historyCurrencyList->toggle(true, anim::type::instant);
|
|
||||||
historyCreditsList->toggle(false, anim::type::instant);
|
|
||||||
} else if (index == 1) {
|
|
||||||
historyCurrencyList->toggle(false, anim::type::instant);
|
|
||||||
historyCreditsList->toggle(true, anim::type::instant);
|
|
||||||
}
|
}
|
||||||
}, container->lifetime());
|
|
||||||
|
|
||||||
if (hasCurrencyTab) {
|
{
|
||||||
Ui::AddSkip(container);
|
const auto &st = st::defaultTabsSlider;
|
||||||
|
slider->entity()->setNaturalWidth(0
|
||||||
|
+ (hasCurrencyTab
|
||||||
|
? st.labelStyle.font->width(currencyTabText)
|
||||||
|
: 0)
|
||||||
|
+ (hasCreditsTab
|
||||||
|
? st.labelStyle.font->width(creditsTabText)
|
||||||
|
: 0)
|
||||||
|
+ rect::m::sum::h(st::boxRowPadding));
|
||||||
|
}
|
||||||
|
|
||||||
const auto historyList = historyCurrencyList->entity();
|
if (hasOneTab) {
|
||||||
const auto addHistoryEntry = [=](
|
if (hasCurrencyTab) {
|
||||||
const Data::EarnHistoryEntry &entry,
|
AddHeader(listsContainer, tr::lng_channel_earn_history_title);
|
||||||
const tr::phrase<> &text) {
|
} else if (hasCreditsTab) {
|
||||||
const auto wrap = historyList->add(
|
AddHeader(
|
||||||
object_ptr<Ui::PaddingWrap<Ui::VerticalLayout>>(
|
listsContainer,
|
||||||
historyList,
|
tr::lng_channel_earn_credits_history);
|
||||||
object_ptr<Ui::VerticalLayout>(historyList),
|
slider->entity()->setActiveSectionFast(1);
|
||||||
QMargins()));
|
|
||||||
const auto inner = wrap->entity();
|
|
||||||
inner->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
inner->add(object_ptr<Ui::FlatLabel>(
|
|
||||||
inner,
|
|
||||||
text(),
|
|
||||||
st::channelEarnSemiboldLabel));
|
|
||||||
|
|
||||||
const auto isIn = entry.type == Data::EarnHistoryEntry::Type::In;
|
|
||||||
const auto recipient = Ui::Text::Wrapped(
|
|
||||||
{ entry.provider },
|
|
||||||
EntityType::Code);
|
|
||||||
if (!recipient.text.isEmpty()) {
|
|
||||||
Ui::AddSkip(inner, st::channelEarnHistoryThreeSkip);
|
|
||||||
const auto label = inner->add(object_ptr<Ui::FlatLabel>(
|
|
||||||
inner,
|
|
||||||
rpl::single(recipient),
|
|
||||||
st::channelEarnHistoryRecipientLabel));
|
|
||||||
label->setBreakEverywhere(true);
|
|
||||||
label->setTryMakeSimilarLines(true);
|
|
||||||
Ui::AddSkip(inner, st::channelEarnHistoryThreeSkip);
|
|
||||||
} else {
|
|
||||||
Ui::AddSkip(inner, st::channelEarnHistoryTwoSkip);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
slider->entity()->setActiveSectionFast(*sectionIndex);
|
||||||
|
}
|
||||||
|
|
||||||
const auto isFailed = entry.status
|
const auto tabCurrencyList = listsContainer->add(
|
||||||
== Data::EarnHistoryEntry::Status::Failed;
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
const auto isPending = entry.status
|
listsContainer,
|
||||||
== Data::EarnHistoryEntry::Status::Pending;
|
object_ptr<Ui::VerticalLayout>(listsContainer)));
|
||||||
const auto dateText = (!entry.dateTo.isNull() || isFailed)
|
const auto tabCreditsList = listsContainer->add(
|
||||||
? (FormatDate(entry.date)
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
+ ' '
|
listsContainer,
|
||||||
+ QChar(8212)
|
object_ptr<Ui::VerticalLayout>(listsContainer)));
|
||||||
+ ' '
|
|
||||||
+ (isFailed
|
|
||||||
? tr::lng_channel_earn_history_out_failed(tr::now)
|
|
||||||
: FormatDate(entry.dateTo)))
|
|
||||||
: isPending
|
|
||||||
? tr::lng_channel_earn_history_pending(tr::now)
|
|
||||||
: FormatDate(entry.date);
|
|
||||||
inner->add(object_ptr<Ui::FlatLabel>(
|
|
||||||
inner,
|
|
||||||
dateText,
|
|
||||||
st::channelEarnHistorySubLabel)
|
|
||||||
)->setTextColorOverride(isFailed
|
|
||||||
? std::make_optional<QColor>(st::menuIconAttentionColor->c)
|
|
||||||
: std::nullopt);
|
|
||||||
|
|
||||||
const auto color = (isIn
|
rpl::single(slider->entity()->activeSection()) | rpl::then(
|
||||||
? st::boxTextFgGood
|
slider->entity()->sectionActivated()
|
||||||
: st::menuIconAttentionColor)->c;
|
) | rpl::start_with_next([=](int index) {
|
||||||
const auto majorLabel = Ui::CreateChild<Ui::FlatLabel>(
|
if (index == 0) {
|
||||||
wrap,
|
tabCurrencyList->toggle(true, anim::type::instant);
|
||||||
st::channelEarnHistoryMajorLabel);
|
tabCreditsList->toggle(false, anim::type::instant);
|
||||||
addEmojiToMajor(majorLabel, rpl::single(entry.amount), isIn, {});
|
} else if (index == 1) {
|
||||||
majorLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
tabCurrencyList->toggle(false, anim::type::instant);
|
||||||
majorLabel->setTextColorOverride(color);
|
tabCreditsList->toggle(true, anim::type::instant);
|
||||||
const auto minorText = MinorPart(entry.amount);
|
}
|
||||||
const auto minorLabel = Ui::CreateChild<Ui::FlatLabel>(
|
*sectionIndex = index;
|
||||||
wrap,
|
}, listsContainer->lifetime());
|
||||||
rpl::single(minorText),
|
|
||||||
st::channelEarnHistoryMinorLabel);
|
|
||||||
minorLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
minorLabel->setTextColorOverride(color);
|
|
||||||
const auto button = Ui::CreateChild<Ui::SettingsButton>(
|
|
||||||
wrap,
|
|
||||||
rpl::single(QString()));
|
|
||||||
Ui::ToggleChildrenVisibility(wrap, true);
|
|
||||||
|
|
||||||
const auto detailsBox = [=, amount = entry.amount, peer = _peer](
|
if (hasCurrencyTab) {
|
||||||
not_null<Ui::GenericBox*> box) {
|
Ui::AddSkip(listsContainer);
|
||||||
box->addTopButton(
|
|
||||||
st::boxTitleClose,
|
|
||||||
[=] { box->closeBox(); });
|
|
||||||
Ui::AddSkip(box->verticalLayout());
|
|
||||||
Ui::AddSkip(box->verticalLayout());
|
|
||||||
const auto labels = box->addRow(
|
|
||||||
object_ptr<Ui::CenterWrap<Ui::RpWidget>>(
|
|
||||||
box,
|
|
||||||
object_ptr<Ui::RpWidget>(box)))->entity();
|
|
||||||
|
|
||||||
|
const auto historyList = tabCurrencyList->entity();
|
||||||
|
const auto addHistoryEntry = [=](
|
||||||
|
const Data::EarnHistoryEntry &entry,
|
||||||
|
const tr::phrase<> &text) {
|
||||||
|
const auto wrap = historyList->add(
|
||||||
|
object_ptr<Ui::PaddingWrap<Ui::VerticalLayout>>(
|
||||||
|
historyList,
|
||||||
|
object_ptr<Ui::VerticalLayout>(historyList),
|
||||||
|
QMargins()));
|
||||||
|
const auto inner = wrap->entity();
|
||||||
|
inner->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
inner->add(object_ptr<Ui::FlatLabel>(
|
||||||
|
inner,
|
||||||
|
text(),
|
||||||
|
st::channelEarnSemiboldLabel));
|
||||||
|
|
||||||
|
const auto isIn
|
||||||
|
= (entry.type == Data::EarnHistoryEntry::Type::In);
|
||||||
|
const auto recipient = Ui::Text::Wrapped(
|
||||||
|
{ entry.provider },
|
||||||
|
EntityType::Code);
|
||||||
|
if (!recipient.text.isEmpty()) {
|
||||||
|
Ui::AddSkip(inner, st::channelEarnHistoryThreeSkip);
|
||||||
|
const auto label = inner->add(object_ptr<Ui::FlatLabel>(
|
||||||
|
inner,
|
||||||
|
rpl::single(recipient),
|
||||||
|
st::channelEarnHistoryRecipientLabel));
|
||||||
|
label->setBreakEverywhere(true);
|
||||||
|
label->setTryMakeSimilarLines(true);
|
||||||
|
Ui::AddSkip(inner, st::channelEarnHistoryThreeSkip);
|
||||||
|
} else {
|
||||||
|
Ui::AddSkip(inner, st::channelEarnHistoryTwoSkip);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto isFailed = entry.status
|
||||||
|
== Data::EarnHistoryEntry::Status::Failed;
|
||||||
|
const auto isPending = entry.status
|
||||||
|
== Data::EarnHistoryEntry::Status::Pending;
|
||||||
|
const auto dateText = (!entry.dateTo.isNull() || isFailed)
|
||||||
|
? (FormatDate(entry.date)
|
||||||
|
+ ' '
|
||||||
|
+ QChar(8212)
|
||||||
|
+ ' '
|
||||||
|
+ (isFailed
|
||||||
|
? tr::lng_channel_earn_history_out_failed(tr::now)
|
||||||
|
: FormatDate(entry.dateTo)))
|
||||||
|
: isPending
|
||||||
|
? tr::lng_channel_earn_history_pending(tr::now)
|
||||||
|
: FormatDate(entry.date);
|
||||||
|
inner->add(object_ptr<Ui::FlatLabel>(
|
||||||
|
inner,
|
||||||
|
dateText,
|
||||||
|
st::channelEarnHistorySubLabel)
|
||||||
|
)->setTextColorOverride(isFailed
|
||||||
|
? std::make_optional<QColor>(
|
||||||
|
st::menuIconAttentionColor->c)
|
||||||
|
: std::nullopt);
|
||||||
|
|
||||||
|
const auto color = (isIn
|
||||||
|
? st::boxTextFgGood
|
||||||
|
: st::menuIconAttentionColor)->c;
|
||||||
const auto majorLabel = Ui::CreateChild<Ui::FlatLabel>(
|
const auto majorLabel = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
labels,
|
wrap,
|
||||||
st::channelEarnOverviewMajorLabel);
|
st::channelEarnHistoryMajorLabel);
|
||||||
addEmojiToMajor(majorLabel, rpl::single(amount), isIn, {});
|
addEmojiToMajor(
|
||||||
|
majorLabel,
|
||||||
|
rpl::single(entry.amount),
|
||||||
|
isIn,
|
||||||
|
{});
|
||||||
majorLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
majorLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
majorLabel->setTextColorOverride(color);
|
majorLabel->setTextColorOverride(color);
|
||||||
|
const auto minorText = MinorPart(entry.amount);
|
||||||
const auto minorLabel = Ui::CreateChild<Ui::FlatLabel>(
|
const auto minorLabel = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
labels,
|
wrap,
|
||||||
minorText,
|
rpl::single(minorText),
|
||||||
st::channelEarnOverviewMinorLabel);
|
st::channelEarnHistoryMinorLabel);
|
||||||
minorLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
minorLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
minorLabel->setTextColorOverride(color);
|
minorLabel->setTextColorOverride(color);
|
||||||
rpl::combine(
|
const auto button = Ui::CreateChild<Ui::SettingsButton>(
|
||||||
majorLabel->sizeValue(),
|
wrap,
|
||||||
minorLabel->sizeValue()
|
rpl::single(QString()));
|
||||||
) | rpl::start_with_next([=](
|
Ui::ToggleChildrenVisibility(wrap, true);
|
||||||
const QSize &majorSize,
|
|
||||||
const QSize &minorSize) {
|
|
||||||
labels->resize(
|
|
||||||
majorSize.width() + minorSize.width(),
|
|
||||||
majorSize.height());
|
|
||||||
majorLabel->moveToLeft(0, 0);
|
|
||||||
minorLabel->moveToRight(
|
|
||||||
0,
|
|
||||||
st::channelEarnOverviewMinorLabelSkip);
|
|
||||||
}, box->lifetime());
|
|
||||||
|
|
||||||
Ui::AddSkip(box->verticalLayout());
|
const auto detailsBox = [=, peer = _peer](
|
||||||
box->addRow(object_ptr<Ui::CenterWrap<>>(
|
not_null<Ui::GenericBox*> box) {
|
||||||
box,
|
box->addTopButton(
|
||||||
object_ptr<Ui::FlatLabel>(
|
st::boxTitleClose,
|
||||||
box,
|
[=] { box->closeBox(); });
|
||||||
dateText,
|
|
||||||
st::channelEarnHistorySubLabel)));
|
|
||||||
Ui::AddSkip(box->verticalLayout());
|
|
||||||
Ui::AddSkip(box->verticalLayout());
|
|
||||||
Ui::AddSkip(box->verticalLayout());
|
|
||||||
box->addRow(object_ptr<Ui::CenterWrap<>>(
|
|
||||||
box,
|
|
||||||
object_ptr<Ui::FlatLabel>(
|
|
||||||
box,
|
|
||||||
isIn
|
|
||||||
? tr::lng_channel_earn_history_in_about()
|
|
||||||
: tr::lng_channel_earn_history_out(),
|
|
||||||
st::channelEarnHistoryDescriptionLabel)));
|
|
||||||
Ui::AddSkip(box->verticalLayout());
|
|
||||||
if (isIn) {
|
|
||||||
Ui::AddSkip(box->verticalLayout());
|
Ui::AddSkip(box->verticalLayout());
|
||||||
}
|
Ui::AddSkip(box->verticalLayout());
|
||||||
|
const auto labels = box->addRow(
|
||||||
if (!recipient.text.isEmpty()) {
|
object_ptr<Ui::CenterWrap<Ui::RpWidget>>(
|
||||||
AddRecipient(box, recipient);
|
|
||||||
}
|
|
||||||
if (isIn) {
|
|
||||||
const auto peerBubble = box->addRow(
|
|
||||||
object_ptr<Ui::CenterWrap<>>(
|
|
||||||
box,
|
box,
|
||||||
object_ptr<Ui::RpWidget>(box)))->entity();
|
object_ptr<Ui::RpWidget>(box)))->entity();
|
||||||
peerBubble->setAttribute(
|
|
||||||
|
const auto majorLabel = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
|
labels,
|
||||||
|
st::channelEarnOverviewMajorLabel);
|
||||||
|
addEmojiToMajor(
|
||||||
|
majorLabel,
|
||||||
|
rpl::single(entry.amount),
|
||||||
|
isIn,
|
||||||
|
{});
|
||||||
|
majorLabel->setAttribute(
|
||||||
Qt::WA_TransparentForMouseEvents);
|
Qt::WA_TransparentForMouseEvents);
|
||||||
const auto left = Ui::CreateChild<Ui::UserpicButton>(
|
majorLabel->setTextColorOverride(color);
|
||||||
peerBubble,
|
const auto minorLabel = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
peer,
|
labels,
|
||||||
st::uploadUserpicButton);
|
minorText,
|
||||||
const auto right = Ui::CreateChild<Ui::FlatLabel>(
|
st::channelEarnOverviewMinorLabel);
|
||||||
peerBubble,
|
minorLabel->setAttribute(
|
||||||
Info::Profile::NameValue(peer),
|
Qt::WA_TransparentForMouseEvents);
|
||||||
st::channelEarnSemiboldLabel);
|
minorLabel->setTextColorOverride(color);
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
left->sizeValue(),
|
majorLabel->sizeValue(),
|
||||||
right->sizeValue()
|
minorLabel->sizeValue()
|
||||||
) | rpl::start_with_next([=](
|
) | rpl::start_with_next([=](
|
||||||
const QSize &leftSize,
|
const QSize &majorSize,
|
||||||
const QSize &rightSize) {
|
const QSize &minorSize) {
|
||||||
const auto padding = QMargins(
|
labels->resize(
|
||||||
st::chatGiveawayPeerPadding.left() * 2,
|
majorSize.width() + minorSize.width(),
|
||||||
st::chatGiveawayPeerPadding.top(),
|
majorSize.height());
|
||||||
st::chatGiveawayPeerPadding.right(),
|
majorLabel->moveToLeft(0, 0);
|
||||||
st::chatGiveawayPeerPadding.bottom());
|
minorLabel->moveToRight(
|
||||||
peerBubble->resize(
|
0,
|
||||||
leftSize.width()
|
st::channelEarnOverviewMinorLabelSkip);
|
||||||
+ rightSize.width()
|
}, box->lifetime());
|
||||||
+ rect::m::sum::h(padding),
|
|
||||||
leftSize.height());
|
Ui::AddSkip(box->verticalLayout());
|
||||||
left->moveToLeft(0, 0);
|
box->addRow(object_ptr<Ui::CenterWrap<>>(
|
||||||
right->moveToRight(padding.right(), padding.top());
|
box,
|
||||||
const auto maxRightSize = box->width()
|
object_ptr<Ui::FlatLabel>(
|
||||||
- rect::m::sum::h(st::boxRowPadding)
|
box,
|
||||||
- rect::m::sum::h(padding)
|
dateText,
|
||||||
- leftSize.width();
|
st::channelEarnHistorySubLabel)));
|
||||||
if (rightSize.width() > maxRightSize) {
|
Ui::AddSkip(box->verticalLayout());
|
||||||
right->resizeToWidth(maxRightSize);
|
Ui::AddSkip(box->verticalLayout());
|
||||||
}
|
Ui::AddSkip(box->verticalLayout());
|
||||||
}, peerBubble->lifetime());
|
box->addRow(object_ptr<Ui::CenterWrap<>>(
|
||||||
peerBubble->paintRequest(
|
box,
|
||||||
) | rpl::start_with_next([=] {
|
object_ptr<Ui::FlatLabel>(
|
||||||
auto p = QPainter(peerBubble);
|
box,
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
isIn
|
||||||
p.setPen(Qt::NoPen);
|
? tr::lng_channel_earn_history_in_about()
|
||||||
p.setBrush(st::windowBgOver);
|
: tr::lng_channel_earn_history_out(),
|
||||||
const auto rect = peerBubble->rect();
|
st::channelEarnHistoryDescriptionLabel)));
|
||||||
const auto radius = rect.height() / 2;
|
Ui::AddSkip(box->verticalLayout());
|
||||||
p.drawRoundedRect(rect, radius, radius);
|
if (isIn) {
|
||||||
}, peerBubble->lifetime());
|
Ui::AddSkip(box->verticalLayout());
|
||||||
}
|
|
||||||
{
|
|
||||||
const auto &st = st::premiumPreviewDoubledLimitsBox;
|
|
||||||
box->setStyle(st);
|
|
||||||
auto button = object_ptr<Ui::RoundButton>(
|
|
||||||
container,
|
|
||||||
(!entry.successLink.isEmpty())
|
|
||||||
? tr::lng_channel_earn_history_out_button()
|
|
||||||
: tr::lng_box_ok(),
|
|
||||||
st::defaultActiveButton);
|
|
||||||
button->resizeToWidth(box->width()
|
|
||||||
- st.buttonPadding.left()
|
|
||||||
- st.buttonPadding.left());
|
|
||||||
if (!entry.successLink.isEmpty()) {
|
|
||||||
button->setAcceptBoth();
|
|
||||||
button->addClickHandler([=](Qt::MouseButton button) {
|
|
||||||
if (button == Qt::LeftButton) {
|
|
||||||
UrlClickHandler::Open(entry.successLink);
|
|
||||||
} else if (button == Qt::RightButton) {
|
|
||||||
ShowMenu(box, entry.successLink);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
button->setClickedCallback([=] { box->closeBox(); });
|
|
||||||
}
|
}
|
||||||
box->addButton(std::move(button));
|
|
||||||
}
|
|
||||||
Ui::AddSkip(box->verticalLayout());
|
|
||||||
Ui::AddSkip(box->verticalLayout());
|
|
||||||
box->addButton(tr::lng_box_ok(), [=] { box->closeBox(); });
|
|
||||||
};
|
|
||||||
|
|
||||||
button->setClickedCallback([=] {
|
if (!recipient.text.isEmpty()) {
|
||||||
_show->showBox(Box(detailsBox));
|
AddRecipient(box, recipient);
|
||||||
});
|
}
|
||||||
wrap->geometryValue(
|
if (isIn) {
|
||||||
) | rpl::start_with_next([=](const QRect &g) {
|
const auto peerBubble = box->addRow(
|
||||||
const auto &padding = st::boxRowPadding;
|
object_ptr<Ui::CenterWrap<>>(
|
||||||
const auto majorTop = (g.height() - majorLabel->height()) / 2;
|
box,
|
||||||
minorLabel->moveToRight(
|
object_ptr<Ui::RpWidget>(box)))->entity();
|
||||||
padding.right(),
|
peerBubble->setAttribute(
|
||||||
majorTop + st::channelEarnHistoryMinorLabelSkip);
|
Qt::WA_TransparentForMouseEvents);
|
||||||
majorLabel->moveToRight(
|
const auto left = Ui::CreateChild<Ui::UserpicButton>(
|
||||||
padding.right() + minorLabel->width(),
|
peerBubble,
|
||||||
majorTop);
|
peer,
|
||||||
const auto rightWrapPadding = rect::m::sum::h(padding)
|
st::uploadUserpicButton);
|
||||||
+ minorLabel->width()
|
const auto right = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
+ majorLabel->width();
|
peerBubble,
|
||||||
wrap->setPadding(
|
Info::Profile::NameValue(peer),
|
||||||
st::channelEarnHistoryOuter
|
st::channelEarnSemiboldLabel);
|
||||||
|
rpl::combine(
|
||||||
|
left->sizeValue(),
|
||||||
|
right->sizeValue()
|
||||||
|
) | rpl::start_with_next([=](
|
||||||
|
const QSize &leftSize,
|
||||||
|
const QSize &rightSize) {
|
||||||
|
const auto padding = QMargins(
|
||||||
|
st::chatGiveawayPeerPadding.left() * 2,
|
||||||
|
st::chatGiveawayPeerPadding.top(),
|
||||||
|
st::chatGiveawayPeerPadding.right(),
|
||||||
|
st::chatGiveawayPeerPadding.bottom());
|
||||||
|
peerBubble->resize(
|
||||||
|
leftSize.width()
|
||||||
|
+ rightSize.width()
|
||||||
|
+ rect::m::sum::h(padding),
|
||||||
|
leftSize.height());
|
||||||
|
left->moveToLeft(0, 0);
|
||||||
|
right->moveToRight(
|
||||||
|
padding.right(),
|
||||||
|
padding.top());
|
||||||
|
const auto maxRightSize = box->width()
|
||||||
|
- rect::m::sum::h(st::boxRowPadding)
|
||||||
|
- rect::m::sum::h(padding)
|
||||||
|
- leftSize.width();
|
||||||
|
if (rightSize.width() > maxRightSize) {
|
||||||
|
right->resizeToWidth(maxRightSize);
|
||||||
|
}
|
||||||
|
}, peerBubble->lifetime());
|
||||||
|
peerBubble->paintRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
auto p = QPainter(peerBubble);
|
||||||
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(st::windowBgOver);
|
||||||
|
const auto rect = peerBubble->rect();
|
||||||
|
const auto radius = rect.height() / 2;
|
||||||
|
p.drawRoundedRect(rect, radius, radius);
|
||||||
|
}, peerBubble->lifetime());
|
||||||
|
}
|
||||||
|
const auto closeBox = [=] { box->closeBox(); };
|
||||||
|
{
|
||||||
|
const auto &st = st::premiumPreviewDoubledLimitsBox;
|
||||||
|
box->setStyle(st);
|
||||||
|
auto button = object_ptr<Ui::RoundButton>(
|
||||||
|
box,
|
||||||
|
(!entry.successLink.isEmpty())
|
||||||
|
? tr::lng_channel_earn_history_out_button()
|
||||||
|
: tr::lng_box_ok(),
|
||||||
|
st::defaultActiveButton);
|
||||||
|
button->resizeToWidth(box->width()
|
||||||
|
- st.buttonPadding.left()
|
||||||
|
- st.buttonPadding.left());
|
||||||
|
if (!entry.successLink.isEmpty()) {
|
||||||
|
button->setAcceptBoth();
|
||||||
|
button->addClickHandler([=](
|
||||||
|
Qt::MouseButton button) {
|
||||||
|
if (button == Qt::LeftButton) {
|
||||||
|
UrlClickHandler::Open(entry.successLink);
|
||||||
|
} else if (button == Qt::RightButton) {
|
||||||
|
ShowMenu(box, entry.successLink);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
button->setClickedCallback(closeBox);
|
||||||
|
}
|
||||||
|
box->addButton(std::move(button));
|
||||||
|
}
|
||||||
|
Ui::AddSkip(box->verticalLayout());
|
||||||
|
Ui::AddSkip(box->verticalLayout());
|
||||||
|
box->addButton(tr::lng_box_ok(), closeBox);
|
||||||
|
};
|
||||||
|
|
||||||
|
button->setClickedCallback([=] {
|
||||||
|
_show->showBox(Box(detailsBox));
|
||||||
|
});
|
||||||
|
wrap->geometryValue(
|
||||||
|
) | rpl::start_with_next([=](const QRect &g) {
|
||||||
|
const auto &padding = st::boxRowPadding;
|
||||||
|
const auto majorTop = (g.height() - majorLabel->height())
|
||||||
|
/ 2;
|
||||||
|
minorLabel->moveToRight(
|
||||||
|
padding.right(),
|
||||||
|
majorTop + st::channelEarnHistoryMinorLabelSkip);
|
||||||
|
majorLabel->moveToRight(
|
||||||
|
padding.right() + minorLabel->width(),
|
||||||
|
majorTop);
|
||||||
|
const auto rightWrapPadding = rect::m::sum::h(padding)
|
||||||
|
+ minorLabel->width()
|
||||||
|
+ majorLabel->width();
|
||||||
|
wrap->setPadding(st::channelEarnHistoryOuter
|
||||||
+ QMargins(padding.left(), 0, rightWrapPadding, 0));
|
+ QMargins(padding.left(), 0, rightWrapPadding, 0));
|
||||||
button->resize(g.size());
|
button->resize(g.size());
|
||||||
button->lower();
|
button->lower();
|
||||||
}, wrap->lifetime());
|
}, wrap->lifetime());
|
||||||
};
|
};
|
||||||
const auto handleSlice = [=](const Data::EarnHistorySlice &slice) {
|
const auto handleSlice = [=](const Data::EarnHistorySlice &s) {
|
||||||
for (const auto &entry : slice.list) {
|
using Type = Data::EarnHistoryEntry::Type;
|
||||||
addHistoryEntry(
|
for (const auto &entry : s.list) {
|
||||||
entry,
|
addHistoryEntry(
|
||||||
(entry.type == Data::EarnHistoryEntry::Type::In)
|
entry,
|
||||||
? tr::lng_channel_earn_history_in
|
(entry.type == Type::In)
|
||||||
: (entry.type == Data::EarnHistoryEntry::Type::Return)
|
? tr::lng_channel_earn_history_in
|
||||||
? tr::lng_channel_earn_history_return
|
: (entry.type == Type::Return)
|
||||||
: tr::lng_channel_earn_history_out);
|
? tr::lng_channel_earn_history_return
|
||||||
}
|
: tr::lng_channel_earn_history_out);
|
||||||
historyList->resizeToWidth(container->width());
|
|
||||||
};
|
|
||||||
handleSlice(data.firstHistorySlice);
|
|
||||||
if (!data.firstHistorySlice.allLoaded) {
|
|
||||||
struct ShowMoreState final {
|
|
||||||
ShowMoreState(not_null<ChannelData*> channel)
|
|
||||||
: api(channel) {
|
|
||||||
}
|
}
|
||||||
Api::ChannelEarnStatistics api;
|
historyList->resizeToWidth(listsContainer->width());
|
||||||
bool loading = false;
|
|
||||||
Data::EarnHistorySlice::OffsetToken token;
|
|
||||||
rpl::variable<int> showed = 0;
|
|
||||||
};
|
};
|
||||||
const auto state = lifetime().make_state<ShowMoreState>(channel);
|
const auto &firstSlice = data.currencyEarn.firstHistorySlice;
|
||||||
state->token = data.firstHistorySlice.token;
|
handleSlice(firstSlice);
|
||||||
state->showed = data.firstHistorySlice.list.size();
|
if (!firstSlice.allLoaded) {
|
||||||
const auto max = data.firstHistorySlice.total;
|
struct ShowMoreState final {
|
||||||
const auto wrap = container->add(
|
ShowMoreState(not_null<ChannelData*> channel)
|
||||||
object_ptr<Ui::SlideWrap<Ui::SettingsButton>>(
|
: api(channel) {
|
||||||
container,
|
}
|
||||||
object_ptr<Ui::SettingsButton>(
|
Api::ChannelEarnStatistics api;
|
||||||
container,
|
bool loading = false;
|
||||||
tr::lng_channel_earn_history_show_more(
|
Data::EarnHistorySlice::OffsetToken token;
|
||||||
lt_count,
|
rpl::variable<int> showed = 0;
|
||||||
state->showed.value(
|
};
|
||||||
) | rpl::map(
|
const auto state
|
||||||
max - rpl::mappers::_1
|
= lifetime().make_state<ShowMoreState>(channel);
|
||||||
) | tr::to_count()),
|
state->token = firstSlice.token;
|
||||||
st::statisticsShowMoreButton)));
|
state->showed = firstSlice.list.size();
|
||||||
const auto button = wrap->entity();
|
const auto max = firstSlice.total;
|
||||||
AddArrow(button);
|
const auto wrap = listsContainer->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::SettingsButton>>(
|
||||||
|
listsContainer,
|
||||||
|
object_ptr<Ui::SettingsButton>(
|
||||||
|
listsContainer,
|
||||||
|
tr::lng_channel_earn_history_show_more(
|
||||||
|
lt_count,
|
||||||
|
state->showed.value(
|
||||||
|
) | rpl::map(
|
||||||
|
max - rpl::mappers::_1
|
||||||
|
) | tr::to_count()),
|
||||||
|
st::statisticsShowMoreButton)));
|
||||||
|
const auto button = wrap->entity();
|
||||||
|
AddArrow(button);
|
||||||
|
|
||||||
wrap->toggle(true, anim::type::instant);
|
wrap->toggle(true, anim::type::instant);
|
||||||
const auto handleReceived = [=](Data::EarnHistorySlice slice) {
|
const auto handleReceived = [=](
|
||||||
state->loading = false;
|
Data::EarnHistorySlice slice) {
|
||||||
handleSlice(slice);
|
state->loading = false;
|
||||||
wrap->toggle(!slice.allLoaded, anim::type::instant);
|
handleSlice(slice);
|
||||||
state->token = slice.token;
|
wrap->toggle(!slice.allLoaded, anim::type::instant);
|
||||||
state->showed = state->showed.current() + slice.list.size();
|
state->token = slice.token;
|
||||||
};
|
state->showed = state->showed.current()
|
||||||
button->setClickedCallback([=] {
|
+ slice.list.size();
|
||||||
if (!state->loading) {
|
};
|
||||||
|
button->setClickedCallback([=] {
|
||||||
|
if (state->loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
state->loading = true;
|
state->loading = true;
|
||||||
state->api.requestHistory(state->token, handleReceived);
|
state->api.requestHistory(state->token, handleReceived);
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
Ui::AddSkip(container);
|
if (hasCreditsTab) {
|
||||||
Ui::AddDivider(container);
|
const auto controller = _controller->parentController();
|
||||||
Ui::AddSkip(container);
|
const auto show = controller->uiShow();
|
||||||
}
|
const auto premiumBot = _peer->owner().peer(data.premiumBotId);
|
||||||
if (hasCreditsTab) {
|
const auto entryClicked = [=](
|
||||||
const auto controller = _controller->parentController();
|
const Data::CreditsHistoryEntry &e) {
|
||||||
const auto show = controller->uiShow();
|
show->show(Box(
|
||||||
const auto premiumBot = _peer->owner().peer(_state.premiumBotId);
|
::Settings::ReceiptCreditsBox,
|
||||||
const auto entryClicked = [=](const Data::CreditsHistoryEntry &e) {
|
controller,
|
||||||
show->show(Box(
|
premiumBot.get(),
|
||||||
::Settings::ReceiptCreditsBox,
|
e));
|
||||||
controller,
|
};
|
||||||
premiumBot.get(),
|
|
||||||
e));
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto star = historyCreditsList->lifetime().make_state<QImage>(
|
const auto star = tabCreditsList->lifetime().make_state<QImage>(
|
||||||
Ui::GenerateStars(st::creditsTopupButton.height, 1));
|
Ui::GenerateStars(st::creditsTopupButton.height, 1));
|
||||||
|
|
||||||
|
Info::Statistics::AddCreditsHistoryList(
|
||||||
|
show,
|
||||||
|
data.creditsStatusSlice,
|
||||||
|
tabCreditsList->entity(),
|
||||||
|
entryClicked,
|
||||||
|
premiumBot,
|
||||||
|
star,
|
||||||
|
true,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
if (hasCurrencyTab || hasCreditsTab) {
|
||||||
|
Ui::AddSkip(listsContainer);
|
||||||
|
Ui::AddDivider(listsContainer);
|
||||||
|
Ui::AddSkip(listsContainer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto historyContainer = container->add(
|
||||||
|
object_ptr<Ui::VerticalLayout>(container));
|
||||||
|
rpl::single(rpl::empty) | rpl::then(
|
||||||
|
_stateUpdated.events()
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
const auto listsContainer = historyContainer->add(
|
||||||
|
object_ptr<Ui::VerticalLayout>(container));
|
||||||
|
rebuildLists(_state, listsContainer);
|
||||||
|
while (historyContainer->count() > 1) {
|
||||||
|
delete historyContainer->widgetAt(0);
|
||||||
|
}
|
||||||
|
}, historyContainer->lifetime());
|
||||||
|
|
||||||
Info::Statistics::AddCreditsHistoryList(
|
|
||||||
show,
|
|
||||||
_state.creditsStatusSlice,
|
|
||||||
historyCreditsList->entity(),
|
|
||||||
entryClicked,
|
|
||||||
premiumBot,
|
|
||||||
star,
|
|
||||||
true,
|
|
||||||
true);
|
|
||||||
Ui::AddSkip(container);
|
|
||||||
Ui::AddDivider(container);
|
|
||||||
Ui::AddSkip(container);
|
|
||||||
}
|
|
||||||
if (channel) {
|
if (channel) {
|
||||||
//constexpr auto kMaxCPM = 50; // Debug.
|
//constexpr auto kMaxCPM = 50; // Debug.
|
||||||
const auto requiredLevel = Data::LevelLimits(session)
|
const auto requiredLevel = Data::LevelLimits(session)
|
||||||
|
|
Loading…
Add table
Reference in a new issue