mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 22:54:01 +02:00
Improve phrases in adding a bot as an admin.
This commit is contained in:
parent
a35888a07b
commit
649f2908e8
13 changed files with 596 additions and 312 deletions
|
@ -163,6 +163,8 @@ PRIVATE
|
||||||
boxes/filters/edit_filter_box.h
|
boxes/filters/edit_filter_box.h
|
||||||
boxes/filters/edit_filter_chats_list.cpp
|
boxes/filters/edit_filter_chats_list.cpp
|
||||||
boxes/filters/edit_filter_chats_list.h
|
boxes/filters/edit_filter_chats_list.h
|
||||||
|
boxes/peers/add_bot_to_chat_box.cpp
|
||||||
|
boxes/peers/add_bot_to_chat_box.h
|
||||||
boxes/peers/add_participants_box.cpp
|
boxes/peers/add_participants_box.cpp
|
||||||
boxes/peers/add_participants_box.h
|
boxes/peers/add_participants_box.h
|
||||||
boxes/peers/edit_contact_box.cpp
|
boxes/peers/edit_contact_box.cpp
|
||||||
|
|
|
@ -1714,6 +1714,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_bot_channels_manage" = "Channels I manage";
|
"lng_bot_channels_manage" = "Channels I manage";
|
||||||
"lng_bot_groups" = "Groups";
|
"lng_bot_groups" = "Groups";
|
||||||
"lng_bot_add_title" = "Add Bot";
|
"lng_bot_add_title" = "Add Bot";
|
||||||
|
"lng_bot_as_admin_check" = "Admin rights";
|
||||||
"lng_bot_add_as_admin" = "Add Bot as Admin";
|
"lng_bot_add_as_admin" = "Add Bot as Admin";
|
||||||
"lng_bot_add_as_member" = "Add Bot as Member";
|
"lng_bot_add_as_member" = "Add Bot as Member";
|
||||||
"lng_bot_sure_add_title" = "Add bot as admin";
|
"lng_bot_sure_add_title" = "Add bot as admin";
|
||||||
|
|
|
@ -89,35 +89,6 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] object_ptr<Ui::RpWidget> CreateSectionSubtitle(
|
|
||||||
not_null<QWidget*> parent,
|
|
||||||
rpl::producer<QString> text) {
|
|
||||||
auto result = object_ptr<Ui::FixedHeightWidget>(
|
|
||||||
parent,
|
|
||||||
st::searchedBarHeight);
|
|
||||||
|
|
||||||
const auto raw = result.data();
|
|
||||||
raw->paintRequest(
|
|
||||||
) | rpl::start_with_next([=](QRect clip) {
|
|
||||||
auto p = QPainter(raw);
|
|
||||||
p.fillRect(clip, st::searchedBarBg);
|
|
||||||
}, raw->lifetime());
|
|
||||||
|
|
||||||
const auto label = Ui::CreateChild<Ui::FlatLabel>(
|
|
||||||
raw,
|
|
||||||
std::move(text),
|
|
||||||
st::windowFilterChatsSectionSubtitle);
|
|
||||||
raw->widthValue(
|
|
||||||
) | rpl::start_with_next([=](int width) {
|
|
||||||
const auto padding = st::windowFilterChatsSectionSubtitlePadding;
|
|
||||||
const auto available = width - padding.left() - padding.right();
|
|
||||||
label->resizeToNaturalWidth(available);
|
|
||||||
label->moveToLeft(padding.left(), padding.top(), width);
|
|
||||||
}, label->lifetime());
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] uint64 TypeId(Flag flag) {
|
[[nodiscard]] uint64 TypeId(Flag flag) {
|
||||||
return PeerId(FakeChatId(static_cast<BareId>(flag))).value;
|
return PeerId(FakeChatId(static_cast<BareId>(flag))).value;
|
||||||
}
|
}
|
||||||
|
@ -291,6 +262,35 @@ void PaintFilterChatsTypeIcon(
|
||||||
icon.paintInCenter(p, rect);
|
icon.paintInCenter(p, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_ptr<Ui::RpWidget> CreatePeerListSectionSubtitle(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
rpl::producer<QString> text) {
|
||||||
|
auto result = object_ptr<Ui::FixedHeightWidget>(
|
||||||
|
parent,
|
||||||
|
st::searchedBarHeight);
|
||||||
|
|
||||||
|
const auto raw = result.data();
|
||||||
|
raw->paintRequest(
|
||||||
|
) | rpl::start_with_next([=](QRect clip) {
|
||||||
|
auto p = QPainter(raw);
|
||||||
|
p.fillRect(clip, st::searchedBarBg);
|
||||||
|
}, raw->lifetime());
|
||||||
|
|
||||||
|
const auto label = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
|
raw,
|
||||||
|
std::move(text),
|
||||||
|
st::windowFilterChatsSectionSubtitle);
|
||||||
|
raw->widthValue(
|
||||||
|
) | rpl::start_with_next([=](int width) {
|
||||||
|
const auto padding = st::windowFilterChatsSectionSubtitlePadding;
|
||||||
|
const auto available = width - padding.left() - padding.right();
|
||||||
|
label->resizeToNaturalWidth(available);
|
||||||
|
label->moveToLeft(padding.left(), padding.top(), width);
|
||||||
|
}, label->lifetime());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
EditFilterChatsListController::EditFilterChatsListController(
|
EditFilterChatsListController::EditFilterChatsListController(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
rpl::producer<QString> title,
|
rpl::producer<QString> title,
|
||||||
|
@ -357,7 +357,7 @@ void EditFilterChatsListController::prepareViewHook() {
|
||||||
object_ptr<Ui::RpWidget> EditFilterChatsListController::prepareTypesList() {
|
object_ptr<Ui::RpWidget> EditFilterChatsListController::prepareTypesList() {
|
||||||
auto result = object_ptr<Ui::VerticalLayout>((QWidget*)nullptr);
|
auto result = object_ptr<Ui::VerticalLayout>((QWidget*)nullptr);
|
||||||
const auto container = result.data();
|
const auto container = result.data();
|
||||||
container->add(CreateSectionSubtitle(
|
container->add(CreatePeerListSectionSubtitle(
|
||||||
container,
|
container,
|
||||||
tr::lng_filters_edit_types()));
|
tr::lng_filters_edit_types()));
|
||||||
container->add(object_ptr<Ui::FixedHeightWidget>(
|
container->add(object_ptr<Ui::FixedHeightWidget>(
|
||||||
|
@ -390,7 +390,7 @@ object_ptr<Ui::RpWidget> EditFilterChatsListController::prepareTypesList() {
|
||||||
container->add(object_ptr<Ui::FixedHeightWidget>(
|
container->add(object_ptr<Ui::FixedHeightWidget>(
|
||||||
container,
|
container,
|
||||||
st::membersMarginBottom));
|
st::membersMarginBottom));
|
||||||
container->add(CreateSectionSubtitle(
|
container->add(CreatePeerListSectionSubtitle(
|
||||||
container,
|
container,
|
||||||
tr::lng_filters_edit_chats()));
|
tr::lng_filters_edit_chats()));
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,10 @@ void PaintFilterChatsTypeIcon(
|
||||||
int outerWidth,
|
int outerWidth,
|
||||||
int size);
|
int size);
|
||||||
|
|
||||||
|
[[nodiscard]] object_ptr<Ui::RpWidget> CreatePeerListSectionSubtitle(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
rpl::producer<QString> text);
|
||||||
|
|
||||||
class EditFilterChatsListController final : public ChatsListBoxController {
|
class EditFilterChatsListController final : public ChatsListBoxController {
|
||||||
public:
|
public:
|
||||||
using Flag = Data::ChatFilter::Flag;
|
using Flag = Data::ChatFilter::Flag;
|
||||||
|
|
|
@ -25,8 +25,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "boxes/peers/edit_participant_box.h"
|
|
||||||
#include "boxes/peers/edit_participants_box.h"
|
|
||||||
#include "dialogs/dialogs_main_list.h"
|
#include "dialogs/dialogs_main_list.h"
|
||||||
#include "window/window_session_controller.h" // showAddContact()
|
#include "window/window_session_controller.h" // showAddContact()
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
|
@ -38,52 +36,6 @@ namespace {
|
||||||
|
|
||||||
constexpr auto kSortByOnlineThrottle = 3 * crl::time(1000);
|
constexpr auto kSortByOnlineThrottle = 3 * crl::time(1000);
|
||||||
|
|
||||||
void ShareBotGame(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
|
||||||
const auto history = chat->owner().history(chat);
|
|
||||||
auto &histories = history->owner().histories();
|
|
||||||
const auto requestType = Data::Histories::RequestType::Send;
|
|
||||||
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
|
||||||
const auto randomId = base::RandomValue<uint64>();
|
|
||||||
const auto api = &chat->session().api();
|
|
||||||
history->sendRequestId = api->request(MTPmessages_SendMedia(
|
|
||||||
MTP_flags(0),
|
|
||||||
chat->input,
|
|
||||||
MTP_int(0),
|
|
||||||
MTP_inputMediaGame(
|
|
||||||
MTP_inputGameShortName(
|
|
||||||
bot->inputUser,
|
|
||||||
MTP_string(bot->botInfo->shareGameShortName))),
|
|
||||||
MTP_string(),
|
|
||||||
MTP_long(randomId),
|
|
||||||
MTPReplyMarkup(),
|
|
||||||
MTPVector<MTPMessageEntity>(),
|
|
||||||
MTP_int(0), // schedule_date
|
|
||||||
MTPInputPeer() // send_as
|
|
||||||
)).done([=](const MTPUpdates &result) {
|
|
||||||
api->applyUpdates(result, randomId);
|
|
||||||
finish();
|
|
||||||
}).fail([=](const MTP::Error &error) {
|
|
||||||
api->sendMessageFail(error, chat);
|
|
||||||
finish();
|
|
||||||
}).afterRequest(
|
|
||||||
history->sendRequestId
|
|
||||||
).send();
|
|
||||||
return history->sendRequestId;
|
|
||||||
});
|
|
||||||
Ui::hideLayer();
|
|
||||||
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddBotToGroup(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
|
||||||
if (bot->isBot() && !bot->botInfo->startGroupToken.isEmpty()) {
|
|
||||||
chat->session().api().sendBotStart(bot, chat);
|
|
||||||
} else {
|
|
||||||
chat->session().api().chatParticipants().add(chat, { 1, bot });
|
|
||||||
}
|
|
||||||
Ui::hideLayer();
|
|
||||||
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// Not used for now.
|
// Not used for now.
|
||||||
|
@ -526,168 +478,6 @@ std::unique_ptr<PeerListRow> ContactsBoxController::createRow(
|
||||||
return std::make_unique<PeerListRow>(user);
|
return std::make_unique<PeerListRow>(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddBotToGroupBoxController::Start(not_null<UserData*> bot) {
|
|
||||||
auto initBox = [=](not_null<PeerListBox*> box) {
|
|
||||||
box->addButton(tr::lng_cancel(), [box] { box->closeBox(); });
|
|
||||||
};
|
|
||||||
Ui::show(Box<PeerListBox>(
|
|
||||||
std::make_unique<AddBotToGroupBoxController>(bot),
|
|
||||||
std::move(initBox)));
|
|
||||||
}
|
|
||||||
|
|
||||||
AddBotToGroupBoxController::AddBotToGroupBoxController(
|
|
||||||
not_null<UserData*> bot)
|
|
||||||
: ChatsListBoxController(SharingBotGame(bot)
|
|
||||||
? std::make_unique<PeerListGlobalSearchController>(&bot->session())
|
|
||||||
: nullptr)
|
|
||||||
, _bot(bot) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Main::Session &AddBotToGroupBoxController::session() const {
|
|
||||||
return _bot->session();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddBotToGroupBoxController::rowClicked(not_null<PeerListRow*> row) {
|
|
||||||
if (sharingBotGame()) {
|
|
||||||
shareBotGame(row->peer());
|
|
||||||
} else {
|
|
||||||
addBotToGroup(row->peer());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddBotToGroupBoxController::shareBotGame(not_null<PeerData*> chat) {
|
|
||||||
auto send = crl::guard(this, [bot = _bot, chat] {
|
|
||||||
ShareBotGame(bot, chat);
|
|
||||||
});
|
|
||||||
auto confirmText = [chat] {
|
|
||||||
if (chat->isUser()) {
|
|
||||||
return tr::lng_bot_sure_share_game(tr::now, lt_user, chat->name);
|
|
||||||
}
|
|
||||||
return tr::lng_bot_sure_share_game_group(tr::now, lt_group, chat->name);
|
|
||||||
}();
|
|
||||||
Ui::show(
|
|
||||||
Ui::MakeConfirmBox({
|
|
||||||
.text = confirmText,
|
|
||||||
.confirmed = std::move(send),
|
|
||||||
}),
|
|
||||||
Ui::LayerOption::KeepOther);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddBotToGroupBoxController::addBotToGroup(not_null<PeerData*> chat) {
|
|
||||||
if (const auto megagroup = chat->asMegagroup()) {
|
|
||||||
if (!megagroup->canAddMembers()) {
|
|
||||||
Ui::show(
|
|
||||||
Ui::MakeInformBox(tr::lng_error_cant_add_member()),
|
|
||||||
Ui::LayerOption::KeepOther);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const auto bot = _bot;
|
|
||||||
const auto close = [=](auto&&...) {
|
|
||||||
Ui::hideLayer();
|
|
||||||
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
|
|
||||||
};
|
|
||||||
const auto saveCallback = SaveAdminCallback(
|
|
||||||
chat,
|
|
||||||
bot,
|
|
||||||
close,
|
|
||||||
close);
|
|
||||||
auto box = object_ptr<EditAdminBox>(nullptr);
|
|
||||||
if (chat->isBroadcast()) {
|
|
||||||
if (bot->botInfo->channelAdminRights) {
|
|
||||||
box = Box<EditAdminBox>(
|
|
||||||
chat,
|
|
||||||
bot,
|
|
||||||
ChatAdminRightsInfo(bot->botInfo->channelAdminRights),
|
|
||||||
QString());
|
|
||||||
}
|
|
||||||
} else if (bot->botInfo->groupAdminRights) {
|
|
||||||
box = Box<EditAdminBox>(
|
|
||||||
chat,
|
|
||||||
bot,
|
|
||||||
ChatAdminRightsInfo(bot->botInfo->groupAdminRights),
|
|
||||||
QString());
|
|
||||||
}
|
|
||||||
if (box) {
|
|
||||||
box->setSaveCallback(saveCallback);
|
|
||||||
Ui::show(std::move(box));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Ui::show(
|
|
||||||
Ui::MakeConfirmBox({
|
|
||||||
tr::lng_bot_sure_invite(tr::now, lt_group, chat->name),
|
|
||||||
crl::guard(this, [=] { AddBotToGroup(bot, chat); }),
|
|
||||||
}),
|
|
||||||
Ui::LayerOption::KeepOther);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto AddBotToGroupBoxController::createRow(not_null<History*> history)
|
|
||||||
-> std::unique_ptr<ChatsListBoxController::Row> {
|
|
||||||
if (!needToCreateRow(history->peer)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return std::make_unique<Row>(history);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AddBotToGroupBoxController::needToCreateRow(
|
|
||||||
not_null<PeerData*> peer) const {
|
|
||||||
if (sharingBotGame()) {
|
|
||||||
if (!peer->canWrite()
|
|
||||||
|| peer->amRestricted(ChatRestriction::SendGames)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (const auto chat = peer->asChat()) {
|
|
||||||
return chat->canAddMembers();
|
|
||||||
} else if (const auto group = peer->asMegagroup()) {
|
|
||||||
return group->canAddMembers();
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AddBotToGroupBoxController::emptyBoxText() const {
|
|
||||||
return !session().data().chatsListLoaded()
|
|
||||||
? tr::lng_contacts_loading(tr::now)
|
|
||||||
: sharingBotGame()
|
|
||||||
? tr::lng_bot_no_chats(tr::now)
|
|
||||||
: tr::lng_bot_no_groups(tr::now);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AddBotToGroupBoxController::noResultsText() const {
|
|
||||||
return !session().data().chatsListLoaded()
|
|
||||||
? tr::lng_contacts_loading(tr::now)
|
|
||||||
: sharingBotGame()
|
|
||||||
? tr::lng_bot_chats_not_found(tr::now)
|
|
||||||
: tr::lng_bot_groups_not_found(tr::now);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddBotToGroupBoxController::updateLabels() {
|
|
||||||
setSearchNoResultsText(noResultsText());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddBotToGroupBoxController::prepareViewHook() {
|
|
||||||
delegate()->peerListSetTitle(sharingBotGame()
|
|
||||||
? tr::lng_bot_choose_chat()
|
|
||||||
: tr::lng_bot_choose_group());
|
|
||||||
updateLabels();
|
|
||||||
session().data().chatsListLoadedEvents(
|
|
||||||
) | rpl::filter([=](Data::Folder *folder) {
|
|
||||||
return !folder;
|
|
||||||
}) | rpl::start_with_next([=] {
|
|
||||||
updateLabels();
|
|
||||||
}, lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
ChooseRecipientBoxController::ChooseRecipientBoxController(
|
ChooseRecipientBoxController::ChooseRecipientBoxController(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
FnMut<void(not_null<PeerData*>)> callback)
|
FnMut<void(not_null<PeerData*>)> callback)
|
||||||
|
|
|
@ -165,38 +165,6 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddBotToGroupBoxController
|
|
||||||
: public ChatsListBoxController
|
|
||||||
, public base::has_weak_ptr {
|
|
||||||
public:
|
|
||||||
static void Start(not_null<UserData*> bot);
|
|
||||||
|
|
||||||
explicit AddBotToGroupBoxController(not_null<UserData*> bot);
|
|
||||||
|
|
||||||
Main::Session &session() const override;
|
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::unique_ptr<Row> createRow(not_null<History*> history) override;
|
|
||||||
void prepareViewHook() override;
|
|
||||||
QString emptyBoxText() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static bool SharingBotGame(not_null<UserData*> bot);
|
|
||||||
|
|
||||||
bool needToCreateRow(not_null<PeerData*> peer) const;
|
|
||||||
bool sharingBotGame() const;
|
|
||||||
QString noResultsText() const;
|
|
||||||
QString descriptionText() const;
|
|
||||||
void updateLabels();
|
|
||||||
|
|
||||||
void shareBotGame(not_null<PeerData*> chat);
|
|
||||||
void addBotToGroup(not_null<PeerData*> chat);
|
|
||||||
|
|
||||||
const not_null<UserData*> _bot;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class ChooseRecipientBoxController
|
class ChooseRecipientBoxController
|
||||||
: public ChatsListBoxController
|
: public ChatsListBoxController
|
||||||
, public base::has_weak_ptr {
|
, public base::has_weak_ptr {
|
||||||
|
|
381
Telegram/SourceFiles/boxes/peers/add_bot_to_chat_box.cpp
Normal file
381
Telegram/SourceFiles/boxes/peers/add_bot_to_chat_box.cpp
Normal file
|
@ -0,0 +1,381 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "boxes/peers/add_bot_to_chat_box.h"
|
||||||
|
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "data/data_user.h"
|
||||||
|
#include "data/data_chat.h"
|
||||||
|
#include "data/data_channel.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_histories.h"
|
||||||
|
#include "history/history.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "boxes/peers/edit_participant_box.h"
|
||||||
|
#include "boxes/peers/edit_participants_box.h"
|
||||||
|
#include "boxes/filters/edit_filter_chats_list.h"
|
||||||
|
#include "ui/boxes/confirm_box.h"
|
||||||
|
#include "base/random.h"
|
||||||
|
#include "base/weak_ptr.h"
|
||||||
|
#include "api/api_chat_participants.h"
|
||||||
|
#include "apiwrap.h"
|
||||||
|
#include "facades.h"
|
||||||
|
#include "styles/style_boxes.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class Controller final
|
||||||
|
: public PeerListController
|
||||||
|
, public base::has_weak_ptr {
|
||||||
|
public:
|
||||||
|
Controller(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
rpl::producer<not_null<PeerData*>> add,
|
||||||
|
Fn<void(not_null<PeerData*> chat)> callback);
|
||||||
|
|
||||||
|
Main::Session &session() const override;
|
||||||
|
void prepare() override;
|
||||||
|
void rowClicked(not_null<PeerListRow*> row) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addRow(not_null<PeerData*> peer);
|
||||||
|
|
||||||
|
const not_null<Main::Session*> _session;
|
||||||
|
Fn<void(not_null<PeerData*> chat)> _callback;
|
||||||
|
std::vector<not_null<PeerData*>> _list;
|
||||||
|
bool _prepared = false;
|
||||||
|
bool _refreshing = false;
|
||||||
|
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void ShareBotGame(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
||||||
|
const auto history = chat->owner().history(chat);
|
||||||
|
auto &histories = history->owner().histories();
|
||||||
|
const auto requestType = Data::Histories::RequestType::Send;
|
||||||
|
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
||||||
|
const auto randomId = base::RandomValue<uint64>();
|
||||||
|
const auto api = &chat->session().api();
|
||||||
|
history->sendRequestId = api->request(MTPmessages_SendMedia(
|
||||||
|
MTP_flags(0),
|
||||||
|
chat->input,
|
||||||
|
MTP_int(0),
|
||||||
|
MTP_inputMediaGame(
|
||||||
|
MTP_inputGameShortName(
|
||||||
|
bot->inputUser,
|
||||||
|
MTP_string(bot->botInfo->shareGameShortName))),
|
||||||
|
MTP_string(),
|
||||||
|
MTP_long(randomId),
|
||||||
|
MTPReplyMarkup(),
|
||||||
|
MTPVector<MTPMessageEntity>(),
|
||||||
|
MTP_int(0), // schedule_date
|
||||||
|
MTPInputPeer() // send_as
|
||||||
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
api->applyUpdates(result, randomId);
|
||||||
|
finish();
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
api->sendMessageFail(error, chat);
|
||||||
|
finish();
|
||||||
|
}).afterRequest(
|
||||||
|
history->sendRequestId
|
||||||
|
).send();
|
||||||
|
return history->sendRequestId;
|
||||||
|
});
|
||||||
|
Ui::hideLayer();
|
||||||
|
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller::Controller(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
rpl::producer<not_null<PeerData*>> add,
|
||||||
|
Fn<void(not_null<PeerData*> chat)> callback)
|
||||||
|
: _session(session)
|
||||||
|
, _callback(std::move(callback)) {
|
||||||
|
std::move(
|
||||||
|
add
|
||||||
|
) | rpl::start_with_next([=](not_null<PeerData*> peer) {
|
||||||
|
if (_prepared) {
|
||||||
|
addRow(peer);
|
||||||
|
} else {
|
||||||
|
_list.push_back(peer);
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
Main::Session &Controller::session() const {
|
||||||
|
return *_session;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::prepare() {
|
||||||
|
_prepared = true;
|
||||||
|
for (const auto &peer : _list) {
|
||||||
|
addRow(peer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::rowClicked(not_null<PeerListRow*> row) {
|
||||||
|
_callback(row->peer());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::addRow(not_null<PeerData*> peer) {
|
||||||
|
if (delegate()->peerListFindRow(peer->id.value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delegate()->peerListAppendRow(std::make_unique<PeerListRow>(peer));
|
||||||
|
if (!_refreshing) {
|
||||||
|
_refreshing = true;
|
||||||
|
Ui::PostponeCall(this, [=] {
|
||||||
|
_refreshing = false;
|
||||||
|
delegate()->peerListRefreshRows();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void AddBotToGroupBoxController::Start(not_null<UserData*> bot) {
|
||||||
|
auto initBox = [=](not_null<PeerListBox*> box) {
|
||||||
|
box->addButton(tr::lng_cancel(), [box] { box->closeBox(); });
|
||||||
|
};
|
||||||
|
Ui::show(Box<PeerListBox>(
|
||||||
|
std::make_unique<AddBotToGroupBoxController>(bot),
|
||||||
|
std::move(initBox)));
|
||||||
|
}
|
||||||
|
|
||||||
|
AddBotToGroupBoxController::AddBotToGroupBoxController(
|
||||||
|
not_null<UserData*> bot)
|
||||||
|
: ChatsListBoxController(SharingBotGame(bot)
|
||||||
|
? std::make_unique<PeerListGlobalSearchController>(&bot->session())
|
||||||
|
: nullptr)
|
||||||
|
, _bot(bot)
|
||||||
|
, _adminToGroup(_bot->botInfo->groupAdminRights != 0)
|
||||||
|
, _adminToChannel(_bot->botInfo->channelAdminRights != 0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Main::Session &AddBotToGroupBoxController::session() const {
|
||||||
|
return _bot->session();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddBotToGroupBoxController::rowClicked(not_null<PeerListRow*> row) {
|
||||||
|
if (sharingBotGame()) {
|
||||||
|
shareBotGame(row->peer());
|
||||||
|
} else {
|
||||||
|
addBotToGroup(row->peer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddBotToGroupBoxController::shareBotGame(not_null<PeerData*> chat) {
|
||||||
|
auto send = crl::guard(this, [bot = _bot, chat] {
|
||||||
|
ShareBotGame(bot, chat);
|
||||||
|
});
|
||||||
|
auto confirmText = [chat] {
|
||||||
|
if (chat->isUser()) {
|
||||||
|
return tr::lng_bot_sure_share_game(tr::now, lt_user, chat->name);
|
||||||
|
}
|
||||||
|
return tr::lng_bot_sure_share_game_group(tr::now, lt_group, chat->name);
|
||||||
|
}();
|
||||||
|
Ui::show(
|
||||||
|
Ui::MakeConfirmBox({
|
||||||
|
.text = confirmText,
|
||||||
|
.confirmed = std::move(send),
|
||||||
|
}),
|
||||||
|
Ui::LayerOption::KeepOther);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddBotToGroupBoxController::addBotToGroup(not_null<PeerData*> chat) {
|
||||||
|
if (const auto megagroup = chat->asMegagroup()) {
|
||||||
|
if (!megagroup->canAddMembers()) {
|
||||||
|
Ui::show(
|
||||||
|
Ui::MakeInformBox(tr::lng_error_cant_add_member()),
|
||||||
|
Ui::LayerOption::KeepOther);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const auto bot = _bot;
|
||||||
|
const auto close = [=](auto&&...) {
|
||||||
|
Ui::hideLayer();
|
||||||
|
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
|
||||||
|
};
|
||||||
|
const auto rights = (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 saveCallback = SaveAdminCallback(
|
||||||
|
chat,
|
||||||
|
bot,
|
||||||
|
close,
|
||||||
|
close);
|
||||||
|
auto box = object_ptr<EditAdminBox>(nullptr);
|
||||||
|
box = Box<EditAdminBox>(
|
||||||
|
chat,
|
||||||
|
bot,
|
||||||
|
ChatAdminRightsInfo(rights),
|
||||||
|
QString(),
|
||||||
|
true);
|
||||||
|
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); }),
|
||||||
|
}),
|
||||||
|
Ui::LayerOption::KeepOther);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto AddBotToGroupBoxController::createRow(not_null<History*> history)
|
||||||
|
-> std::unique_ptr<ChatsListBoxController::Row> {
|
||||||
|
if (!needToCreateRow(history->peer)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return std::make_unique<Row>(history);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AddBotToGroupBoxController::needToCreateRow(
|
||||||
|
not_null<PeerData*> peer) const {
|
||||||
|
if (sharingBotGame()) {
|
||||||
|
if (!peer->canWrite()
|
||||||
|
|| peer->amRestricted(ChatRestriction::SendGames)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (const auto chat = peer->asChat()) {
|
||||||
|
if (_adminToGroup && chat->canAddAdmins()) {
|
||||||
|
_groups.fire_copy(peer);
|
||||||
|
} else {
|
||||||
|
return chat->canAddMembers();
|
||||||
|
}
|
||||||
|
} else if (const auto group = peer->asMegagroup()) {
|
||||||
|
if (_adminToGroup && group->canAddAdmins()) {
|
||||||
|
_groups.fire_copy(peer);
|
||||||
|
} else {
|
||||||
|
return group->canAddMembers();
|
||||||
|
}
|
||||||
|
} else if (const auto channel = peer->asBroadcast()) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AddBotToGroupBoxController::emptyBoxText() const {
|
||||||
|
return !session().data().chatsListLoaded()
|
||||||
|
? tr::lng_contacts_loading(tr::now)
|
||||||
|
: (sharingBotGame() || _adminToChannel)
|
||||||
|
? tr::lng_bot_no_chats(tr::now)
|
||||||
|
: tr::lng_bot_no_groups(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AddBotToGroupBoxController::noResultsText() const {
|
||||||
|
return !session().data().chatsListLoaded()
|
||||||
|
? tr::lng_contacts_loading(tr::now)
|
||||||
|
: (sharingBotGame() || _adminToChannel)
|
||||||
|
? tr::lng_bot_chats_not_found(tr::now)
|
||||||
|
: tr::lng_bot_groups_not_found(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddBotToGroupBoxController::updateLabels() {
|
||||||
|
setSearchNoResultsText(noResultsText());
|
||||||
|
}
|
||||||
|
|
||||||
|
object_ptr<Ui::RpWidget> AddBotToGroupBoxController::prepareAdminnedChats() {
|
||||||
|
auto result = object_ptr<Ui::VerticalLayout>((QWidget*)nullptr);
|
||||||
|
const auto container = result.data();
|
||||||
|
|
||||||
|
const auto callback = [=](not_null<PeerData*> chat) {
|
||||||
|
addBotToGroup(chat);
|
||||||
|
};
|
||||||
|
|
||||||
|
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 delegate = container->lifetime().make_state<
|
||||||
|
PeerListContentDelegateSimple
|
||||||
|
>();
|
||||||
|
const auto controller = container->lifetime().make_state<Controller>(
|
||||||
|
&session(),
|
||||||
|
items.events(),
|
||||||
|
callback);
|
||||||
|
const auto content = result->add(object_ptr<PeerListContent>(
|
||||||
|
container,
|
||||||
|
controller));
|
||||||
|
delegate->setContent(content);
|
||||||
|
controller->setDelegate(delegate);
|
||||||
|
|
||||||
|
container->add(object_ptr<Ui::FixedHeightWidget>(
|
||||||
|
container,
|
||||||
|
st::membersMarginBottom));
|
||||||
|
};
|
||||||
|
if (_adminToChannel) {
|
||||||
|
addList(tr::lng_bot_channels_manage, _channels);
|
||||||
|
}
|
||||||
|
if (_adminToGroup) {
|
||||||
|
addList(tr::lng_bot_groups_manage, _groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::merge(
|
||||||
|
_groups.events(),
|
||||||
|
_channels.events()
|
||||||
|
) | rpl::take(1) | rpl::start_with_next([=] {
|
||||||
|
container->add(CreatePeerListSectionSubtitle(
|
||||||
|
container,
|
||||||
|
tr::lng_bot_groups()));
|
||||||
|
}, container->lifetime());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddBotToGroupBoxController::prepareViewHook() {
|
||||||
|
delegate()->peerListSetTitle((sharingBotGame() || _adminToChannel)
|
||||||
|
? tr::lng_bot_choose_chat()
|
||||||
|
: tr::lng_bot_choose_group());
|
||||||
|
if (_adminToGroup || _adminToChannel) {
|
||||||
|
delegate()->peerListSetAboveWidget(prepareAdminnedChats());
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLabels();
|
||||||
|
session().data().chatsListLoadedEvents(
|
||||||
|
) | rpl::filter([=](Data::Folder *folder) {
|
||||||
|
return !folder;
|
||||||
|
}) | rpl::start_with_next([=] {
|
||||||
|
updateLabels();
|
||||||
|
}, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddBotToGroup(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
||||||
|
if (bot->isBot() && !bot->botInfo->startGroupToken.isEmpty()) {
|
||||||
|
chat->session().api().sendBotStart(bot, chat);
|
||||||
|
} else {
|
||||||
|
chat->session().api().chatParticipants().add(chat, { 1, bot });
|
||||||
|
}
|
||||||
|
Ui::hideLayer();
|
||||||
|
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
|
||||||
|
}
|
49
Telegram/SourceFiles/boxes/peers/add_bot_to_chat_box.h
Normal file
49
Telegram/SourceFiles/boxes/peers/add_bot_to_chat_box.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "boxes/peer_list_controllers.h"
|
||||||
|
|
||||||
|
class AddBotToGroupBoxController
|
||||||
|
: public ChatsListBoxController
|
||||||
|
, public base::has_weak_ptr {
|
||||||
|
public:
|
||||||
|
static void Start(not_null<UserData*> bot);
|
||||||
|
|
||||||
|
explicit AddBotToGroupBoxController(not_null<UserData*> bot);
|
||||||
|
|
||||||
|
Main::Session &session() const override;
|
||||||
|
void rowClicked(not_null<PeerListRow*> row) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<Row> createRow(not_null<History*> history) override;
|
||||||
|
void prepareViewHook() override;
|
||||||
|
QString emptyBoxText() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool SharingBotGame(not_null<UserData*> bot);
|
||||||
|
|
||||||
|
object_ptr<Ui::RpWidget> prepareAdminnedChats();
|
||||||
|
|
||||||
|
bool needToCreateRow(not_null<PeerData*> peer) const;
|
||||||
|
bool sharingBotGame() const;
|
||||||
|
QString noResultsText() const;
|
||||||
|
void updateLabels();
|
||||||
|
|
||||||
|
void shareBotGame(not_null<PeerData*> chat);
|
||||||
|
void addBotToGroup(not_null<PeerData*> chat);
|
||||||
|
|
||||||
|
const not_null<UserData*> _bot;
|
||||||
|
rpl::event_stream<not_null<PeerData*>> _groups;
|
||||||
|
rpl::event_stream<not_null<PeerData*>> _channels;
|
||||||
|
bool _adminToGroup = false;
|
||||||
|
bool _adminToChannel = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void AddBotToGroup(not_null<UserData*> bot, not_null<PeerData*> chat);
|
|
@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "settings/settings_privacy_security.h"
|
#include "settings/settings_privacy_security.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "boxes/passcode_box.h"
|
#include "boxes/passcode_box.h"
|
||||||
|
#include "boxes/peers/add_bot_to_chat_box.h"
|
||||||
#include "boxes/peers/edit_peer_permissions_box.h"
|
#include "boxes/peers/edit_peer_permissions_box.h"
|
||||||
#include "boxes/peers/edit_peer_info_box.h"
|
#include "boxes/peers/edit_peer_info_box.h"
|
||||||
#include "data/data_peer_values.h"
|
#include "data/data_peer_values.h"
|
||||||
|
@ -198,7 +199,8 @@ EditAdminBox::EditAdminBox(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
not_null<UserData*> user,
|
not_null<UserData*> user,
|
||||||
ChatAdminRightsInfo rights,
|
ChatAdminRightsInfo rights,
|
||||||
const QString &rank)
|
const QString &rank,
|
||||||
|
bool addingBot)
|
||||||
: EditParticipantBox(
|
: EditParticipantBox(
|
||||||
nullptr,
|
nullptr,
|
||||||
peer,
|
peer,
|
||||||
|
@ -206,7 +208,8 @@ EditAdminBox::EditAdminBox(
|
||||||
(rights.flags != 0))
|
(rights.flags != 0))
|
||||||
, _show(this)
|
, _show(this)
|
||||||
, _oldRights(rights)
|
, _oldRights(rights)
|
||||||
, _oldRank(rank) {
|
, _oldRank(rank)
|
||||||
|
, _addingBot(addingBot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatAdminRightsInfo EditAdminBox::defaultRights() const {
|
ChatAdminRightsInfo EditAdminBox::defaultRights() const {
|
||||||
|
@ -236,12 +239,40 @@ void EditAdminBox::prepare() {
|
||||||
|
|
||||||
EditParticipantBox::prepare();
|
EditParticipantBox::prepare();
|
||||||
|
|
||||||
setTitle(_oldRights.flags
|
setTitle(_addingBot
|
||||||
|
? tr::lng_bot_add_title()
|
||||||
|
: _oldRights.flags
|
||||||
? tr::lng_rights_edit_admin()
|
? tr::lng_rights_edit_admin()
|
||||||
: tr::lng_channel_add_admin());
|
: tr::lng_channel_add_admin());
|
||||||
|
|
||||||
addControl(
|
if (_addingBot && !peer()->isBroadcast() && _saveCallback) {
|
||||||
object_ptr<Ui::BoxContentDivider>(this),
|
addControl(
|
||||||
|
object_ptr<Ui::BoxContentDivider>(this),
|
||||||
|
st::rightsDividerMargin / 2);
|
||||||
|
_addAsAdmin = addControl(
|
||||||
|
object_ptr<Ui::Checkbox>(
|
||||||
|
this,
|
||||||
|
tr::lng_bot_as_admin_check(tr::now),
|
||||||
|
st::rightsCheckbox,
|
||||||
|
std::make_unique<Ui::ToggleView>(
|
||||||
|
st::rightsToggle,
|
||||||
|
true)),
|
||||||
|
st::rightsToggleMargin + (st::rightsDividerMargin / 2));
|
||||||
|
_addAsAdmin->checkedChanges(
|
||||||
|
) | rpl::start_with_next([=](bool checked) {
|
||||||
|
_adminControlsWrap->toggle(checked, anim::type::normal);
|
||||||
|
refreshButtons();
|
||||||
|
}, _addAsAdmin->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
_adminControlsWrap = addControl(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
|
this,
|
||||||
|
object_ptr<Ui::VerticalLayout>(this)));
|
||||||
|
const auto inner = _adminControlsWrap->entity();
|
||||||
|
|
||||||
|
inner->add(
|
||||||
|
object_ptr<Ui::BoxContentDivider>(inner),
|
||||||
st::rightsDividerMargin);
|
st::rightsDividerMargin);
|
||||||
|
|
||||||
const auto chat = peer()->asChat();
|
const auto chat = peer()->asChat();
|
||||||
|
@ -290,21 +321,21 @@ void EditAdminBox::prepare() {
|
||||||
? chat->anyoneCanAddMembers()
|
? chat->anyoneCanAddMembers()
|
||||||
: channel->anyoneCanAddMembers();
|
: channel->anyoneCanAddMembers();
|
||||||
auto [checkboxes, getChecked, changes] = CreateEditAdminRights(
|
auto [checkboxes, getChecked, changes] = CreateEditAdminRights(
|
||||||
this,
|
inner,
|
||||||
tr::lng_rights_edit_admin_header(),
|
tr::lng_rights_edit_admin_header(),
|
||||||
prepareFlags,
|
prepareFlags,
|
||||||
disabledMessages,
|
disabledMessages,
|
||||||
isGroup,
|
isGroup,
|
||||||
anyoneCanAddMembers);
|
anyoneCanAddMembers);
|
||||||
addControl(std::move(checkboxes), QMargins());
|
inner->add(std::move(checkboxes), QMargins());
|
||||||
|
|
||||||
auto selectedFlags = rpl::single(
|
auto selectedFlags = rpl::single(
|
||||||
getChecked()
|
getChecked()
|
||||||
) | rpl::then(std::move(
|
) | rpl::then(std::move(
|
||||||
changes
|
changes
|
||||||
));
|
));
|
||||||
_aboutAddAdmins = addControl(
|
_aboutAddAdmins = inner->add(
|
||||||
object_ptr<Ui::FlatLabel>(this, st::boxDividerLabel),
|
object_ptr<Ui::FlatLabel>(inner, st::boxDividerLabel),
|
||||||
st::rightsAboutMargin);
|
st::rightsAboutMargin);
|
||||||
rpl::duplicate(
|
rpl::duplicate(
|
||||||
selectedFlags
|
selectedFlags
|
||||||
|
@ -318,6 +349,7 @@ void EditAdminBox::prepare() {
|
||||||
if (canTransferOwnership()) {
|
if (canTransferOwnership()) {
|
||||||
const auto allFlags = AdminRightsForOwnershipTransfer(isGroup);
|
const auto allFlags = AdminRightsForOwnershipTransfer(isGroup);
|
||||||
setupTransferButton(
|
setupTransferButton(
|
||||||
|
inner,
|
||||||
isGroup
|
isGroup
|
||||||
)->toggleOn(rpl::duplicate(
|
)->toggleOn(rpl::duplicate(
|
||||||
selectedFlags
|
selectedFlags
|
||||||
|
@ -327,37 +359,76 @@ void EditAdminBox::prepare() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canSave()) {
|
if (canSave()) {
|
||||||
const auto rank = (chat || channel->isMegagroup())
|
_rank = (chat || channel->isMegagroup())
|
||||||
? addRankInput().get()
|
? addRankInput(inner).get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
_finishSave = [=, value = getChecked] {
|
||||||
addButton(tr::lng_settings_save(), [=, value = getChecked] {
|
|
||||||
if (!_saveCallback) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto newFlags = (value() | ChatAdminRight::Other)
|
const auto newFlags = (value() | ChatAdminRight::Other)
|
||||||
& ((!channel || channel->amCreator())
|
& ((!channel || channel->amCreator())
|
||||||
? ~Flags(0)
|
? ~Flags(0)
|
||||||
: channel->adminRights());
|
: channel->adminRights());
|
||||||
_saveCallback(
|
_saveCallback(
|
||||||
_oldRights,
|
_addingBot ? ChatAdminRightsInfo() : _oldRights,
|
||||||
ChatAdminRightsInfo(newFlags),
|
ChatAdminRightsInfo(newFlags),
|
||||||
rank ? rank->getLastText().trimmed() : QString());
|
_rank ? _rank->getLastText().trimmed() : QString());
|
||||||
});
|
};
|
||||||
|
_save = [=] {
|
||||||
|
if (!_saveCallback) {
|
||||||
|
return;
|
||||||
|
} else if (_addAsAdmin && !_addAsAdmin->checked()) {
|
||||||
|
AddBotToGroup(user(), peer());
|
||||||
|
return;
|
||||||
|
} else if (_addingBot) {
|
||||||
|
const auto phrase = peer()->isBroadcast()
|
||||||
|
? tr::lng_bot_sure_add_text_channel
|
||||||
|
: tr::lng_bot_sure_add_text_group;
|
||||||
|
_confirmBox = getDelegate()->show(Ui::MakeConfirmBox({
|
||||||
|
phrase(
|
||||||
|
tr::now,
|
||||||
|
lt_group,
|
||||||
|
Ui::Text::Bold(peer()->name),
|
||||||
|
Ui::Text::WithEntities),
|
||||||
|
crl::guard(this, [=] { finishAddAdmin(); })
|
||||||
|
}), Ui::LayerOption::KeepOther);
|
||||||
|
} else {
|
||||||
|
_finishSave();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditAdminBox::finishAddAdmin() {
|
||||||
|
_finishSave();
|
||||||
|
if (_confirmBox) {
|
||||||
|
_confirmBox->closeBox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditAdminBox::refreshButtons() {
|
||||||
|
clearButtons();
|
||||||
|
if (canSave()) {
|
||||||
|
addButton(!_addingBot
|
||||||
|
? tr::lng_settings_save()
|
||||||
|
: _adminControlsWrap->toggled()
|
||||||
|
? tr::lng_bot_add_as_admin()
|
||||||
|
: tr::lng_bot_add_as_member(), _save);
|
||||||
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
||||||
} else {
|
} else {
|
||||||
addButton(tr::lng_box_ok(), [=] { closeBox(); });
|
addButton(tr::lng_box_ok(), [=] { closeBox(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<Ui::InputField*> EditAdminBox::addRankInput() {
|
not_null<Ui::InputField*> EditAdminBox::addRankInput(
|
||||||
addControl(
|
not_null<Ui::VerticalLayout*> container) {
|
||||||
object_ptr<Ui::BoxContentDivider>(this),
|
container->add(
|
||||||
|
object_ptr<Ui::BoxContentDivider>(container),
|
||||||
st::rightsRankMargin);
|
st::rightsRankMargin);
|
||||||
|
|
||||||
addControl(
|
container->add(
|
||||||
object_ptr<Ui::FlatLabel>(
|
object_ptr<Ui::FlatLabel>(
|
||||||
this,
|
container,
|
||||||
tr::lng_rights_edit_admin_rank_name(),
|
tr::lng_rights_edit_admin_rank_name(),
|
||||||
st::rightsHeaderLabel),
|
st::rightsHeaderLabel),
|
||||||
st::rightsHeaderMargin);
|
st::rightsHeaderMargin);
|
||||||
|
@ -372,9 +443,9 @@ not_null<Ui::InputField*> EditAdminBox::addRankInput() {
|
||||||
}
|
}
|
||||||
Unexpected("Peer type in EditAdminBox::addRankInput.");
|
Unexpected("Peer type in EditAdminBox::addRankInput.");
|
||||||
}();
|
}();
|
||||||
const auto result = addControl(
|
const auto result = container->add(
|
||||||
object_ptr<Ui::InputField>(
|
object_ptr<Ui::InputField>(
|
||||||
this,
|
container,
|
||||||
st::customBadgeField,
|
st::customBadgeField,
|
||||||
(isOwner ? tr::lng_owner_badge : tr::lng_admin_badge)(),
|
(isOwner ? tr::lng_owner_badge : tr::lng_admin_badge)(),
|
||||||
TextUtilities::RemoveEmoji(_oldRank)),
|
TextUtilities::RemoveEmoji(_oldRank)),
|
||||||
|
@ -389,9 +460,9 @@ not_null<Ui::InputField*> EditAdminBox::addRankInput() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
addControl(
|
container->add(
|
||||||
object_ptr<Ui::FlatLabel>(
|
object_ptr<Ui::FlatLabel>(
|
||||||
this,
|
container,
|
||||||
tr::lng_rights_edit_admin_rank_about(
|
tr::lng_rights_edit_admin_rank_about(
|
||||||
lt_title,
|
lt_title,
|
||||||
(isOwner ? tr::lng_owner_badge : tr::lng_admin_badge)()),
|
(isOwner ? tr::lng_owner_badge : tr::lng_admin_badge)()),
|
||||||
|
@ -413,19 +484,20 @@ bool EditAdminBox::canTransferOwnership() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<Ui::SlideWrap<Ui::RpWidget>*> EditAdminBox::setupTransferButton(
|
not_null<Ui::SlideWrap<Ui::RpWidget>*> EditAdminBox::setupTransferButton(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
bool isGroup) {
|
bool isGroup) {
|
||||||
const auto wrap = addControl(
|
const auto wrap = container->add(
|
||||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
this,
|
container,
|
||||||
object_ptr<Ui::VerticalLayout>(this)));
|
object_ptr<Ui::VerticalLayout>(container)));
|
||||||
|
|
||||||
const auto container = wrap->entity();
|
const auto inner = wrap->entity();
|
||||||
|
|
||||||
container->add(
|
inner->add(
|
||||||
object_ptr<Ui::BoxContentDivider>(container),
|
object_ptr<Ui::BoxContentDivider>(inner),
|
||||||
{ 0, st::infoProfileSkip, 0, st::infoProfileSkip });
|
{ 0, st::infoProfileSkip, 0, st::infoProfileSkip });
|
||||||
container->add(EditPeerInfoBox::CreateButton(
|
inner->add(EditPeerInfoBox::CreateButton(
|
||||||
this,
|
inner,
|
||||||
(isGroup
|
(isGroup
|
||||||
? tr::lng_rights_transfer_group
|
? tr::lng_rights_transfer_group
|
||||||
: tr::lng_rights_transfer_channel)(),
|
: tr::lng_rights_transfer_channel)(),
|
||||||
|
|
|
@ -18,6 +18,7 @@ class Checkbox;
|
||||||
class Radiobutton;
|
class Radiobutton;
|
||||||
class RadiobuttonGroup;
|
class RadiobuttonGroup;
|
||||||
class CalendarBox;
|
class CalendarBox;
|
||||||
|
class VerticalLayout;
|
||||||
template <typename Widget>
|
template <typename Widget>
|
||||||
class SlideWrap;
|
class SlideWrap;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
@ -71,7 +72,8 @@ public:
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
not_null<UserData*> user,
|
not_null<UserData*> user,
|
||||||
ChatAdminRightsInfo rights,
|
ChatAdminRightsInfo rights,
|
||||||
const QString &rank);
|
const QString &rank,
|
||||||
|
bool addingBot = false);
|
||||||
|
|
||||||
void setSaveCallback(
|
void setSaveCallback(
|
||||||
Fn<void(
|
Fn<void(
|
||||||
|
@ -87,7 +89,8 @@ protected:
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] ChatAdminRightsInfo defaultRights() const;
|
[[nodiscard]] ChatAdminRightsInfo defaultRights() const;
|
||||||
|
|
||||||
not_null<Ui::InputField*> addRankInput();
|
not_null<Ui::InputField*> addRankInput(
|
||||||
|
not_null<Ui::VerticalLayout*> container);
|
||||||
void transferOwnership();
|
void transferOwnership();
|
||||||
void transferOwnershipChecked();
|
void transferOwnershipChecked();
|
||||||
bool handleTransferPasswordError(const QString &error);
|
bool handleTransferPasswordError(const QString &error);
|
||||||
|
@ -99,9 +102,13 @@ private:
|
||||||
bool canSave() const {
|
bool canSave() const {
|
||||||
return _saveCallback != nullptr;
|
return _saveCallback != nullptr;
|
||||||
}
|
}
|
||||||
|
void finishAddAdmin();
|
||||||
|
void refreshButtons();
|
||||||
void refreshAboutAddAdminsText(bool canAddAdmins);
|
void refreshAboutAddAdminsText(bool canAddAdmins);
|
||||||
bool canTransferOwnership() const;
|
bool canTransferOwnership() const;
|
||||||
not_null<Ui::SlideWrap<Ui::RpWidget>*> setupTransferButton(bool isGroup);
|
not_null<Ui::SlideWrap<Ui::RpWidget>*> setupTransferButton(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
bool isGroup);
|
||||||
|
|
||||||
const Ui::BoxShow _show;
|
const Ui::BoxShow _show;
|
||||||
const ChatAdminRightsInfo _oldRights;
|
const ChatAdminRightsInfo _oldRights;
|
||||||
|
@ -111,9 +118,16 @@ private:
|
||||||
ChatAdminRightsInfo,
|
ChatAdminRightsInfo,
|
||||||
const QString &rank)> _saveCallback;
|
const QString &rank)> _saveCallback;
|
||||||
|
|
||||||
|
QPointer<Ui::BoxContent> _confirmBox;
|
||||||
|
Ui::Checkbox *_addAsAdmin = nullptr;
|
||||||
|
Ui::SlideWrap<Ui::VerticalLayout> *_adminControlsWrap = nullptr;
|
||||||
|
Ui::InputField *_rank = nullptr;
|
||||||
QPointer<Ui::FlatLabel> _aboutAddAdmins;
|
QPointer<Ui::FlatLabel> _aboutAddAdmins;
|
||||||
mtpRequestId _checkTransferRequestId = 0;
|
mtpRequestId _checkTransferRequestId = 0;
|
||||||
mtpRequestId _transferRequestId = 0;
|
mtpRequestId _transferRequestId = 0;
|
||||||
|
Fn<void()> _save, _finishSave;
|
||||||
|
|
||||||
|
bool _addingBot = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/peer_list_box.h"
|
#include "boxes/peer_list_box.h"
|
||||||
#include "boxes/peer_list_controllers.h"
|
#include "boxes/peer_list_controllers.h"
|
||||||
#include "boxes/add_contact_box.h"
|
#include "boxes/add_contact_box.h"
|
||||||
|
#include "boxes/peers/add_bot_to_chat_box.h"
|
||||||
#include "boxes/peers/edit_contact_box.h"
|
#include "boxes/peers/edit_contact_box.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
|
|
|
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/add_contact_box.h"
|
#include "boxes/add_contact_box.h"
|
||||||
#include "boxes/create_poll_box.h"
|
#include "boxes/create_poll_box.h"
|
||||||
#include "boxes/pin_messages_box.h"
|
#include "boxes/pin_messages_box.h"
|
||||||
|
#include "boxes/peers/add_bot_to_chat_box.h"
|
||||||
#include "boxes/peers/add_participants_box.h"
|
#include "boxes/peers/add_participants_box.h"
|
||||||
#include "boxes/peers/edit_contact_box.h"
|
#include "boxes/peers/edit_contact_box.h"
|
||||||
#include "ui/boxes/report_box.h"
|
#include "ui/boxes/report_box.h"
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
|
||||||
#include "boxes/add_contact_box.h"
|
#include "boxes/add_contact_box.h"
|
||||||
|
#include "boxes/peers/add_bot_to_chat_box.h"
|
||||||
#include "boxes/peers/edit_peer_info_box.h"
|
#include "boxes/peers/edit_peer_info_box.h"
|
||||||
#include "boxes/peer_list_controllers.h"
|
#include "boxes/peer_list_controllers.h"
|
||||||
#include "boxes/delete_messages_box.h"
|
#include "boxes/delete_messages_box.h"
|
||||||
|
|
Loading…
Add table
Reference in a new issue