Search and save state in common groups.

This commit is contained in:
John Preston 2017-11-03 22:26:14 +04:00
parent a6361d6221
commit 628c8e10f7
22 changed files with 290 additions and 85 deletions

View file

@ -28,13 +28,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "mtproto/sender.h"
#include "window/window_controller.h"
#include "ui/widgets/scroll_area.h"
#include "ui/search_field_controller.h"
#include "apiwrap.h"
namespace Info {
namespace CommonGroups {
namespace {
constexpr int kCommonGroupsPerPage = 40;
constexpr auto kCommonGroupsPerPage = 40;
constexpr auto kCommonGroupsSearchAfter = 20;
class ListController
: public PeerListController
@ -49,7 +51,22 @@ public:
void rowClicked(not_null<PeerListRow*> row) override;
void loadMoreRows() override;
std::unique_ptr<PeerListRow> createRestoredRow(
not_null<PeerData*> peer) override {
return createRow(peer);
}
std::unique_ptr<PeerListState> saveState() override;
void restoreState(std::unique_ptr<PeerListState> state) override;
private:
std::unique_ptr<PeerListRow> createRow(not_null<PeerData*> peer);
struct SavedState : SavedStateBase {
int32 preloadGroupId = 0;
bool allLoaded = false;
bool wasLoading = false;
};
const not_null<Controller*> _controller;
not_null<UserData*> _user;
mtpRequestId _preloadRequestId = 0;
@ -64,6 +81,14 @@ ListController::ListController(
: PeerListController()
, _controller(controller)
, _user(user) {
_controller->setSearchEnabledByContent(false);
}
std::unique_ptr<PeerListRow> ListController::createRow(
not_null<PeerData*> peer) {
auto result = std::make_unique<PeerListRow>(peer);
result->setCustomStatus(QString());
return result;
}
void ListController::prepare() {
@ -90,9 +115,8 @@ void ListController::loadMoreRows() {
for_const (auto &chatData, list) {
if (auto chat = App::feedChat(chatData)) {
if (!chat->migrateTo()) {
auto row = std::make_unique<PeerListRow>(chat);
row->setCustomStatus(QString());
delegate()->peerListAppendRow(std::move(row));
delegate()->peerListAppendRow(
createRow(chat));
}
_preloadGroupId = chat->bareId();
_allLoaded = false;
@ -101,9 +125,48 @@ void ListController::loadMoreRows() {
delegate()->peerListRefreshRows();
}
}
auto fullCount = delegate()->peerListFullRowsCount();
if (fullCount > kCommonGroupsSearchAfter) {
_controller->setSearchEnabledByContent(true);
}
}).send();
}
std::unique_ptr<PeerListState> ListController::saveState() {
auto result = PeerListController::saveState();
auto my = std::make_unique<SavedState>();
my->preloadGroupId = _preloadGroupId;
my->allLoaded = _allLoaded;
if (auto requestId = base::take(_preloadRequestId)) {
request(requestId).cancel();
my->wasLoading = true;
}
result->controllerState = std::move(my);
return result;
}
void ListController::restoreState(
std::unique_ptr<PeerListState> state) {
auto typeErasedState = state
? state->controllerState.get()
: nullptr;
if (auto my = dynamic_cast<SavedState*>(typeErasedState)) {
if (auto requestId = base::take(_preloadRequestId)) {
request(requestId).cancel();
}
_allLoaded = my->allLoaded;
_preloadGroupId = my->preloadGroupId;
if (my->wasLoading) {
loadMoreRows();
}
PeerListController::restoreState(std::move(state));
auto fullCount = delegate()->peerListFullRowsCount();
if (fullCount > kCommonGroupsSearchAfter) {
_controller->setSearchEnabledByContent(true);
}
}
}
void ListController::rowClicked(not_null<PeerListRow*> row) {
_controller->window()->showPeerHistory(
row->peer(),
@ -117,11 +180,17 @@ InnerWidget::InnerWidget(
not_null<Controller*> controller,
not_null<UserData*> user)
: RpWidget(parent)
, _controller(controller)
, _user(user)
, _listController(std::make_unique<ListController>(controller, _user))
, _list(setupList(this, _listController.get())) {
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());
}
void InnerWidget::visibleTopBottomUpdated(
@ -131,9 +200,11 @@ void InnerWidget::visibleTopBottomUpdated(
}
void InnerWidget::saveState(not_null<Memento*> memento) {
memento->setListState(_listController->saveState());
}
void InnerWidget::restoreState(not_null<Memento*> memento) {
_listController->restoreState(std::move(memento->listState()));
}
int InnerWidget::desiredHeight() const {

View file

@ -80,6 +80,7 @@ private:
RpWidget *parent,
not_null<PeerListController*> controller) const;
not_null<Controller*> _controller;
not_null<UserData*> _user;
std::unique_ptr<PeerListController> _listController;
object_ptr<ListWidget> _list;

View file

@ -22,7 +22,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "info/common_groups/info_common_groups_inner_widget.h"
#include "info/info_controller.h"
#include "ui/search_field_controller.h"
#include "ui/widgets/scroll_area.h"
#include "styles/style_info.h"
namespace Info {
namespace CommonGroups {
@ -43,6 +45,16 @@ object_ptr<ContentWidget> Memento::createWidget(
return std::move(result);
}
void Memento::setListState(std::unique_ptr<PeerListState> state) {
_listState = std::move(state);
}
std::unique_ptr<PeerListState> Memento::listState() {
return std::move(_listState);
}
Memento::~Memento() = default;
Widget::Widget(
QWidget *parent,
not_null<Controller*> controller,
@ -77,7 +89,7 @@ void Widget::setInternalState(const QRect &geometry, not_null<Memento*> memento)
restoreState(memento);
}
std::unique_ptr<ContentMemento> Widget::createMemento() {
std::unique_ptr<ContentMemento> Widget::doCreateMemento() {
auto result = std::make_unique<Memento>(user()->bareId());
saveState(result.get());
return std::move(result);
@ -92,7 +104,6 @@ void Widget::restoreState(not_null<Memento*> memento) {
_inner->restoreState(memento);
auto scrollTop = memento->scrollTop();
scrollTopRestore(memento->scrollTop());
// TODO is setVisibleTopBottom called?
}
} // namespace CommonGroups

View file

@ -23,6 +23,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include <rpl/producer.h>
#include "info/info_content_widget.h"
struct PeerListState;
namespace Ui {
class SearchFieldController;
} // namespace Ui
namespace Info {
namespace CommonGroups {
@ -45,7 +51,13 @@ public:
return peerToUser(peerId());
}
void setListState(std::unique_ptr<PeerListState> state);
std::unique_ptr<PeerListState> listState();
~Memento();
private:
std::unique_ptr<PeerListState> _listState;
};
@ -60,7 +72,6 @@ public:
bool showInternal(
not_null<ContentMemento*> memento) override;
std::unique_ptr<ContentMemento> createMemento() override;
void setInternalState(
const QRect &geometry,
@ -70,6 +81,8 @@ private:
void saveState(not_null<Memento*> memento);
void restoreState(not_null<Memento*> memento);
std::unique_ptr<ContentMemento> doCreateMemento() override;
InnerWidget *_inner = nullptr;
};

View file

@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include <rpl/range.h>
#include "window/window_controller.h"
#include "ui/widgets/scroll_area.h"
#include "ui/search_field_controller.h"
#include "lang/lang_keys.h"
#include "info/profile/info_profile_widget.h"
#include "info/media/info_media_widget.h"
@ -43,6 +44,8 @@ ContentWidget::ContentWidget(
: RpWidget(parent)
, _controller(controller)
, _scroll(this, st::infoScroll) {
using namespace rpl::mappers;
setAttribute(Qt::WA_OpaquePaintEvent);
_controller->wrapValue()
| rpl::start_with_next([this](Wrap value) {
@ -51,6 +54,13 @@ ContentWidget::ContentWidget(
: st::profileBg;
update();
}, lifetime());
rpl::combine(
_controller->wrapValue(),
_controller->searchEnabledByContent(),
($1 == Wrap::Layer) && $2)
| rpl::start_with_next([this](bool shown) {
refreshSearchField(shown);
}, lifetime());
_scrollTopSkip.changes()
| rpl::start_with_next([this] {
updateControlsGeometry();
@ -62,6 +72,9 @@ void ContentWidget::resizeEvent(QResizeEvent *e) {
}
void ContentWidget::updateControlsGeometry() {
if (!_inner) {
return;
}
auto newScrollTop = _scroll->scrollTop() + _topDelta;
auto scrollGeometry = rect().marginsRemoved(
QMargins(0, _scrollTopSkip.current(), 0, 0));
@ -75,10 +88,18 @@ void ContentWidget::updateControlsGeometry() {
_scroll->scrollToY(newScrollTop);
}
auto scrollTop = _scroll->scrollTop();
_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
_inner->setVisibleTopBottom(
scrollTop,
scrollTop + _scroll->height());
}
}
std::unique_ptr<ContentMemento> ContentWidget::createMemento() {
auto result = doCreateMemento();
_controller->saveSearchState(result.get());
return result;
}
void ContentWidget::paintEvent(QPaintEvent *e) {
Painter p(this);
p.fillRect(e->rect(), _bg);
@ -100,8 +121,7 @@ void ContentWidget::setGeometryWithTopMoved(
}
Ui::RpWidget *ContentWidget::doSetInnerWidget(
object_ptr<RpWidget> inner,
int scrollTopSkip) {
object_ptr<RpWidget> inner) {
using namespace rpl::mappers;
_inner = _scroll->setOwnedWidget(std::move(inner));
@ -119,8 +139,6 @@ Ui::RpWidget *ContentWidget::doSetInnerWidget(
inner->setVisibleTopBottom(top, bottom);
}, _inner->lifetime());
setScrollTopSkip(scrollTopSkip);
return _inner;
}
@ -176,4 +194,24 @@ rpl::producer<SelectedItems> ContentWidget::selectedListValue() const {
return rpl::single(SelectedItems(Storage::SharedMediaType::Photo));
}
void ContentWidget::refreshSearchField(bool shown) {
auto search = _controller->searchFieldController();
if (search && shown) {
_searchField = search->createRowView(
this,
st::infoLayerMediaSearch);
auto field = _searchField.get();
widthValue()
| rpl::start_with_next([field](int newWidth) {
field->resizeToWidth(newWidth);
field->moveToLeft(0, 0);
}, field->lifetime());
field->show();
setScrollTopSkip(field->heightNoMargins() - st::lineWidth);
} else {
_searchField = nullptr;
setScrollTopSkip(0);
}
}
} // namespace Info

View file

@ -46,7 +46,7 @@ public:
virtual bool showInternal(
not_null<ContentMemento*> memento) = 0;
virtual std::unique_ptr<ContentMemento> createMemento() = 0;
std::unique_ptr<ContentMemento> createMemento();
virtual rpl::producer<Section> sectionRequest() const;
virtual void setIsStackBottom(bool isStackBottom) {
@ -77,11 +77,9 @@ public:
protected:
template <typename Widget>
Widget *setInnerWidget(
object_ptr<Widget> inner,
int scrollTopSkip = 0) {
Widget *setInnerWidget(object_ptr<Widget> inner) {
return static_cast<Widget*>(
doSetInnerWidget(std::move(inner), scrollTopSkip));
doSetInnerWidget(std::move(inner)));
}
not_null<Controller*> controller() const {
@ -97,10 +95,11 @@ protected:
void scrollTo(const Ui::ScrollToRequest &request);
private:
RpWidget *doSetInnerWidget(
object_ptr<RpWidget> inner,
int scrollTopSkip);
RpWidget *doSetInnerWidget(object_ptr<RpWidget> inner);
void updateControlsGeometry();
void refreshSearchField(bool shown);
virtual std::unique_ptr<ContentMemento> doCreateMemento() = 0;
const not_null<Controller*> _controller;
@ -108,6 +107,7 @@ private:
rpl::variable<int> _scrollTopSkip = -1;
object_ptr<Ui::ScrollArea> _scroll;
Ui::RpWidget *_inner = nullptr;
base::unique_qptr<Ui::RpWidget> _searchField = nullptr;
// Saving here topDelta in setGeometryWithTopMoved() to get it passed to resizeEvent().
int _topDelta = 0;
@ -149,12 +149,19 @@ public:
QString searchFieldQuery() const {
return _searchFieldQuery;
}
void setSearchEnabledByContent(bool enabled) {
_searchEnabledByContent = enabled;
}
bool searchEnabledByContent() const {
return _searchEnabledByContent;
}
private:
const PeerId _peerId = 0;
const PeerId _migratedPeerId = 0;
int _scrollTop = 0;
QString _searchFieldQuery;
bool _searchEnabledByContent = false;
};

View file

@ -85,8 +85,8 @@ void Controller::updateSearchControllers(
: Section::MediaType::kCount;
auto hasMediaSearch = isMedia
&& SharedMediaAllowSearch(mediaType);
// auto hasCommonGroupsSearch
// = (_section.type() == Section::Type::CommonGroups);
auto hasCommonGroupsSearch
= (_section.type() == Section::Type::CommonGroups);
auto searchQuery = memento->searchFieldQuery();
if (isMedia) {
_searchController
@ -98,15 +98,18 @@ void Controller::updateSearchControllers(
} else {
_searchController = nullptr;
}
if (hasMediaSearch) {
if (hasMediaSearch || hasCommonGroupsSearch) {
_searchFieldController
= std::make_unique<Ui::SearchFieldController>(
searchQuery);
_searchFieldController->queryValue()
| rpl::start_with_next([=](QString &&query) {
_searchController->setQuery(
produceSearchQuery(std::move(query)));
}, _searchFieldController->lifetime());
if (_searchController) {
_searchFieldController->queryValue()
| rpl::start_with_next([=](QString &&query) {
_searchController->setQuery(
produceSearchQuery(std::move(query)));
}, _searchFieldController->lifetime());
}
_seachEnabledByContent = memento->searchEnabledByContent();
} else {
_searchFieldController = nullptr;
}
@ -116,6 +119,8 @@ void Controller::saveSearchState(not_null<ContentMemento*> memento) {
if (_searchFieldController) {
memento->setSearchFieldQuery(
_searchFieldController->query());
memento->setSearchEnabledByContent(
_seachEnabledByContent.current());
}
if (_searchController) {
auto mediaMemento = dynamic_cast<Media::Memento*>(

View file

@ -106,6 +106,12 @@ public:
Ui::SearchFieldController *searchFieldController() const {
return _searchFieldController.get();
}
void setSearchEnabledByContent(bool enabled) {
_seachEnabledByContent = enabled;
}
rpl::producer<bool> searchEnabledByContent() const {
return _seachEnabledByContent.value();
}
rpl::producer<SparseIdsMergedSlice> mediaSource(
SparseIdsMergedSlice::UniversalMsgId aroundId,
int limitBefore,
@ -137,6 +143,7 @@ private:
std::unique_ptr<Ui::SearchFieldController> _searchFieldController;
std::unique_ptr<Api::DelayedSearchController> _searchController;
rpl::variable<bool> _seachEnabledByContent = false;
rpl::lifetime _lifetime;

View file

@ -34,11 +34,19 @@ Memento::Memento(PeerId peerId)
}
Memento::Memento(PeerId peerId, Section section)
: Memento(Default(peerId, section)) {
: Memento(DefaultStack(peerId, section)) {
}
Memento::Memento(std::unique_ptr<ContentMemento> content)
: _content(std::move(content)) {
Memento::Memento(std::vector<std::unique_ptr<ContentMemento>> stack)
: _stack(std::move(stack)) {
}
std::vector<std::unique_ptr<ContentMemento>> Memento::DefaultStack(
PeerId peerId,
Section section) {
auto result = std::vector<std::unique_ptr<ContentMemento>>();
result.push_back(Default(peerId, section));
return result;
}
std::unique_ptr<ContentMemento> Memento::Default(
@ -98,8 +106,8 @@ object_ptr<Window::LayerWidget> Memento::createLayer(
return nullptr;
}
void Memento::setInner(std::unique_ptr<ContentMemento> content) {
_content = std::move(content);
std::vector<std::unique_ptr<ContentMemento>> Memento::takeStack() {
return std::move(_stack);
}
Memento::~Memento() = default;

View file

@ -42,7 +42,7 @@ class Memento final : public Window::SectionMemento {
public:
Memento(PeerId peerId);
Memento(PeerId peerId, Section section);
Memento(std::unique_ptr<ContentMemento> content);
Memento(std::vector<std::unique_ptr<ContentMemento>> stack);
object_ptr<Window::SectionWidget> createWidget(
QWidget *parent,
@ -54,19 +54,27 @@ public:
not_null<Window::Controller*> controller,
const QRect &geometry) override;
void setInner(std::unique_ptr<ContentMemento> content);
int stackSize() const {
return int(_stack.size());
}
std::vector<std::unique_ptr<ContentMemento>> takeStack();
not_null<ContentMemento*> content() {
return _content.get();
Expects(!_stack.empty());
return _stack.back().get();
}
~Memento();
private:
static std::vector<std::unique_ptr<ContentMemento>> DefaultStack(
PeerId peerId,
Section section);
static std::unique_ptr<ContentMemento> Default(
PeerId peerId,
Section section);
std::unique_ptr<ContentMemento> _content;
std::vector<std::unique_ptr<ContentMemento>> _stack;
};

View file

@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include "info/info_top_bar.h"
#include <rpl/never.h>
#include "styles/style_info.h"
#include "lang/lang_keys.h"
#include "info/info_wrap_widget.h"
@ -64,10 +65,11 @@ void TopBar::enableBackButton(bool enable) {
}
void TopBar::createSearchView(
not_null<Ui::SearchFieldController*> controller) {
setSearchField(controller->createField(
this,
_st.searchRow.field));
not_null<Ui::SearchFieldController*> controller,
rpl::producer<bool> &&shown) {
setSearchField(
controller->createField(this, _st.searchRow.field),
std::move(shown));
}
void TopBar::pushButton(base::unique_qptr<Ui::RpWidget> button) {
@ -81,15 +83,18 @@ void TopBar::pushButton(base::unique_qptr<Ui::RpWidget> button) {
}
void TopBar::setSearchField(
base::unique_qptr<Ui::InputField> field) {
base::unique_qptr<Ui::InputField> field,
rpl::producer<bool> &&shown) {
if (auto value = field.release()) {
createSearchView(value);
createSearchView(value, std::move(shown));
} else {
_searchView = nullptr;
}
}
void TopBar::createSearchView(not_null<Ui::InputField*> field) {
void TopBar::createSearchView(
not_null<Ui::InputField*> field,
rpl::producer<bool> &&shown) {
_searchView = base::make_unique_q<Ui::FixedHeightWidget>(
this,
_st.searchRow.height);
@ -162,12 +167,22 @@ void TopBar::createSearchView(not_null<Ui::InputField*> field) {
| rpl::start_with_done([=] {
field->setParent(nullptr);
removeButton(search);
setSearchField(nullptr);
setSearchField(nullptr, rpl::never<bool>());
}, _searchView->lifetime());
toggleSearchMode(
!field->getLastText().isEmpty(),
anim::type::instant);
std::move(shown)
| rpl::start_with_next([=](bool visible) {
if (!field->getLastText().isEmpty()) {
return;
}
toggleSearchMode(false, anim::type::instant);
wrap->setVisible(visible);
search->toggle(visible, anim::type::instant);
}, wrap->lifetime());
}
void TopBar::removeButton(not_null<Ui::RpWidget*> button) {

View file

@ -60,7 +60,8 @@ public:
}
void createSearchView(
not_null<Ui::SearchFieldController*> controller);
not_null<Ui::SearchFieldController*> controller,
rpl::producer<bool> &&shown);
protected:
int resizeGetHeight(int newWidth) override;
@ -71,8 +72,12 @@ private:
void pushButton(base::unique_qptr<Ui::RpWidget> button);
void removeButton(not_null<Ui::RpWidget*> button);
void setSearchField(base::unique_qptr<Ui::InputField> field);
void createSearchView(not_null<Ui::InputField*> field);
void setSearchField(
base::unique_qptr<Ui::InputField> field,
rpl::producer<bool> &&shown);
void createSearchView(
not_null<Ui::InputField*> field,
rpl::producer<bool> &&shown);
const style::InfoTopBar &_st;
object_ptr<Ui::IconButton> _back = { nullptr };

View file

@ -78,7 +78,24 @@ WrapWidget::WrapWidget(
refreshTopBarOverride(std::move(items));
});
}, lifetime());
showNewContent(memento->content());
restoreHistoryStack(memento->takeStack());
}
void WrapWidget::restoreHistoryStack(
std::vector<std::unique_ptr<ContentMemento>> stack) {
Expects(!stack.empty());
Expects(_historyStack.empty());
auto content = std::move(stack.back());
stack.pop_back();
if (!stack.empty()) {
_historyStack.reserve(stack.size());
for (auto &stackItem : stack) {
auto item = StackItem();
item.section = std::move(stackItem);
_historyStack.push_back(std::move(item));
}
}
showNewContent(content.get());
}
std::unique_ptr<Controller> WrapWidget::createController(
@ -232,7 +249,9 @@ void WrapWidget::createTopBar() {
} else if (requireTopBarSearch()) {
auto search = _controller->searchFieldController();
Assert(search != nullptr);
_topBar->createSearchView(search);
_topBar->createSearchView(
search,
_controller->searchEnabledByContent());
}
_topBar->move(0, 0);
@ -469,6 +488,9 @@ bool WrapWidget::showInternal(
not_null<Window::SectionMemento*> memento,
const Window::SectionShow &params) {
if (auto infoMemento = dynamic_cast<Memento*>(memento.get())) {
if (infoMemento->stackSize() > 1) {
return false;
}
auto content = infoMemento->content();
if (_controller->validateMementoPeer(content)) {
if (_content->showInternal(content)) {
@ -484,7 +506,13 @@ bool WrapWidget::showInternal(
}
std::unique_ptr<Window::SectionMemento> WrapWidget::createMemento() {
return std::make_unique<Memento>(_content->createMemento());
auto stack = std::vector<std::unique_ptr<ContentMemento>>();
stack.reserve(_historyStack.size() + 1);
for (auto &stackItem : _historyStack) {
stack.push_back(std::move(stackItem.section));
}
stack.push_back(_content->createMemento());
return std::make_unique<Memento>(std::move(stack));
}
rpl::producer<int> WrapWidget::desiredHeightValue() const {

View file

@ -142,6 +142,8 @@ private:
};
struct StackItem;
void restoreHistoryStack(
std::vector<std::unique_ptr<ContentMemento>> stack);
void showBackFromStack();
void showNewContent(not_null<ContentMemento*> memento);
void showNewContent(

View file

@ -58,6 +58,12 @@ void InnerWidget::setupOtherTypes() {
_otherTypes.destroy();
refreshHeight();
}
}, lifetime());
rpl::combine(
_controller->wrapValue(),
_controller->searchEnabledByContent())
| rpl::start_with_next([this](Wrap wrap, bool enabled) {
_searchEnabled = enabled;
refreshSearchField();
}, lifetime());
}
@ -204,7 +210,7 @@ void InnerWidget::switchToTab(Memento &&memento) {
void InnerWidget::refreshSearchField() {
auto search = _controller->searchFieldController();
if (search && _otherTabs) {
if (search && _otherTabs && _searchEnabled) {
_searchField = search->createRowView(
this,
st::infoMediaSearch);
@ -216,7 +222,6 @@ void InnerWidget::refreshSearchField() {
}
object_ptr<ListWidget> InnerWidget::setupList() {
refreshSearchField();
auto result = object_ptr<ListWidget>(
this,
_controller);

View file

@ -86,6 +86,7 @@ private:
object_ptr<Ui::PlainShadow> _otherTabsShadow = { nullptr };
base::unique_qptr<Ui::RpWidget> _searchField = nullptr;
object_ptr<ListWidget> _list = { nullptr };
bool _searchEnabled = false;
bool _inResize = false;

View file

@ -49,6 +49,7 @@ constexpr auto kPreloadedScreensCount = 4;
constexpr auto kPreloadIfLessThanScreens = 2;
constexpr auto kPreloadedScreensCountFull
= kPreloadedScreensCount + 1 + kPreloadedScreensCount;
constexpr auto kMediaCountForSearch = 10;
UniversalMsgId GetUniversalId(FullMsgId itemId) {
return (itemId.channel != 0)
@ -552,6 +553,7 @@ ListWidget::ListWidget(
}
void ListWidget::start() {
_controller->setSearchEnabledByContent(false);
ObservableViewer(*Window::Theme::Background())
| rpl::start_with_next([this](const auto &update) {
if (update.paletteChanged()) {
@ -889,6 +891,10 @@ void ListWidget::refreshRows() {
_sections.push_back(std::move(section));
}
if (_layouts.size() > kMediaCountForSearch) {
_controller->setSearchEnabledByContent(true);
}
clearStaleLayouts();
resizeToWidth(width());

View file

@ -91,10 +91,6 @@ Widget::Widget(
| rpl::start_with_next([this](int skip) {
scrollTo({ skip, -1 });
}, _inner->lifetime());
controller->wrapValue()
| rpl::start_with_next([this] {
refreshSearchField();
}, lifetime());
}
rpl::producer<SelectedItems> Widget::selectedListValue() const {
@ -123,14 +119,13 @@ void Widget::setInternalState(const QRect &geometry, not_null<Memento*> memento)
restoreState(memento);
}
std::unique_ptr<ContentMemento> Widget::createMemento() {
std::unique_ptr<ContentMemento> Widget::doCreateMemento() {
auto result = std::make_unique<Memento>(controller());
saveState(result.get());
return std::move(result);
}
void Widget::saveState(not_null<Memento*> memento) {
controller()->saveSearchState(memento);
_inner->saveState(memento);
}
@ -138,25 +133,5 @@ void Widget::restoreState(not_null<Memento*> memento) {
_inner->restoreState(memento);
}
void Widget::refreshSearchField() {
auto search = controller()->searchFieldController();
if (search && controller()->wrap() == Wrap::Layer) {
_searchField = search->createRowView(
this,
st::infoLayerMediaSearch);
auto field = _searchField.get();
widthValue()
| rpl::start_with_next([field](int newWidth) {
field->resizeToWidth(newWidth);
field->moveToLeft(0, 0);
}, field->lifetime());
field->show();
setScrollTopSkip(field->heightNoMargins() - st::lineWidth);
} else {
_searchField = nullptr;
setScrollTopSkip(0);
}
}
} // namespace Media
} // namespace Info

View file

@ -106,7 +106,6 @@ public:
bool showInternal(
not_null<ContentMemento*> memento) override;
std::unique_ptr<ContentMemento> createMemento() override;
void setInternalState(
const QRect &geometry,
@ -119,10 +118,9 @@ private:
void saveState(not_null<Memento*> memento);
void restoreState(not_null<Memento*> memento);
void refreshSearchField();
std::unique_ptr<ContentMemento> doCreateMemento() override;
InnerWidget *_inner = nullptr;
base::unique_qptr<Ui::RpWidget> _searchField = nullptr;
};

View file

@ -43,7 +43,7 @@ namespace Info {
namespace Profile {
namespace {
constexpr auto kEnableSearchMembersAfterCount = 50;
constexpr auto kEnableSearchMembersAfterCount = 20;
} // namespace

View file

@ -92,7 +92,7 @@ void Widget::setInternalState(const QRect &geometry, not_null<Memento*> memento)
restoreState(memento);
}
std::unique_ptr<ContentMemento> Widget::createMemento() {
std::unique_ptr<ContentMemento> Widget::doCreateMemento() {
auto result = std::make_unique<Memento>(controller());
saveState(result.get());
return std::move(result);

View file

@ -79,7 +79,6 @@ public:
bool showInternal(
not_null<ContentMemento*> memento) override;
std::unique_ptr<ContentMemento> createMemento() override;
void setInternalState(
const QRect &geometry,
@ -91,6 +90,8 @@ private:
void saveState(not_null<Memento*> memento);
void restoreState(not_null<Memento*> memento);
std::unique_ptr<ContentMemento> doCreateMemento() override;
InnerWidget *_inner = nullptr;
};