From b816d33d48b975381be5e6a1f9eb2e75cc959217 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 15 Aug 2017 12:35:19 +0300 Subject: [PATCH] Replace add bot to group box with PeerListBox. --- Telegram/SourceFiles/boxes/peer_list_box.cpp | 17 +- .../boxes/peer_list_controllers.cpp | 177 +++++++++++++++++- .../SourceFiles/boxes/peer_list_controllers.h | 31 +++ Telegram/SourceFiles/mainwidget.cpp | 8 +- .../SourceFiles/profile/profile_cover.cpp | 3 +- 5 files changed, 223 insertions(+), 13 deletions(-) diff --git a/Telegram/SourceFiles/boxes/peer_list_box.cpp b/Telegram/SourceFiles/boxes/peer_list_box.cpp index 80036f9bc8..acb23f68d7 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_box.cpp @@ -380,10 +380,25 @@ void PeerListRow::refreshStatus() { if (!_initialized || _statusType == StatusType::Custom) { return; } + _statusType = StatusType::LastSeen; if (auto user = peer()->asUser()) { auto time = unixtime(); setStatusText(App::onlineText(user, time)); - _statusType = App::onlineColorUse(user, time) ? StatusType::Online : StatusType::LastSeen; + if (App::onlineColorUse(user, time)) { + _statusType = StatusType::Online; + } + } else if (auto chat = peer()->asChat()) { + if (!chat->amIn()) { + setStatusText(lang(lng_chat_status_unaccessible)); + } else if (chat->count > 0) { + setStatusText(lng_chat_status_members(lt_count, chat->count)); + } else { + setStatusText(lang(lng_group_status)); + } + } else if (peer()->isMegagroup()) { + setStatusText(lang(lng_group_status)); + } else if (peer()->isChannel()) { + setStatusText(lang(lng_channel_status)); } } diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index a4a65e6437..ee97f118ce 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -205,11 +205,8 @@ void ChatsListBoxController::rebuildRows() { auto appendList = [this](auto chats) { auto count = 0; for_const (auto row, chats->all()) { - auto history = row->history(); - if (history->peer->isUser()) { - if (appendRow(history)) { - ++count; - } + if (appendRow(row->history())) { + ++count; } } return count; @@ -233,10 +230,14 @@ void ChatsListBoxController::checkForEmptyRows() { } else { auto &sessionData = Auth().data(); auto loaded = sessionData.contactsLoaded().value() && sessionData.allChatsLoaded().value(); - setDescriptionText(lang(loaded ? lng_contacts_not_found : lng_contacts_loading)); + setDescriptionText(loaded ? emptyBoxText() : lang(lng_contacts_loading)); } } +QString ChatsListBoxController::emptyBoxText() const { + return lang(lng_contacts_not_found); +} + std::unique_ptr ChatsListBoxController::createSearchRow(gsl::not_null peer) { return createRow(App::history(peer)); } @@ -656,3 +657,167 @@ void EditChatAdminsBoxController::Start(gsl::not_null chat) { }; Ui::show(Box(std::move(controller), std::move(initBox))); } + +void AddBotToGroupBoxController::Start(gsl::not_null bot) { + auto initBox = [bot](gsl::not_null box) { + box->addButton(langFactory(lng_cancel), [box] { box->closeBox(); }); + }; + Ui::show(Box(std::make_unique(bot), std::move(initBox))); +} + +AddBotToGroupBoxController::AddBotToGroupBoxController(gsl::not_null bot) +: ChatsListBoxController(SharingBotGame(bot) + ? std::make_unique() + : nullptr) +, _bot(bot) { +} + +void AddBotToGroupBoxController::rowClicked(gsl::not_null row) { + if (sharingBotGame()) { + shareBotGame(row->peer()); + } else { + addBotToGroup(row->peer()); + } +} + +void AddBotToGroupBoxController::shareBotGame(gsl::not_null chat) { + auto weak = base::make_weak_unique(this); + auto send = [weak, bot = _bot, chat] { + if (!weak) { + return; + } + auto history = App::historyLoaded(chat); + auto afterRequestId = history ? history->sendRequestId : 0; + auto randomId = rand_value(); + auto gameShortName = bot->botInfo->shareGameShortName; + auto inputGame = MTP_inputGameShortName( + bot->inputUser, + MTP_string(gameShortName)); + auto request = MTPmessages_SendMedia( + MTP_flags(0), + chat->input, + MTP_int(0), + MTP_inputMediaGame(inputGame), + MTP_long(randomId), + MTPnullMarkup); + auto done = App::main()->rpcDone(&MainWidget::sentUpdatesReceived); + auto fail = App::main()->rpcFail(&MainWidget::sendMessageFail); + auto requestId = MTP::send(request, done, fail, 0, 0, afterRequestId); + if (history) { + history->sendRequestId = requestId; + } + Ui::hideLayer(); + Ui::showPeerHistory(chat, ShowAtUnreadMsgId); + }; + auto confirmText = [chat] { + if (chat->isUser()) { + return lng_bot_sure_share_game(lt_user, App::peerName(chat)); + } + return lng_bot_sure_share_game_group(lt_group, chat->name); + }; + Ui::show(Box(confirmText(), send), KeepOtherLayers); +} + +void AddBotToGroupBoxController::addBotToGroup(gsl::not_null chat) { + if (auto megagroup = chat->asMegagroup()) { + if (!megagroup->canAddMembers()) { + Ui::show(Box(lang(lng_error_cant_add_member)), KeepOtherLayers); + return; + } + } + auto weak = base::make_weak_unique(this); + auto send = [weak, bot = _bot, chat] { + if (!weak) { + return; + } + if (auto &info = bot->botInfo) { + if (!info->startGroupToken.isEmpty()) { + auto request = MTPmessages_StartBot( + bot->inputUser, + chat->input, + MTP_long(rand_value()), + MTP_string(info->startGroupToken)); + auto done = App::main()->rpcDone( + &MainWidget::sentUpdatesReceived); + auto fail = App::main()->rpcFail( + &MainWidget::addParticipantFail, + { bot, chat }); + MTP::send(request, done, fail); + } else { + App::main()->addParticipants( + chat, + { 1, bot }); + } + } else { + App::main()->addParticipants( + chat, + { 1, bot }); + } + Ui::hideLayer(); + Ui::showPeerHistory(chat, ShowAtUnreadMsgId); + }; + auto confirmText = lng_bot_sure_invite(lt_group, chat->name); + Ui::show(Box(confirmText, send), KeepOtherLayers); +} + +std::unique_ptr AddBotToGroupBoxController::createRow(gsl::not_null history) { + if (!needToCreateRow(history->peer)) { + return nullptr; + } + return std::make_unique(history); +} + +bool AddBotToGroupBoxController::needToCreateRow(gsl::not_null peer) const { + if (sharingBotGame()) { + if (!peer->canWrite()) { + return false; + } + if (auto group = peer->asMegagroup()) { + if (group->restrictedRights().is_send_games()) { + return false; + } + } + return true; + } + if (auto chat = peer->asChat()) { + if (chat->canEdit()) { + return true; + } + } else if (auto group = peer->asMegagroup()) { + return group->canAddMembers(); + } + return false; +} + +bool AddBotToGroupBoxController::SharingBotGame(gsl::not_null bot) { + auto &info = bot->botInfo; + return (info && !info->shareGameShortName.isEmpty()); +} + +bool AddBotToGroupBoxController::sharingBotGame() const { + return SharingBotGame(_bot); +} + +QString AddBotToGroupBoxController::emptyBoxText() const { + return lang(Auth().data().allChatsLoaded().value() + ? (sharingBotGame() ? lng_bot_no_chats : lng_bot_no_groups) + : lng_contacts_loading); +} + +QString AddBotToGroupBoxController::noResultsText() const { + return lang(Auth().data().allChatsLoaded().value() + ? (sharingBotGame() ? lng_bot_chats_not_found : lng_bot_groups_not_found) + : lng_contacts_loading); +} + +void AddBotToGroupBoxController::updateLabels() { + setSearchNoResultsText(noResultsText()); +} + +void AddBotToGroupBoxController::prepareViewHook() { + delegate()->peerListSetTitle(langFactory(sharingBotGame() + ? lng_bot_choose_chat + : lng_bot_choose_group)); + updateLabels(); + subscribe(Auth().data().allChatsLoaded(), [this](bool) { updateLabels(); }); +} diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.h b/Telegram/SourceFiles/boxes/peer_list_controllers.h index c0241d72d8..4d633e2366 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.h +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.h @@ -22,6 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "boxes/peer_list_box.h" #include "base/flat_set.h" +#include "base/weak_unique_ptr.h" class PeerListRowWithLink : public PeerListRow { public: @@ -89,6 +90,7 @@ protected: virtual void prepareViewHook() = 0; virtual void updateRowHook(gsl::not_null row) { } + virtual QString emptyBoxText() const; private: void rebuildRows(); @@ -180,3 +182,32 @@ private: base::flat_set> _alreadyIn; }; + +class AddBotToGroupBoxController : public ChatsListBoxController, public base::enable_weak_from_this { +public: + static void Start(gsl::not_null bot); + + AddBotToGroupBoxController(gsl::not_null bot); + + void rowClicked(gsl::not_null row) override; + +protected: + std::unique_ptr createRow(gsl::not_null history) override; + void prepareViewHook() override; + QString emptyBoxText() const override; + +private: + static bool SharingBotGame(gsl::not_null bot); + + bool needToCreateRow(gsl::not_null peer) const; + bool sharingBotGame() const; + QString noResultsText() const; + QString descriptionText() const; + void updateLabels(); + + void shareBotGame(gsl::not_null chat); + void addBotToGroup(gsl::not_null chat); + + gsl::not_null _bot; + +}; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 66b96fb4af..b149a76f67 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -51,7 +51,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "boxes/confirm_box.h" #include "boxes/sticker_set_box.h" #include "boxes/mute_settings_box.h" -#include "boxes/contacts_box.h" +#include "boxes/peer_list_controllers.h" #include "boxes/download_path_box.h" #include "storage/localstorage.h" #include "shortcuts.h" @@ -3968,14 +3968,14 @@ void MainWidget::openPeerByName(const QString &username, MsgId msgId, const QStr if (msgId == ShowAtGameShareMsgId) { if (peer->isUser() && peer->asUser()->botInfo && !startToken.isEmpty()) { peer->asUser()->botInfo->shareGameShortName = startToken; - Ui::show(Box(peer->asUser())); + AddBotToGroupBoxController::Start(peer->asUser()); } else { Ui::showPeerHistoryAsync(peer->id, ShowAtUnreadMsgId, Ui::ShowWay::Forward); } } else if (msgId == ShowAtProfileMsgId && !peer->isChannel()) { if (peer->isUser() && peer->asUser()->botInfo && !peer->asUser()->botInfo->cantJoinGroups && !startToken.isEmpty()) { peer->asUser()->botInfo->startGroupToken = startToken; - Ui::show(Box(peer->asUser())); + AddBotToGroupBoxController::Start(peer->asUser()); } else if (peer->isUser() && peer->asUser()->botInfo) { // Always open bot chats, even from mention links. Ui::showPeerHistoryAsync(peer->id, ShowAtUnreadMsgId, Ui::ShowWay::Forward); @@ -4055,7 +4055,7 @@ void MainWidget::usernameResolveDone(QPair msgIdAndStartToken, c if (msgId == ShowAtProfileMsgId && !peer->isChannel()) { if (peer->isUser() && peer->asUser()->botInfo && !peer->asUser()->botInfo->cantJoinGroups && !startToken.isEmpty()) { peer->asUser()->botInfo->startGroupToken = startToken; - Ui::show(Box(peer->asUser())); + AddBotToGroupBoxController::Start(peer->asUser()); } else if (peer->isUser() && peer->asUser()->botInfo) { // Always open bot chats, even from mention links. Ui::showPeerHistoryAsync(peer->id, ShowAtUnreadMsgId, Ui::ShowWay::Forward); diff --git a/Telegram/SourceFiles/profile/profile_cover.cpp b/Telegram/SourceFiles/profile/profile_cover.cpp index ff276a633f..00ca529fe6 100644 --- a/Telegram/SourceFiles/profile/profile_cover.cpp +++ b/Telegram/SourceFiles/profile/profile_cover.cpp @@ -29,7 +29,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "ui/widgets/labels.h" #include "observer_peer.h" #include "boxes/confirm_box.h" -#include "boxes/contacts_box.h" #include "boxes/photo_crop_box.h" #include "boxes/peer_list_controllers.h" #include "lang/lang_keys.h" @@ -549,7 +548,7 @@ void CoverWidget::onAddMember() { void CoverWidget::onAddBotToGroup() { if (_peerUser && _peerUser->botInfo) { - Ui::show(Box(_peerUser)); + AddBotToGroupBoxController::Start(_peerUser); } }