mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Add bot to group / channel by link with rights.
This commit is contained in:
parent
649f2908e8
commit
468917a91a
11 changed files with 302 additions and 102 deletions
|
@ -3526,9 +3526,11 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
|||
finishForwarding(action);
|
||||
}
|
||||
|
||||
void ApiWrap::sendBotStart(not_null<UserData*> bot, PeerData *chat) {
|
||||
void ApiWrap::sendBotStart(
|
||||
not_null<UserData*> bot,
|
||||
PeerData *chat,
|
||||
const QString &startTokenForChat) {
|
||||
Expects(bot->isBot());
|
||||
Expects(chat == nullptr || !bot->botInfo->startGroupToken.isEmpty());
|
||||
|
||||
if (chat && chat->isChannel() && !chat->isMegagroup()) {
|
||||
ShowAddParticipantsError("USER_BOT", chat, { 1, bot });
|
||||
|
@ -3536,20 +3538,28 @@ void ApiWrap::sendBotStart(not_null<UserData*> bot, PeerData *chat) {
|
|||
}
|
||||
|
||||
auto &info = bot->botInfo;
|
||||
auto &token = chat ? info->startGroupToken : info->startToken;
|
||||
auto &token = chat ? startTokenForChat : info->startToken;
|
||||
if (token.isEmpty()) {
|
||||
auto message = MessageToSend(
|
||||
Api::SendAction(_session->data().history(bot)));
|
||||
message.textWithTags = { qsl("/start"), TextWithTags::Tags() };
|
||||
Api::SendAction(_session->data().history(chat
|
||||
? chat
|
||||
: bot.get())));
|
||||
message.textWithTags = { u"/start"_q, TextWithTags::Tags() };
|
||||
if (chat) {
|
||||
message.textWithTags.text += '@' + bot->username;
|
||||
}
|
||||
sendMessage(std::move(message));
|
||||
return;
|
||||
}
|
||||
const auto randomId = base::RandomValue<uint64>();
|
||||
if (!chat) {
|
||||
info->startToken = QString();
|
||||
}
|
||||
request(MTPmessages_StartBot(
|
||||
bot->inputUser,
|
||||
chat ? chat->input : MTP_inputPeerEmpty(),
|
||||
MTP_long(randomId),
|
||||
MTP_string(base::take(token))
|
||||
MTP_string(token)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
|
|
|
@ -320,7 +320,10 @@ public:
|
|||
void cancelLocalItem(not_null<HistoryItem*> item);
|
||||
|
||||
void sendMessage(MessageToSend &&message);
|
||||
void sendBotStart(not_null<UserData*> bot, PeerData *chat = nullptr);
|
||||
void sendBotStart(
|
||||
not_null<UserData*> bot,
|
||||
PeerData *chat = nullptr,
|
||||
const QString &startTokenForChat = QString());
|
||||
void sendInlineResult(
|
||||
not_null<UserData*> bot,
|
||||
not_null<InlineBots::Result*> data,
|
||||
|
|
|
@ -19,6 +19,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/peers/edit_participants_box.h"
|
||||
#include "boxes/filters/edit_filter_chats_list.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "base/random.h"
|
||||
#include "base/weak_ptr.h"
|
||||
#include "api/api_chat_participants.h"
|
||||
|
@ -54,7 +56,10 @@ private:
|
|||
|
||||
};
|
||||
|
||||
void ShareBotGame(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
||||
void ShareBotGame(
|
||||
not_null<UserData*> bot,
|
||||
not_null<PeerData*> chat,
|
||||
const QString &shortName) {
|
||||
const auto history = chat->owner().history(chat);
|
||||
auto &histories = history->owner().histories();
|
||||
const auto requestType = Data::Histories::RequestType::Send;
|
||||
|
@ -68,7 +73,7 @@ void ShareBotGame(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
|||
MTP_inputMediaGame(
|
||||
MTP_inputGameShortName(
|
||||
bot->inputUser,
|
||||
MTP_string(bot->botInfo->shareGameShortName))),
|
||||
MTP_string(shortName))),
|
||||
MTP_string(),
|
||||
MTP_long(randomId),
|
||||
MTPReplyMarkup(),
|
||||
|
@ -138,23 +143,40 @@ void Controller::addRow(not_null<PeerData*> peer) {
|
|||
|
||||
} // namespace
|
||||
|
||||
void AddBotToGroupBoxController::Start(not_null<UserData*> bot) {
|
||||
void AddBotToGroupBoxController::Start(
|
||||
not_null<UserData*> bot,
|
||||
Scope scope,
|
||||
const QString &token,
|
||||
ChatAdminRights requestedRights) {
|
||||
auto initBox = [=](not_null<PeerListBox*> box) {
|
||||
box->addButton(tr::lng_cancel(), [box] { box->closeBox(); });
|
||||
};
|
||||
Ui::show(Box<PeerListBox>(
|
||||
std::make_unique<AddBotToGroupBoxController>(bot),
|
||||
std::make_unique<AddBotToGroupBoxController>(
|
||||
bot,
|
||||
scope,
|
||||
token,
|
||||
requestedRights),
|
||||
std::move(initBox)));
|
||||
}
|
||||
|
||||
AddBotToGroupBoxController::AddBotToGroupBoxController(
|
||||
not_null<UserData*> bot)
|
||||
: ChatsListBoxController(SharingBotGame(bot)
|
||||
not_null<UserData*> bot,
|
||||
Scope scope,
|
||||
const QString &token,
|
||||
ChatAdminRights requestedRights)
|
||||
: ChatsListBoxController((scope == Scope::ShareGame)
|
||||
? std::make_unique<PeerListGlobalSearchController>(&bot->session())
|
||||
: nullptr)
|
||||
, _bot(bot)
|
||||
, _adminToGroup(_bot->botInfo->groupAdminRights != 0)
|
||||
, _adminToChannel(_bot->botInfo->channelAdminRights != 0) {
|
||||
, _scope(scope)
|
||||
, _token(token)
|
||||
, _requestedRights(requestedRights)
|
||||
, _adminToGroup((scope == Scope::GroupAdmin)
|
||||
|| (scope == Scope::All && _bot->botInfo->groupAdminRights != 0))
|
||||
, _adminToChannel((scope == Scope::ChannelAdmin)
|
||||
|| (scope == Scope::All && _bot->botInfo->channelAdminRights != 0))
|
||||
, _memberToGroup(scope == Scope::All) {
|
||||
}
|
||||
|
||||
Main::Session &AddBotToGroupBoxController::session() const {
|
||||
|
@ -170,8 +192,8 @@ void AddBotToGroupBoxController::rowClicked(not_null<PeerListRow*> row) {
|
|||
}
|
||||
|
||||
void AddBotToGroupBoxController::shareBotGame(not_null<PeerData*> chat) {
|
||||
auto send = crl::guard(this, [bot = _bot, chat] {
|
||||
ShareBotGame(bot, chat);
|
||||
auto send = crl::guard(this, [bot = _bot, chat, token = _token] {
|
||||
ShareBotGame(bot, chat, token);
|
||||
});
|
||||
auto confirmText = [chat] {
|
||||
if (chat->isUser()) {
|
||||
|
@ -187,6 +209,34 @@ void AddBotToGroupBoxController::shareBotGame(not_null<PeerData*> chat) {
|
|||
Ui::LayerOption::KeepOther);
|
||||
}
|
||||
|
||||
void AddBotToGroupBoxController::requestExistingRights(
|
||||
not_null<ChannelData*> channel) {
|
||||
if (_existingRightsChannel == channel) {
|
||||
return;
|
||||
}
|
||||
_existingRightsChannel = channel;
|
||||
_bot->session().api().request(_existingRightsRequestId).cancel();
|
||||
_existingRightsRequestId = _bot->session().api().request(
|
||||
MTPchannels_GetParticipant(
|
||||
_existingRightsChannel->inputChannel,
|
||||
_bot->input)
|
||||
).done([=](const MTPchannels_ChannelParticipant &result) {
|
||||
result.match([&](const MTPDchannels_channelParticipant &data) {
|
||||
channel->owner().processUsers(data.vusers());
|
||||
const auto participant = Api::ChatParticipant(
|
||||
data.vparticipant(),
|
||||
channel);
|
||||
_existingRights = participant.rights().flags;
|
||||
_existingRank = participant.rank();
|
||||
addBotToGroup(_existingRightsChannel);
|
||||
});
|
||||
}).fail([=] {
|
||||
_existingRights = ChatAdminRights();
|
||||
_existingRank = QString();
|
||||
addBotToGroup(_existingRightsChannel);
|
||||
}).send();
|
||||
}
|
||||
|
||||
void AddBotToGroupBoxController::addBotToGroup(not_null<PeerData*> chat) {
|
||||
if (const auto megagroup = chat->asMegagroup()) {
|
||||
if (!megagroup->canAddMembers()) {
|
||||
|
@ -196,38 +246,66 @@ void AddBotToGroupBoxController::addBotToGroup(not_null<PeerData*> chat) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (_existingRightsChannel != chat) {
|
||||
_existingRights = {};
|
||||
_existingRank = QString();
|
||||
_existingRightsChannel = nullptr;
|
||||
_bot->session().api().request(_existingRightsRequestId).cancel();
|
||||
}
|
||||
const auto requestedAddAdmin = (_scope == Scope::GroupAdmin)
|
||||
|| (_scope == Scope::ChannelAdmin);
|
||||
if (chat->isChannel()
|
||||
&& requestedAddAdmin
|
||||
&& !_existingRights.has_value()) {
|
||||
requestExistingRights(chat->asChannel());
|
||||
return;
|
||||
}
|
||||
const auto bot = _bot;
|
||||
const auto close = [=](auto&&...) {
|
||||
Ui::hideLayer();
|
||||
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
|
||||
};
|
||||
const auto rights = (chat->isBroadcast()
|
||||
&& chat->asBroadcast()->canAddAdmins())
|
||||
const auto rights = requestedAddAdmin
|
||||
? _requestedRights
|
||||
: (chat->isBroadcast()
|
||||
&& chat->asBroadcast()->canAddAdmins())
|
||||
? bot->botInfo->channelAdminRights
|
||||
: ((chat->isMegagroup() && chat->asMegagroup()->canAddAdmins())
|
||||
|| (chat->isChat() && chat->asChat()->canAddAdmins()))
|
||||
? bot->botInfo->groupAdminRights
|
||||
: ChatAdminRights();
|
||||
if (rights) {
|
||||
const auto addingAdmin = requestedAddAdmin || (rights != 0);
|
||||
if (addingAdmin) {
|
||||
const auto scope = _scope;
|
||||
const auto token = _token;
|
||||
const auto done = [=](
|
||||
ChatAdminRightsInfo newRights,
|
||||
const QString &rank) {
|
||||
if (scope == Scope::GroupAdmin) {
|
||||
chat->session().api().sendBotStart(bot, chat, token);
|
||||
}
|
||||
close();
|
||||
};
|
||||
const auto saveCallback = SaveAdminCallback(
|
||||
chat,
|
||||
bot,
|
||||
close,
|
||||
done,
|
||||
close);
|
||||
auto box = object_ptr<EditAdminBox>(nullptr);
|
||||
box = Box<EditAdminBox>(
|
||||
auto box = Box<EditAdminBox>(
|
||||
chat,
|
||||
bot,
|
||||
ChatAdminRightsInfo(rights),
|
||||
QString(),
|
||||
true);
|
||||
_existingRank,
|
||||
EditAdminBotFields{
|
||||
_token,
|
||||
_existingRights.value_or(ChatAdminRights()) });
|
||||
box->setSaveCallback(saveCallback);
|
||||
Ui::show(std::move(box), Ui::LayerOption::KeepOther);
|
||||
} else {
|
||||
Ui::show(
|
||||
Ui::MakeConfirmBox({
|
||||
tr::lng_bot_sure_invite(tr::now, lt_group, chat->name),
|
||||
crl::guard(this, [=] { AddBotToGroup(bot, chat); }),
|
||||
crl::guard(this, [=] { AddBotToGroup(bot, chat, _token); }),
|
||||
}),
|
||||
Ui::LayerOption::KeepOther);
|
||||
}
|
||||
|
@ -251,32 +329,33 @@ bool AddBotToGroupBoxController::needToCreateRow(
|
|||
return true;
|
||||
}
|
||||
if (const auto chat = peer->asChat()) {
|
||||
if (_adminToGroup && chat->canAddAdmins()) {
|
||||
if (onlyAdminToGroup()) {
|
||||
return chat->canAddAdmins();
|
||||
} else if (_adminToGroup && chat->canAddAdmins()) {
|
||||
_groups.fire_copy(peer);
|
||||
} else {
|
||||
} else if (!onlyAdminToChannel()) {
|
||||
return chat->canAddMembers();
|
||||
}
|
||||
} else if (const auto group = peer->asMegagroup()) {
|
||||
if (_adminToGroup && group->canAddAdmins()) {
|
||||
if (onlyAdminToGroup()) {
|
||||
return group->canAddAdmins();
|
||||
} else if (_adminToGroup && group->canAddAdmins()) {
|
||||
_groups.fire_copy(peer);
|
||||
} else {
|
||||
} else if (!onlyAdminToChannel()) {
|
||||
return group->canAddMembers();
|
||||
}
|
||||
} else if (const auto channel = peer->asBroadcast()) {
|
||||
if (_adminToChannel && channel->canAddAdmins()) {
|
||||
if (onlyAdminToChannel()) {
|
||||
return channel->canAddAdmins();
|
||||
} else if (_adminToChannel && channel->canAddAdmins()) {
|
||||
_channels.fire_copy(peer);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AddBotToGroupBoxController::SharingBotGame(not_null<UserData*> bot) {
|
||||
const auto &info = bot->botInfo;
|
||||
return (info && !info->shareGameShortName.isEmpty());
|
||||
}
|
||||
|
||||
bool AddBotToGroupBoxController::sharingBotGame() const {
|
||||
return SharingBotGame(_bot);
|
||||
return (_scope == Scope::ShareGame);
|
||||
}
|
||||
|
||||
QString AddBotToGroupBoxController::emptyBoxText() const {
|
||||
|
@ -310,29 +389,31 @@ object_ptr<Ui::RpWidget> AddBotToGroupBoxController::prepareAdminnedChats() {
|
|||
const auto addList = [&](
|
||||
tr::phrase<> subtitle,
|
||||
rpl::event_stream<not_null<PeerData*>> &items) {
|
||||
container->add(CreatePeerListSectionSubtitle(
|
||||
container,
|
||||
subtitle()));
|
||||
container->add(object_ptr<Ui::FixedHeightWidget>(
|
||||
container,
|
||||
st::membersMarginTop));
|
||||
const auto wrap = container->add(
|
||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
container,
|
||||
object_ptr<Ui::VerticalLayout>(container)));
|
||||
wrap->hide(anim::type::instant);
|
||||
|
||||
const auto delegate = container->lifetime().make_state<
|
||||
const auto inner = wrap->entity();
|
||||
inner->add(CreatePeerListSectionSubtitle(inner, subtitle()));
|
||||
|
||||
const auto delegate = inner->lifetime().make_state<
|
||||
PeerListContentDelegateSimple
|
||||
>();
|
||||
const auto controller = container->lifetime().make_state<Controller>(
|
||||
const auto controller = inner->lifetime().make_state<Controller>(
|
||||
&session(),
|
||||
items.events(),
|
||||
callback);
|
||||
const auto content = result->add(object_ptr<PeerListContent>(
|
||||
const auto content = inner->add(object_ptr<PeerListContent>(
|
||||
container,
|
||||
controller));
|
||||
delegate->setContent(content);
|
||||
controller->setDelegate(delegate);
|
||||
|
||||
container->add(object_ptr<Ui::FixedHeightWidget>(
|
||||
container,
|
||||
st::membersMarginBottom));
|
||||
items.events() | rpl::take(1) | rpl::start_with_next([=] {
|
||||
wrap->show(anim::type::instant);
|
||||
}, inner->lifetime());
|
||||
};
|
||||
if (_adminToChannel) {
|
||||
addList(tr::lng_bot_channels_manage, _channels);
|
||||
|
@ -353,11 +434,20 @@ object_ptr<Ui::RpWidget> AddBotToGroupBoxController::prepareAdminnedChats() {
|
|||
return result;
|
||||
}
|
||||
|
||||
bool AddBotToGroupBoxController::onlyAdminToGroup() const {
|
||||
return _adminToGroup && !_memberToGroup && !_adminToChannel;
|
||||
}
|
||||
|
||||
bool AddBotToGroupBoxController::onlyAdminToChannel() const {
|
||||
return _adminToChannel && !_memberToGroup && !_adminToGroup;
|
||||
}
|
||||
|
||||
void AddBotToGroupBoxController::prepareViewHook() {
|
||||
delegate()->peerListSetTitle((sharingBotGame() || _adminToChannel)
|
||||
? tr::lng_bot_choose_chat()
|
||||
: tr::lng_bot_choose_group());
|
||||
if (_adminToGroup || _adminToChannel) {
|
||||
if ((_adminToGroup && !onlyAdminToGroup())
|
||||
|| (_adminToChannel && !onlyAdminToChannel())) {
|
||||
delegate()->peerListSetAboveWidget(prepareAdminnedChats());
|
||||
}
|
||||
|
||||
|
@ -370,9 +460,12 @@ void AddBotToGroupBoxController::prepareViewHook() {
|
|||
}, lifetime());
|
||||
}
|
||||
|
||||
void AddBotToGroup(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
||||
if (bot->isBot() && !bot->botInfo->startGroupToken.isEmpty()) {
|
||||
chat->session().api().sendBotStart(bot, chat);
|
||||
void AddBotToGroup(
|
||||
not_null<UserData*> bot,
|
||||
not_null<PeerData*> chat,
|
||||
const QString &startToken) {
|
||||
if (!startToken.isEmpty()) {
|
||||
chat->session().api().sendBotStart(bot, chat, startToken);
|
||||
} else {
|
||||
chat->session().api().chatParticipants().add(chat, { 1, bot });
|
||||
}
|
||||
|
|
|
@ -8,14 +8,30 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "data/data_chat_participant_status.h"
|
||||
|
||||
class AddBotToGroupBoxController
|
||||
: public ChatsListBoxController
|
||||
, public base::has_weak_ptr {
|
||||
public:
|
||||
static void Start(not_null<UserData*> bot);
|
||||
enum class Scope {
|
||||
None,
|
||||
GroupAdmin,
|
||||
ChannelAdmin,
|
||||
ShareGame,
|
||||
All,
|
||||
};
|
||||
static void Start(
|
||||
not_null<UserData*> bot,
|
||||
Scope scope = Scope::All,
|
||||
const QString &token = QString(),
|
||||
ChatAdminRights requestedRights = {});
|
||||
|
||||
explicit AddBotToGroupBoxController(not_null<UserData*> bot);
|
||||
AddBotToGroupBoxController(
|
||||
not_null<UserData*> bot,
|
||||
Scope scope,
|
||||
const QString &token,
|
||||
ChatAdminRights requestedRights);
|
||||
|
||||
Main::Session &session() const override;
|
||||
void rowClicked(not_null<PeerListRow*> row) override;
|
||||
|
@ -26,9 +42,10 @@ protected:
|
|||
QString emptyBoxText() const override;
|
||||
|
||||
private:
|
||||
static bool SharingBotGame(not_null<UserData*> bot);
|
||||
[[nodiscard]] object_ptr<Ui::RpWidget> prepareAdminnedChats();
|
||||
|
||||
object_ptr<Ui::RpWidget> prepareAdminnedChats();
|
||||
[[nodiscard]] bool onlyAdminToGroup() const;
|
||||
[[nodiscard]] bool onlyAdminToChannel() const;
|
||||
|
||||
bool needToCreateRow(not_null<PeerData*> peer) const;
|
||||
bool sharingBotGame() const;
|
||||
|
@ -37,13 +54,28 @@ private:
|
|||
|
||||
void shareBotGame(not_null<PeerData*> chat);
|
||||
void addBotToGroup(not_null<PeerData*> chat);
|
||||
void requestExistingRights(not_null<ChannelData*> channel);
|
||||
|
||||
const not_null<UserData*> _bot;
|
||||
const Scope _scope = Scope::None;
|
||||
const QString _token;
|
||||
const ChatAdminRights _requestedRights;
|
||||
|
||||
ChannelData *_existingRightsChannel = nullptr;
|
||||
mtpRequestId _existingRightsRequestId = 0;
|
||||
std::optional<ChatAdminRights> _existingRights;
|
||||
QString _existingRank;
|
||||
|
||||
rpl::event_stream<not_null<PeerData*>> _groups;
|
||||
rpl::event_stream<not_null<PeerData*>> _channels;
|
||||
|
||||
bool _adminToGroup = false;
|
||||
bool _adminToChannel = false;
|
||||
bool _memberToGroup = false;
|
||||
|
||||
};
|
||||
|
||||
void AddBotToGroup(not_null<UserData*> bot, not_null<PeerData*> chat);
|
||||
void AddBotToGroup(
|
||||
not_null<UserData*> bot,
|
||||
not_null<PeerData*> chat,
|
||||
const QString &startToken);
|
||||
|
|
|
@ -200,7 +200,7 @@ EditAdminBox::EditAdminBox(
|
|||
not_null<UserData*> user,
|
||||
ChatAdminRightsInfo rights,
|
||||
const QString &rank,
|
||||
bool addingBot)
|
||||
std::optional<EditAdminBotFields> addingBot)
|
||||
: EditParticipantBox(
|
||||
nullptr,
|
||||
peer,
|
||||
|
@ -209,7 +209,7 @@ EditAdminBox::EditAdminBox(
|
|||
, _show(this)
|
||||
, _oldRights(rights)
|
||||
, _oldRank(rank)
|
||||
, _addingBot(addingBot) {
|
||||
, _addingBot(std::move(addingBot)) {
|
||||
}
|
||||
|
||||
ChatAdminRightsInfo EditAdminBox::defaultRights() const {
|
||||
|
@ -240,12 +240,17 @@ void EditAdminBox::prepare() {
|
|||
EditParticipantBox::prepare();
|
||||
|
||||
setTitle(_addingBot
|
||||
? tr::lng_bot_add_title()
|
||||
? (_addingBot->existing
|
||||
? tr::lng_rights_edit_admin()
|
||||
: tr::lng_bot_add_title())
|
||||
: _oldRights.flags
|
||||
? tr::lng_rights_edit_admin()
|
||||
: tr::lng_channel_add_admin());
|
||||
|
||||
if (_addingBot && !peer()->isBroadcast() && _saveCallback) {
|
||||
if (_addingBot
|
||||
&& !_addingBot->existing
|
||||
&& !peer()->isBroadcast()
|
||||
&& _saveCallback) {
|
||||
addControl(
|
||||
object_ptr<Ui::BoxContentDivider>(this),
|
||||
st::rightsDividerMargin / 2);
|
||||
|
@ -277,7 +282,9 @@ void EditAdminBox::prepare() {
|
|||
|
||||
const auto chat = peer()->asChat();
|
||||
const auto channel = peer()->asChannel();
|
||||
const auto prepareRights = _oldRights.flags
|
||||
const auto prepareRights = _addingBot
|
||||
? ChatAdminRightsInfo(_oldRights.flags | _addingBot->existing)
|
||||
: _oldRights.flags
|
||||
? _oldRights
|
||||
: defaultRights();
|
||||
const auto disabledByDefaults = (channel && !channel->isMegagroup())
|
||||
|
@ -368,7 +375,7 @@ void EditAdminBox::prepare() {
|
|||
? ~Flags(0)
|
||||
: channel->adminRights());
|
||||
_saveCallback(
|
||||
_addingBot ? ChatAdminRightsInfo() : _oldRights,
|
||||
_oldRights,
|
||||
ChatAdminRightsInfo(newFlags),
|
||||
_rank ? _rank->getLastText().trimmed() : QString());
|
||||
};
|
||||
|
@ -376,9 +383,9 @@ void EditAdminBox::prepare() {
|
|||
if (!_saveCallback) {
|
||||
return;
|
||||
} else if (_addAsAdmin && !_addAsAdmin->checked()) {
|
||||
AddBotToGroup(user(), peer());
|
||||
AddBotToGroup(user(), peer(), _addingBot->token);
|
||||
return;
|
||||
} else if (_addingBot) {
|
||||
} else if (_addingBot && !_addingBot->existing) {
|
||||
const auto phrase = peer()->isBroadcast()
|
||||
? tr::lng_bot_sure_add_text_channel
|
||||
: tr::lng_bot_sure_add_text_group;
|
||||
|
@ -409,7 +416,7 @@ void EditAdminBox::finishAddAdmin() {
|
|||
void EditAdminBox::refreshButtons() {
|
||||
clearButtons();
|
||||
if (canSave()) {
|
||||
addButton(!_addingBot
|
||||
addButton((!_addingBot || _addingBot->existing)
|
||||
? tr::lng_settings_save()
|
||||
: _adminControlsWrap->toggled()
|
||||
? tr::lng_bot_add_as_admin()
|
||||
|
|
|
@ -65,6 +65,11 @@ private:
|
|||
|
||||
};
|
||||
|
||||
struct EditAdminBotFields {
|
||||
QString token;
|
||||
ChatAdminRights existing;
|
||||
};
|
||||
|
||||
class EditAdminBox : public EditParticipantBox {
|
||||
public:
|
||||
EditAdminBox(
|
||||
|
@ -73,7 +78,7 @@ public:
|
|||
not_null<UserData*> user,
|
||||
ChatAdminRightsInfo rights,
|
||||
const QString &rank,
|
||||
bool addingBot = false);
|
||||
std::optional<EditAdminBotFields> addingBot = {});
|
||||
|
||||
void setSaveCallback(
|
||||
Fn<void(
|
||||
|
@ -127,7 +132,7 @@ private:
|
|||
mtpRequestId _transferRequestId = 0;
|
||||
Fn<void()> _save, _finishSave;
|
||||
|
||||
bool _addingBot = false;
|
||||
std::optional<EditAdminBotFields> _addingBot;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -251,6 +251,39 @@ bool ShowWallPaper(
|
|||
params);
|
||||
}
|
||||
|
||||
[[nodiscard]] ChatAdminRights ParseRequestedAdminRights(
|
||||
const QString &value) {
|
||||
auto result = ChatAdminRights();
|
||||
for (const auto &element : value.split(QRegularExpression("[+ ]"))) {
|
||||
if (element == u"change_info"_q) {
|
||||
result |= ChatAdminRight::ChangeInfo;
|
||||
} else if (element == u"post_messages"_q) {
|
||||
result |= ChatAdminRight::PostMessages;
|
||||
} else if (element == u"edit_messages"_q) {
|
||||
result |= ChatAdminRight::EditMessages;
|
||||
} else if (element == u"delete_messages"_q) {
|
||||
result |= ChatAdminRight::DeleteMessages;
|
||||
} else if (element == u"restrict_members"_q) {
|
||||
result |= ChatAdminRight::BanUsers;
|
||||
} else if (element == u"invite_users"_q) {
|
||||
result |= ChatAdminRight::InviteUsers;
|
||||
} else if (element == u"pin_messages"_q) {
|
||||
result |= ChatAdminRight::PinMessages;
|
||||
} else if (element == u"promote_members"_q) {
|
||||
result |= ChatAdminRight::AddAdmins;
|
||||
} else if (element == u"manage_video_chats"_q) {
|
||||
result |= ChatAdminRight::ManageCall;
|
||||
} else if (element == u"anonymous"_q) {
|
||||
result |= ChatAdminRight::Anonymous;
|
||||
} else if (element == u"manage_chat"_q) {
|
||||
result |= ChatAdminRight::Other;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ResolveUsernameOrPhone(
|
||||
Window::SessionController *controller,
|
||||
const Match &match,
|
||||
|
@ -278,18 +311,24 @@ bool ResolveUsernameOrPhone(
|
|||
} else if (!validDomain(domain) && !validPhone(phone)) {
|
||||
return false;
|
||||
}
|
||||
auto start = qsl("start");
|
||||
auto startToken = params.value(start);
|
||||
if (startToken.isEmpty()) {
|
||||
start = qsl("startgroup");
|
||||
startToken = params.value(start);
|
||||
if (startToken.isEmpty()) {
|
||||
start = QString();
|
||||
}
|
||||
using BotStartType = Window::BotStartType;
|
||||
auto startType = BotStartType::None;
|
||||
auto startToken = params.value(u"start"_q);
|
||||
if (!startToken.isEmpty()) {
|
||||
startType = BotStartType::Personal;
|
||||
} else if (params.contains(u"startgroup"_q)) {
|
||||
startType = BotStartType::Group;
|
||||
startToken = params.value(u"startgroup"_q);
|
||||
} else if (params.contains(u"startchannel"_q)) {
|
||||
startType = BotStartType::Channel;
|
||||
}
|
||||
auto post = ShowAtUnreadMsgId;
|
||||
auto adminRights = ChatAdminRights();
|
||||
if (startType == BotStartType::Group
|
||||
|| startType == BotStartType::Channel) {
|
||||
post = ShowAtProfileMsgId;
|
||||
adminRights = ParseRequestedAdminRights(params.value(u"admin"_q));
|
||||
}
|
||||
auto post = (start == qsl("startgroup"))
|
||||
? ShowAtProfileMsgId
|
||||
: ShowAtUnreadMsgId;
|
||||
const auto postParam = params.value(qsl("post"));
|
||||
if (const auto postId = postParam.toInt()) {
|
||||
post = postId;
|
||||
|
@ -301,7 +340,8 @@ bool ResolveUsernameOrPhone(
|
|||
const auto gameParam = params.value(qsl("game"));
|
||||
if (!gameParam.isEmpty() && validDomain(gameParam)) {
|
||||
startToken = gameParam;
|
||||
post = ShowAtGameShareMsgId;
|
||||
post = ShowAtProfileMsgId;
|
||||
startType = BotStartType::ShareGame;
|
||||
}
|
||||
const auto fromMessageId = context.value<ClickHandlerContext>().itemId;
|
||||
using Navigation = Window::SessionNavigation;
|
||||
|
@ -318,7 +358,9 @@ bool ResolveUsernameOrPhone(
|
|||
Navigation::ThreadId{ threadId }
|
||||
}
|
||||
: Navigation::RepliesByLinkInfo{ v::null },
|
||||
.startType = startType,
|
||||
.startToken = startToken,
|
||||
.startAdminRights = adminRights,
|
||||
.voicechatHash = (params.contains(u"livestream"_q)
|
||||
? std::make_optional(params.value(u"livestream"_q))
|
||||
: params.contains(u"videochat"_q)
|
||||
|
|
|
@ -84,7 +84,6 @@ constexpr auto ShowAtTheEndMsgId = MsgId(SpecialMsgIdShift + 1);
|
|||
constexpr auto SwitchAtTopMsgId = MsgId(SpecialMsgIdShift + 2);
|
||||
constexpr auto ShowAtProfileMsgId = MsgId(SpecialMsgIdShift + 3);
|
||||
constexpr auto ShowAndStartBotMsgId = MsgId(SpecialMsgIdShift + 4);
|
||||
constexpr auto ShowAtGameShareMsgId = MsgId(SpecialMsgIdShift + 5);
|
||||
constexpr auto ShowForChooseMessagesMsgId = MsgId(SpecialMsgIdShift + 6);
|
||||
|
||||
static_assert(SpecialMsgIdShift + 0xFF < 0);
|
||||
|
|
|
@ -20,7 +20,7 @@ struct BotInfo {
|
|||
std::vector<BotCommand> commands;
|
||||
Ui::Text::String text = { int(st::msgMinWidth) }; // description
|
||||
|
||||
QString startToken, startGroupToken, shareGameShortName;
|
||||
QString startToken;
|
||||
Dialogs::EntryState inlineReturnTo;
|
||||
|
||||
ChatAdminRights groupAdminRights;
|
||||
|
|
|
@ -338,6 +338,7 @@ void SessionNavigation::showPeerByLinkResolved(
|
|||
}).send();
|
||||
return;
|
||||
}
|
||||
using Scope = AddBotToGroupBoxController::Scope;
|
||||
const auto &replies = info.repliesInfo;
|
||||
if (const auto threadId = std::get_if<ThreadId>(&replies)) {
|
||||
showRepliesForMessage(
|
||||
|
@ -351,31 +352,28 @@ void SessionNavigation::showPeerByLinkResolved(
|
|||
info.messageId,
|
||||
commentId->id,
|
||||
params);
|
||||
} else if (info.messageId == ShowAtGameShareMsgId) {
|
||||
const auto user = peer->asUser();
|
||||
if (user && user->isBot() && !info.startToken.isEmpty()) {
|
||||
user->botInfo->shareGameShortName = info.startToken;
|
||||
AddBotToGroupBoxController::Start(user);
|
||||
} else {
|
||||
crl::on_main(this, [=] {
|
||||
showPeerHistory(peer->id, params);
|
||||
});
|
||||
}
|
||||
} else if (info.messageId == ShowAtProfileMsgId && !peer->isChannel()) {
|
||||
const auto user = peer->asUser();
|
||||
if (user
|
||||
&& user->isBot()
|
||||
&& !user->botInfo->cantJoinGroups
|
||||
&& !info.startToken.isEmpty()) {
|
||||
user->botInfo->startGroupToken = info.startToken;
|
||||
AddBotToGroupBoxController::Start(user);
|
||||
} else if (user && user->isBot()) {
|
||||
const auto scope = (info.startType == BotStartType::ShareGame)
|
||||
? Scope::ShareGame
|
||||
: (info.startType == BotStartType::Group)
|
||||
? (info.startAdminRights ? Scope::GroupAdmin : Scope::All)
|
||||
: (info.startType == BotStartType::Channel)
|
||||
? Scope::ChannelAdmin
|
||||
: Scope::None;
|
||||
if (!user || !user->isBot()) {
|
||||
showPeerInfo(peer, params);
|
||||
} else if (scope != Scope::None) {
|
||||
AddBotToGroupBoxController::Start(
|
||||
user,
|
||||
scope,
|
||||
info.startToken,
|
||||
info.startAdminRights);
|
||||
} else {
|
||||
// Always open bot chats, even from mention links.
|
||||
crl::on_main(this, [=] {
|
||||
showPeerHistory(peer->id, params);
|
||||
});
|
||||
} else {
|
||||
showPeerInfo(peer, params);
|
||||
}
|
||||
} else {
|
||||
const auto user = peer->asUser();
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "base/observer.h"
|
||||
#include "base/weak_ptr.h"
|
||||
#include "base/timer.h"
|
||||
#include "data/data_chat_participant_status.h"
|
||||
#include "dialogs/dialogs_key.h"
|
||||
#include "ui/layers/layer_widget.h"
|
||||
#include "ui/layers/show.h"
|
||||
|
@ -86,6 +87,14 @@ enum class GifPauseReason {
|
|||
using GifPauseReasons = base::flags<GifPauseReason>;
|
||||
inline constexpr bool is_flag_type(GifPauseReason) { return true; };
|
||||
|
||||
enum class BotStartType {
|
||||
None,
|
||||
Personal,
|
||||
Group,
|
||||
Channel,
|
||||
ShareGame,
|
||||
};
|
||||
|
||||
struct PeerThemeOverride {
|
||||
PeerData *peer = nullptr;
|
||||
std::shared_ptr<Ui::ChatTheme> theme;
|
||||
|
@ -178,7 +187,9 @@ public:
|
|||
QString phone;
|
||||
MsgId messageId = ShowAtUnreadMsgId;
|
||||
RepliesByLinkInfo repliesInfo;
|
||||
BotStartType startType = BotStartType::None;
|
||||
QString startToken;
|
||||
ChatAdminRights startAdminRights;
|
||||
std::optional<QString> voicechatHash;
|
||||
FullMsgId clickFromMessageId;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue