tdesktop/Telegram/SourceFiles/info/feed/info_feed_channels.cpp

348 lines
9.5 KiB
C++
Raw Normal View History

2018-01-22 19:51:38 +00:00
/*
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 "info/feed/info_feed_channels.h"
#include "info/feed/info_feed_channels_controllers.h"
2018-01-22 19:51:38 +00:00
#include "info/profile/info_profile_icon.h"
#include "info/profile/info_profile_button.h"
#include "info/profile/info_profile_values.h"
2018-01-22 19:51:38 +00:00
#include "info/info_controller.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/scroll_area.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/search_field_controller.h"
#include "boxes/peer_list_controllers.h"
#include "data/data_feed.h"
#include "lang/lang_keys.h"
2018-01-22 19:51:38 +00:00
#include "styles/style_boxes.h"
#include "styles/style_info.h"
namespace Info {
namespace FeedProfile {
namespace {
constexpr auto kEnableSearchChannelsAfterCount = 20;
} // namespace
Channels::Channels(
QWidget *parent,
not_null<Controller*> controller)
: RpWidget(parent)
, _controller(controller)
, _feed(_controller->key().feed())
, _listController(std::make_unique<ChannelsController>(_controller)) {
2018-01-22 19:51:38 +00:00
setupHeader();
setupList();
setContent(_list.data());
_listController->setDelegate(static_cast<PeerListDelegate*>(this));
_controller->searchFieldController()->queryValue(
) | rpl::start_with_next([this](QString &&query) {
peerListScrollToTop();
content()->searchQueryChanged(std::move(query));
}, lifetime());
Profile::FeedChannelsCountValue(
_feed
) | rpl::start_with_next([this](int count) {
const auto enabled = (count >= kEnableSearchChannelsAfterCount);
_controller->setSearchEnabledByContent(enabled);
}, lifetime());
2018-01-22 19:51:38 +00:00
}
int Channels::desiredHeight() const {
auto desired = _header ? _header->height() : 0;
desired += st::infoMembersList.item.height
* std::max(int(_feed->channels().size()), _list->fullRowsCount());
2018-01-22 19:51:38 +00:00
return qMax(height(), desired);
}
rpl::producer<Ui::ScrollToRequest> Channels::scrollToRequests() const {
return _scrollToRequests.events();
}
std::unique_ptr<ChannelsState> Channels::saveState() {
auto result = std::make_unique<ChannelsState>();
result->list = _listController->saveState();
return result;
}
void Channels::restoreState(std::unique_ptr<ChannelsState> state) {
if (!state) {
return;
}
_listController->restoreState(std::move(state->list));
}
void Channels::setupHeader() {
if (_controller->section().type() == Section::Type::Members) {
return;
}
_header = object_ptr<Ui::FixedHeightWidget>(
this,
st::infoMembersHeader);
auto parent = _header.data();
_openChannels = Ui::CreateChild<Profile::Button>(
parent,
rpl::single(QString()));
object_ptr<Profile::FloatingIcon>(
parent,
st::infoIconMembers,
st::infoIconPosition);
_titleWrap = Ui::CreateChild<Ui::RpWidget>(parent);
_title = setupTitle();
_addChannel = Ui::CreateChild<Ui::IconButton>(
_openChannels,
st::infoMembersAddMember);
_search = Ui::CreateChild<Ui::IconButton>(
_openChannels,
st::infoMembersSearch);
setupButtons();
widthValue(
) | rpl::start_with_next([this](int width) {
_header->resizeToWidth(width);
}, _header->lifetime());
}
object_ptr<Ui::FlatLabel> Channels::setupTitle() {
auto result = object_ptr<Ui::FlatLabel>(
_titleWrap,
Profile::FeedChannelsCountValue(
_feed
) | rpl::map([](int count) {
return lng_feed_channels(lt_count, count);
}) | Profile::ToUpperValue(),
2018-01-22 19:51:38 +00:00
st::infoBlockHeaderLabel);
result->setAttribute(Qt::WA_TransparentForMouseEvents);
return result;
}
void Channels::setupButtons() {
using namespace rpl::mappers;
_openChannels->addClickHandler([this] {
showChannelsWithSearch(false);
});
//auto addMemberShown = CanAddMemberValue(_peer)
// | rpl::start_spawning(lifetime());
//_addChannel->showOn(rpl::duplicate(addMemberShown));
//_addChannel->addClickHandler([this] { // TODO throttle(ripple duration)
// this->addMember();
//});
//auto searchShown = MembersCountValue(_peer)
// | rpl::map(_1 >= kEnableSearchMembersAfterCount)
// | rpl::distinct_until_changed()
// | rpl::start_spawning(lifetime());
//_search->showOn(rpl::duplicate(searchShown));
//_search->addClickHandler([this] { // TODO throttle(ripple duration)
// this->showMembersWithSearch(true);
//});
//rpl::combine(
// std::move(addMemberShown),
// std::move(searchShown)
//) | rpl::start_with_next([this] {
// updateHeaderControlsGeometry(width());
//}, lifetime());
}
void Channels::setupList() {
auto topSkip = _header ? _header->height() : 0;
_list = object_ptr<ListWidget>(
this,
_listController.get(),
st::infoCommonGroupsList);
2018-01-22 19:51:38 +00:00
_list->scrollToRequests(
) | rpl::start_with_next([this](Ui::ScrollToRequest request) {
auto addmin = (request.ymin < 0 || !_header)
? 0
: _header->height();
auto addmax = (request.ymax < 0 || !_header)
? 0
: _header->height();
_scrollToRequests.fire({
request.ymin + addmin,
request.ymax + addmax });
}, _list->lifetime());
widthValue(
) | rpl::start_with_next([this](int newWidth) {
_list->resizeToWidth(newWidth);
}, _list->lifetime());
_list->heightValue(
) | rpl::start_with_next([=](int listHeight) {
auto newHeight = (listHeight > st::membersMarginBottom)
? (topSkip
+ listHeight
+ st::membersMarginBottom)
: 0;
resize(width(), newHeight);
}, _list->lifetime());
_list->moveToLeft(0, topSkip);
}
int Channels::resizeGetHeight(int newWidth) {
if (_header) {
updateHeaderControlsGeometry(newWidth);
}
return heightNoMargins();
}
//void Channels::updateSearchEnabledByContent() {
// _controller->setSearchEnabledByContent(
// peerListFullRowsCount() >= kEnableSearchMembersAfterCount);
//}
void Channels::updateHeaderControlsGeometry(int newWidth) {
_openChannels->setGeometry(0, st::infoProfileSkip, newWidth, st::infoMembersHeader - st::infoProfileSkip - st::infoMembersHeaderPaddingBottom);
auto availableWidth = newWidth
- st::infoMembersButtonPosition.x();
//auto cancelLeft = availableWidth - _cancelSearch->width();
//_cancelSearch->moveToLeft(
// cancelLeft,
// st::infoMembersButtonPosition.y());
//auto searchShownLeft = st::infoIconPosition.x()
// - st::infoMembersSearch.iconPosition.x();
//auto searchHiddenLeft = availableWidth - _search->width();
//auto searchShown = _searchShownAnimation.current(_searchShown ? 1. : 0.);
//auto searchCurrentLeft = anim::interpolate(
// searchHiddenLeft,
// searchShownLeft,
// searchShown);
//_search->moveToLeft(
// searchCurrentLeft,
// st::infoMembersButtonPosition.y());
//if (!_search->isHidden()) {
// availableWidth -= st::infoMembersSearch.width;
//}
_addChannel->moveToLeft(
availableWidth - _addChannel->width(),
st::infoMembersButtonPosition.y(),
newWidth);
if (!_addChannel->isHidden()) {
availableWidth -= st::infoMembersSearch.width;
}
_search->moveToLeft(
availableWidth - _search->width(),
st::infoMembersButtonPosition.y(),
newWidth);
//auto fieldLeft = anim::interpolate(
// cancelLeft,
// st::infoBlockHeaderPosition.x(),
// searchShown);
//_searchField->setGeometryToLeft(
// fieldLeft,
// st::infoMembersSearchTop,
// cancelLeft - fieldLeft,
// _searchField->height());
//_titleWrap->resize(
// searchCurrentLeft - st::infoBlockHeaderPosition.x(),
// _title->height());
_titleWrap->resize(
availableWidth - _addChannel->width() - st::infoBlockHeaderPosition.x(),
_title->height());
_titleWrap->moveToLeft(
st::infoBlockHeaderPosition.x(),
st::infoBlockHeaderPosition.y(),
newWidth);
_titleWrap->setAttribute(Qt::WA_TransparentForMouseEvents);
//_title->resizeToWidth(searchHiddenLeft);
_title->resizeToWidth(_titleWrap->width());
_title->moveToLeft(0, 0);
}
void Channels::addChannel() {
//if (const auto chat = _peer->asChat()) {
// if (chat->count >= Global::ChatSizeMax() && chat->amCreator()) {
// Ui::show(Box<ConvertToSupergroupBox>(chat));
// } else {
// AddParticipantsBoxController::Start(chat);
// }
//} else if (const auto channel = _peer->asChannel()) {
// const auto state = _listController->saveState();
// const auto users = ranges::view::all(
// state->list
// ) | ranges::view::transform([](not_null<PeerData*> peer) {
// return peer->asUser();
// }) | ranges::to_vector;
// AddParticipantsBoxController::Start(
// channel,
// { users.begin(), users.end() });
//}
}
void Channels::showChannelsWithSearch(bool withSearch) {
//auto contentMemento = std::make_unique<Info::Members::Memento>(
// _controller);
//contentMemento->setState(saveState());
//contentMemento->setSearchStartsFocused(withSearch);
//auto mementoStack = std::vector<std::unique_ptr<ContentMemento>>();
//mementoStack.push_back(std::move(contentMemento));
//_controller->showSection(
// Info::Memento(std::move(mementoStack)));
}
void Channels::visibleTopBottomUpdated(
int visibleTop,
int visibleBottom) {
setChildVisibleTopBottom(_list, visibleTop, visibleBottom);
}
void Channels::peerListSetTitle(base::lambda<QString()> title) {
}
void Channels::peerListSetAdditionalTitle(
base::lambda<QString()> title) {
}
bool Channels::peerListIsRowSelected(not_null<PeerData*> peer) {
return false;
}
int Channels::peerListSelectedRowsCount() {
return 0;
}
std::vector<not_null<PeerData*>> Channels::peerListCollectSelectedRows() {
return {};
}
void Channels::peerListScrollToTop() {
_scrollToRequests.fire({ -1, -1 });
}
void Channels::peerListAddSelectedRowInBunch(not_null<PeerData*> peer) {
Unexpected("Item selection in Info::Profile::Members.");
}
void Channels::peerListFinishSelectedRowsBunch() {
}
void Channels::peerListSetDescription(
object_ptr<Ui::FlatLabel> description) {
description.destroy();
}
} // namespace FeedProfile
} // namespace Info