Suggest inviting by link if privacy disallows adding.
This commit is contained in:
parent
7682ccf6a7
commit
f3e15c7fcd
|
@ -1110,6 +1110,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_profile_copy_phone" = "Copy Phone Number";
|
||||
"lng_profile_copy_fullname" = "Copy Name";
|
||||
|
||||
"lng_via_link_group_one" = "**{user}** restricts adding them to groups.\nYou can send them an invite link as message instead.";
|
||||
"lng_via_link_group_many#one" = "**{count} user** restricts adding them to groups.\nYou can send them an invite link as message instead.";
|
||||
"lng_via_link_group_many#other" = "**{count} users** restrict adding them to groups.\nYou can send them an invite link as message instead.";
|
||||
"lng_via_link_channel_one" = "**{user}** restricts adding them to channels.\nYou can send them an invite link as message instead.";
|
||||
"lng_via_link_channel_many#one" = "**{count} user** restricts adding them to channels.\nYou can send them an invite link as message instead.";
|
||||
"lng_via_link_channel_many#other" = "**{count} users** restrict adding them to channels.\nYou can send them an invite link as message instead.";
|
||||
"lng_via_link_send" = "Send Invite Link";
|
||||
"lng_via_link_cant" = "You can't create a link";
|
||||
"lng_via_link_cant_one" = "**{user}** can only by invited via link, but you don't have permission to share invite links to this group.";
|
||||
"lng_via_link_cant_many#one" = "**{count} user** can only by invited via link, but you don't have permission to share invite links to this group.";
|
||||
"lng_via_link_cant_many#other" = "**{count} users** can only by invited via link, but you don't have permission to share invite links to this group.";
|
||||
"lng_via_link_shared_one" = "Link shared with **{user}**.";
|
||||
"lng_via_link_shared_many#one" = "Link shared with **{count} user**.";
|
||||
"lng_via_link_shared_many#other" = "Link shared with **{count} users**.";
|
||||
|
||||
"lng_info_mobile_label" = "Mobile";
|
||||
"lng_info_mobile_context_menu_fragment_about" = "This number is not tied to a SIM card and was acquired on {link}.";
|
||||
"lng_info_mobile_context_menu_fragment_about_link" = "Fragment";
|
||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "apiwrap.h"
|
||||
#include "boxes/add_contact_box.h" // ShowAddParticipantsError
|
||||
#include "boxes/peers/add_participants_box.h" // ChatInviteForbidden
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_channel_admins.h"
|
||||
|
@ -463,6 +464,7 @@ void ChatParticipants::requestCountDelayed(
|
|||
void ChatParticipants::add(
|
||||
not_null<PeerData*> peer,
|
||||
const std::vector<not_null<UserData*>> &users,
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
bool passGroupHistory,
|
||||
Fn<void(bool)> done) {
|
||||
if (const auto chat = peer->asChat()) {
|
||||
|
@ -475,14 +477,15 @@ void ChatParticipants::add(
|
|||
chat->session().api().applyUpdates(result);
|
||||
if (done) done(true);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
ShowAddParticipantsError(error.type(), peer, { 1, user });
|
||||
const auto type = error.type();
|
||||
ShowAddParticipantsError(type, peer, { 1, user }, show);
|
||||
if (done) done(false);
|
||||
}).afterDelay(kSmallDelayMs).send();
|
||||
}
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
const auto hasBot = ranges::any_of(users, &UserData::isBot);
|
||||
if (!peer->isMegagroup() && hasBot) {
|
||||
ShowAddParticipantsError("USER_BOT", peer, users);
|
||||
ShowAddParticipantsError("USER_BOT", peer, users, show);
|
||||
return;
|
||||
}
|
||||
auto list = QVector<MTPInputUser>();
|
||||
|
@ -496,8 +499,12 @@ void ChatParticipants::add(
|
|||
channel->session().api().applyUpdates(result);
|
||||
requestCountDelayed(channel);
|
||||
if (callback) callback(true);
|
||||
ChatInviteForbidden(
|
||||
show,
|
||||
channel,
|
||||
CollectForbiddenUsers(&channel->session(), result));
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
ShowAddParticipantsError(error.type(), peer, users);
|
||||
ShowAddParticipantsError(error.type(), peer, users, show);
|
||||
if (callback) callback(false);
|
||||
}).afterDelay(kSmallDelayMs).send();
|
||||
};
|
||||
|
|
|
@ -14,6 +14,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
class ApiWrap;
|
||||
class ChannelData;
|
||||
|
||||
namespace Ui {
|
||||
class Show;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Api {
|
||||
|
||||
class ChatParticipant final {
|
||||
|
@ -95,6 +99,7 @@ public:
|
|||
void add(
|
||||
not_null<PeerData*> peer,
|
||||
const std::vector<not_null<UserData*>> &users,
|
||||
std::shared_ptr<Ui::Show> show = nullptr,
|
||||
bool passGroupHistory = true,
|
||||
Fn<void(bool)> done = nullptr);
|
||||
|
||||
|
|
|
@ -3709,7 +3709,8 @@ void ApiWrap::sendBotStart(
|
|||
applyUpdates(result);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (chat) {
|
||||
ShowAddParticipantsError(error.type(), chat, { 1, bot });
|
||||
const auto type = error.type();
|
||||
ShowAddParticipantsError(type, chat, { 1, bot });
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
|
|
@ -112,7 +112,12 @@ void ChatCreateDone(
|
|||
if (done) {
|
||||
done(chat);
|
||||
} else {
|
||||
const auto show = std::make_shared<Window::Show>(navigation);
|
||||
navigation->showPeerHistory(chat);
|
||||
ChatInviteForbidden(
|
||||
show,
|
||||
chat,
|
||||
CollectForbiddenUsers(&chat->session(), updates));
|
||||
}
|
||||
};
|
||||
if (!success) {
|
||||
|
@ -173,7 +178,8 @@ TextWithEntities PeerFloodErrorText(
|
|||
void ShowAddParticipantsError(
|
||||
const QString &error,
|
||||
not_null<PeerData*> chat,
|
||||
const std::vector<not_null<UserData*>> &users) {
|
||||
const std::vector<not_null<UserData*>> &users,
|
||||
std::shared_ptr<Ui::Show> show) {
|
||||
if (error == u"USER_BOT"_q) {
|
||||
const auto channel = chat->asChannel();
|
||||
if ((users.size() == 1)
|
||||
|
@ -220,6 +226,9 @@ void ShowAddParticipantsError(
|
|||
const auto text = PeerFloodErrorText(&chat->session(), type);
|
||||
Ui::show(Ui::MakeInformBox(text), Ui::LayerOption::KeepOther);
|
||||
return;
|
||||
} else if (error == u"USER_PRIVACY_RESTRICTED"_q && show) {
|
||||
ChatInviteForbidden(show, chat, users);
|
||||
return;
|
||||
}
|
||||
const auto text = [&] {
|
||||
if (error == u"USER_BOT"_q) {
|
||||
|
@ -689,9 +698,6 @@ void GroupInfoBox::createGroup(
|
|||
inputs.push_back(user->inputUser);
|
||||
}
|
||||
}
|
||||
if (inputs.empty()) {
|
||||
return;
|
||||
}
|
||||
_creationRequestId = _api.request(MTPmessages_CreateChat(
|
||||
MTP_flags(_ttlPeriod
|
||||
? MTPmessages_CreateChat::Flag::f_ttl_period
|
||||
|
@ -703,6 +709,7 @@ void GroupInfoBox::createGroup(
|
|||
auto image = _photo->takeResultImage();
|
||||
const auto period = _ttlPeriod;
|
||||
const auto navigation = _navigation;
|
||||
const auto controller = navigation->parentController();
|
||||
const auto done = _done;
|
||||
|
||||
getDelegate()->hideLayer(); // Destroys 'this'.
|
||||
|
@ -763,13 +770,10 @@ void GroupInfoBox::submit() {
|
|||
not_null<PeerListBox*> box) {
|
||||
auto create = [box, title, weak] {
|
||||
if (const auto strong = weak.data()) {
|
||||
auto rows = box->collectSelectedRows();
|
||||
if (!rows.empty()) {
|
||||
strong->createGroup(
|
||||
box.get(),
|
||||
title,
|
||||
std::move(rows));
|
||||
}
|
||||
strong->createGroup(
|
||||
box.get(),
|
||||
title,
|
||||
box->collectSelectedRows());
|
||||
}
|
||||
};
|
||||
box->addButton(tr::lng_create_group_create(), std::move(create));
|
||||
|
|
|
@ -48,7 +48,8 @@ enum class PeerFloodType {
|
|||
void ShowAddParticipantsError(
|
||||
const QString &error,
|
||||
not_null<PeerData*> chat,
|
||||
const std::vector<not_null<UserData*>> &users);
|
||||
const std::vector<not_null<UserData*>> &users,
|
||||
std::shared_ptr<Ui::Show> show = nullptr);
|
||||
|
||||
class AddContactBox : public Ui::BoxContent {
|
||||
public:
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/peers/add_participants_box.h"
|
||||
|
||||
#include "api/api_chat_participants.h"
|
||||
#include "api/api_invite_links.h"
|
||||
#include "boxes/peers/edit_participant_box.h"
|
||||
#include "boxes/peers/edit_peer_type_box.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
|
@ -22,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/history.h"
|
||||
#include "dialogs/dialogs_indexed_list.h"
|
||||
#include "ui/text/text_utilities.h" // Ui::Text::RichLangValue
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
|
@ -33,12 +35,48 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "apiwrap.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_settings.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kParticipantsFirstPageCount = 16;
|
||||
constexpr auto kParticipantsPerPage = 200;
|
||||
|
||||
class InviteForbiddenController final : public PeerListController {
|
||||
public:
|
||||
InviteForbiddenController(
|
||||
not_null<PeerData*> peer,
|
||||
std::vector<not_null<UserData*>> users);
|
||||
|
||||
Main::Session &session() const override;
|
||||
void prepare() override;
|
||||
void rowClicked(not_null<PeerListRow*> row) override;
|
||||
|
||||
[[nodiscard]] bool canInvite() const {
|
||||
return _can;
|
||||
}
|
||||
[[nodiscard]] rpl::producer<int> selectedValue() const {
|
||||
return _selected.value();
|
||||
}
|
||||
|
||||
void send(
|
||||
std::vector<not_null<PeerData*>> list,
|
||||
Ui::ShowPtr show,
|
||||
Fn<void()> close);
|
||||
|
||||
private:
|
||||
void appendRow(not_null<UserData*> user);
|
||||
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(
|
||||
not_null<UserData*> user) const;
|
||||
|
||||
const not_null<PeerData*> _peer;
|
||||
const std::vector<not_null<UserData*>> _users;
|
||||
const bool _can = false;
|
||||
rpl::variable<int> _selected;
|
||||
bool _sending = false;
|
||||
|
||||
};
|
||||
|
||||
base::flat_set<not_null<UserData*>> GetAlreadyInFromPeer(PeerData *peer) {
|
||||
if (!peer) {
|
||||
return {};
|
||||
|
@ -54,6 +92,148 @@ base::flat_set<not_null<UserData*>> GetAlreadyInFromPeer(PeerData *peer) {
|
|||
return {};
|
||||
}
|
||||
|
||||
InviteForbiddenController::InviteForbiddenController(
|
||||
not_null<PeerData*> peer,
|
||||
std::vector<not_null<UserData*>> users)
|
||||
: _peer(peer)
|
||||
, _users(std::move(users))
|
||||
, _can(peer->isChat()
|
||||
? peer->asChat()->canHaveInviteLink()
|
||||
: peer->asChannel()->canHaveInviteLink())
|
||||
, _selected(_can ? int(_users.size()) : 0) {
|
||||
}
|
||||
|
||||
Main::Session &InviteForbiddenController::session() const {
|
||||
return _peer->session();
|
||||
}
|
||||
|
||||
void InviteForbiddenController::prepare() {
|
||||
const auto broadcast = _peer->isBroadcast();
|
||||
const auto count = int(_users.size());
|
||||
const auto phraseCounted = !_can
|
||||
? tr::lng_via_link_cant_many
|
||||
: broadcast
|
||||
? tr::lng_via_link_channel_many
|
||||
: tr::lng_via_link_group_many;
|
||||
const auto phraseNamed = !_can
|
||||
? tr::lng_via_link_cant_one
|
||||
: broadcast
|
||||
? tr::lng_via_link_channel_one
|
||||
: tr::lng_via_link_group_one;
|
||||
auto text = (count != 1)
|
||||
? phraseCounted(
|
||||
lt_count,
|
||||
rpl::single<float64>(count),
|
||||
Ui::Text::RichLangValue)
|
||||
: phraseNamed(
|
||||
lt_user,
|
||||
rpl::single(TextWithEntities{ _users.front()->name() }),
|
||||
Ui::Text::RichLangValue);
|
||||
delegate()->peerListSetAboveWidget(object_ptr<Ui::PaddingWrap<>>(
|
||||
(QWidget*)nullptr,
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
(QWidget*)nullptr,
|
||||
std::move(text),
|
||||
st::requestPeerRestriction),
|
||||
st::boxRowPadding));
|
||||
delegate()->peerListSetTitle(
|
||||
_can ? tr::lng_profile_add_via_link() : tr::lng_via_link_cant());
|
||||
|
||||
for (const auto &user : _users) {
|
||||
appendRow(user);
|
||||
}
|
||||
delegate()->peerListRefreshRows();
|
||||
}
|
||||
|
||||
void InviteForbiddenController::rowClicked(not_null<PeerListRow*> row) {
|
||||
if (!_can) {
|
||||
return;
|
||||
}
|
||||
const auto checked = row->checked();
|
||||
delegate()->peerListSetRowChecked(row, !checked);
|
||||
_selected = _selected.current() + (checked ? -1 : 1);
|
||||
}
|
||||
|
||||
void InviteForbiddenController::appendRow(not_null<UserData*> user) {
|
||||
if (!delegate()->peerListFindRow(user->id.value)) {
|
||||
auto row = createRow(user);
|
||||
const auto raw = row.get();
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
if (_can) {
|
||||
delegate()->peerListSetRowChecked(raw, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InviteForbiddenController::send(
|
||||
std::vector<not_null<PeerData*>> list,
|
||||
Ui::ShowPtr show,
|
||||
Fn<void()> close) {
|
||||
if (_sending || list.empty()) {
|
||||
return;
|
||||
}
|
||||
_sending = true;
|
||||
const auto chat = _peer->asChat();
|
||||
const auto channel = _peer->asChannel();
|
||||
const auto sendLink = [=] {
|
||||
const auto link = chat ? chat->inviteLink() : channel->inviteLink();
|
||||
if (link.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
auto &api = _peer->session().api();
|
||||
auto options = Api::SendOptions();
|
||||
for (const auto &to : list) {
|
||||
const auto history = to->owner().history(to);
|
||||
auto message = Api::MessageToSend(
|
||||
Api::SendAction(history, options));
|
||||
message.textWithTags = { link };
|
||||
message.action.clearDraft = false;
|
||||
api.sendMessage(std::move(message));
|
||||
}
|
||||
auto text = (list.size() == 1)
|
||||
? tr::lng_via_link_shared_one(
|
||||
tr::now,
|
||||
lt_user,
|
||||
TextWithEntities{ list.front()->name() },
|
||||
Ui::Text::RichLangValue)
|
||||
: tr::lng_via_link_shared_many(
|
||||
tr::now,
|
||||
lt_count,
|
||||
int(list.size()),
|
||||
Ui::Text::RichLangValue);
|
||||
close();
|
||||
Ui::Toast::Show(
|
||||
show->toastParent(),
|
||||
{ .text = std::move(text), .st = &st::defaultToast });
|
||||
return true;
|
||||
};
|
||||
const auto sendForFull = [=] {
|
||||
if (!sendLink()) {
|
||||
_peer->session().api().inviteLinks().create(_peer, [=](auto) {
|
||||
if (!sendLink()) {
|
||||
close();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
if (_peer->isFullLoaded()) {
|
||||
sendForFull();
|
||||
} else if (!sendLink()) {
|
||||
_peer->session().api().requestFullPeer(_peer);
|
||||
_peer->session().changes().peerUpdates(
|
||||
_peer,
|
||||
Data::PeerUpdate::Flag::FullInfo
|
||||
) | rpl::start_with_next([=] {
|
||||
sendForFull();
|
||||
}, lifetime());
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<PeerListRow> InviteForbiddenController::createRow(
|
||||
not_null<UserData*> user) const {
|
||||
return std::make_unique<PeerListRow>(user);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AddParticipantsBoxController::AddParticipantsBoxController(
|
||||
|
@ -245,14 +425,19 @@ void AddParticipantsBoxController::inviteSelectedUsers(
|
|||
if (users.empty()) {
|
||||
return;
|
||||
}
|
||||
const auto show = std::make_shared<Ui::BoxShow>(box);
|
||||
const auto request = [=](bool checked) {
|
||||
_peer->session().api().chatParticipants().add(_peer, users, checked);
|
||||
_peer->session().api().chatParticipants().add(
|
||||
_peer,
|
||||
users,
|
||||
show,
|
||||
checked);
|
||||
};
|
||||
if (_peer->isChannel()) {
|
||||
request(false);
|
||||
return done();
|
||||
}
|
||||
Ui::BoxShow(box).showBox(Box([=](not_null<Ui::GenericBox*> box) {
|
||||
show->showBox(Box([=](not_null<Ui::GenericBox*> box) {
|
||||
auto checkbox = object_ptr<Ui::Checkbox>(
|
||||
box.get(),
|
||||
tr::lng_participant_invite_history(),
|
||||
|
@ -371,6 +556,81 @@ void AddParticipantsBoxController::Start(
|
|||
Start(navigation, channel, {}, true);
|
||||
}
|
||||
|
||||
std::vector<not_null<UserData*>> CollectForbiddenUsers(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPUpdates &updates) {
|
||||
const auto owner = &session->data();
|
||||
auto result = std::vector<not_null<UserData*>>();
|
||||
const auto add = [&](const MTPUpdate &update) {
|
||||
if (update.type() == mtpc_updateGroupInvitePrivacyForbidden) {
|
||||
const auto user = owner->userLoaded(UserId(
|
||||
update.c_updateGroupInvitePrivacyForbidden().vuser_id()));
|
||||
if (user) {
|
||||
result.push_back(user);
|
||||
}
|
||||
}
|
||||
};
|
||||
const auto collect = [&](const MTPVector<MTPUpdate> &updates) {
|
||||
for (const auto &update : updates.v) {
|
||||
add(update);
|
||||
}
|
||||
};
|
||||
updates.match([&](const MTPDupdates &data) {
|
||||
collect(data.vupdates());
|
||||
}, [&](const MTPDupdatesCombined &data) {
|
||||
collect(data.vupdates());
|
||||
}, [&](const MTPDupdateShort &data) {
|
||||
add(data.vupdate());
|
||||
}, [](const auto &other) {
|
||||
LOG(("Api Error: CollectForbiddenUsers for wrong updates type."));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ChatInviteForbidden(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
not_null<PeerData*> peer,
|
||||
std::vector<not_null<UserData*>> forbidden) {
|
||||
if (forbidden.empty() || !show || !show->valid()) {
|
||||
return false;
|
||||
}
|
||||
auto controller = std::make_unique<InviteForbiddenController>(
|
||||
peer,
|
||||
std::move(forbidden));
|
||||
const auto weak = controller.get();
|
||||
auto initBox = [=](not_null<PeerListBox*> box) {
|
||||
const auto can = weak->canInvite();
|
||||
if (!can) {
|
||||
box->addButton(tr::lng_close(), [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
return;
|
||||
}
|
||||
weak->selectedValue(
|
||||
) | rpl::map(
|
||||
rpl::mappers::_1 > 0
|
||||
) | rpl::distinct_until_changed(
|
||||
) | rpl::start_with_next([=](bool has) {
|
||||
box->clearButtons();
|
||||
if (has) {
|
||||
box->addButton(tr::lng_via_link_send(), [=] {
|
||||
weak->send(
|
||||
box->collectSelectedRows(),
|
||||
std::make_shared<Ui::BoxShow>(box),
|
||||
crl::guard(box, [=] { box->closeBox(); }));
|
||||
});
|
||||
}
|
||||
box->addButton(tr::lng_create_group_skip(), [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
}, box->lifetime());
|
||||
};
|
||||
show->showBox(
|
||||
Box<PeerListBox>(std::move(controller), std::move(initBox)),
|
||||
Ui::LayerOption::KeepOther);
|
||||
return true;
|
||||
}
|
||||
|
||||
AddSpecialBoxController::AddSpecialBoxController(
|
||||
not_null<PeerData*> peer,
|
||||
Role role,
|
||||
|
|
|
@ -73,6 +73,14 @@ private:
|
|||
|
||||
};
|
||||
|
||||
[[nodiscard]] std::vector<not_null<UserData*>> CollectForbiddenUsers(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPUpdates &updates);
|
||||
bool ChatInviteForbidden(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
not_null<PeerData*> peer,
|
||||
std::vector<not_null<UserData*>> forbidden);
|
||||
|
||||
// Adding an admin, banned or restricted user from channel members
|
||||
// with search + contacts search + global search.
|
||||
class AddSpecialBoxController
|
||||
|
|
|
@ -219,12 +219,14 @@ object_ptr<Ui::BoxContent> PrepareInviteBox(
|
|||
}
|
||||
};
|
||||
const auto inviteWithAdd = [=](
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
const std::vector<not_null<UserData*>> &users,
|
||||
const std::vector<not_null<UserData*>> &nonMembers,
|
||||
Fn<void()> finish) {
|
||||
peer->session().api().chatParticipants().add(
|
||||
peer,
|
||||
nonMembers,
|
||||
show,
|
||||
true,
|
||||
[=](bool) { invite(users); finish(); });
|
||||
};
|
||||
|
@ -257,7 +259,10 @@ object_ptr<Ui::BoxContent> PrepareInviteBox(
|
|||
finish();
|
||||
};
|
||||
const auto done = [=] {
|
||||
inviteWithAdd(users, nonMembers, finishWithConfirm);
|
||||
const auto show = (*shared)
|
||||
? std::make_shared<Ui::BoxShow>(*shared)
|
||||
: nullptr;
|
||||
inviteWithAdd(show, users, nonMembers, finishWithConfirm);
|
||||
};
|
||||
auto box = ConfirmBox({
|
||||
.text = text,
|
||||
|
|
|
@ -360,7 +360,9 @@ void MainWindow::ensureLayerCreated() {
|
|||
return;
|
||||
}
|
||||
_layer = base::make_unique_q<Ui::LayerStackWidget>(
|
||||
bodyWidget());
|
||||
bodyWidget(),
|
||||
crl::guard(this, [=] {
|
||||
return std::make_shared<Window::Show>(&controller()); }));
|
||||
|
||||
_layer->hideFinishEvents(
|
||||
) | rpl::filter([=] {
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit f3744c4ba3ddadd47e280a1ef5fbd002d357d10a
|
||||
Subproject commit 849a84050356a1321eedc36eb5296374e42fadd6
|
Loading…
Reference in New Issue