mirror of
https://github.com/vale981/tdesktop
synced 2025-03-05 09:41:41 -05:00
Suggest adding bots to channels as admins.
This commit is contained in:
parent
c259921269
commit
4002739682
10 changed files with 203 additions and 172 deletions
|
@ -1090,7 +1090,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_cant_invite_banned" = "Sorry, only admin can add this user.";
|
||||
"lng_cant_invite_privacy" = "Sorry, you cannot add this user to groups because of their privacy settings.";
|
||||
"lng_cant_invite_privacy_channel" = "Sorry, you cannot add this user to channels because of their privacy settings.";
|
||||
"lng_cant_invite_bot_to_channel" = "Sorry, bots can only be added to channels as administrators.";
|
||||
"lng_cant_do_this" = "Sorry, this action is unavailable.";
|
||||
"lng_cant_invite_offer_admin" = "Bots can only be added as administrators.";
|
||||
"lng_cant_invite_make_admin" = "Make admin";
|
||||
|
||||
"lng_send_button" = "Send";
|
||||
"lng_message_ph" = "Write a message...";
|
||||
|
|
|
@ -56,9 +56,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace {
|
||||
|
||||
constexpr auto kReloadChannelMembersTimeout = 1000; // 1 second wait before reload members in channel after adding
|
||||
constexpr auto kSaveCloudDraftTimeout = 1000; // save draft to the cloud with 1 sec extra delay
|
||||
constexpr auto kSaveDraftBeforeQuitTimeout = 1500; // give the app 1.5 secs to save drafts to cloud when quitting
|
||||
// 1 second wait before reload members in channel after adding.
|
||||
constexpr auto kReloadChannelMembersTimeout = 1000;
|
||||
|
||||
// Save draft to the cloud with 1 sec extra delay.
|
||||
constexpr auto kSaveCloudDraftTimeout = 1000;
|
||||
|
||||
// Give the app 1.5 secs to save drafts to cloud when quitting.
|
||||
constexpr auto kSaveDraftBeforeQuitTimeout = 1500;
|
||||
|
||||
// Max users in one super group invite request.
|
||||
constexpr auto kMaxUsersPerInvite = 100;
|
||||
|
||||
// How many messages from chat history server should forward to user,
|
||||
// that was added to this chat.
|
||||
constexpr auto kForwardMessagesOnAdd = 100;
|
||||
|
||||
constexpr auto kProxyPromotionInterval = TimeId(60 * 60);
|
||||
constexpr auto kProxyPromotionMinDelay = TimeId(10);
|
||||
constexpr auto kSmallDelayMs = 5;
|
||||
|
@ -3565,6 +3578,57 @@ void ApiWrap::checkForUnreadMentions(
|
|||
}
|
||||
}
|
||||
|
||||
void ApiWrap::addChatParticipants(
|
||||
not_null<PeerData*> peer,
|
||||
const std::vector<not_null<UserData*>> &users) {
|
||||
if (const auto chat = peer->asChat()) {
|
||||
for (const auto user : users) {
|
||||
request(MTPmessages_AddChatUser(
|
||||
chat->inputChat,
|
||||
user->inputUser,
|
||||
MTP_int(kForwardMessagesOnAdd)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
ShowAddParticipantsError(error.type(), peer, { 1, user });
|
||||
}).afterDelay(TimeMs(5)).send();
|
||||
}
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
const auto bot = ranges::find_if(users, [](not_null<UserData*> user) {
|
||||
return user->botInfo != nullptr;
|
||||
});
|
||||
if (!peer->isMegagroup() && bot != end(users)) {
|
||||
ShowAddParticipantsError("USER_BOT", peer, users);
|
||||
return;
|
||||
}
|
||||
auto list = QVector<MTPInputUser>();
|
||||
list.reserve(qMin(int(users.size()), int(kMaxUsersPerInvite)));
|
||||
const auto send = [&] {
|
||||
request(MTPchannels_InviteToChannel(
|
||||
channel->inputChannel,
|
||||
MTP_vector<MTPInputUser>(list)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result);
|
||||
requestParticipantsCountDelayed(channel);
|
||||
}).fail([=](const RPCError &error) {
|
||||
ShowAddParticipantsError(error.type(), peer, users);
|
||||
}).afterDelay(TimeMs(5)).send();
|
||||
};
|
||||
for (const auto user : users) {
|
||||
list.push_back(user->inputUser);
|
||||
if (list.size() == kMaxUsersPerInvite) {
|
||||
send();
|
||||
list.clear();
|
||||
}
|
||||
}
|
||||
if (!list.empty()) {
|
||||
send();
|
||||
}
|
||||
} else {
|
||||
Unexpected("User in ApiWrap::addChatParticipants.");
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::cancelEditChatAdmins(not_null<ChatData*> chat) {
|
||||
_chatAdminsEnabledRequests.take(
|
||||
chat
|
||||
|
@ -4556,26 +4620,36 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
|||
}
|
||||
}
|
||||
|
||||
void ApiWrap::sendBotStart(not_null<UserData*> bot) {
|
||||
void ApiWrap::sendBotStart(not_null<UserData*> bot, PeerData *chat) {
|
||||
Expects(bot->botInfo != nullptr);
|
||||
Expects(chat == nullptr || !bot->botInfo->startGroupToken.isEmpty());
|
||||
|
||||
const auto token = bot->botInfo->startToken;
|
||||
if (chat && chat->isChannel() && !chat->isMegagroup()) {
|
||||
ShowAddParticipantsError("USER_BOT", chat, { 1, bot });
|
||||
return;
|
||||
}
|
||||
|
||||
auto &info = bot->botInfo;
|
||||
auto &token = chat ? info->startGroupToken : info->startToken;
|
||||
if (token.isEmpty()) {
|
||||
auto message = ApiWrap::MessageToSend(App::history(bot));
|
||||
message.textWithTags = { qsl("/start"), TextWithTags::Tags() };
|
||||
sendMessage(std::move(message));
|
||||
} else {
|
||||
bot->botInfo->startToken = QString();
|
||||
const auto randomId = rand_value<uint64>();
|
||||
request(MTPmessages_StartBot(
|
||||
bot->inputUser,
|
||||
MTP_inputPeerEmpty(),
|
||||
MTP_long(randomId),
|
||||
MTP_string(token)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result);
|
||||
}).send();
|
||||
return;
|
||||
}
|
||||
const auto randomId = rand_value<uint64>();
|
||||
request(MTPmessages_StartBot(
|
||||
bot->inputUser,
|
||||
chat ? chat->input : MTP_inputPeerEmpty(),
|
||||
MTP_long(randomId),
|
||||
MTP_string(base::take(token))
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
if (chat) {
|
||||
ShowAddParticipantsError(error.type(), chat, { 1, bot });
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ApiWrap::sendInlineResult(
|
||||
|
|
|
@ -260,6 +260,9 @@ public:
|
|||
int availableCount,
|
||||
const QVector<MTPChannelParticipant> &list)> callbackList,
|
||||
Fn<void()> callbackNotModified = nullptr);
|
||||
void addChatParticipants(
|
||||
not_null<PeerData*> peer,
|
||||
const std::vector<not_null<UserData*>> &users);
|
||||
|
||||
struct SendOptions {
|
||||
SendOptions(not_null<History*> history);
|
||||
|
@ -329,7 +332,7 @@ public:
|
|||
bool handleSupportSwitch = false;
|
||||
};
|
||||
void sendMessage(MessageToSend &&message);
|
||||
void sendBotStart(not_null<UserData*> bot);
|
||||
void sendBotStart(not_null<UserData*> bot, PeerData *chat = nullptr);
|
||||
void sendInlineResult(
|
||||
not_null<UserData*> bot,
|
||||
not_null<InlineBots::Result*> data,
|
||||
|
|
|
@ -16,7 +16,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/confirm_box.h"
|
||||
#include "boxes/photo_crop_box.h"
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "boxes/edit_participant_box.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "profile/profile_channel_controllers.h"
|
||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
|
@ -67,6 +69,77 @@ QString PeerFloodErrorText(PeerFloodType type) {
|
|||
return lng_cant_send_to_not_contact(lt_more_info, link);
|
||||
}
|
||||
|
||||
void ShowAddParticipantsError(
|
||||
const QString &error,
|
||||
not_null<PeerData*> chat,
|
||||
const std::vector<not_null<UserData*>> &users) {
|
||||
if (error == qstr("USER_BOT")) {
|
||||
const auto channel = chat->asChannel();
|
||||
if ((users.size() == 1)
|
||||
&& (users.front()->botInfo != nullptr)
|
||||
&& channel
|
||||
&& !channel->isMegagroup()
|
||||
&& channel->canAddAdmins()) {
|
||||
const auto makeAdmin = [=] {
|
||||
const auto user = users.front();
|
||||
const auto weak = std::make_shared<QPointer<EditAdminBox>>();
|
||||
const auto close = [=] {
|
||||
if (*weak) {
|
||||
(*weak)->closeBox();
|
||||
}
|
||||
};
|
||||
const auto saveCallback = Profile::SaveAdminCallback(
|
||||
channel,
|
||||
user,
|
||||
[=](auto&&...) { close(); },
|
||||
close);
|
||||
auto box = Box<EditAdminBox>(
|
||||
channel,
|
||||
user,
|
||||
MTP_channelAdminRights(MTP_flags(0)));
|
||||
box->setSaveCallback(saveCallback);
|
||||
*weak = Ui::show(std::move(box));
|
||||
};
|
||||
Ui::show(
|
||||
Box<ConfirmBox>(
|
||||
lang(lng_cant_invite_offer_admin),
|
||||
lang(lng_cant_invite_make_admin),
|
||||
lang(lng_cancel),
|
||||
makeAdmin),
|
||||
LayerOption::KeepOther);
|
||||
return;
|
||||
}
|
||||
}
|
||||
const auto bot = ranges::find_if(users, [](not_null<UserData*> user) {
|
||||
return user->botInfo != nullptr;
|
||||
});
|
||||
const auto hasBot = (bot != end(users));
|
||||
const auto text = [&] {
|
||||
if (error == qstr("USER_BOT")) {
|
||||
return lang(lng_cant_invite_bot_to_channel);
|
||||
} else if (error == qstr("USER_LEFT_CHAT")) {
|
||||
// Trying to return a user who has left.
|
||||
} else if (error == qstr("USER_KICKED")) {
|
||||
// Trying to return a user who was kicked by admin.
|
||||
return lang(lng_cant_invite_banned);
|
||||
} else if (error == qstr("USER_PRIVACY_RESTRICTED")) {
|
||||
return lang(lng_cant_invite_privacy);
|
||||
} else if (error == qstr("USER_NOT_MUTUAL_CONTACT")) {
|
||||
// Trying to return user who does not have me in contacts.
|
||||
return lang(lng_failed_add_not_mutual);
|
||||
} else if (error == qstr("USER_ALREADY_PARTICIPANT") && hasBot) {
|
||||
return lang(lng_bot_already_in_group);
|
||||
} else if (error == qstr("PEER_FLOOD")) {
|
||||
const auto isGroup = (chat->isChat() || chat->isMegagroup());
|
||||
return PeerFloodErrorText(isGroup
|
||||
? PeerFloodType::InviteGroup
|
||||
: PeerFloodType::InviteChannel);
|
||||
}
|
||||
return lang(lng_failed_add_participant);
|
||||
}();
|
||||
Ui::show(Box<InformBox>(text), LayerOption::KeepOther);
|
||||
}
|
||||
|
||||
class RevokePublicLinkBox::Inner : public TWidget, private MTP::Sender {
|
||||
public:
|
||||
Inner(QWidget *parent, Fn<void()> revokeCallback);
|
||||
|
|
|
@ -38,6 +38,10 @@ enum class PeerFloodType {
|
|||
InviteChannel,
|
||||
};
|
||||
QString PeerFloodErrorText(PeerFloodType type);
|
||||
void ShowAddParticipantsError(
|
||||
const QString &error,
|
||||
not_null<PeerData*> chat,
|
||||
const std::vector<not_null<UserData*>> &users);
|
||||
|
||||
class AddContactBox : public BoxContent, public RPCSender {
|
||||
public:
|
||||
|
|
|
@ -71,32 +71,34 @@ void ShareBotGame(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
|||
}
|
||||
|
||||
void AddBotToGroup(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
||||
if (auto &info = bot->botInfo) {
|
||||
if (!info->startGroupToken.isEmpty()) {
|
||||
MTP::send(
|
||||
MTPmessages_StartBot(
|
||||
bot->inputUser,
|
||||
chat->input,
|
||||
MTP_long(rand_value<uint64>()),
|
||||
MTP_string(info->startGroupToken)),
|
||||
App::main()->rpcDone(&MainWidget::sentUpdatesReceived),
|
||||
App::main()->rpcFail(
|
||||
&MainWidget::addParticipantFail,
|
||||
{ bot, chat }));
|
||||
} else {
|
||||
App::main()->addParticipants(
|
||||
chat,
|
||||
{ 1, bot });
|
||||
}
|
||||
if (bot->botInfo && !bot->botInfo->startGroupToken.isEmpty()) {
|
||||
Auth().api().sendBotStart(bot, chat);
|
||||
} else {
|
||||
App::main()->addParticipants(
|
||||
chat,
|
||||
{ 1, bot });
|
||||
Auth().api().addChatParticipants(chat, { 1, bot });
|
||||
}
|
||||
Ui::hideLayer();
|
||||
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
|
||||
}
|
||||
|
||||
bool InviteSelectedUsers(
|
||||
not_null<PeerListBox*> box,
|
||||
not_null<PeerData*> chat) {
|
||||
const auto rows = box->peerListCollectSelectedRows();
|
||||
const auto users = ranges::view::all(
|
||||
rows
|
||||
) | ranges::view::transform([](not_null<PeerData*> peer) {
|
||||
Expects(peer->isUser());
|
||||
Expects(!peer->isSelf());
|
||||
|
||||
return not_null<UserData*>(peer->asUser());
|
||||
}) | ranges::to_vector;
|
||||
if (users.empty()) {
|
||||
return false;
|
||||
}
|
||||
Auth().api().addChatParticipants(chat, users);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Not used for now.
|
||||
|
@ -544,18 +546,9 @@ void AddParticipantsBoxController::updateTitle() {
|
|||
}
|
||||
|
||||
void AddParticipantsBoxController::Start(not_null<ChatData*> chat) {
|
||||
auto initBox = [chat](not_null<PeerListBox*> box) {
|
||||
box->addButton(langFactory(lng_participant_invite), [box, chat] {
|
||||
auto rows = box->peerListCollectSelectedRows();
|
||||
if (!rows.empty()) {
|
||||
auto users = std::vector<not_null<UserData*>>();
|
||||
for (auto peer : rows) {
|
||||
auto user = peer->asUser();
|
||||
Assert(user != nullptr);
|
||||
Assert(!user->isSelf());
|
||||
users.push_back(peer->asUser());
|
||||
}
|
||||
App::main()->addParticipants(chat, users);
|
||||
auto initBox = [=](not_null<PeerListBox*> box) {
|
||||
box->addButton(langFactory(lng_participant_invite), [=] {
|
||||
if (InviteSelectedUsers(box, chat)) {
|
||||
Ui::showPeerHistory(chat, ShowAtTheEndMsgId);
|
||||
}
|
||||
});
|
||||
|
@ -570,17 +563,8 @@ void AddParticipantsBoxController::Start(
|
|||
bool justCreated) {
|
||||
auto initBox = [channel, justCreated](not_null<PeerListBox*> box) {
|
||||
auto subscription = std::make_shared<rpl::lifetime>();
|
||||
box->addButton(langFactory(lng_participant_invite), [box, channel, subscription] {
|
||||
auto rows = box->peerListCollectSelectedRows();
|
||||
if (!rows.empty()) {
|
||||
auto users = std::vector<not_null<UserData*>>();
|
||||
for (auto peer : rows) {
|
||||
auto user = peer->asUser();
|
||||
Assert(user != nullptr);
|
||||
Assert(!user->isSelf());
|
||||
users.push_back(peer->asUser());
|
||||
}
|
||||
App::main()->addParticipants(channel, users);
|
||||
box->addButton(langFactory(lng_participant_invite), [=, subscription] {
|
||||
if (InviteSelectedUsers(box, channel)) {
|
||||
if (channel->isMegagroup()) {
|
||||
Ui::showPeerHistory(channel, ShowAtTheEndMsgId);
|
||||
} else {
|
||||
|
@ -830,7 +814,7 @@ void AddBotToGroupBoxController::shareBotGame(not_null<PeerData*> chat) {
|
|||
}
|
||||
|
||||
void AddBotToGroupBoxController::addBotToGroup(not_null<PeerData*> chat) {
|
||||
if (auto megagroup = chat->asMegagroup()) {
|
||||
if (const auto megagroup = chat->asMegagroup()) {
|
||||
if (!megagroup->canAddMembers()) {
|
||||
Ui::show(
|
||||
Box<InformBox>(lang(lng_error_cant_add_member)),
|
||||
|
|
|
@ -192,6 +192,7 @@ private:
|
|||
bool isAlreadyIn(not_null<UserData*> user) const;
|
||||
int fullCount() const;
|
||||
void updateTitle();
|
||||
bool inviteSelectedUsers(not_null<PeerData*> chat) const;
|
||||
|
||||
PeerData *_peer = nullptr;
|
||||
base::flat_set<not_null<UserData*>> _alreadyIn;
|
||||
|
|
|
@ -26,8 +26,6 @@ enum {
|
|||
|
||||
MTPKillFileSessionTimeout = 5000, // how much time without upload / download causes additional session kill
|
||||
|
||||
MaxUsersPerInvite = 100, // max users in one super group invite request
|
||||
|
||||
MTPChannelGetDifferenceLimit = 100,
|
||||
|
||||
MaxSelectedItems = 100,
|
||||
|
@ -273,8 +271,6 @@ enum {
|
|||
IdleMsecs = 60 * 1000, // after 60secs without user input we think we are idle
|
||||
|
||||
SendViewsTimeout = 1000, // send views each second
|
||||
|
||||
ForwardOnAdd = 100, // how many messages from chat history server should forward to user, that was added to this chat
|
||||
};
|
||||
|
||||
inline const QRegularExpression &cRussianLetters() {
|
||||
|
|
|
@ -908,91 +908,6 @@ void MainWidget::deleteAndExit(ChatData *chat) {
|
|||
rpcFail(&MainWidget::leaveChatFailed, peer));
|
||||
}
|
||||
|
||||
void MainWidget::addParticipants(
|
||||
not_null<PeerData*> chatOrChannel,
|
||||
const std::vector<not_null<UserData*>> &users) {
|
||||
if (auto chat = chatOrChannel->asChat()) {
|
||||
for_const (auto user, users) {
|
||||
MTP::send(
|
||||
MTPmessages_AddChatUser(
|
||||
chat->inputChat,
|
||||
user->inputUser,
|
||||
MTP_int(ForwardOnAdd)),
|
||||
rpcDone(&MainWidget::sentUpdatesReceived),
|
||||
rpcFail(&MainWidget::addParticipantFail, { user, chat }),
|
||||
0,
|
||||
5);
|
||||
}
|
||||
} else if (auto channel = chatOrChannel->asChannel()) {
|
||||
QVector<MTPInputUser> inputUsers;
|
||||
inputUsers.reserve(qMin(int(users.size()), int(MaxUsersPerInvite)));
|
||||
for (auto i = users.cbegin(), e = users.cend(); i != e; ++i) {
|
||||
inputUsers.push_back((*i)->inputUser);
|
||||
if (inputUsers.size() == MaxUsersPerInvite) {
|
||||
MTP::send(
|
||||
MTPchannels_InviteToChannel(
|
||||
channel->inputChannel,
|
||||
MTP_vector<MTPInputUser>(inputUsers)),
|
||||
rpcDone(&MainWidget::inviteToChannelDone, { channel }),
|
||||
rpcFail(&MainWidget::addParticipantsFail, { channel }),
|
||||
0,
|
||||
5);
|
||||
inputUsers.clear();
|
||||
}
|
||||
}
|
||||
if (!inputUsers.isEmpty()) {
|
||||
MTP::send(
|
||||
MTPchannels_InviteToChannel(
|
||||
channel->inputChannel,
|
||||
MTP_vector<MTPInputUser>(inputUsers)),
|
||||
rpcDone(&MainWidget::inviteToChannelDone, { channel }),
|
||||
rpcFail(&MainWidget::addParticipantsFail, { channel }),
|
||||
0,
|
||||
5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWidget::addParticipantFail(UserAndPeer data, const RPCError &error) {
|
||||
if (MTP::isDefaultHandledError(error)) return false;
|
||||
|
||||
QString text = lang(lng_failed_add_participant);
|
||||
if (error.type() == qstr("USER_LEFT_CHAT")) { // trying to return a user who has left
|
||||
} else if (error.type() == qstr("USER_KICKED")) { // trying to return a user who was kicked by admin
|
||||
text = lang(lng_cant_invite_banned);
|
||||
} else if (error.type() == qstr("USER_PRIVACY_RESTRICTED")) {
|
||||
text = lang(lng_cant_invite_privacy);
|
||||
} else if (error.type() == qstr("USER_NOT_MUTUAL_CONTACT")) { // trying to return user who does not have me in contacts
|
||||
text = lang(lng_failed_add_not_mutual);
|
||||
} else if (error.type() == qstr("USER_ALREADY_PARTICIPANT") && data.user->botInfo) {
|
||||
text = lang(lng_bot_already_in_group);
|
||||
} else if (error.type() == qstr("PEER_FLOOD")) {
|
||||
text = PeerFloodErrorText((data.peer->isChat() || data.peer->isMegagroup()) ? PeerFloodType::InviteGroup : PeerFloodType::InviteChannel);
|
||||
}
|
||||
Ui::show(Box<InformBox>(text));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainWidget::addParticipantsFail(
|
||||
not_null<ChannelData*> channel,
|
||||
const RPCError &error) {
|
||||
if (MTP::isDefaultHandledError(error)) return false;
|
||||
|
||||
QString text = lang(lng_failed_add_participant);
|
||||
if (error.type() == qstr("USER_LEFT_CHAT")) { // trying to return banned user to his group
|
||||
} else if (error.type() == qstr("USER_KICKED")) { // trying to return a user who was kicked by admin
|
||||
text = lang(lng_cant_invite_banned);
|
||||
} else if (error.type() == qstr("USER_PRIVACY_RESTRICTED")) {
|
||||
text = lang(channel->isMegagroup() ? lng_cant_invite_privacy : lng_cant_invite_privacy_channel);
|
||||
} else if (error.type() == qstr("USER_NOT_MUTUAL_CONTACT")) { // trying to return user who does not have me in contacts
|
||||
text = lang(channel->isMegagroup() ? lng_failed_add_not_mutual : lng_failed_add_not_mutual_channel);
|
||||
} else if (error.type() == qstr("PEER_FLOOD")) {
|
||||
text = PeerFloodErrorText(PeerFloodType::InviteGroup);
|
||||
}
|
||||
Ui::show(Box<InformBox>(text));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainWidget::sendMessageFail(const RPCError &error) {
|
||||
if (MTP::isDefaultHandledError(error)) return false;
|
||||
|
||||
|
@ -2318,13 +2233,6 @@ bool MainWidget::deleteChannelFailed(const RPCError &error) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void MainWidget::inviteToChannelDone(
|
||||
not_null<ChannelData*> channel,
|
||||
const MTPUpdates &updates) {
|
||||
sentUpdatesReceived(updates);
|
||||
Auth().api().requestParticipantsCountDelayed(channel);
|
||||
}
|
||||
|
||||
void MainWidget::historyToDown(History *history) {
|
||||
_history->historyToDown(history);
|
||||
}
|
||||
|
|
|
@ -125,9 +125,6 @@ public:
|
|||
return sentUpdatesReceived(0, updates);
|
||||
}
|
||||
bool deleteChannelFailed(const RPCError &error);
|
||||
void inviteToChannelDone(
|
||||
not_null<ChannelData*> channel,
|
||||
const MTPUpdates &updates);
|
||||
void historyToDown(History *hist);
|
||||
void dialogsToUp();
|
||||
void newUnreadMsg(
|
||||
|
@ -201,18 +198,6 @@ public:
|
|||
bool deleteHistory = true);
|
||||
void deleteAndExit(ChatData *chat);
|
||||
|
||||
void addParticipants(
|
||||
not_null<PeerData*> chatOrChannel,
|
||||
const std::vector<not_null<UserData*>> &users);
|
||||
struct UserAndPeer {
|
||||
UserData *user;
|
||||
PeerData *peer;
|
||||
};
|
||||
bool addParticipantFail(UserAndPeer data, const RPCError &e);
|
||||
bool addParticipantsFail(
|
||||
not_null<ChannelData*> channel,
|
||||
const RPCError &e); // for multi invite in channels
|
||||
|
||||
bool sendMessageFail(const RPCError &error);
|
||||
|
||||
Dialogs::IndexedList *contactsList();
|
||||
|
|
Loading…
Add table
Reference in a new issue