/* 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 "dialogs/dialogs_search_from_controllers.h" #include "lang/lang_keys.h" #include "data/data_peer_values.h" #include "observer_peer.h" #include "auth_session.h" #include "apiwrap.h" namespace Dialogs { void ShowSearchFromBox( not_null navigation, not_null peer, Fn)> callback, Fn closedCallback) { auto createController = [ navigation, peer, callback = std::move(callback) ]() -> std::unique_ptr { if (peer) { if (auto chat = peer->asChat()) { return std::make_unique( navigation, chat, std::move(callback)); } else if (auto group = peer->asMegagroup()) { return std::make_unique( navigation, group, std::move(callback)); } } return nullptr; }; if (auto controller = createController()) { auto subscription = std::make_shared(); auto box = Ui::show(Box(std::move(controller), [subscription](not_null box) { box->addButton(langFactory(lng_cancel), [box, subscription] { box->closeBox(); }); }), LayerOption::KeepOther); box->boxClosing() | rpl::start_with_next( std::move(closedCallback), *subscription); } } ChatSearchFromController::ChatSearchFromController( not_null navigation, not_null chat, Fn)> callback) : PeerListController() , _chat(chat) , _callback(std::move(callback)) { } void ChatSearchFromController::prepare() { setSearchNoResultsText(lang(lng_blocked_list_not_found)); delegate()->peerListSetSearchMode(PeerListSearchMode::Enabled); delegate()->peerListSetTitle(langFactory(lng_search_messages_from)); rebuildRows(); subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::MembersChanged, [this](const Notify::PeerUpdate &update) { if (update.peer == _chat) { rebuildRows(); } })); } void ChatSearchFromController::rowClicked(not_null row) { Expects(row->peer()->isUser()); const auto onstack = _callback; onstack(row->peer()->asUser()); } void ChatSearchFromController::rebuildRows() { auto ms = getms(); auto wasEmpty = !delegate()->peerListFullRowsCount(); auto now = unixtime(); const auto byOnline = [&](not_null user) { return Data::SortByOnlineValue(user, now); }; auto ordered = QMultiMap>(); if (_chat->noParticipantInfo()) { Auth().api().requestFullPeer(_chat); } else if (!_chat->participants.empty()) { for (const auto [user, version] : _chat->participants) { ordered.insertMulti(byOnline(user), user); } } for_const (auto user, _chat->lastAuthors) { if (user->isInaccessible()) continue; appendRow(user); if (!ordered.isEmpty()) { ordered.remove(byOnline(user), user); } } if (!ordered.isEmpty()) { for (auto i = ordered.cend(), b = ordered.cbegin(); i != b;) { appendRow(*(--i)); } } checkForEmptyRows(); delegate()->peerListRefreshRows(); } void ChatSearchFromController::checkForEmptyRows() { if (delegate()->peerListFullRowsCount()) { setDescriptionText(QString()); } else { setDescriptionText(lang(lng_contacts_loading)); } } void ChatSearchFromController::appendRow(not_null user) { if (!delegate()->peerListFindRow(user->id)) { delegate()->peerListAppendRow(std::make_unique(user)); } } ChannelSearchFromController::ChannelSearchFromController( not_null navigation, not_null channel, Fn)> callback) : ParticipantsBoxController( navigation, channel, ParticipantsBoxController::Role::Members) , _callback(std::move(callback)) { } void ChannelSearchFromController::prepare() { ParticipantsBoxController::prepare(); delegate()->peerListSetTitle(langFactory(lng_search_messages_from)); } void ChannelSearchFromController::rowClicked(not_null row) { Expects(row->peer()->isUser()); const auto onstack = _callback; onstack(row->peer()->asUser()); } std::unique_ptr ChannelSearchFromController::createRow(not_null user) const { return std::make_unique(user); } } // namespace Dialogs