mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-08-10 05:33:50 +00:00
Switched top bar suggestion driver to spec table.
This commit is contained in:
@@ -8,51 +8,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "dialogs/dialogs_top_bar_suggestion.h"
|
||||
|
||||
#include "api/api_authorizations.h"
|
||||
#include "api/api_credits.h"
|
||||
#include "api/api_peer_photo.h"
|
||||
#include "api/api_premium.h"
|
||||
#include "apiwrap.h"
|
||||
#include "base/call_delayed.h"
|
||||
#include "boxes/star_gift_box.h" // ShowStarGiftBox.
|
||||
#include "boxes/star_gift_auction_box.h"
|
||||
#include "boxes/unconfirmed_auth_denied_box.h"
|
||||
#include "core/application.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "core/ui_integration.h"
|
||||
#include "data/components/gift_auctions.h"
|
||||
#include "data/components/promo_suggestions.h"
|
||||
#include "data/data_birthday.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_peer_values.h" // Data::AmPremiumValue.
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "dialogs/suggestions/suggestion.h"
|
||||
#include "dialogs/ui/dialogs_top_bar_suggestion_content.h"
|
||||
#include "history/view/history_view_group_call_bar.h"
|
||||
#include "info/profile/info_profile_values.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "settings/sections/settings_active_sessions.h"
|
||||
#include "settings/settings_credits_graphics.h"
|
||||
#include "settings/sections/settings_premium.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/controls/userpic_button.h"
|
||||
#include "ui/effects/credits_graphics.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/rect.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/vertical_list.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
||||
namespace Dialogs {
|
||||
namespace {
|
||||
@@ -64,88 +33,6 @@ namespace {
|
||||
return window->sessionController();
|
||||
}
|
||||
|
||||
[[nodiscard]] QString FormatAuthInfo(const Data::UnreviewedAuth &auth) {
|
||||
const auto location = auth.location.isEmpty()
|
||||
? QString()
|
||||
: "\U0001F30D " + auth.location;
|
||||
const auto device = auth.device.isEmpty()
|
||||
? QString()
|
||||
: "\U0001F4F1 " + auth.device;
|
||||
|
||||
if (!location.isEmpty() && !device.isEmpty()) {
|
||||
return location + " (" + device + ")";
|
||||
} else if (!location.isEmpty()) {
|
||||
return location;
|
||||
} else if (!device.isEmpty()) {
|
||||
return device;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void ShowAuthToast(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
not_null<Main::Session*> session,
|
||||
const std::vector<Data::UnreviewedAuth> &list,
|
||||
bool confirmed) {
|
||||
if (confirmed) {
|
||||
auto text = tr::lng_unconfirmed_auth_confirmed_message(
|
||||
tr::now,
|
||||
lt_link,
|
||||
tr::link(tr::lng_settings_sessions_title(tr::now)),
|
||||
tr::rich);
|
||||
auto filter = [=](
|
||||
ClickHandlerPtr handler,
|
||||
Qt::MouseButton button) {
|
||||
if (const auto controller = FindSessionController(parent)) {
|
||||
session->api().authorizations().reload();
|
||||
controller->showSettings(Settings::SessionsId());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
Ui::Toast::Show(parent->window(), Ui::Toast::Config{
|
||||
.title = tr::lng_unconfirmed_auth_confirmed(tr::now),
|
||||
.text = std::move(text),
|
||||
.filter = std::move(filter),
|
||||
.duration = crl::time(5000),
|
||||
});
|
||||
} else {
|
||||
auto messageText = QString();
|
||||
if (list.size() == 1) {
|
||||
messageText = tr::lng_unconfirmed_auth_denied_single(
|
||||
tr::now,
|
||||
lt_country,
|
||||
FormatAuthInfo(list.front()));
|
||||
} else {
|
||||
auto authList = QString('\n');
|
||||
for (auto i = 0; i < std::min(int(list.size()), 10); ++i) {
|
||||
const auto info = FormatAuthInfo(list[i]);
|
||||
if (!info.isEmpty()) {
|
||||
authList += "• " + info + "\n";
|
||||
}
|
||||
}
|
||||
messageText = tr::lng_unconfirmed_auth_denied_multiple(
|
||||
tr::now,
|
||||
lt_country,
|
||||
authList);
|
||||
}
|
||||
if (const auto controller = FindSessionController(parent)) {
|
||||
const auto count = float64(list.size());
|
||||
controller->show(Box(ShowAuthDeniedBox, count, messageText));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto kSugSetBirthday = "BIRTHDAY_SETUP"_cs;
|
||||
constexpr auto kSugBirthdayContacts = "BIRTHDAY_CONTACTS_TODAY"_cs;
|
||||
constexpr auto kSugPremiumAnnual = "PREMIUM_ANNUAL"_cs;
|
||||
constexpr auto kSugPremiumUpgrade = "PREMIUM_UPGRADE"_cs;
|
||||
constexpr auto kSugPremiumRestore = "PREMIUM_RESTORE"_cs;
|
||||
constexpr auto kSugPremiumGrace = "PREMIUM_GRACE"_cs;
|
||||
constexpr auto kSugSetUserpic = "USERPIC_SETUP"_cs;
|
||||
constexpr auto kSugLowCreditsSubs = "STARS_SUBSCRIPTION_LOW_BALANCE"_cs;
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
|
||||
@@ -169,21 +56,18 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
|
||||
|
||||
struct State {
|
||||
TopBarSuggestionContent *content = nullptr;
|
||||
UnconfirmedAuthWrap *unconfirmedWarning = nullptr;
|
||||
base::unique_qptr<Ui::SlideWrap<Ui::RpWidget>> wrap;
|
||||
rpl::variable<Toggle> desiredWrapToggle;
|
||||
rpl::variable<bool> outerWrapToggle;
|
||||
rpl::lifetime birthdayLifetime;
|
||||
rpl::lifetime premiumLifetime;
|
||||
rpl::lifetime userpicLifetime;
|
||||
rpl::lifetime creditsLifetime;
|
||||
rpl::lifetime auctionsLifetime;
|
||||
std::unique_ptr<Api::CreditsHistory> creditsHistory;
|
||||
rpl::lifetime activeLifetime;
|
||||
Fn<void()> prepareSnapshot;
|
||||
};
|
||||
|
||||
const auto state = lifetime.make_state<State>();
|
||||
state->outerWrapToggle = rpl::duplicate(outerWrapToggleValue);
|
||||
const auto ensureContent = [=] {
|
||||
|
||||
const auto ensureContent
|
||||
= [=]() -> not_null<TopBarSuggestionContent*> {
|
||||
if (!state->content) {
|
||||
const auto window = FindSessionController(parent);
|
||||
state->content = Ui::CreateChild<TopBarSuggestionContent>(
|
||||
@@ -193,497 +77,92 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
|
||||
state->content->setCollapseProgress(
|
||||
rpl::duplicate(childListShown));
|
||||
}
|
||||
return state->content;
|
||||
};
|
||||
const auto ensureWrap = [=](not_null<Ui::RpWidget*> child) {
|
||||
if (!state->wrap) {
|
||||
state->wrap
|
||||
= base::make_unique_q<Ui::SlideWrap<Ui::RpWidget>>(
|
||||
parent,
|
||||
object_ptr<Ui::RpWidget>::fromRaw(child));
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ false, anim::type::instant });
|
||||
}
|
||||
|
||||
const auto context = TopBarSuggestions::Context{
|
||||
.parent = parent,
|
||||
.session = session,
|
||||
.ensureContent = ensureContent,
|
||||
.findController = [=]()
|
||||
-> not_null<Window::SessionController*> {
|
||||
return FindSessionController(parent);
|
||||
},
|
||||
.childListShown = [=]() -> rpl::producer<float64> {
|
||||
return rpl::duplicate(childListShown);
|
||||
},
|
||||
};
|
||||
|
||||
const auto specs = lifetime.make_state<std::vector<
|
||||
TopBarSuggestions::Spec>>(TopBarSuggestions::AllSpecs());
|
||||
ranges::sort(
|
||||
*specs,
|
||||
std::greater<>(),
|
||||
&TopBarSuggestions::Spec::priority);
|
||||
|
||||
const auto processCurrentSuggestion = [=](auto repeat) -> void {
|
||||
state->birthdayLifetime.destroy();
|
||||
state->premiumLifetime.destroy();
|
||||
state->userpicLifetime.destroy();
|
||||
state->creditsLifetime.destroy();
|
||||
state->auctionsLifetime.destroy();
|
||||
state->activeLifetime.destroy();
|
||||
|
||||
if (!session->api().authorizations().unreviewed().empty()) {
|
||||
state->content = nullptr;
|
||||
state->wrap = nullptr;
|
||||
const auto &list
|
||||
= session->api().authorizations().unreviewed();
|
||||
const auto hashes = ranges::views::all(
|
||||
list
|
||||
) | ranges::views::transform([](const auto &auth) {
|
||||
return auth.hash;
|
||||
}) | ranges::to_vector;
|
||||
const auto recompute = [=] { repeat(repeat); };
|
||||
const auto wonHere = std::make_shared<bool>(false);
|
||||
const auto activated = std::make_shared<bool>(false);
|
||||
|
||||
const auto content = CreateUnconfirmedAuthContent(
|
||||
parent,
|
||||
list,
|
||||
[=](bool confirmed) {
|
||||
ShowAuthToast(parent, session, list, confirmed);
|
||||
session->api().authorizations().review(
|
||||
hashes,
|
||||
confirmed);
|
||||
for (auto i = 0; i < int(specs->size()); ++i) {
|
||||
const auto &spec = (*specs)[i];
|
||||
if (!spec.available(context)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*activated = true;
|
||||
|
||||
auto args = TopBarSuggestions::ActivateArgs{
|
||||
.context = context,
|
||||
.lifetime = &state->activeLifetime,
|
||||
.done = [=](
|
||||
not_null<Ui::RpWidget*> widget,
|
||||
Fn<void()> prepareSnapshot) {
|
||||
if (state->wrap
|
||||
&& state->wrap->entity() != widget.get()) {
|
||||
state->wrap = nullptr;
|
||||
if (widget.get() != state->content) {
|
||||
state->content = nullptr;
|
||||
}
|
||||
state->prepareSnapshot = nullptr;
|
||||
}
|
||||
if (!state->wrap) {
|
||||
state->wrap = base::make_unique_q<
|
||||
Ui::SlideWrap<Ui::RpWidget>>(
|
||||
parent,
|
||||
object_ptr<Ui::RpWidget>::fromRaw(widget));
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ false, anim::type::instant });
|
||||
state->prepareSnapshot = std::move(
|
||||
prepareSnapshot);
|
||||
}
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ true, anim::type::normal });
|
||||
*wonHere = true;
|
||||
},
|
||||
rpl::duplicate(childListShown));
|
||||
ensureWrap(content);
|
||||
const auto wasUnconfirmedWarning = state->unconfirmedWarning;
|
||||
state->unconfirmedWarning = content;
|
||||
state->desiredWrapToggle.force_assign(Toggle{
|
||||
true,
|
||||
(state->unconfirmedWarning != wasUnconfirmedWarning)
|
||||
? anim::type::instant
|
||||
: anim::type::normal,
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
if (state->unconfirmedWarning) {
|
||||
state->unconfirmedWarning = nullptr;
|
||||
state->wrap = nullptr;
|
||||
}
|
||||
.recompute = recompute,
|
||||
};
|
||||
spec.activate(std::move(args));
|
||||
break;
|
||||
}
|
||||
|
||||
ensureContent();
|
||||
ensureWrap(state->content);
|
||||
const auto content = state->content;
|
||||
if (*wonHere || *activated) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state->wrap) {
|
||||
return;
|
||||
}
|
||||
const auto wrap = state->wrap.get();
|
||||
using RightIcon = TopBarSuggestionContent::RightIcon;
|
||||
const auto promo = &session->promoSuggestions();
|
||||
const auto auctions = &session->giftAuctions();
|
||||
if (auctions->hasActive()) {
|
||||
using namespace Data;
|
||||
struct Button {
|
||||
rpl::variable<TextWithEntities> text;
|
||||
Fn<void()> callback;
|
||||
base::has_weak_ptr guard;
|
||||
};
|
||||
auto &lifetime = state->auctionsLifetime;
|
||||
const auto button = lifetime.template make_state<Button>();
|
||||
const auto window = FindSessionController(parent);
|
||||
auctions->active(
|
||||
) | rpl::on_next([=](ActiveAuctions &&active) {
|
||||
const auto empty = active.list.empty();
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ !empty, anim::type::normal });
|
||||
if (empty) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto text = Ui::ActiveAuctionsState(active);
|
||||
const auto textColorOverride = text.someOutbid
|
||||
? st::attentionButtonFg->c
|
||||
: std::optional<QColor>();
|
||||
content->setContent(
|
||||
Ui::ActiveAuctionsTitle(active),
|
||||
std::move(text.text),
|
||||
Core::TextContext({ .session = session }),
|
||||
textColorOverride);
|
||||
button->text = Ui::ActiveAuctionsButton(active);
|
||||
button->callback = Ui::ActiveAuctionsCallback(
|
||||
window,
|
||||
active);
|
||||
}, state->auctionsLifetime);
|
||||
const auto callback = crl::guard(&button->guard, [=] {
|
||||
button->callback();
|
||||
});
|
||||
content->setRightButton(button->text.value(), callback);
|
||||
content->setClickedCallback(callback);
|
||||
content->setLeadingWidget(nullptr);
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ true, anim::type::normal });
|
||||
return;
|
||||
} else if (const auto custom = promo->custom()) {
|
||||
content->setRightIcon(RightIcon::Close);
|
||||
content->setLeadingWidget(nullptr);
|
||||
content->setClickedCallback([=] {
|
||||
const auto controller = FindSessionController(parent);
|
||||
UrlClickHandler::Open(
|
||||
custom->url,
|
||||
QVariant::fromValue(ClickHandlerContext{
|
||||
.sessionWindow = base::make_weak(controller),
|
||||
}));
|
||||
});
|
||||
content->setHideCallback([=] {
|
||||
promo->dismiss(custom->suggestion);
|
||||
repeat(repeat);
|
||||
});
|
||||
|
||||
content->setContent(
|
||||
custom->title,
|
||||
custom->description,
|
||||
Core::TextContext({ .session = session }));
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ true, anim::type::normal });
|
||||
return;
|
||||
} else if (session->premiumCanBuy()
|
||||
&& promo->current(kSugPremiumGrace.utf8())) {
|
||||
content->setRightIcon(RightIcon::Close);
|
||||
content->setLeadingWidget(nullptr);
|
||||
content->setClickedCallback([=] {
|
||||
const auto controller = FindSessionController(parent);
|
||||
UrlClickHandler::Open(
|
||||
u"https://t.me/premiumbot?start=status"_q,
|
||||
QVariant::fromValue(ClickHandlerContext{
|
||||
.sessionWindow = base::make_weak(controller),
|
||||
}));
|
||||
});
|
||||
content->setHideCallback([=] {
|
||||
promo->dismiss(kSugPremiumGrace.utf8());
|
||||
repeat(repeat);
|
||||
});
|
||||
content->setContent(
|
||||
tr::lng_dialogs_suggestions_premium_grace_title(
|
||||
tr::now,
|
||||
tr::bold),
|
||||
tr::lng_dialogs_suggestions_premium_grace_about(
|
||||
tr::now,
|
||||
TextWithEntities::Simple));
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ true, anim::type::normal });
|
||||
return;
|
||||
} else if (session->premiumCanBuy()
|
||||
&& promo->current(kSugLowCreditsSubs.utf8())) {
|
||||
state->creditsHistory = std::make_unique<Api::CreditsHistory>(
|
||||
session->user(),
|
||||
false,
|
||||
false);
|
||||
const auto show = [=](
|
||||
const QString &peers,
|
||||
uint64 needed,
|
||||
uint64 whole) {
|
||||
if (whole > needed) {
|
||||
return;
|
||||
}
|
||||
content->setRightIcon(RightIcon::Close);
|
||||
content->setLeadingWidget(nullptr);
|
||||
content->setClickedCallback([=] {
|
||||
const auto controller = FindSessionController(parent);
|
||||
controller->uiShow()->show(Box(
|
||||
Settings::SmallBalanceBox,
|
||||
controller->uiShow(),
|
||||
needed,
|
||||
Settings::SmallBalanceSubscription{ peers },
|
||||
[=] {
|
||||
promo->dismiss(kSugLowCreditsSubs.utf8());
|
||||
repeat(repeat);
|
||||
}));
|
||||
});
|
||||
content->setHideCallback([=] {
|
||||
promo->dismiss(kSugLowCreditsSubs.utf8());
|
||||
repeat(repeat);
|
||||
});
|
||||
|
||||
content->setContent(
|
||||
tr::lng_dialogs_suggestions_credits_sub_low_title(
|
||||
tr::now,
|
||||
lt_count,
|
||||
float64(needed - whole),
|
||||
lt_emoji,
|
||||
Ui::MakeCreditsIconEntity(),
|
||||
lt_channels,
|
||||
{ peers },
|
||||
tr::bold),
|
||||
tr::lng_dialogs_suggestions_credits_sub_low_about(
|
||||
tr::now,
|
||||
TextWithEntities::Simple),
|
||||
Ui::MakeCreditsIconContext(
|
||||
content->contentTitleSt().font->height,
|
||||
1));
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ true, anim::type::normal });
|
||||
};
|
||||
session->credits().load();
|
||||
state->creditsLifetime.destroy();
|
||||
session->credits().balanceValue() | rpl::on_next([=] {
|
||||
state->creditsLifetime.destroy();
|
||||
state->creditsHistory->requestSubscriptions(
|
||||
Data::CreditsStatusSlice::OffsetToken(),
|
||||
[=](Data::CreditsStatusSlice slice) {
|
||||
state->creditsHistory = nullptr;
|
||||
auto peers = QStringList();
|
||||
auto credits = uint64(0);
|
||||
for (const auto &entry : slice.subscriptions) {
|
||||
if (entry.barePeerId) {
|
||||
const auto peer = session->data().peer(
|
||||
PeerId(entry.barePeerId));
|
||||
peers.append(peer->name());
|
||||
credits += entry.subscription.credits;
|
||||
}
|
||||
}
|
||||
show(
|
||||
peers.join(", "),
|
||||
credits,
|
||||
session->credits().balance().whole());
|
||||
},
|
||||
true);
|
||||
}, state->creditsLifetime);
|
||||
|
||||
return;
|
||||
} else if (session->premiumCanBuy()
|
||||
&& promo->current(kSugBirthdayContacts.utf8())) {
|
||||
promo->requestContactBirthdays(crl::guard(content, [=] {
|
||||
const auto users = promo->knownBirthdaysToday().value_or(
|
||||
std::vector<UserId>());
|
||||
if (users.empty()) {
|
||||
repeat(repeat);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto controller = FindSessionController(parent);
|
||||
const auto isSingle = users.size() == 1;
|
||||
const auto first = session->data().user(users.front());
|
||||
content->setRightIcon(RightIcon::Close);
|
||||
content->setClickedCallback([=] {
|
||||
if (isSingle) {
|
||||
Ui::ShowStarGiftBox(controller, first);
|
||||
} else {
|
||||
Ui::ChooseStarGiftRecipient(controller);
|
||||
}
|
||||
});
|
||||
content->setHideCallback([=] {
|
||||
promo->dismiss(kSugBirthdayContacts.utf8());
|
||||
controller->showToast(
|
||||
tr::lng_dialogs_suggestions_birthday_contact_dismiss(
|
||||
tr::now));
|
||||
repeat(repeat);
|
||||
});
|
||||
auto title = isSingle
|
||||
? tr::lng_dialogs_suggestions_birthday_contact_title(
|
||||
tr::now,
|
||||
lt_text,
|
||||
{ first->shortName() },
|
||||
tr::rich)
|
||||
: tr::lng_dialogs_suggestions_birthday_contacts_title(
|
||||
tr::now,
|
||||
lt_count,
|
||||
users.size(),
|
||||
tr::rich);
|
||||
auto text = isSingle
|
||||
? tr::lng_dialogs_suggestions_birthday_contact_about(
|
||||
tr::now,
|
||||
TextWithEntities::Simple)
|
||||
: tr::lng_dialogs_suggestions_birthday_contacts_about(
|
||||
tr::now,
|
||||
TextWithEntities::Simple);
|
||||
content->setContent(std::move(title), std::move(text));
|
||||
if (!isSingle) {
|
||||
struct UserViews {
|
||||
std::vector<HistoryView::UserpicInRow> inRow;
|
||||
QImage userpics;
|
||||
};
|
||||
auto inRow
|
||||
= std::vector<HistoryView::UserpicInRow>();
|
||||
for (const auto &id : users) {
|
||||
if (inRow.size() >= 3) {
|
||||
break;
|
||||
}
|
||||
if (const auto user = session->data().user(id)) {
|
||||
inRow.push_back({ .peer = user });
|
||||
}
|
||||
}
|
||||
const auto &userpicsSt
|
||||
= st::historyCommentsUserpics;
|
||||
const auto rowCount = int(inRow.size());
|
||||
const auto rowWidth
|
||||
= rowCount * userpicsSt.size - userpicsSt.shift;
|
||||
const auto rowHeight = userpicsSt.size;
|
||||
const auto widget
|
||||
= Ui::CreateChild<Ui::RpWidget>(content);
|
||||
widget->resize(rowWidth, rowHeight);
|
||||
const auto s = widget->lifetime(
|
||||
).template make_state<UserViews>();
|
||||
s->inRow = std::move(inRow);
|
||||
widget->paintRequest() | rpl::on_next([=] {
|
||||
auto p = QPainter(widget);
|
||||
if (HistoryView::NeedRegenerateUserpics(
|
||||
s->userpics,
|
||||
s->inRow)) {
|
||||
HistoryView::GenerateUserpicsInRow(
|
||||
s->userpics,
|
||||
s->inRow,
|
||||
st::historyCommentsUserpics,
|
||||
3);
|
||||
}
|
||||
p.drawImage(0, 0, s->userpics);
|
||||
}, widget->lifetime());
|
||||
content->setLeadingWidget(widget);
|
||||
} else {
|
||||
const auto fake = Ui::CreateChild<Ui::UserpicButton>(
|
||||
content,
|
||||
first,
|
||||
st::uploadUserpicButton);
|
||||
content->setLeadingWidget(fake);
|
||||
}
|
||||
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ true, anim::type::normal });
|
||||
}));
|
||||
return;
|
||||
} else if (promo->current(kSugSetBirthday.utf8())
|
||||
&& !Data::IsBirthdayToday(session->user()->birthday())) {
|
||||
content->setRightIcon(RightIcon::Close);
|
||||
content->setLeadingWidget(nullptr);
|
||||
content->setClickedCallback([=] {
|
||||
const auto controller = FindSessionController(parent);
|
||||
Core::App().openInternalUrl(
|
||||
u"internal:edit_birthday:add_privacy"_q,
|
||||
QVariant::fromValue(ClickHandlerContext{
|
||||
.sessionWindow = base::make_weak(controller),
|
||||
}));
|
||||
|
||||
state->birthdayLifetime = Info::Profile::BirthdayValue(
|
||||
session->user()
|
||||
) | rpl::map(
|
||||
Data::IsBirthdayTodayValue
|
||||
) | rpl::flatten_latest(
|
||||
) | rpl::distinct_until_changed(
|
||||
) | rpl::on_next([=] {
|
||||
repeat(repeat);
|
||||
});
|
||||
});
|
||||
content->setHideCallback([=] {
|
||||
promo->dismiss(kSugSetBirthday.utf8());
|
||||
repeat(repeat);
|
||||
});
|
||||
content->setContent(
|
||||
tr::lng_dialogs_suggestions_birthday_title(
|
||||
tr::now,
|
||||
tr::bold),
|
||||
tr::lng_dialogs_suggestions_birthday_about(
|
||||
tr::now,
|
||||
TextWithEntities::Simple));
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ true, anim::type::normal });
|
||||
return;
|
||||
} else if (session->premiumPossible() && !session->premium()) {
|
||||
const auto isPremiumAnnual = promo->current(
|
||||
kSugPremiumAnnual.utf8());
|
||||
const auto isPremiumRestore = !isPremiumAnnual
|
||||
&& promo->current(kSugPremiumRestore.utf8());
|
||||
const auto isPremiumUpgrade = !isPremiumAnnual
|
||||
&& !isPremiumRestore
|
||||
&& promo->current(kSugPremiumUpgrade.utf8());
|
||||
const auto set = [=](QString discount) {
|
||||
constexpr auto kMinus = QChar(0x2212);
|
||||
const auto &title = isPremiumAnnual
|
||||
? tr::lng_dialogs_suggestions_premium_annual_title
|
||||
: isPremiumRestore
|
||||
? tr::lng_dialogs_suggestions_premium_restore_title
|
||||
: tr::lng_dialogs_suggestions_premium_upgrade_title;
|
||||
const auto &description = isPremiumAnnual
|
||||
? tr::lng_dialogs_suggestions_premium_annual_about
|
||||
: isPremiumRestore
|
||||
? tr::lng_dialogs_suggestions_premium_restore_about
|
||||
: tr::lng_dialogs_suggestions_premium_upgrade_about;
|
||||
content->setContent(
|
||||
title(
|
||||
tr::now,
|
||||
lt_text,
|
||||
{ discount.replace(kMinus, QChar()) },
|
||||
tr::bold),
|
||||
description(tr::now, TextWithEntities::Simple));
|
||||
content->setClickedCallback([=] {
|
||||
const auto controller = FindSessionController(parent);
|
||||
Settings::ShowPremium(controller, "dialogs_hint");
|
||||
promo->dismiss(isPremiumAnnual
|
||||
? kSugPremiumAnnual.utf8()
|
||||
: isPremiumRestore
|
||||
? kSugPremiumRestore.utf8()
|
||||
: kSugPremiumUpgrade.utf8());
|
||||
repeat(repeat);
|
||||
});
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ true, anim::type::normal });
|
||||
};
|
||||
if (isPremiumAnnual || isPremiumRestore || isPremiumUpgrade) {
|
||||
content->setRightIcon(RightIcon::Arrow);
|
||||
content->setLeadingWidget(nullptr);
|
||||
const auto api = &session->api().premium();
|
||||
api->statusTextValue() | rpl::on_next([=] {
|
||||
for (const auto &o : api->subscriptionOptions()) {
|
||||
if (o.months == 12) {
|
||||
set(o.discount);
|
||||
state->premiumLifetime.destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, state->premiumLifetime);
|
||||
api->reload();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (promo->current(kSugSetUserpic.utf8())
|
||||
&& !session->user()->userpicPhotoId()) {
|
||||
const auto controller = FindSessionController(parent);
|
||||
content->setRightIcon(RightIcon::Close);
|
||||
const auto upload = Ui::CreateChild<Ui::UserpicButton>(
|
||||
content,
|
||||
&controller->window(),
|
||||
Ui::UserpicButton::Role::ChoosePhoto,
|
||||
st::uploadUserpicButton);
|
||||
content->setLeadingWidget(upload);
|
||||
upload->chosenImages() | rpl::on_next([=](
|
||||
Ui::UserpicButton::ChosenImage &&chosen) {
|
||||
if (chosen.type == Ui::UserpicButton::ChosenType::Set) {
|
||||
session->api().peerPhoto().upload(
|
||||
session->user(),
|
||||
{
|
||||
std::move(chosen.image),
|
||||
chosen.markup.documentId,
|
||||
chosen.markup.colors,
|
||||
});
|
||||
}
|
||||
}, upload->lifetime());
|
||||
|
||||
state->userpicLifetime = session->changes().peerUpdates(
|
||||
session->user(),
|
||||
Data::PeerUpdate::Flag::Photo
|
||||
) | rpl::on_next([=] {
|
||||
if (session->user()->userpicPhotoId()) {
|
||||
repeat(repeat);
|
||||
}
|
||||
});
|
||||
|
||||
content->setHideCallback([=] {
|
||||
promo->dismiss(kSugSetUserpic.utf8());
|
||||
repeat(repeat);
|
||||
});
|
||||
|
||||
content->setClickedCallback([=] {
|
||||
const auto syntetic = [=](QEvent::Type type) {
|
||||
Ui::SendSynteticMouseEvent(
|
||||
upload,
|
||||
type,
|
||||
Qt::LeftButton,
|
||||
upload->mapToGlobal(QPoint(0, 0)));
|
||||
};
|
||||
syntetic(QEvent::MouseMove);
|
||||
syntetic(QEvent::MouseButtonPress);
|
||||
syntetic(QEvent::MouseButtonRelease);
|
||||
});
|
||||
content->setContent(
|
||||
tr::lng_dialogs_suggestions_userpics_title(
|
||||
tr::now,
|
||||
tr::bold),
|
||||
tr::lng_dialogs_suggestions_userpics_about(
|
||||
tr::now,
|
||||
TextWithEntities::Simple));
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ true, anim::type::normal });
|
||||
return;
|
||||
}
|
||||
state->desiredWrapToggle.force_assign(
|
||||
Toggle{ false, anim::type::normal });
|
||||
base::call_delayed(st::slideWrapDuration * 2, wrap, [=] {
|
||||
state->content = nullptr;
|
||||
state->wrap = nullptr;
|
||||
state->prepareSnapshot = nullptr;
|
||||
consumer.put_next(nullptr);
|
||||
});
|
||||
};
|
||||
@@ -724,10 +203,8 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
|
||||
}, lifetime);
|
||||
|
||||
rpl::duplicate(prepareCollapseSnapshot) | rpl::on_next([=] {
|
||||
if (state->unconfirmedWarning) {
|
||||
state->unconfirmedWarning->prepareCollapseSnapshot();
|
||||
} else if (state->content) {
|
||||
state->content->prepareCollapseSnapshot();
|
||||
if (state->prepareSnapshot) {
|
||||
state->prepareSnapshot();
|
||||
}
|
||||
}, lifetime);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user