mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-14 13:17:08 +02:00
Show toast on invite attempt to premium required.
This commit is contained in:
parent
f3f660a180
commit
f6a95df550
7 changed files with 193 additions and 145 deletions
|
@ -565,8 +565,9 @@ bool PremiumGiftCodeOptions::giveawayGiftsPurchaseAvailable() const {
|
|||
}
|
||||
|
||||
RequirePremiumState ResolveRequiresPremiumToWrite(
|
||||
not_null<History*> history) {
|
||||
const auto user = history->peer->asUser();
|
||||
not_null<PeerData*> peer,
|
||||
History *maybeHistory) {
|
||||
const auto user = peer->asUser();
|
||||
if (!user
|
||||
|| !user->someRequirePremiumToWrite()
|
||||
|| user->session().premium()) {
|
||||
|
@ -575,21 +576,36 @@ RequirePremiumState ResolveRequiresPremiumToWrite(
|
|||
return user->meRequiresPremiumToWrite()
|
||||
? RequirePremiumState::Yes
|
||||
: RequirePremiumState::No;
|
||||
} else if (user->flags() & UserDataFlag::MutualContact) {
|
||||
return RequirePremiumState::No;
|
||||
} else if (!maybeHistory) {
|
||||
return RequirePremiumState::Unknown;
|
||||
}
|
||||
|
||||
const auto update = [&](bool require) {
|
||||
using Flag = UserDataFlag;
|
||||
constexpr auto known = Flag::RequirePremiumToWriteKnown;
|
||||
constexpr auto me = Flag::MeRequiresPremiumToWrite;
|
||||
user->setFlags((user->flags() & ~me)
|
||||
| known
|
||||
| (require ? me : Flag()));
|
||||
};
|
||||
// We allow this potentially-heavy loop because in case we've opened
|
||||
// the chat and have a lot of messages `requires_premium` will be known.
|
||||
for (const auto &block : history->blocks) {
|
||||
for (const auto &block : maybeHistory->blocks) {
|
||||
for (const auto &view : block->messages) {
|
||||
const auto item = view->data();
|
||||
if (!item->out() && !item->isService()) {
|
||||
using Flag = UserDataFlag;
|
||||
constexpr auto known = Flag::RequirePremiumToWriteKnown;
|
||||
constexpr auto me = Flag::MeRequiresPremiumToWrite;
|
||||
user->setFlags((user->flags() | known) & ~me);
|
||||
update(false);
|
||||
return RequirePremiumState::No;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (user->isContact() // Here we know, that we're not in his contacts.
|
||||
&& maybeHistory->loadedAtTop() // And no incoming messages.
|
||||
&& maybeHistory->loadedAtBottom()) {
|
||||
update(true);
|
||||
}
|
||||
return RequirePremiumState::Unknown;
|
||||
}
|
||||
|
||||
|
|
|
@ -212,6 +212,7 @@ enum class RequirePremiumState {
|
|||
No,
|
||||
};
|
||||
[[nodiscard]] RequirePremiumState ResolveRequiresPremiumToWrite(
|
||||
not_null<History*> history);
|
||||
not_null<PeerData*> peer,
|
||||
History *maybeHistory);
|
||||
|
||||
} // namespace Api
|
||||
|
|
|
@ -258,27 +258,24 @@ bool PeerListGlobalSearchController::isLoading() {
|
|||
return _timer.isActive() || _requestId;
|
||||
}
|
||||
|
||||
void ChatsListBoxController::RowDelegate::rowPreloadUserpic(
|
||||
not_null<Row*> row) {
|
||||
row->PeerListRow::preloadUserpic();
|
||||
RecipientRow::RecipientRow(
|
||||
not_null<PeerData*> peer,
|
||||
const style::PeerListItem *maybeLockedSt,
|
||||
History *maybeHistory)
|
||||
: PeerListRow(peer)
|
||||
, _maybeHistory(maybeHistory)
|
||||
, _resolvePremiumRequired(maybeLockedSt != nullptr) {
|
||||
if (maybeLockedSt
|
||||
&& (Api::ResolveRequiresPremiumToWrite(peer, maybeHistory)
|
||||
== Api::RequirePremiumState::Yes)) {
|
||||
_lockedSt = maybeLockedSt;
|
||||
}
|
||||
}
|
||||
|
||||
ChatsListBoxController::Row::Row(
|
||||
not_null<History*> history,
|
||||
RowDelegate *delegate)
|
||||
: PeerListRow(history->peer)
|
||||
, _history(history)
|
||||
, _delegate(delegate) {
|
||||
}
|
||||
|
||||
auto ChatsListBoxController::Row::generatePaintUserpicCallback(
|
||||
bool forceRound)
|
||||
-> PaintRoundImageCallback {
|
||||
PaintRoundImageCallback RecipientRow::generatePaintUserpicCallback(
|
||||
bool forceRound) {
|
||||
auto result = PeerListRow::generatePaintUserpicCallback(forceRound);
|
||||
if (_locked) {
|
||||
const auto st = _delegate
|
||||
? _delegate->rowSt().get()
|
||||
: &st::defaultPeerListItem;
|
||||
if (const auto st = _lockedSt) {
|
||||
return [=](Painter &p, int x, int y, int outerWidth, int size) {
|
||||
result(p, x, y, outerWidth, size);
|
||||
PaintPremiumRequiredLock(p, st, x, y, outerWidth, size);
|
||||
|
@ -287,12 +284,62 @@ auto ChatsListBoxController::Row::generatePaintUserpicCallback(
|
|||
return result;
|
||||
}
|
||||
|
||||
void ChatsListBoxController::Row::preloadUserpic() {
|
||||
if (_delegate) {
|
||||
_delegate->rowPreloadUserpic(this);
|
||||
} else {
|
||||
PeerListRow::preloadUserpic();
|
||||
bool RecipientRow::refreshLock(
|
||||
not_null<const style::PeerListItem*> maybeLockedSt) {
|
||||
if (const auto user = peer()->asUser()) {
|
||||
const auto locked = _resolvePremiumRequired
|
||||
&& (Api::ResolveRequiresPremiumToWrite(user, _maybeHistory)
|
||||
== Api::RequirePremiumState::Yes);
|
||||
if (this->locked() != locked) {
|
||||
setLocked(locked ? maybeLockedSt.get() : nullptr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RecipientRow::preloadUserpic() {
|
||||
PeerListRow::preloadUserpic();
|
||||
|
||||
if (!_resolvePremiumRequired) {
|
||||
return;
|
||||
} else if (Api::ResolveRequiresPremiumToWrite(peer(), _maybeHistory)
|
||||
== Api::RequirePremiumState::Unknown) {
|
||||
const auto user = peer()->asUser();
|
||||
user->session().api().premium().resolvePremiumRequired(user);
|
||||
}
|
||||
}
|
||||
|
||||
void TrackPremiumRequiredChanges(
|
||||
not_null<PeerListController*> controller,
|
||||
rpl::lifetime &lifetime) {
|
||||
const auto session = &controller->session();
|
||||
rpl::merge(
|
||||
Data::AmPremiumValue(session) | rpl::to_empty,
|
||||
session->api().premium().somePremiumRequiredResolved()
|
||||
) | rpl::start_with_next([=] {
|
||||
const auto st = &controller->computeListSt().item;
|
||||
const auto delegate = controller->delegate();
|
||||
const auto process = [&](not_null<PeerListRow*> raw) {
|
||||
if (static_cast<RecipientRow*>(raw.get())->refreshLock(st)) {
|
||||
delegate->peerListUpdateRow(raw);
|
||||
}
|
||||
};
|
||||
auto count = delegate->peerListFullRowsCount();
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
process(delegate->peerListRowAt(i));
|
||||
}
|
||||
count = delegate->peerListSearchRowsCount();
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
process(delegate->peerListSearchRowAt(i));
|
||||
}
|
||||
}, lifetime);
|
||||
}
|
||||
|
||||
ChatsListBoxController::Row::Row(
|
||||
not_null<History*> history,
|
||||
const style::PeerListItem *maybeLockedSt)
|
||||
: RecipientRow(history->peer, maybeLockedSt, history) {
|
||||
}
|
||||
|
||||
ChatsListBoxController::ChatsListBoxController(
|
||||
|
@ -662,7 +709,7 @@ std::unique_ptr<PeerListRow> ContactsBoxController::createRow(
|
|||
return std::make_unique<PeerListRow>(user);
|
||||
}
|
||||
|
||||
ChooseRecipientPremiumRequiredError WritePremiumRequiredError(
|
||||
RecipientPremiumRequiredError WritePremiumRequiredError(
|
||||
not_null<UserData*> user) {
|
||||
return {
|
||||
.text = tr::lng_send_non_premium_message_toast(
|
||||
|
@ -706,52 +753,13 @@ void ChooseRecipientBoxController::prepareViewHook() {
|
|||
delegate()->peerListSetTitle(tr::lng_forward_choose());
|
||||
|
||||
if (_premiumRequiredError) {
|
||||
rpl::merge(
|
||||
Data::AmPremiumValue(_session) | rpl::to_empty,
|
||||
_session->api().premium().somePremiumRequiredResolved()
|
||||
) | rpl::start_with_next([=] {
|
||||
refreshLockedRows();
|
||||
}, _lifetime);
|
||||
TrackPremiumRequiredChanges(this, lifetime());
|
||||
}
|
||||
}
|
||||
|
||||
void ChooseRecipientBoxController::refreshLockedRows() {
|
||||
const auto process = [&](not_null<PeerListRow*> raw) {
|
||||
const auto row = static_cast<Row*>(raw.get());
|
||||
if (const auto user = row->peer()->asUser()) {
|
||||
const auto history = row->history();
|
||||
const auto locked = (Api::ResolveRequiresPremiumToWrite(history)
|
||||
== Api::RequirePremiumState::Yes);
|
||||
if (row->locked() != locked) {
|
||||
row->setLocked(locked);
|
||||
delegate()->peerListUpdateRow(row);
|
||||
}
|
||||
}
|
||||
};
|
||||
auto count = delegate()->peerListFullRowsCount();
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
process(delegate()->peerListRowAt(i));
|
||||
}
|
||||
count = delegate()->peerListSearchRowsCount();
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
process(delegate()->peerListSearchRowAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
void ChooseRecipientBoxController::rowPreloadUserpic(not_null<Row*> row) {
|
||||
row->PeerListRow::preloadUserpic();
|
||||
|
||||
if (!_premiumRequiredError) {
|
||||
return;
|
||||
} else if (Api::ResolveRequiresPremiumToWrite(row->history())
|
||||
== Api::RequirePremiumState::Unknown) {
|
||||
const auto user = row->peer()->asUser();
|
||||
session().api().premium().resolvePremiumRequired(user);
|
||||
}
|
||||
}
|
||||
|
||||
not_null<const style::PeerListItem*> ChooseRecipientBoxController::rowSt() {
|
||||
return &computeListSt().item;
|
||||
bool ChooseRecipientBoxController::showLockedError(
|
||||
not_null<PeerListRow*> row) {
|
||||
return RecipientRow::ShowLockedError(this, row, _premiumRequiredError);
|
||||
}
|
||||
|
||||
void ChooseRecipientBoxController::rowClicked(not_null<PeerListRow*> row) {
|
||||
|
@ -808,15 +816,17 @@ void ChooseRecipientBoxController::rowClicked(not_null<PeerListRow*> row) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ChooseRecipientBoxController::showLockedError(
|
||||
not_null<PeerListRow*> row) const {
|
||||
if (!static_cast<Row*>(row.get())->locked()) {
|
||||
bool RecipientRow::ShowLockedError(
|
||||
not_null<PeerListController*> controller,
|
||||
not_null<PeerListRow*> row,
|
||||
Fn<RecipientPremiumRequiredError(not_null<UserData*>)> error) {
|
||||
if (!static_cast<RecipientRow*>(row.get())->locked()) {
|
||||
return false;
|
||||
}
|
||||
::Settings::ShowPremiumPromoToast(
|
||||
delegate()->peerListUiShow(),
|
||||
controller->delegate()->peerListUiShow(),
|
||||
ChatHelpers::ResolveWindowDefault(),
|
||||
_premiumRequiredError(row->peer()->asUser()).text,
|
||||
error(row->peer()->asUser()).text,
|
||||
u"require_premium"_q);
|
||||
return true;
|
||||
}
|
||||
|
@ -840,13 +850,7 @@ auto ChooseRecipientBoxController::createRow(
|
|||
}
|
||||
auto result = std::make_unique<Row>(
|
||||
history,
|
||||
static_cast<RowDelegate*>(this));
|
||||
if (_premiumRequiredError) {
|
||||
const auto require = Api::ResolveRequiresPremiumToWrite(history);
|
||||
if (require == Api::RequirePremiumState::Yes) {
|
||||
result->setLocked(true);
|
||||
}
|
||||
}
|
||||
_premiumRequiredError ? &computeListSt().item : nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,38 +93,63 @@ private:
|
|||
|
||||
};
|
||||
|
||||
struct RecipientPremiumRequiredError {
|
||||
TextWithEntities text;
|
||||
};
|
||||
|
||||
[[nodiscard]] RecipientPremiumRequiredError WritePremiumRequiredError(
|
||||
not_null<UserData*> user);
|
||||
|
||||
class RecipientRow : public PeerListRow {
|
||||
public:
|
||||
explicit RecipientRow(
|
||||
not_null<PeerData*> peer,
|
||||
const style::PeerListItem *maybeLockedSt = nullptr,
|
||||
History *maybeHistory = nullptr);
|
||||
|
||||
bool refreshLock(not_null<const style::PeerListItem*> maybeLockedSt);
|
||||
|
||||
[[nodiscard]] static bool ShowLockedError(
|
||||
not_null<PeerListController*> controller,
|
||||
not_null<PeerListRow*> row,
|
||||
Fn<RecipientPremiumRequiredError(not_null<UserData*>)> error);
|
||||
|
||||
[[nodiscard]] History *maybeHistory() const {
|
||||
return _maybeHistory;
|
||||
}
|
||||
[[nodiscard]] bool locked() const {
|
||||
return _lockedSt != nullptr;
|
||||
}
|
||||
void setLocked(const style::PeerListItem *lockedSt) {
|
||||
_lockedSt = lockedSt;
|
||||
}
|
||||
PaintRoundImageCallback generatePaintUserpicCallback(
|
||||
bool forceRound) override;
|
||||
|
||||
void preloadUserpic() override;
|
||||
|
||||
private:
|
||||
History *_maybeHistory = nullptr;
|
||||
const style::PeerListItem *_lockedSt = nullptr;
|
||||
bool _resolvePremiumRequired = false;
|
||||
|
||||
};
|
||||
|
||||
void TrackPremiumRequiredChanges(
|
||||
not_null<PeerListController*> controller,
|
||||
rpl::lifetime &lifetime);
|
||||
|
||||
class ChatsListBoxController : public PeerListController {
|
||||
public:
|
||||
class Row;
|
||||
class RowDelegate {
|
||||
class Row : public RecipientRow {
|
||||
public:
|
||||
virtual void rowPreloadUserpic(not_null<Row*> row);
|
||||
[[nodiscard]] virtual auto rowSt()
|
||||
-> not_null<const style::PeerListItem*> = 0;
|
||||
};
|
||||
|
||||
class Row : public PeerListRow {
|
||||
public:
|
||||
Row(not_null<History*> history, RowDelegate *delegate = nullptr);
|
||||
Row(
|
||||
not_null<History*> history,
|
||||
const style::PeerListItem *maybeLockedSt = nullptr);
|
||||
|
||||
[[nodiscard]] not_null<History*> history() const {
|
||||
return _history;
|
||||
return maybeHistory();
|
||||
}
|
||||
[[nodiscard]] bool locked() const {
|
||||
return _locked;
|
||||
}
|
||||
void setLocked(bool locked) {
|
||||
_locked = locked;
|
||||
}
|
||||
PaintRoundImageCallback generatePaintUserpicCallback(
|
||||
bool forceRound) override;
|
||||
|
||||
void preloadUserpic() override;
|
||||
|
||||
private:
|
||||
const not_null<History*> _history;
|
||||
RowDelegate *_delegate = nullptr;
|
||||
bool _locked = false;
|
||||
|
||||
};
|
||||
|
||||
|
@ -231,26 +256,18 @@ private:
|
|||
|
||||
};
|
||||
|
||||
struct ChooseRecipientPremiumRequiredError {
|
||||
TextWithEntities text;
|
||||
};
|
||||
|
||||
[[nodiscard]] ChooseRecipientPremiumRequiredError WritePremiumRequiredError(
|
||||
not_null<UserData*> user);
|
||||
|
||||
struct ChooseRecipientArgs {
|
||||
not_null<Main::Session*> session;
|
||||
FnMut<void(not_null<Data::Thread*>)> callback;
|
||||
Fn<bool(not_null<Data::Thread*>)> filter;
|
||||
|
||||
using PremiumRequiredError = ChooseRecipientPremiumRequiredError;
|
||||
using PremiumRequiredError = RecipientPremiumRequiredError;
|
||||
Fn<PremiumRequiredError(not_null<UserData*>)> premiumRequiredError;
|
||||
};
|
||||
|
||||
class ChooseRecipientBoxController
|
||||
: public ChatsListBoxController
|
||||
, public base::has_weak_ptr
|
||||
, private ChatsListBoxController::RowDelegate {
|
||||
, public base::has_weak_ptr {
|
||||
public:
|
||||
ChooseRecipientBoxController(
|
||||
not_null<Main::Session*> session,
|
||||
|
@ -267,21 +284,15 @@ protected:
|
|||
void prepareViewHook() override;
|
||||
std::unique_ptr<Row> createRow(not_null<History*> history) override;
|
||||
|
||||
[[nodiscard]] bool showLockedError(not_null<PeerListRow*> row) const;
|
||||
bool showLockedError(not_null<PeerListRow*> row);
|
||||
|
||||
private:
|
||||
void refreshLockedRows();
|
||||
void rowPreloadUserpic(not_null<Row*> row) override;
|
||||
not_null<const style::PeerListItem*> rowSt() override;
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
FnMut<void(not_null<Data::Thread*>)> _callback;
|
||||
Fn<bool(not_null<Data::Thread*>)> _filter;
|
||||
Fn<ChooseRecipientPremiumRequiredError(
|
||||
Fn<RecipientPremiumRequiredError(
|
||||
not_null<UserData*>)> _premiumRequiredError;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
class ChooseTopicSearchController : public PeerListSearchController {
|
||||
|
|
|
@ -267,6 +267,10 @@ void AddParticipantsBoxController::subscribeToMigration() {
|
|||
}
|
||||
|
||||
void AddParticipantsBoxController::rowClicked(not_null<PeerListRow*> row) {
|
||||
const auto premiumRequiredError = WritePremiumRequiredError;
|
||||
if (RecipientRow::ShowLockedError(this, row, premiumRequiredError)) {
|
||||
return;
|
||||
}
|
||||
const auto &serverConfig = session().serverConfig();
|
||||
auto count = fullCount();
|
||||
auto limit = _peer && (_peer->isChat() || _peer->isMegagroup())
|
||||
|
@ -332,8 +336,10 @@ std::unique_ptr<PeerListRow> AddParticipantsBoxController::createRow(
|
|||
if (user->isSelf()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto result = std::make_unique<PeerListRow>(user);
|
||||
if (isAlreadyIn(user)) {
|
||||
const auto already = isAlreadyIn(user);
|
||||
const auto maybeLockedSt = already ? nullptr : &computeListSt().item;
|
||||
auto result = std::make_unique<RecipientRow>(user, maybeLockedSt);
|
||||
if (already) {
|
||||
result->setDisabledState(PeerListRow::State::DisabledChecked);
|
||||
}
|
||||
return result;
|
||||
|
@ -707,6 +713,8 @@ void AddSpecialBoxController::prepare() {
|
|||
loadMoreRows();
|
||||
}
|
||||
delegate()->peerListRefreshRows();
|
||||
|
||||
TrackPremiumRequiredChanges(this, lifetime());
|
||||
}
|
||||
|
||||
void AddSpecialBoxController::prepareChatRows(not_null<ChatData*> chat) {
|
||||
|
|
|
@ -741,8 +741,10 @@ void ShareBox::Inner::refreshLockedRows() {
|
|||
auto changed = false;
|
||||
for (const auto &[peer, data] : _dataMap) {
|
||||
const auto history = data->history;
|
||||
const auto locked = (Api::ResolveRequiresPremiumToWrite(history)
|
||||
== Api::RequirePremiumState::Yes);
|
||||
const auto locked = (Api::ResolveRequiresPremiumToWrite(
|
||||
history->peer,
|
||||
history
|
||||
) == Api::RequirePremiumState::Yes);
|
||||
if (data->locked != locked) {
|
||||
data->locked = locked;
|
||||
changed = true;
|
||||
|
@ -750,8 +752,10 @@ void ShareBox::Inner::refreshLockedRows() {
|
|||
}
|
||||
for (const auto &data : d_byUsernameFiltered) {
|
||||
const auto history = data->history;
|
||||
const auto locked = (Api::ResolveRequiresPremiumToWrite(history)
|
||||
== Api::RequirePremiumState::Yes);
|
||||
const auto locked = (Api::ResolveRequiresPremiumToWrite(
|
||||
history->peer,
|
||||
history
|
||||
) == Api::RequirePremiumState::Yes);
|
||||
if (data->locked != locked) {
|
||||
data->locked = locked;
|
||||
changed = true;
|
||||
|
@ -821,8 +825,10 @@ void ShareBox::Inner::updateChatName(not_null<Chat*> chat) {
|
|||
void ShareBox::Inner::initChatLocked(not_null<Chat*> chat) {
|
||||
if (_descriptor.premiumRequiredError) {
|
||||
const auto history = chat->history;
|
||||
const auto require = Api::ResolveRequiresPremiumToWrite(history);
|
||||
if (require == Api::RequirePremiumState::Yes) {
|
||||
if (Api::ResolveRequiresPremiumToWrite(
|
||||
history->peer,
|
||||
history
|
||||
) == Api::RequirePremiumState::Yes) {
|
||||
chat->locked = true;
|
||||
}
|
||||
}
|
||||
|
@ -949,8 +955,10 @@ void ShareBox::Inner::preloadUserpic(not_null<Dialogs::Entry*> entry) {
|
|||
const auto history = entry->asHistory();
|
||||
if (!_descriptor.premiumRequiredError || !history) {
|
||||
return;
|
||||
} else if (Api::ResolveRequiresPremiumToWrite(history)
|
||||
== Api::RequirePremiumState::Unknown) {
|
||||
} else if (Api::ResolveRequiresPremiumToWrite(
|
||||
history->peer,
|
||||
history
|
||||
) == Api::RequirePremiumState::Unknown) {
|
||||
const auto user = history->peer->asUser();
|
||||
_descriptor.session->api().premium().resolvePremiumRequired(user);
|
||||
}
|
||||
|
@ -1661,7 +1669,7 @@ void FastShareMessage(
|
|||
}
|
||||
|
||||
auto SharePremiumRequiredError()
|
||||
-> Fn<ChooseRecipientPremiumRequiredError(not_null<UserData*>)> {
|
||||
-> Fn<RecipientPremiumRequiredError(not_null<UserData*>)> {
|
||||
return WritePremiumRequiredError;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,9 +69,9 @@ void FastShareMessage(
|
|||
not_null<Window::SessionController*> controller,
|
||||
not_null<HistoryItem*> item);
|
||||
|
||||
struct ChooseRecipientPremiumRequiredError;
|
||||
struct RecipientPremiumRequiredError;
|
||||
[[nodiscard]] auto SharePremiumRequiredError()
|
||||
-> Fn<ChooseRecipientPremiumRequiredError(not_null<UserData*>)>;
|
||||
-> Fn<RecipientPremiumRequiredError(not_null<UserData*>)>;
|
||||
|
||||
class ShareBox final : public Ui::BoxContent {
|
||||
public:
|
||||
|
@ -106,7 +106,7 @@ public:
|
|||
} forwardOptions;
|
||||
HistoryView::ScheduleBoxStyleArgs scheduleBoxStyle;
|
||||
|
||||
using PremiumRequiredError = ChooseRecipientPremiumRequiredError;
|
||||
using PremiumRequiredError = RecipientPremiumRequiredError;
|
||||
Fn<PremiumRequiredError(not_null<UserData*>)> premiumRequiredError;
|
||||
};
|
||||
ShareBox(QWidget*, Descriptor &&descriptor);
|
||||
|
|
Loading…
Add table
Reference in a new issue