mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Add cache for global media search requests.
This commit is contained in:
parent
d59eb8e731
commit
3f0d687656
9 changed files with 119 additions and 110 deletions
|
@ -1427,6 +1427,9 @@ void Widget::updateSuggestions(anim::type animated) {
|
||||||
controller(),
|
controller(),
|
||||||
TopPeersContent(&session()),
|
TopPeersContent(&session()),
|
||||||
RecentPeersContent(&session()));
|
RecentPeersContent(&session()));
|
||||||
|
_suggestions->clearSearchQueryRequests() | rpl::start_with_next([=] {
|
||||||
|
setSearchQuery(QString());
|
||||||
|
}, _suggestions->lifetime());
|
||||||
_searchSuggestionsLocked = false;
|
_searchSuggestionsLocked = false;
|
||||||
|
|
||||||
rpl::merge(
|
rpl::merge(
|
||||||
|
@ -2934,7 +2937,11 @@ void Widget::updateCancelSearch() {
|
||||||
|
|
||||||
QString Widget::validateSearchQuery() {
|
QString Widget::validateSearchQuery() {
|
||||||
const auto query = currentSearchQuery();
|
const auto query = currentSearchQuery();
|
||||||
if (_searchState.tab == ChatSearchTab::PublicPosts) {
|
if (!_subsectionTopBar
|
||||||
|
&& _suggestions
|
||||||
|
&& _suggestions->consumeSearchQuery(query)) {
|
||||||
|
return QString();
|
||||||
|
} else if (_searchState.tab == ChatSearchTab::PublicPosts) {
|
||||||
if (_searchHashOrCashtag == HashOrCashtag::None) {
|
if (_searchHashOrCashtag == HashOrCashtag::None) {
|
||||||
_searchHashOrCashtag = HashOrCashtag::Hashtag;
|
_searchHashOrCashtag = HashOrCashtag::Hashtag;
|
||||||
}
|
}
|
||||||
|
@ -3932,9 +3939,18 @@ void Widget::setSearchQuery(const QString &query, int cursorPosition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Widget::cancelSearch(CancelSearchOptions options) {
|
bool Widget::cancelSearch(CancelSearchOptions options) {
|
||||||
|
const auto clearingSuggestionsQuery = _suggestions
|
||||||
|
&& _suggestions->consumeSearchQuery(QString());
|
||||||
|
if (clearingSuggestionsQuery) {
|
||||||
|
setSearchQuery(QString());
|
||||||
|
if (!options.forceFullCancel) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
cancelSearchRequest();
|
cancelSearchRequest();
|
||||||
auto updatedState = _searchState;
|
auto updatedState = _searchState;
|
||||||
const auto clearingQuery = !updatedState.query.isEmpty();
|
const auto clearingQuery = clearingSuggestionsQuery
|
||||||
|
|| !updatedState.query.isEmpty();
|
||||||
const auto forceFullCancel = options.forceFullCancel;
|
const auto forceFullCancel = options.forceFullCancel;
|
||||||
auto clearingInChat = (forceFullCancel || !clearingQuery)
|
auto clearingInChat = (forceFullCancel || !clearingQuery)
|
||||||
&& (updatedState.inChat
|
&& (updatedState.inChat
|
||||||
|
|
|
@ -48,6 +48,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/delayed_activation.h"
|
#include "ui/delayed_activation.h"
|
||||||
#include "ui/dynamic_thumbnails.h"
|
#include "ui/dynamic_thumbnails.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
|
#include "ui/search_field_controller.h"
|
||||||
#include "ui/unread_badge_paint.h"
|
#include "ui/unread_badge_paint.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "window/window_separate_id.h"
|
#include "window/window_separate_id.h"
|
||||||
|
@ -66,6 +67,7 @@ constexpr auto kCollapsedChannelsCount = 5;
|
||||||
constexpr auto kProbablyMaxChannels = 1000;
|
constexpr auto kProbablyMaxChannels = 1000;
|
||||||
constexpr auto kCollapsedAppsCount = 5;
|
constexpr auto kCollapsedAppsCount = 5;
|
||||||
constexpr auto kProbablyMaxApps = 100;
|
constexpr auto kProbablyMaxApps = 100;
|
||||||
|
constexpr auto kSearchQueryDelay = crl::time(900);
|
||||||
|
|
||||||
class RecentRow final : public PeerListRow {
|
class RecentRow final : public PeerListRow {
|
||||||
public:
|
public:
|
||||||
|
@ -1335,7 +1337,8 @@ Suggestions::Suggestions(
|
||||||
, _appsContent(
|
, _appsContent(
|
||||||
_appsScroll->setOwnedWidget(object_ptr<Ui::VerticalLayout>(this)))
|
_appsScroll->setOwnedWidget(object_ptr<Ui::VerticalLayout>(this)))
|
||||||
, _recentApps(setupRecentApps())
|
, _recentApps(setupRecentApps())
|
||||||
, _popularApps(setupPopularApps()) {
|
, _popularApps(setupPopularApps())
|
||||||
|
, _searchQueryTimer([=] { applySearchQuery(); }) {
|
||||||
setupTabs();
|
setupTabs();
|
||||||
setupChats();
|
setupChats();
|
||||||
setupChannels();
|
setupChannels();
|
||||||
|
@ -1754,6 +1757,43 @@ void Suggestions::chooseRow() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Suggestions::consumeSearchQuery(const QString &query) {
|
||||||
|
using Type = MediaType;
|
||||||
|
const auto key = _key.current();
|
||||||
|
const auto tab = key.tab;
|
||||||
|
const auto type = (key.tab == Tab::Media) ? key.mediaType : Type::kCount;
|
||||||
|
if (tab != Tab::Downloads
|
||||||
|
&& type != Type::File
|
||||||
|
&& type != Type::Link
|
||||||
|
&& type != Type::MusicFile) {
|
||||||
|
return false;
|
||||||
|
} else if (_searchQuery == query) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_searchQuery = query;
|
||||||
|
_persist = !_searchQuery.isEmpty();
|
||||||
|
if (query.isEmpty() || tab == Tab::Downloads) {
|
||||||
|
_searchQueryTimer.cancel();
|
||||||
|
applySearchQuery();
|
||||||
|
} else {
|
||||||
|
_searchQueryTimer.callOnce(kSearchQueryDelay);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Suggestions::applySearchQuery() {
|
||||||
|
const auto key = _key.current();
|
||||||
|
const auto controller = _mediaLists[key].wrap->controller();
|
||||||
|
const auto search = controller->searchFieldController();
|
||||||
|
if (search->query() != _searchQuery) {
|
||||||
|
search->setQuery(_searchQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> Suggestions::clearSearchQueryRequests() const {
|
||||||
|
return _clearSearchQueryRequests.events();
|
||||||
|
}
|
||||||
|
|
||||||
Data::Thread *Suggestions::updateFromParentDrag(QPoint globalPosition) {
|
Data::Thread *Suggestions::updateFromParentDrag(QPoint globalPosition) {
|
||||||
switch (_key.current().tab) {
|
switch (_key.current().tab) {
|
||||||
case Tab::Chats: return updateFromChatsDrag(globalPosition);
|
case Tab::Chats: return updateFromChatsDrag(globalPosition);
|
||||||
|
@ -1825,8 +1865,10 @@ void Suggestions::switchTab(Key key) {
|
||||||
if (was == key) {
|
if (was == key) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
consumeSearchQuery(QString());
|
||||||
_key = key;
|
_key = key;
|
||||||
_persist = false;
|
_persist = false;
|
||||||
|
_clearSearchQueryRequests.fire({});
|
||||||
if (_tabs->isHidden()) {
|
if (_tabs->isHidden()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "base/object_ptr.h"
|
#include "base/object_ptr.h"
|
||||||
|
#include "base/timer.h"
|
||||||
#include "dialogs/ui/top_peers_strip.h"
|
#include "dialogs/ui/top_peers_strip.h"
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
|
@ -64,6 +65,9 @@ public:
|
||||||
void selectJump(Qt::Key direction, int pageSize = 0);
|
void selectJump(Qt::Key direction, int pageSize = 0);
|
||||||
void chooseRow();
|
void chooseRow();
|
||||||
|
|
||||||
|
bool consumeSearchQuery(const QString &query);
|
||||||
|
[[nodiscard]] rpl::producer<> clearSearchQueryRequests() const;
|
||||||
|
|
||||||
[[nodiscard]] Data::Thread *updateFromParentDrag(QPoint globalPosition);
|
[[nodiscard]] Data::Thread *updateFromParentDrag(QPoint globalPosition);
|
||||||
void dragLeft();
|
void dragLeft();
|
||||||
|
|
||||||
|
@ -193,6 +197,7 @@ private:
|
||||||
|
|
||||||
void handlePressForChatPreview(PeerId id, Fn<void(bool)> callback);
|
void handlePressForChatPreview(PeerId id, Fn<void(bool)> callback);
|
||||||
void updateControlsGeometry();
|
void updateControlsGeometry();
|
||||||
|
void applySearchQuery();
|
||||||
|
|
||||||
const not_null<Window::SessionController*> _controller;
|
const not_null<Window::SessionController*> _controller;
|
||||||
|
|
||||||
|
@ -231,6 +236,9 @@ private:
|
||||||
const std::unique_ptr<ObjectList> _popularApps;
|
const std::unique_ptr<ObjectList> _popularApps;
|
||||||
|
|
||||||
base::flat_map<Key, MediaList> _mediaLists;
|
base::flat_map<Key, MediaList> _mediaLists;
|
||||||
|
rpl::event_stream<> _clearSearchQueryRequests;
|
||||||
|
QString _searchQuery;
|
||||||
|
base::Timer _searchQueryTimer;
|
||||||
|
|
||||||
Ui::Animations::Simple _shownAnimation;
|
Ui::Animations::Simple _shownAnimation;
|
||||||
Fn<void()> _showFinished;
|
Fn<void()> _showFinished;
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "info/global_media/info_global_media_provider.h"
|
#include "info/global_media/info_global_media_provider.h"
|
||||||
#include "info/global_media/info_global_media_widget.h"
|
#include "info/global_media/info_global_media_widget.h"
|
||||||
|
#include "info/media/info_media_empty_widget.h"
|
||||||
#include "info/media/info_media_list_widget.h"
|
#include "info/media/info_media_list_widget.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
|
@ -18,75 +19,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace Info::GlobalMedia {
|
namespace Info::GlobalMedia {
|
||||||
|
|
||||||
class EmptyWidget : public Ui::RpWidget {
|
|
||||||
public:
|
|
||||||
EmptyWidget(QWidget *parent);
|
|
||||||
|
|
||||||
void setFullHeight(rpl::producer<int> fullHeightValue);
|
|
||||||
void setSearchQuery(const QString &query);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
object_ptr<Ui::FlatLabel> _text;
|
|
||||||
int _height = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
EmptyWidget::EmptyWidget(QWidget *parent)
|
|
||||||
: RpWidget(parent)
|
|
||||||
, _text(this, st::infoEmptyLabel) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmptyWidget::setFullHeight(rpl::producer<int> fullHeightValue) {
|
|
||||||
std::move(
|
|
||||||
fullHeightValue
|
|
||||||
) | rpl::start_with_next([this](int fullHeight) {
|
|
||||||
// Make icon center be on 1/3 height.
|
|
||||||
auto iconCenter = fullHeight / 3;
|
|
||||||
auto iconHeight = st::infoEmptyFile.height();
|
|
||||||
auto iconTop = iconCenter - iconHeight / 2;
|
|
||||||
_height = iconTop + st::infoEmptyIconTop;
|
|
||||||
resizeToWidth(width());
|
|
||||||
}, lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmptyWidget::setSearchQuery(const QString &query) {
|
|
||||||
_text->setText(query.isEmpty()
|
|
||||||
? tr::lng_media_file_empty(tr::now)
|
|
||||||
: tr::lng_media_file_empty_search(tr::now));
|
|
||||||
resizeToWidth(width());
|
|
||||||
}
|
|
||||||
|
|
||||||
int EmptyWidget::resizeGetHeight(int newWidth) {
|
|
||||||
auto labelTop = _height - st::infoEmptyLabelTop;
|
|
||||||
auto labelWidth = newWidth - 2 * st::infoEmptyLabelSkip;
|
|
||||||
_text->resizeToNaturalWidth(labelWidth);
|
|
||||||
|
|
||||||
auto labelLeft = (newWidth - _text->width()) / 2;
|
|
||||||
_text->moveToLeft(labelLeft, labelTop, newWidth);
|
|
||||||
|
|
||||||
update();
|
|
||||||
return _height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmptyWidget::paintEvent(QPaintEvent *e) {
|
|
||||||
auto p = QPainter(this);
|
|
||||||
|
|
||||||
const auto iconLeft = (width() - st::infoEmptyFile.width()) / 2;
|
|
||||||
const auto iconTop = height() - st::infoEmptyIconTop;
|
|
||||||
st::infoEmptyFile.paint(p, iconLeft, iconTop, width());
|
|
||||||
}
|
|
||||||
|
|
||||||
InnerWidget::InnerWidget(
|
InnerWidget::InnerWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Controller*> controller)
|
not_null<Controller*> controller)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
, _empty(this) {
|
, _empty(this) {
|
||||||
|
_empty->setType(type());
|
||||||
_empty->heightValue(
|
_empty->heightValue(
|
||||||
) | rpl::start_with_next(
|
) | rpl::start_with_next(
|
||||||
[this] { refreshHeight(); },
|
[this] { refreshHeight(); },
|
||||||
|
|
|
@ -21,16 +21,17 @@ enum class SharedMediaType : signed char;
|
||||||
} // namespace Storage
|
} // namespace Storage
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
|
|
||||||
class Controller;
|
class Controller;
|
||||||
struct SelectedItems;
|
struct SelectedItems;
|
||||||
enum class SelectionAction;
|
enum class SelectionAction;
|
||||||
|
} // namespace Info
|
||||||
|
|
||||||
namespace Media {
|
namespace Info::Media {
|
||||||
class ListWidget;
|
class ListWidget;
|
||||||
} // namespace Media
|
class EmptyWidget;
|
||||||
|
} // namespace Info::Media
|
||||||
|
|
||||||
namespace GlobalMedia {
|
namespace Info::GlobalMedia {
|
||||||
|
|
||||||
class Memento;
|
class Memento;
|
||||||
class EmptyWidget;
|
class EmptyWidget;
|
||||||
|
@ -71,7 +72,7 @@ private:
|
||||||
const not_null<Controller*> _controller;
|
const not_null<Controller*> _controller;
|
||||||
|
|
||||||
object_ptr<Media::ListWidget> _list = { nullptr };
|
object_ptr<Media::ListWidget> _list = { nullptr };
|
||||||
object_ptr<EmptyWidget> _empty;
|
object_ptr<Media::EmptyWidget> _empty;
|
||||||
|
|
||||||
bool _inResize = false;
|
bool _inResize = false;
|
||||||
|
|
||||||
|
@ -81,5 +82,4 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GlobalMedia
|
} // namespace Info::GlobalMedia
|
||||||
} // namespace Info
|
|
||||||
|
|
|
@ -227,18 +227,6 @@ void Provider::checkPreload(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Provider::applyListQuery(const QString &query) {
|
|
||||||
if (_totalListQuery == query) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_totalListQuery = query;
|
|
||||||
_totalList.clear();
|
|
||||||
_totalOffsetPosition = Data::MessagePosition();
|
|
||||||
_totalOffsetRate = 0;
|
|
||||||
_totalFullCount = 0;
|
|
||||||
_totalLoaded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<GlobalMediaSlice> Provider::source(
|
rpl::producer<GlobalMediaSlice> Provider::source(
|
||||||
Type type,
|
Type type,
|
||||||
Data::MessagePosition aroundId,
|
Data::MessagePosition aroundId,
|
||||||
|
@ -247,7 +235,7 @@ rpl::producer<GlobalMediaSlice> Provider::source(
|
||||||
int limitAfter) {
|
int limitAfter) {
|
||||||
Expects(_type == type);
|
Expects(_type == type);
|
||||||
|
|
||||||
applyListQuery(query);
|
_totalListQuery = query;
|
||||||
return [=](auto consumer) {
|
return [=](auto consumer) {
|
||||||
auto lifetime = rpl::lifetime();
|
auto lifetime = rpl::lifetime();
|
||||||
const auto session = &_controller->session();
|
const auto session = &_controller->session();
|
||||||
|
@ -268,7 +256,7 @@ rpl::producer<GlobalMediaSlice> Provider::source(
|
||||||
state->pushAndLoadMore = [=] {
|
state->pushAndLoadMore = [=] {
|
||||||
auto result = fillRequest(aroundId, limitBefore, limitAfter);
|
auto result = fillRequest(aroundId, limitBefore, limitAfter);
|
||||||
consumer.put_next(std::move(result.slice));
|
consumer.put_next(std::move(result.slice));
|
||||||
if (!_totalLoaded && result.notEnough) {
|
if (!currentList()->loaded && result.notEnough) {
|
||||||
state->requestId = requestMore(state->pushAndLoadMore);
|
state->requestId = requestMore(state->pushAndLoadMore);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -280,30 +268,32 @@ rpl::producer<GlobalMediaSlice> Provider::source(
|
||||||
|
|
||||||
mtpRequestId Provider::requestMore(Fn<void()> loaded) {
|
mtpRequestId Provider::requestMore(Fn<void()> loaded) {
|
||||||
const auto done = [=](const Api::GlobalMediaResult &result) {
|
const auto done = [=](const Api::GlobalMediaResult &result) {
|
||||||
|
const auto list = currentList();
|
||||||
if (result.messageIds.empty()) {
|
if (result.messageIds.empty()) {
|
||||||
_totalLoaded = true;
|
list->loaded = true;
|
||||||
_totalFullCount = _totalList.size();
|
list->fullCount = list->list.size();
|
||||||
} else {
|
} else {
|
||||||
_totalList.reserve(_totalList.size() + result.messageIds.size());
|
list->list.reserve(list->list.size() + result.messageIds.size());
|
||||||
_totalFullCount = result.fullCount;
|
list->fullCount = result.fullCount;
|
||||||
for (const auto &position : result.messageIds) {
|
for (const auto &position : result.messageIds) {
|
||||||
_seenIds.emplace(position.fullId);
|
_seenIds.emplace(position.fullId);
|
||||||
_totalOffsetPosition = position;
|
list->offsetPosition = position;
|
||||||
_totalList.push_back(position);
|
list->list.push_back(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result.offsetRate) {
|
if (!result.offsetRate) {
|
||||||
_totalLoaded = true;
|
list->loaded = true;
|
||||||
} else {
|
} else {
|
||||||
_totalOffsetRate = result.offsetRate;
|
list->offsetRate = result.offsetRate;
|
||||||
}
|
}
|
||||||
loaded();
|
loaded();
|
||||||
};
|
};
|
||||||
|
const auto list = currentList();
|
||||||
return _controller->session().api().requestGlobalMedia(
|
return _controller->session().api().requestGlobalMedia(
|
||||||
_type,
|
_type,
|
||||||
_totalListQuery,
|
_totalListQuery,
|
||||||
_totalOffsetRate,
|
list->offsetRate,
|
||||||
_totalOffsetPosition,
|
list->offsetPosition,
|
||||||
done);
|
done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,24 +301,25 @@ Provider::FillResult Provider::fillRequest(
|
||||||
Data::MessagePosition aroundId,
|
Data::MessagePosition aroundId,
|
||||||
int limitBefore,
|
int limitBefore,
|
||||||
int limitAfter) {
|
int limitAfter) {
|
||||||
|
const auto list = currentList();
|
||||||
const auto i = ranges::lower_bound(
|
const auto i = ranges::lower_bound(
|
||||||
_totalList,
|
list->list,
|
||||||
aroundId,
|
aroundId,
|
||||||
std::greater<>());
|
std::greater<>());
|
||||||
const auto hasAfter = int(i - begin(_totalList));
|
const auto hasAfter = int(i - begin(list->list));
|
||||||
const auto hasBefore = int(end(_totalList) - i);
|
const auto hasBefore = int(end(list->list) - i);
|
||||||
const auto takeAfter = std::min(limitAfter, hasAfter);
|
const auto takeAfter = std::min(limitAfter, hasAfter);
|
||||||
const auto takeBefore = std::min(limitBefore, hasBefore);
|
const auto takeBefore = std::min(limitBefore, hasBefore);
|
||||||
auto list = std::vector<Data::MessagePosition>{
|
auto messages = std::vector<Data::MessagePosition>{
|
||||||
i - takeAfter,
|
i - takeAfter,
|
||||||
i + takeBefore,
|
i + takeBefore,
|
||||||
};
|
};
|
||||||
return FillResult{
|
return FillResult{
|
||||||
.slice = GlobalMediaSlice(
|
.slice = GlobalMediaSlice(
|
||||||
GlobalMediaKey{ aroundId },
|
GlobalMediaKey{ aroundId },
|
||||||
std::move(list),
|
std::move(messages),
|
||||||
((!_totalList.empty() || _totalLoaded)
|
((!list->list.empty() || list->loaded)
|
||||||
? _totalFullCount
|
? list->fullCount
|
||||||
: std::optional<int>()),
|
: std::optional<int>()),
|
||||||
hasAfter - takeAfter),
|
hasAfter - takeAfter),
|
||||||
.notEnough = (takeBefore < limitBefore),
|
.notEnough = (takeBefore < limitBefore),
|
||||||
|
@ -400,6 +391,10 @@ void Provider::clearStaleLayouts() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Provider::List *Provider::currentList() {
|
||||||
|
return &_totalLists[_totalListQuery];
|
||||||
|
}
|
||||||
|
|
||||||
rpl::producer<not_null<Media::BaseLayout*>> Provider::layoutRemoved() {
|
rpl::producer<not_null<Media::BaseLayout*>> Provider::layoutRemoved() {
|
||||||
return _layoutRemoved.events();
|
return _layoutRemoved.events();
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,13 @@ private:
|
||||||
GlobalMediaSlice slice;
|
GlobalMediaSlice slice;
|
||||||
bool notEnough = false;
|
bool notEnough = false;
|
||||||
};
|
};
|
||||||
|
struct List {
|
||||||
|
std::vector<Data::MessagePosition> list;
|
||||||
|
Data::MessagePosition offsetPosition;
|
||||||
|
int32 offsetRate = 0;
|
||||||
|
int fullCount = 0;
|
||||||
|
bool loaded = false;
|
||||||
|
};
|
||||||
|
|
||||||
bool sectionHasFloatingHeader() override;
|
bool sectionHasFloatingHeader() override;
|
||||||
QString sectionTitle(not_null<const BaseLayout*> item) override;
|
QString sectionTitle(not_null<const BaseLayout*> item) override;
|
||||||
|
@ -154,7 +161,7 @@ private:
|
||||||
void itemRemoved(not_null<const HistoryItem*> item);
|
void itemRemoved(not_null<const HistoryItem*> item);
|
||||||
void markLayoutsStale();
|
void markLayoutsStale();
|
||||||
void clearStaleLayouts();
|
void clearStaleLayouts();
|
||||||
void applyListQuery(const QString &query);
|
[[nodiscard]] List *currentList();
|
||||||
[[nodiscard]] FillResult fillRequest(
|
[[nodiscard]] FillResult fillRequest(
|
||||||
Data::MessagePosition aroundId,
|
Data::MessagePosition aroundId,
|
||||||
int limitBefore,
|
int limitBefore,
|
||||||
|
@ -174,11 +181,7 @@ private:
|
||||||
rpl::event_stream<> _refreshed;
|
rpl::event_stream<> _refreshed;
|
||||||
|
|
||||||
QString _totalListQuery;
|
QString _totalListQuery;
|
||||||
std::vector<Data::MessagePosition> _totalList;
|
base::flat_map<QString, List> _totalLists;
|
||||||
Data::MessagePosition _totalOffsetPosition;
|
|
||||||
int32 _totalOffsetRate = 0;
|
|
||||||
int _totalFullCount = 0;
|
|
||||||
bool _totalLoaded = false;
|
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
rpl::lifetime _viewerLifetime;
|
rpl::lifetime _viewerLifetime;
|
||||||
|
|
|
@ -92,6 +92,10 @@ rpl::producer<QString> SearchFieldController::queryChanges() const {
|
||||||
return _query.changes();
|
return _query.changes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchFieldController::setQuery(const QString &query) {
|
||||||
|
_query = query;
|
||||||
|
}
|
||||||
|
|
||||||
base::unique_qptr<Ui::InputField> SearchFieldController::createField(
|
base::unique_qptr<Ui::InputField> SearchFieldController::createField(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
const style::InputField &st) {
|
const style::InputField &st) {
|
||||||
|
|
|
@ -40,6 +40,8 @@ public:
|
||||||
rpl::producer<QString> queryValue() const;
|
rpl::producer<QString> queryValue() const;
|
||||||
rpl::producer<QString> queryChanges() const;
|
rpl::producer<QString> queryChanges() const;
|
||||||
|
|
||||||
|
void setQuery(const QString &query);
|
||||||
|
|
||||||
rpl::lifetime &lifetime() {
|
rpl::lifetime &lifetime() {
|
||||||
return _lifetime;
|
return _lifetime;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue