mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Check if bot is in group or if can be added.
This commit is contained in:
parent
17ce93fd5e
commit
4234f0b797
4 changed files with 208 additions and 67 deletions
|
@ -4089,6 +4089,50 @@ void ApiWrap::saveContactSignupSilent(bool silent) {
|
|||
_contactSignupSilentRequestId = requestId;
|
||||
}
|
||||
|
||||
auto ApiWrap::botCommonGroups(not_null<UserData*> bot) const
|
||||
-> std::optional<std::vector<not_null<PeerData*>>> {
|
||||
const auto i = _botCommonGroups.find(bot);
|
||||
return (i != end(_botCommonGroups))
|
||||
? i->second
|
||||
: std::optional<std::vector<not_null<PeerData*>>>();
|
||||
}
|
||||
|
||||
void ApiWrap::requestBotCommonGroups(
|
||||
not_null<UserData*> bot,
|
||||
Fn<void()> done) {
|
||||
if (_botCommonGroupsRequests.contains(bot)) {
|
||||
return;
|
||||
}
|
||||
_botCommonGroupsRequests.emplace(bot, done);
|
||||
const auto finish = [=](std::vector<not_null<PeerData*>> list) {
|
||||
_botCommonGroups.emplace(bot, std::move(list));
|
||||
if (const auto callback = _botCommonGroupsRequests.take(bot)) {
|
||||
(*callback)();
|
||||
}
|
||||
};
|
||||
const auto limit = 100;
|
||||
request(MTPmessages_GetCommonChats(
|
||||
bot->inputUser,
|
||||
MTP_long(0), // max_id
|
||||
MTP_int(limit)
|
||||
)).done([=](const MTPmessages_Chats &result) {
|
||||
const auto chats = result.match([](const auto &data) {
|
||||
return &data.vchats().v;
|
||||
});
|
||||
auto &owner = session().data();
|
||||
auto list = std::vector<not_null<PeerData*>>();
|
||||
list.reserve(chats->size());
|
||||
for (const auto &chat : *chats) {
|
||||
if (const auto peer = owner.processChat(chat)) {
|
||||
list.push_back(peer);
|
||||
}
|
||||
}
|
||||
finish(std::move(list));
|
||||
}).fail([=] {
|
||||
finish({});
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ApiWrap::saveSelfBio(const QString &text) {
|
||||
if (_bio.requestId) {
|
||||
if (text != _bio.requestedText) {
|
||||
|
|
|
@ -352,6 +352,10 @@ public:
|
|||
std::optional<bool> contactSignupSilentCurrent() const;
|
||||
void saveContactSignupSilent(bool silent);
|
||||
|
||||
[[nodiscard]] auto botCommonGroups(not_null<UserData*> bot) const
|
||||
-> std::optional<std::vector<not_null<PeerData*>>>;
|
||||
void requestBotCommonGroups(not_null<UserData*> bot, Fn<void()> done);
|
||||
|
||||
void saveSelfBio(const QString &text);
|
||||
|
||||
[[nodiscard]] Api::Authorizations &authorizations();
|
||||
|
@ -692,6 +696,11 @@ private:
|
|||
std::optional<bool> _contactSignupSilent;
|
||||
rpl::event_stream<bool> _contactSignupSilentChanges;
|
||||
|
||||
base::flat_map<
|
||||
not_null<UserData*>,
|
||||
std::vector<not_null<PeerData*>>> _botCommonGroups;
|
||||
base::flat_map<not_null<UserData*>, Fn<void()>> _botCommonGroupsRequests;
|
||||
|
||||
base::flat_map<FullMsgId, QString> _unlikelyMessageLinks;
|
||||
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "boxes/peers/choose_peer_box.h"
|
||||
|
||||
#include "apiwrap.h" // ApiWrap::botCommonGroups / requestBotCommonGroups.
|
||||
#include "boxes/add_contact_box.h"
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "boxes/premium_limits_box.h"
|
||||
|
@ -18,8 +19,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/history_item_reply_markup.h"
|
||||
#include "info/profile/info_profile_icon.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h" // Session::api().
|
||||
#include "settings/settings_common.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "window/window_session_controller.h"
|
||||
|
@ -55,10 +58,87 @@ private:
|
|||
const not_null<Window::SessionNavigation*> _navigation;
|
||||
not_null<UserData*> _bot;
|
||||
RequestPeerQuery _query;
|
||||
base::flat_set<not_null<PeerData*>> _commonGroups;
|
||||
Fn<void(not_null<PeerData*>)> _callback;
|
||||
|
||||
};
|
||||
|
||||
using RightsMap = std::vector<std::pair<ChatAdminRight, tr::phrase<>>>;
|
||||
|
||||
[[nodiscard]] RightsMap GroupRights() {
|
||||
using Flag = ChatAdminRight;
|
||||
return {
|
||||
{ Flag::ChangeInfo, tr::lng_request_group_change_info },
|
||||
{
|
||||
Flag::DeleteMessages,
|
||||
tr::lng_request_group_delete_messages },
|
||||
{ Flag::BanUsers, tr::lng_request_group_ban_users },
|
||||
{ Flag::InviteByLinkOrAdd, tr::lng_request_group_invite },
|
||||
{ Flag::PinMessages, tr::lng_request_group_pin_messages },
|
||||
{ Flag::ManageTopics, tr::lng_request_group_manage_topics },
|
||||
{
|
||||
Flag::ManageCall,
|
||||
tr::lng_request_group_manage_video_chats },
|
||||
{ Flag::Anonymous, tr::lng_request_group_anonymous },
|
||||
{ Flag::AddAdmins, tr::lng_request_group_add_admins },
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] RightsMap BroadcastRights() {
|
||||
using Flag = ChatAdminRight;
|
||||
return {
|
||||
{ Flag::ChangeInfo, tr::lng_request_channel_change_info },
|
||||
{
|
||||
Flag::PostMessages,
|
||||
tr::lng_request_channel_post_messages },
|
||||
{
|
||||
Flag::EditMessages,
|
||||
tr::lng_request_channel_edit_messages },
|
||||
{
|
||||
Flag::DeleteMessages,
|
||||
tr::lng_request_channel_delete_messages },
|
||||
{
|
||||
Flag::InviteByLinkOrAdd,
|
||||
tr::lng_request_channel_add_subscribers },
|
||||
{
|
||||
Flag::ManageCall,
|
||||
tr::lng_request_channel_manage_livestreams },
|
||||
{ Flag::AddAdmins, tr::lng_request_channel_add_admins },
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] QString RightsText(
|
||||
ChatAdminRights rights,
|
||||
const RightsMap &phrases) {
|
||||
auto list = QStringList();
|
||||
for (const auto &[flag, phrase] : phrases) {
|
||||
if (rights & flag) {
|
||||
list.push_back(phrase(tr::now));
|
||||
}
|
||||
}
|
||||
const auto count = list.size();
|
||||
if (!count) {
|
||||
return QString();
|
||||
}
|
||||
const auto last = list.back();
|
||||
return (count > 1)
|
||||
? tr::lng_request_peer_rights_and(
|
||||
tr::now,
|
||||
lt_rights,
|
||||
list.mid(0, count - 1).join(", "),
|
||||
lt_last,
|
||||
last)
|
||||
: last;
|
||||
}
|
||||
|
||||
[[nodiscard]] QString GroupRightsText(ChatAdminRights rights) {
|
||||
return RightsText(rights, GroupRights());
|
||||
}
|
||||
|
||||
[[nodiscard]] QString BroadcastRightsText(ChatAdminRights rights) {
|
||||
return RightsText(rights, BroadcastRights());
|
||||
}
|
||||
|
||||
[[nodiscard]] QStringList RestrictionsList(RequestPeerQuery query) {
|
||||
using Flag = ChatAdminRight;
|
||||
using Type = RequestPeerQuery::Type;
|
||||
|
@ -74,30 +154,11 @@ private:
|
|||
result.push_back(no(tr::now));
|
||||
}
|
||||
};
|
||||
const auto addRights = [&](
|
||||
ChatAdminRights rights,
|
||||
std::vector<std::pair<Flag, tr::phrase<>>> phrases) {
|
||||
auto list = QStringList();
|
||||
for (const auto &[flag, phrase] : phrases) {
|
||||
if (rights & flag) {
|
||||
list.push_back(phrase(tr::now));
|
||||
}
|
||||
const auto addRights = [&](const QString &rights) {
|
||||
if (!rights.isEmpty()) {
|
||||
result.push_back(
|
||||
tr::lng_request_peer_rights(tr::now, lt_rights, rights));
|
||||
}
|
||||
const auto count = list.size();
|
||||
if (!count) {
|
||||
return;
|
||||
}
|
||||
const auto last = list.back();
|
||||
const auto full = (count > 1)
|
||||
? tr::lng_request_peer_rights_and(
|
||||
tr::now,
|
||||
lt_rights,
|
||||
list.mid(0, count - 1).join(", "),
|
||||
lt_last,
|
||||
last)
|
||||
: last;
|
||||
result.push_back(
|
||||
tr::lng_request_peer_rights(tr::now, lt_rights, full));
|
||||
};
|
||||
switch (query.type) {
|
||||
case Type::User:
|
||||
|
@ -120,21 +181,7 @@ private:
|
|||
if (query.amCreator) {
|
||||
result.push_back(tr::lng_request_group_am_owner(tr::now));
|
||||
} else {
|
||||
addRights(query.myRights, {
|
||||
{ Flag::ChangeInfo, tr::lng_request_group_change_info },
|
||||
{
|
||||
Flag::DeleteMessages,
|
||||
tr::lng_request_group_delete_messages },
|
||||
{ Flag::BanUsers, tr::lng_request_group_ban_users },
|
||||
{ Flag::InviteByLinkOrAdd, tr::lng_request_group_invite },
|
||||
{ Flag::PinMessages, tr::lng_request_group_pin_messages },
|
||||
{ Flag::ManageTopics, tr::lng_request_group_manage_topics },
|
||||
{
|
||||
Flag::ManageCall,
|
||||
tr::lng_request_group_manage_video_chats },
|
||||
{ Flag::Anonymous, tr::lng_request_group_anonymous },
|
||||
{ Flag::AddAdmins, tr::lng_request_group_add_admins },
|
||||
});
|
||||
addRights(GroupRightsText(query.myRights));
|
||||
}
|
||||
break;
|
||||
case Type::Broadcast:
|
||||
|
@ -145,25 +192,7 @@ private:
|
|||
if (query.amCreator) {
|
||||
result.push_back(tr::lng_request_channel_am_owner(tr::now));
|
||||
} else {
|
||||
addRights(query.myRights, {
|
||||
{ Flag::ChangeInfo, tr::lng_request_channel_change_info },
|
||||
{
|
||||
Flag::PostMessages,
|
||||
tr::lng_request_channel_post_messages },
|
||||
{
|
||||
Flag::EditMessages,
|
||||
tr::lng_request_channel_edit_messages },
|
||||
{
|
||||
Flag::DeleteMessages,
|
||||
tr::lng_request_channel_delete_messages },
|
||||
{
|
||||
Flag::InviteByLinkOrAdd,
|
||||
tr::lng_request_channel_add_subscribers },
|
||||
{
|
||||
Flag::ManageCall,
|
||||
tr::lng_request_channel_manage_livestreams },
|
||||
{ Flag::AddAdmins, tr::lng_request_channel_add_admins },
|
||||
});
|
||||
addRights(BroadcastRightsText(query.myRights));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -175,10 +204,48 @@ object_ptr<Ui::BoxContent> MakeConfirmBox(
|
|||
not_null<PeerData*> peer,
|
||||
RequestPeerQuery query,
|
||||
Fn<void()> confirmed) {
|
||||
auto text = TextWithEntities{ "Sure?.." };
|
||||
const auto user = peer->asUser();
|
||||
const auto name = user ? user->firstName : peer->name();
|
||||
const auto botName = bot->name();
|
||||
auto text = tr::lng_request_peer_confirm(
|
||||
tr::now,
|
||||
lt_chat,
|
||||
Ui::Text::Bold(name),
|
||||
lt_bot,
|
||||
Ui::Text::Bold(botName),
|
||||
Ui::Text::WithEntities);
|
||||
if (!user) {
|
||||
const auto rights = peer->isBroadcast()
|
||||
? BroadcastRightsText(query.botRights)
|
||||
: GroupRightsText(query.botRights);
|
||||
if (!rights.isEmpty()) {
|
||||
text.append('\n').append('\n').append(
|
||||
tr::lng_request_peer_confirm_rights(
|
||||
tr::now,
|
||||
lt_bot,
|
||||
Ui::Text::Bold(botName),
|
||||
lt_chat,
|
||||
Ui::Text::Bold(name),
|
||||
lt_rights,
|
||||
TextWithEntities{ rights },
|
||||
Ui::Text::WithEntities));
|
||||
} else if (!peer->isBroadcast() && query.isBotParticipant) {
|
||||
const auto common = bot->session().api().botCommonGroups(bot);
|
||||
if (!common || !ranges::contains(*common, peer)) {
|
||||
text.append('\n').append('\n').append(
|
||||
tr::lng_request_peer_confirm_add(
|
||||
tr::now,
|
||||
lt_bot,
|
||||
Ui::Text::Bold(botName),
|
||||
lt_chat,
|
||||
Ui::Text::Bold(name),
|
||||
Ui::Text::WithEntities));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ui::MakeConfirmBox({
|
||||
.text = std::move(text),
|
||||
.confirmed = std::move(confirmed),
|
||||
.confirmed = [=](Fn<void()> close) { confirmed(); close(); },
|
||||
.confirmText = tr::lng_request_peer_confirm_send(tr::now),
|
||||
});
|
||||
}
|
||||
|
@ -206,7 +273,8 @@ object_ptr<Ui::BoxContent> CreatePeerByQueryBox(
|
|||
|
||||
[[nodiscard]] bool FilterPeerByQuery(
|
||||
not_null<PeerData*> peer,
|
||||
RequestPeerQuery query) {
|
||||
RequestPeerQuery query,
|
||||
const base::flat_set<not_null<PeerData*>> &commonGroups) {
|
||||
using Type = RequestPeerQuery::Type;
|
||||
using Restriction = RequestPeerQuery::Restriction;
|
||||
const auto checkRestriction = [](Restriction restriction, bool value) {
|
||||
|
@ -239,7 +307,13 @@ object_ptr<Ui::BoxContent> CreatePeerByQueryBox(
|
|||
&& checkRights(
|
||||
query.myRights,
|
||||
chat ? chat->amCreator() : megagroup->amCreator(),
|
||||
chat ? chat->adminRights() : megagroup->adminRights());
|
||||
chat ? chat->adminRights() : megagroup->adminRights())
|
||||
&& (!query.isBotParticipant
|
||||
|| query.myRights
|
||||
|| commonGroups.contains(peer)
|
||||
|| (chat
|
||||
? chat->canAddMembers()
|
||||
: megagroup->canAddMembers()));
|
||||
}
|
||||
case Type::Broadcast: {
|
||||
const auto broadcast = peer->asBroadcast();
|
||||
|
@ -265,6 +339,9 @@ ChoosePeerBoxController::ChoosePeerBoxController(
|
|||
, _bot(bot)
|
||||
, _query(query)
|
||||
, _callback(std::move(callback)) {
|
||||
if (const auto list = _bot->session().api().botCommonGroups(_bot)) {
|
||||
_commonGroups = { begin(*list), end(*list) };
|
||||
}
|
||||
}
|
||||
|
||||
Main::Session &ChoosePeerBoxController::session() const {
|
||||
|
@ -358,7 +435,7 @@ void ChoosePeerBoxController::rowClicked(not_null<PeerListRow*> row) {
|
|||
|
||||
auto ChoosePeerBoxController::createRow(not_null<History*> history)
|
||||
-> std::unique_ptr<Row> {
|
||||
return FilterPeerByQuery(history->peer, _query)
|
||||
return FilterPeerByQuery(history->peer, _query, _commonGroups)
|
||||
? std::make_unique<Row>(history)
|
||||
: nullptr;
|
||||
}
|
||||
|
@ -388,11 +465,23 @@ QString ChoosePeerBoxController::emptyBoxText() const {
|
|||
|
||||
} // namespace
|
||||
|
||||
QPointer<Ui::BoxContent> ShowChoosePeerBox(
|
||||
void ShowChoosePeerBox(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<UserData*> bot,
|
||||
RequestPeerQuery query,
|
||||
Fn<void(not_null<PeerData*>)> &&chosen) {
|
||||
Fn<void(not_null<PeerData*>)> chosen) {
|
||||
const auto needCommonGroups = query.isBotParticipant
|
||||
&& (query.type == RequestPeerQuery::Type::Group)
|
||||
&& !query.myRights;
|
||||
if (needCommonGroups && !bot->session().api().botCommonGroups(bot)) {
|
||||
const auto weak = base::make_weak(navigation);
|
||||
bot->session().api().requestBotCommonGroups(bot, [=] {
|
||||
if (const auto strong = weak.get()) {
|
||||
ShowChoosePeerBox(strong, bot, query, chosen);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
const auto weak = std::make_shared<QPointer<Ui::BoxContent>>();
|
||||
auto initBox = [=](not_null<PeerListBox*> box) {
|
||||
box->addButton(tr::lng_cancel(), [box] {
|
||||
|
@ -412,5 +501,4 @@ QPointer<Ui::BoxContent> ShowChoosePeerBox(
|
|||
query,
|
||||
std::move(callback)),
|
||||
std::move(initBox)), Ui::LayerOption::KeepOther);
|
||||
return weak->data();
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@ namespace Window {
|
|||
class SessionNavigation;
|
||||
} // namespace Window
|
||||
|
||||
QPointer<Ui::BoxContent> ShowChoosePeerBox(
|
||||
void ShowChoosePeerBox(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<UserData*> bot,
|
||||
RequestPeerQuery query,
|
||||
Fn<void(not_null<PeerData*>)> &&chosen);
|
||||
Fn<void(not_null<PeerData*>)> chosen);
|
||||
|
|
Loading…
Add table
Reference in a new issue