mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Improve chats search loading indication.
This commit is contained in:
parent
032fe3e0fc
commit
5810149a77
4 changed files with 57 additions and 24 deletions
|
@ -2588,6 +2588,15 @@ void InnerWidget::dragPinnedFromTouch() {
|
||||||
updateReorderPinned(now);
|
updateReorderPinned(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InnerWidget::searchRequested(bool loading) {
|
||||||
|
_searchWaiting = false;
|
||||||
|
_searchLoading = loading;
|
||||||
|
if (loading) {
|
||||||
|
clearSearchResults(true);
|
||||||
|
}
|
||||||
|
refresh(true);
|
||||||
|
}
|
||||||
|
|
||||||
void InnerWidget::applySearchState(SearchState state) {
|
void InnerWidget::applySearchState(SearchState state) {
|
||||||
if (_searchState == state) {
|
if (_searchState == state) {
|
||||||
return;
|
return;
|
||||||
|
@ -2700,9 +2709,13 @@ void InnerWidget::applySearchState(SearchState state) {
|
||||||
clearMouseSelection(true);
|
clearMouseSelection(true);
|
||||||
}
|
}
|
||||||
if (_state != WidgetState::Default) {
|
if (_state != WidgetState::Default) {
|
||||||
_searchLoading = true;
|
_searchWaiting = true;
|
||||||
_searchMessages.fire({});
|
_searchRequests.fire(otherChanged
|
||||||
refresh(true);
|
? SearchRequestDelay::Instant
|
||||||
|
: SearchRequestDelay::Delayed);
|
||||||
|
if (_searchWaiting) {
|
||||||
|
refresh(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2918,8 +2931,8 @@ rpl::producer<Ui::ScrollToRequest> InnerWidget::dialogMoved() const {
|
||||||
return _dialogMoved.events();
|
return _dialogMoved.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> InnerWidget::searchMessages() const {
|
rpl::producer<SearchRequestDelay> InnerWidget::searchRequests() const {
|
||||||
return _searchMessages.events();
|
return _searchRequests.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<QString> InnerWidget::completeHashtagRequests() const {
|
rpl::producer<QString> InnerWidget::completeHashtagRequests() const {
|
||||||
|
@ -3007,6 +3020,7 @@ void InnerWidget::searchReceived(
|
||||||
HistoryItem *inject,
|
HistoryItem *inject,
|
||||||
SearchRequestType type,
|
SearchRequestType type,
|
||||||
int fullCount) {
|
int fullCount) {
|
||||||
|
_searchWaiting = false;
|
||||||
_searchLoading = false;
|
_searchLoading = false;
|
||||||
|
|
||||||
const auto uniquePeers = uniqueSearchResults();
|
const auto uniquePeers = uniqueSearchResults();
|
||||||
|
@ -3171,7 +3185,7 @@ void InnerWidget::refreshEmpty() {
|
||||||
&& _searchResults.empty()
|
&& _searchResults.empty()
|
||||||
&& _peerSearchResults.empty()
|
&& _peerSearchResults.empty()
|
||||||
&& _hashtagResults.empty();
|
&& _hashtagResults.empty();
|
||||||
if (_searchLoading || !empty) {
|
if (_searchLoading || _searchWaiting || !empty) {
|
||||||
if (_searchEmpty) {
|
if (_searchEmpty) {
|
||||||
_searchEmpty->hide();
|
_searchEmpty->hide();
|
||||||
}
|
}
|
||||||
|
@ -3185,7 +3199,7 @@ void InnerWidget::refreshEmpty() {
|
||||||
_searchEmpty->show();
|
_searchEmpty->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_searchLoading || !empty) {
|
if ((!_searchLoading && !_searchWaiting) || !empty) {
|
||||||
_loadingAnimation.destroy();
|
_loadingAnimation.destroy();
|
||||||
} else if (!_loadingAnimation) {
|
} else if (!_loadingAnimation) {
|
||||||
_loadingAnimation = Ui::CreateLoadingDialogRowWidget(
|
_loadingAnimation = Ui::CreateLoadingDialogRowWidget(
|
||||||
|
|
|
@ -71,7 +71,7 @@ struct ChosenRow {
|
||||||
bool newWindow : 1 = false;
|
bool newWindow : 1 = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SearchRequestType {
|
enum class SearchRequestType : uchar {
|
||||||
FromStart,
|
FromStart,
|
||||||
FromOffset,
|
FromOffset,
|
||||||
PeerFromStart,
|
PeerFromStart,
|
||||||
|
@ -80,6 +80,12 @@ enum class SearchRequestType {
|
||||||
MigratedFromOffset,
|
MigratedFromOffset,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SearchRequestDelay : uchar {
|
||||||
|
InCache,
|
||||||
|
Instant,
|
||||||
|
Delayed,
|
||||||
|
};
|
||||||
|
|
||||||
enum class WidgetState {
|
enum class WidgetState {
|
||||||
Default,
|
Default,
|
||||||
Filtered,
|
Filtered,
|
||||||
|
@ -145,6 +151,7 @@ public:
|
||||||
}
|
}
|
||||||
[[nodiscard]] bool hasFilteredResults() const;
|
[[nodiscard]] bool hasFilteredResults() const;
|
||||||
|
|
||||||
|
void searchRequested(bool loading);
|
||||||
void applySearchState(SearchState state);
|
void applySearchState(SearchState state);
|
||||||
[[nodiscard]] auto searchTagsChanges() const
|
[[nodiscard]] auto searchTagsChanges() const
|
||||||
-> rpl::producer<std::vector<Data::ReactionId>>;
|
-> rpl::producer<std::vector<Data::ReactionId>>;
|
||||||
|
@ -168,7 +175,7 @@ public:
|
||||||
[[nodiscard]] rpl::producer<int> scrollByDeltaRequests() const;
|
[[nodiscard]] rpl::producer<int> scrollByDeltaRequests() const;
|
||||||
[[nodiscard]] rpl::producer<Ui::ScrollToRequest> mustScrollTo() const;
|
[[nodiscard]] rpl::producer<Ui::ScrollToRequest> mustScrollTo() const;
|
||||||
[[nodiscard]] rpl::producer<Ui::ScrollToRequest> dialogMoved() 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<QString> completeHashtagRequests() const;
|
||||||
[[nodiscard]] rpl::producer<> refreshHashtagsRequests() const;
|
[[nodiscard]] rpl::producer<> refreshHashtagsRequests() const;
|
||||||
|
|
||||||
|
@ -529,7 +536,7 @@ private:
|
||||||
|
|
||||||
rpl::event_stream<Ui::ScrollToRequest> _mustScrollTo;
|
rpl::event_stream<Ui::ScrollToRequest> _mustScrollTo;
|
||||||
rpl::event_stream<Ui::ScrollToRequest> _dialogMoved;
|
rpl::event_stream<Ui::ScrollToRequest> _dialogMoved;
|
||||||
rpl::event_stream<> _searchMessages;
|
rpl::event_stream<SearchRequestDelay> _searchRequests;
|
||||||
rpl::event_stream<QString> _completeHashtagRequests;
|
rpl::event_stream<QString> _completeHashtagRequests;
|
||||||
rpl::event_stream<> _refreshHashtagsRequests;
|
rpl::event_stream<> _refreshHashtagsRequests;
|
||||||
|
|
||||||
|
@ -547,6 +554,7 @@ private:
|
||||||
|
|
||||||
bool _savedSublists = false;
|
bool _savedSublists = false;
|
||||||
bool _searchLoading = false;
|
bool _searchLoading = false;
|
||||||
|
bool _searchWaiting = false;
|
||||||
|
|
||||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,7 @@ namespace {
|
||||||
|
|
||||||
constexpr auto kSearchPerPage = 50;
|
constexpr auto kSearchPerPage = 50;
|
||||||
constexpr auto kStoriesExpandDuration = crl::time(200);
|
constexpr auto kStoriesExpandDuration = crl::time(200);
|
||||||
|
constexpr auto kSearchRequestDelay = crl::time(900);
|
||||||
|
|
||||||
base::options::toggle OptionForumHideChatsList({
|
base::options::toggle OptionForumHideChatsList({
|
||||||
.id = kOptionForumHideChatsList,
|
.id = kOptionForumHideChatsList,
|
||||||
|
@ -324,9 +325,9 @@ Widget::Widget(
|
||||||
_scroll->scrollToY(st + _inner->st()->height);
|
_scroll->scrollToY(st + _inner->st()->height);
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
_inner->searchMessages(
|
_inner->searchRequests(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=](SearchRequestDelay delay) {
|
||||||
searchRequested();
|
searchRequested(delay);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
_inner->completeHashtagRequests(
|
_inner->completeHashtagRequests(
|
||||||
) | rpl::start_with_next([=](const QString &tag) {
|
) | rpl::start_with_next([=](const QString &tag) {
|
||||||
|
@ -1921,7 +1922,7 @@ void Widget::loadMoreBlockedByDate() {
|
||||||
session().api().requestMoreBlockedByDateDialogs();
|
session().api().requestMoreBlockedByDateDialogs();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Widget::search(bool inCache) {
|
bool Widget::search(bool inCache, SearchRequestDelay delay) {
|
||||||
_processingSearch = true;
|
_processingSearch = true;
|
||||||
const auto guard = gsl::finally([&] {
|
const auto guard = gsl::finally([&] {
|
||||||
_processingSearch = false;
|
_processingSearch = false;
|
||||||
|
@ -1950,7 +1951,7 @@ bool Widget::search(bool inCache) {
|
||||||
return true;
|
return true;
|
||||||
} else if (inCache) {
|
} else if (inCache) {
|
||||||
const auto success = _singleMessageSearch.lookup(query, [=] {
|
const auto success = _singleMessageSearch.lookup(query, [=] {
|
||||||
searchRequested();
|
searchRequested(delay);
|
||||||
});
|
});
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2068,6 +2069,9 @@ bool Widget::search(bool inCache) {
|
||||||
}).send();
|
}).send();
|
||||||
_searchQueries.emplace(_searchRequest, _searchQuery);
|
_searchQueries.emplace(_searchRequest, _searchQuery);
|
||||||
}
|
}
|
||||||
|
_inner->searchRequested(true);
|
||||||
|
} else {
|
||||||
|
_inner->searchRequested(false);
|
||||||
}
|
}
|
||||||
const auto peerQuery = Api::ConvertPeerSearchQuery(query);
|
const auto peerQuery = Api::ConvertPeerSearchQuery(query);
|
||||||
if (searchForPeersRequired(peerQuery)) {
|
if (searchForPeersRequired(peerQuery)) {
|
||||||
|
@ -2130,9 +2134,14 @@ bool Widget::searchForTopicsRequired(const QString &query) const {
|
||||||
&& !_openedForum->topicsList()->loaded();
|
&& !_openedForum->topicsList()->loaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::searchRequested() {
|
void Widget::searchRequested(SearchRequestDelay delay) {
|
||||||
if (!search(true)) {
|
if (search(true, delay)) {
|
||||||
_searchTimer.callOnce(AutoSearchTimeout);
|
return;
|
||||||
|
} else if (delay == SearchRequestDelay::Instant) {
|
||||||
|
_searchTimer.cancel();
|
||||||
|
search();
|
||||||
|
} else {
|
||||||
|
_searchTimer.callOnce(kSearchRequestDelay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2187,10 +2196,11 @@ void Widget::searchTopics() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::searchMore() {
|
void Widget::searchMore() {
|
||||||
if (_searchRequest || _searchInHistoryRequest) {
|
if (_searchRequest
|
||||||
|
|| _searchInHistoryRequest
|
||||||
|
|| _searchTimer.isActive()) {
|
||||||
return;
|
return;
|
||||||
}
|
} else if (!_searchFull) {
|
||||||
if (!_searchFull) {
|
|
||||||
if (const auto peer = searchInPeer()) {
|
if (const auto peer = searchInPeer()) {
|
||||||
auto &histories = session().data().histories();
|
auto &histories = session().data().histories();
|
||||||
const auto topic = searchInTopic();
|
const auto topic = searchInTopic();
|
||||||
|
|
|
@ -74,7 +74,8 @@ class FakeRow;
|
||||||
class Key;
|
class Key;
|
||||||
struct ChosenRow;
|
struct ChosenRow;
|
||||||
class InnerWidget;
|
class InnerWidget;
|
||||||
enum class SearchRequestType;
|
enum class SearchRequestType : uchar;
|
||||||
|
enum class SearchRequestDelay : uchar;
|
||||||
class Suggestions;
|
class Suggestions;
|
||||||
class ChatSearchIn;
|
class ChatSearchIn;
|
||||||
enum class ChatSearchTab : uchar;
|
enum class ChatSearchTab : uchar;
|
||||||
|
@ -156,8 +157,8 @@ private:
|
||||||
[[nodiscard]] QString currentSearchQuery() const;
|
[[nodiscard]] QString currentSearchQuery() const;
|
||||||
[[nodiscard]] int currentSearchQueryCursorPosition() const;
|
[[nodiscard]] int currentSearchQueryCursorPosition() const;
|
||||||
void clearSearchField();
|
void clearSearchField();
|
||||||
void searchRequested();
|
void searchRequested(SearchRequestDelay delay);
|
||||||
bool search(bool inCache = false);
|
bool search(bool inCache = false, SearchRequestDelay after = {});
|
||||||
void searchTopics();
|
void searchTopics();
|
||||||
void searchMore();
|
void searchMore();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue