Improve chats search loading indication.

This commit is contained in:
John Preston 2024-06-16 10:27:00 +04:00
parent 032fe3e0fc
commit 5810149a77
4 changed files with 57 additions and 24 deletions

View file

@ -2588,6 +2588,15 @@ void InnerWidget::dragPinnedFromTouch() {
updateReorderPinned(now);
}
void InnerWidget::searchRequested(bool loading) {
_searchWaiting = false;
_searchLoading = loading;
if (loading) {
clearSearchResults(true);
}
refresh(true);
}
void InnerWidget::applySearchState(SearchState state) {
if (_searchState == state) {
return;
@ -2700,9 +2709,13 @@ void InnerWidget::applySearchState(SearchState state) {
clearMouseSelection(true);
}
if (_state != WidgetState::Default) {
_searchLoading = true;
_searchMessages.fire({});
refresh(true);
_searchWaiting = true;
_searchRequests.fire(otherChanged
? SearchRequestDelay::Instant
: SearchRequestDelay::Delayed);
if (_searchWaiting) {
refresh(true);
}
}
}
@ -2918,8 +2931,8 @@ rpl::producer<Ui::ScrollToRequest> InnerWidget::dialogMoved() const {
return _dialogMoved.events();
}
rpl::producer<> InnerWidget::searchMessages() const {
return _searchMessages.events();
rpl::producer<SearchRequestDelay> InnerWidget::searchRequests() const {
return _searchRequests.events();
}
rpl::producer<QString> InnerWidget::completeHashtagRequests() const {
@ -3007,6 +3020,7 @@ void InnerWidget::searchReceived(
HistoryItem *inject,
SearchRequestType type,
int fullCount) {
_searchWaiting = false;
_searchLoading = false;
const auto uniquePeers = uniqueSearchResults();
@ -3171,7 +3185,7 @@ void InnerWidget::refreshEmpty() {
&& _searchResults.empty()
&& _peerSearchResults.empty()
&& _hashtagResults.empty();
if (_searchLoading || !empty) {
if (_searchLoading || _searchWaiting || !empty) {
if (_searchEmpty) {
_searchEmpty->hide();
}
@ -3185,7 +3199,7 @@ void InnerWidget::refreshEmpty() {
_searchEmpty->show();
}
if (!_searchLoading || !empty) {
if ((!_searchLoading && !_searchWaiting) || !empty) {
_loadingAnimation.destroy();
} else if (!_loadingAnimation) {
_loadingAnimation = Ui::CreateLoadingDialogRowWidget(

View file

@ -71,7 +71,7 @@ struct ChosenRow {
bool newWindow : 1 = false;
};
enum class SearchRequestType {
enum class SearchRequestType : uchar {
FromStart,
FromOffset,
PeerFromStart,
@ -80,6 +80,12 @@ enum class SearchRequestType {
MigratedFromOffset,
};
enum class SearchRequestDelay : uchar {
InCache,
Instant,
Delayed,
};
enum class WidgetState {
Default,
Filtered,
@ -145,6 +151,7 @@ public:
}
[[nodiscard]] bool hasFilteredResults() const;
void searchRequested(bool loading);
void applySearchState(SearchState state);
[[nodiscard]] auto searchTagsChanges() const
-> rpl::producer<std::vector<Data::ReactionId>>;
@ -168,7 +175,7 @@ public:
[[nodiscard]] rpl::producer<int> scrollByDeltaRequests() const;
[[nodiscard]] rpl::producer<Ui::ScrollToRequest> mustScrollTo() const;
[[nodiscard]] rpl::producer<Ui::ScrollToRequest> dialogMoved() const;
[[nodiscard]] rpl::producer<> searchMessages() const;
[[nodiscard]] rpl::producer<SearchRequestDelay> searchRequests() const;
[[nodiscard]] rpl::producer<QString> completeHashtagRequests() const;
[[nodiscard]] rpl::producer<> refreshHashtagsRequests() const;
@ -529,7 +536,7 @@ private:
rpl::event_stream<Ui::ScrollToRequest> _mustScrollTo;
rpl::event_stream<Ui::ScrollToRequest> _dialogMoved;
rpl::event_stream<> _searchMessages;
rpl::event_stream<SearchRequestDelay> _searchRequests;
rpl::event_stream<QString> _completeHashtagRequests;
rpl::event_stream<> _refreshHashtagsRequests;
@ -547,6 +554,7 @@ private:
bool _savedSublists = false;
bool _searchLoading = false;
bool _searchWaiting = false;
base::unique_qptr<Ui::PopupMenu> _menu;

View file

@ -95,6 +95,7 @@ namespace {
constexpr auto kSearchPerPage = 50;
constexpr auto kStoriesExpandDuration = crl::time(200);
constexpr auto kSearchRequestDelay = crl::time(900);
base::options::toggle OptionForumHideChatsList({
.id = kOptionForumHideChatsList,
@ -324,9 +325,9 @@ Widget::Widget(
_scroll->scrollToY(st + _inner->st()->height);
}
}, lifetime());
_inner->searchMessages(
) | rpl::start_with_next([=] {
searchRequested();
_inner->searchRequests(
) | rpl::start_with_next([=](SearchRequestDelay delay) {
searchRequested(delay);
}, lifetime());
_inner->completeHashtagRequests(
) | rpl::start_with_next([=](const QString &tag) {
@ -1921,7 +1922,7 @@ void Widget::loadMoreBlockedByDate() {
session().api().requestMoreBlockedByDateDialogs();
}
bool Widget::search(bool inCache) {
bool Widget::search(bool inCache, SearchRequestDelay delay) {
_processingSearch = true;
const auto guard = gsl::finally([&] {
_processingSearch = false;
@ -1950,7 +1951,7 @@ bool Widget::search(bool inCache) {
return true;
} else if (inCache) {
const auto success = _singleMessageSearch.lookup(query, [=] {
searchRequested();
searchRequested(delay);
});
if (!success) {
return false;
@ -2068,6 +2069,9 @@ bool Widget::search(bool inCache) {
}).send();
_searchQueries.emplace(_searchRequest, _searchQuery);
}
_inner->searchRequested(true);
} else {
_inner->searchRequested(false);
}
const auto peerQuery = Api::ConvertPeerSearchQuery(query);
if (searchForPeersRequired(peerQuery)) {
@ -2130,9 +2134,14 @@ bool Widget::searchForTopicsRequired(const QString &query) const {
&& !_openedForum->topicsList()->loaded();
}
void Widget::searchRequested() {
if (!search(true)) {
_searchTimer.callOnce(AutoSearchTimeout);
void Widget::searchRequested(SearchRequestDelay delay) {
if (search(true, delay)) {
return;
} else if (delay == SearchRequestDelay::Instant) {
_searchTimer.cancel();
search();
} else {
_searchTimer.callOnce(kSearchRequestDelay);
}
}
@ -2187,10 +2196,11 @@ void Widget::searchTopics() {
}
void Widget::searchMore() {
if (_searchRequest || _searchInHistoryRequest) {
if (_searchRequest
|| _searchInHistoryRequest
|| _searchTimer.isActive()) {
return;
}
if (!_searchFull) {
} else if (!_searchFull) {
if (const auto peer = searchInPeer()) {
auto &histories = session().data().histories();
const auto topic = searchInTopic();

View file

@ -74,7 +74,8 @@ class FakeRow;
class Key;
struct ChosenRow;
class InnerWidget;
enum class SearchRequestType;
enum class SearchRequestType : uchar;
enum class SearchRequestDelay : uchar;
class Suggestions;
class ChatSearchIn;
enum class ChatSearchTab : uchar;
@ -156,8 +157,8 @@ private:
[[nodiscard]] QString currentSearchQuery() const;
[[nodiscard]] int currentSearchQueryCursorPosition() const;
void clearSearchField();
void searchRequested();
bool search(bool inCache = false);
void searchRequested(SearchRequestDelay delay);
bool search(bool inCache = false, SearchRequestDelay after = {});
void searchTopics();
void searchMore();