mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Add global search chat type filter.
This commit is contained in:
parent
5f10c1875c
commit
44bfdbdc83
8 changed files with 167 additions and 12 deletions
|
@ -4146,6 +4146,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_search_messages_from" = "Show messages from";
|
"lng_search_messages_from" = "Show messages from";
|
||||||
"lng_search_messages_n_of_amount" = "{n} of {amount}";
|
"lng_search_messages_n_of_amount" = "{n} of {amount}";
|
||||||
"lng_search_messages_none" = "No results";
|
"lng_search_messages_none" = "No results";
|
||||||
|
"lng_search_filter_all" = "All chats";
|
||||||
|
"lng_search_filter_private" = "Private chats";
|
||||||
|
"lng_search_filter_group" = "Group chats";
|
||||||
|
"lng_search_filter_channel" = "Channels";
|
||||||
|
|
||||||
"lng_media_save_progress" = "{ready} of {total} {mb}";
|
"lng_media_save_progress" = "{ready} of {total} {mb}";
|
||||||
"lng_mediaview_save_as" = "Save As...";
|
"lng_mediaview_save_as" = "Save As...";
|
||||||
|
@ -5998,6 +6002,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_search_tab_no_results_text" = "There were no results for \"{query}\".";
|
"lng_search_tab_no_results_text" = "There were no results for \"{query}\".";
|
||||||
"lng_search_tab_no_results_retry" = "Try another hashtag.";
|
"lng_search_tab_no_results_retry" = "Try another hashtag.";
|
||||||
"lng_search_tab_by_hashtag" = "Enter a hashtag to find messages containing it.";
|
"lng_search_tab_by_hashtag" = "Enter a hashtag to find messages containing it.";
|
||||||
|
"lng_search_tab_try_in_all" = "Search in All Messages";
|
||||||
|
|
||||||
"lng_contact_details_button" = "View Contact";
|
"lng_contact_details_button" = "View Contact";
|
||||||
"lng_contact_details_title" = "Contact details";
|
"lng_contact_details_title" = "Contact details";
|
||||||
|
|
|
@ -79,6 +79,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
#include "styles/style_color_indices.h"
|
#include "styles/style_color_indices.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
|
#include "styles/style_media_player.h"
|
||||||
#include "styles/style_menu_icons.h"
|
#include "styles/style_menu_icons.h"
|
||||||
|
|
||||||
#include <QtWidgets/QApplication>
|
#include <QtWidgets/QApplication>
|
||||||
|
@ -143,7 +144,8 @@ constexpr auto kPreviewPostsLimit = 3;
|
||||||
|
|
||||||
[[nodiscard]] object_ptr<SearchEmpty> MakeSearchEmpty(
|
[[nodiscard]] object_ptr<SearchEmpty> MakeSearchEmpty(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
SearchState state) {
|
SearchState state,
|
||||||
|
Fn<void()> resetChatTypeFilter) {
|
||||||
const auto query = state.query.trimmed();
|
const auto query = state.query.trimmed();
|
||||||
const auto hashtag = !query.isEmpty() && (query[0] == '#');
|
const auto hashtag = !query.isEmpty() && (query[0] == '#');
|
||||||
const auto trimmed = hashtag ? query.mid(1).trimmed() : query;
|
const auto trimmed = hashtag ? query.mid(1).trimmed() : query;
|
||||||
|
@ -157,6 +159,9 @@ constexpr auto kPreviewPostsLimit = 3;
|
||||||
const auto waiting = trimmed.isEmpty()
|
const auto waiting = trimmed.isEmpty()
|
||||||
&& state.tags.empty()
|
&& state.tags.empty()
|
||||||
&& !fromPeer;
|
&& !fromPeer;
|
||||||
|
const auto suggestAllChats = !waiting
|
||||||
|
&& state.tab == ChatSearchTab::MyMessages
|
||||||
|
&& state.filter != ChatTypeFilter::All;
|
||||||
const auto icon = waiting
|
const auto icon = waiting
|
||||||
? SearchEmptyIcon::Search
|
? SearchEmptyIcon::Search
|
||||||
: SearchEmptyIcon::NoResults;
|
: SearchEmptyIcon::NoResults;
|
||||||
|
@ -180,7 +185,10 @@ constexpr auto kPreviewPostsLimit = 3;
|
||||||
tr::now,
|
tr::now,
|
||||||
lt_query,
|
lt_query,
|
||||||
trimmed.mid(0, kQueryPreviewLimit)));
|
trimmed.mid(0, kQueryPreviewLimit)));
|
||||||
if (hashtag) {
|
if (suggestAllChats) {
|
||||||
|
text.append("\n\n").append(
|
||||||
|
Ui::Text::Link(tr::lng_search_tab_try_in_all(tr::now)));
|
||||||
|
} else if (hashtag) {
|
||||||
text.append("\n").append(
|
text.append("\n").append(
|
||||||
tr::lng_search_tab_no_results_retry(tr::now));
|
tr::lng_search_tab_no_results_retry(tr::now));
|
||||||
}
|
}
|
||||||
|
@ -190,11 +198,29 @@ constexpr auto kPreviewPostsLimit = 3;
|
||||||
parent,
|
parent,
|
||||||
icon,
|
icon,
|
||||||
rpl::single(std::move(text)));
|
rpl::single(std::move(text)));
|
||||||
|
if (suggestAllChats) {
|
||||||
|
result->handlerActivated(
|
||||||
|
) | rpl::start_with_next(resetChatTypeFilter, result->lifetime());
|
||||||
|
}
|
||||||
result->show();
|
result->show();
|
||||||
result->resizeToWidth(parent->width());
|
result->resizeToWidth(parent->width());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] QString ChatTypeFilterLabel(ChatTypeFilter filter) {
|
||||||
|
switch (filter) {
|
||||||
|
case ChatTypeFilter::All:
|
||||||
|
return tr::lng_search_filter_all(tr::now);
|
||||||
|
case ChatTypeFilter::Private:
|
||||||
|
return tr::lng_search_filter_private(tr::now);
|
||||||
|
case ChatTypeFilter::Groups:
|
||||||
|
return tr::lng_search_filter_group(tr::now);
|
||||||
|
case ChatTypeFilter::Channels:
|
||||||
|
return tr::lng_search_filter_channel(tr::now);
|
||||||
|
}
|
||||||
|
Unexpected("Chat type filter in search results.");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct InnerWidget::CollapsedRow {
|
struct InnerWidget::CollapsedRow {
|
||||||
|
@ -1184,6 +1210,25 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
p.setFont(st::searchedBarFont);
|
p.setFont(st::searchedBarFont);
|
||||||
p.setPen(st::searchedBarFg);
|
p.setPen(st::searchedBarFg);
|
||||||
p.drawTextLeft(st::searchedBarPosition.x(), st::searchedBarPosition.y(), width(), text);
|
p.drawTextLeft(st::searchedBarPosition.x(), st::searchedBarPosition.y(), width(), text);
|
||||||
|
const auto filterOver = _selectedChatTypeFilter
|
||||||
|
|| _pressedChatTypeFilter;
|
||||||
|
const auto filterFont = filterOver
|
||||||
|
? st::searchedBarFont->underline()
|
||||||
|
: st::searchedBarFont;
|
||||||
|
if (_searchState.tab == ChatSearchTab::MyMessages) {
|
||||||
|
const auto text = ChatTypeFilterLabel(_searchState.filter);
|
||||||
|
if (!_chatTypeFilterWidth) {
|
||||||
|
_chatTypeFilterWidth = filterFont->width(text);
|
||||||
|
}
|
||||||
|
p.setFont(filterFont);
|
||||||
|
p.drawTextLeft(
|
||||||
|
(width()
|
||||||
|
- st::searchedBarPosition.x()
|
||||||
|
- _chatTypeFilterWidth),
|
||||||
|
st::searchedBarPosition.y(),
|
||||||
|
width(),
|
||||||
|
text);
|
||||||
|
}
|
||||||
p.translate(0, st::searchedBarHeight);
|
p.translate(0, st::searchedBarHeight);
|
||||||
|
|
||||||
auto skip = searchedOffset();
|
auto skip = searchedOffset();
|
||||||
|
@ -1701,6 +1746,20 @@ void InnerWidget::selectByMouse(QPoint globalPosition) {
|
||||||
_searchedSelected = searchedSelected;
|
_searchedSelected = searchedSelected;
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
}
|
}
|
||||||
|
auto selectedChatTypeFilter = false;
|
||||||
|
const auto from = skip - st::searchedBarHeight;
|
||||||
|
if (mouseY <= skip && mouseY >= from) {
|
||||||
|
const auto left = width()
|
||||||
|
- _chatTypeFilterWidth
|
||||||
|
- 2 * st::searchedBarPosition.x();
|
||||||
|
if (_chatTypeFilterWidth > 0 && local.x() >= left) {
|
||||||
|
selectedChatTypeFilter = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_selectedChatTypeFilter != selectedChatTypeFilter) {
|
||||||
|
update(0, from, width(), st::searchedBarHeight);
|
||||||
|
_selectedChatTypeFilter = selectedChatTypeFilter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!inTags && wasSelected != isSelected()) {
|
if (!inTags && wasSelected != isSelected()) {
|
||||||
setCursor(wasSelected ? style::cur_default : style::cur_pointer);
|
setCursor(wasSelected ? style::cur_default : style::cur_pointer);
|
||||||
|
@ -1742,6 +1801,7 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
setPreviewPressed(_previewSelected);
|
setPreviewPressed(_previewSelected);
|
||||||
setSearchedPressed(_searchedSelected);
|
setSearchedPressed(_searchedSelected);
|
||||||
_pressedMorePosts = _selectedMorePosts;
|
_pressedMorePosts = _selectedMorePosts;
|
||||||
|
_pressedChatTypeFilter = _selectedChatTypeFilter;
|
||||||
|
|
||||||
const auto alt = (e->modifiers() & Qt::AltModifier);
|
const auto alt = (e->modifiers() & Qt::AltModifier);
|
||||||
if (alt && showChatPreview()) {
|
if (alt && showChatPreview()) {
|
||||||
|
@ -2139,6 +2199,8 @@ void InnerWidget::mousePressReleased(
|
||||||
setSearchedPressed(-1);
|
setSearchedPressed(-1);
|
||||||
const auto pressedMorePosts = _pressedMorePosts;
|
const auto pressedMorePosts = _pressedMorePosts;
|
||||||
_pressedMorePosts = false;
|
_pressedMorePosts = false;
|
||||||
|
const auto pressedChatTypeFilter = _pressedChatTypeFilter;
|
||||||
|
_pressedChatTypeFilter = false;
|
||||||
if (wasDragging) {
|
if (wasDragging) {
|
||||||
selectByMouse(globalPosition);
|
selectByMouse(globalPosition);
|
||||||
}
|
}
|
||||||
|
@ -2163,7 +2225,9 @@ void InnerWidget::mousePressReleased(
|
||||||
|| (searchedPressed >= 0
|
|| (searchedPressed >= 0
|
||||||
&& searchedPressed == _searchedSelected)
|
&& searchedPressed == _searchedSelected)
|
||||||
|| (pressedMorePosts
|
|| (pressedMorePosts
|
||||||
&& pressedMorePosts == _selectedMorePosts)) {
|
&& pressedMorePosts == _selectedMorePosts)
|
||||||
|
|| (pressedChatTypeFilter
|
||||||
|
&& pressedChatTypeFilter == _selectedChatTypeFilter)) {
|
||||||
if (pressedBotApp && (pressed || filteredPressed >= 0)) {
|
if (pressedBotApp && (pressed || filteredPressed >= 0)) {
|
||||||
const auto &row = pressed
|
const auto &row = pressed
|
||||||
? pressed
|
? pressed
|
||||||
|
@ -2690,6 +2754,7 @@ void InnerWidget::clearSelection() {
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
_collapsedSelected = -1;
|
_collapsedSelected = -1;
|
||||||
_selectedMorePosts = false;
|
_selectedMorePosts = false;
|
||||||
|
_selectedChatTypeFilter = false;
|
||||||
_selected = nullptr;
|
_selected = nullptr;
|
||||||
_filteredSelected
|
_filteredSelected
|
||||||
= _searchedSelected
|
= _searchedSelected
|
||||||
|
@ -3001,6 +3066,10 @@ void InnerWidget::applySearchState(SearchState state) {
|
||||||
if (state.inChat) {
|
if (state.inChat) {
|
||||||
onHashtagFilterUpdate(QStringView());
|
onHashtagFilterUpdate(QStringView());
|
||||||
}
|
}
|
||||||
|
if (state.filter != _searchState.filter) {
|
||||||
|
_chatTypeFilterWidth = 0;
|
||||||
|
update();
|
||||||
|
}
|
||||||
_searchState = std::move(state);
|
_searchState = std::move(state);
|
||||||
_searchHashOrCashtag = IsHashOrCashtagSearchQuery(_searchState.query);
|
_searchHashOrCashtag = IsHashOrCashtagSearchQuery(_searchState.query);
|
||||||
_searchWithPostsPreview = computeSearchWithPostsPreview();
|
_searchWithPostsPreview = computeSearchWithPostsPreview();
|
||||||
|
@ -3269,6 +3338,11 @@ rpl::producer<ChatSearchTab> InnerWidget::changeSearchTabRequests() const {
|
||||||
return _changeSearchTabRequests.events();
|
return _changeSearchTabRequests.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto InnerWidget::changeSearchFilterRequests() const
|
||||||
|
-> rpl::producer<ChatTypeFilter>{
|
||||||
|
return _changeSearchFilterRequests.events();
|
||||||
|
}
|
||||||
|
|
||||||
rpl::producer<> InnerWidget::cancelSearchRequests() const {
|
rpl::producer<> InnerWidget::cancelSearchRequests() const {
|
||||||
return _cancelSearchRequests.events();
|
return _cancelSearchRequests.events();
|
||||||
}
|
}
|
||||||
|
@ -3557,7 +3631,9 @@ void InnerWidget::refreshEmpty() {
|
||||||
}
|
}
|
||||||
} else if (_searchEmptyState != _searchState) {
|
} else if (_searchEmptyState != _searchState) {
|
||||||
_searchEmptyState = _searchState;
|
_searchEmptyState = _searchState;
|
||||||
_searchEmpty = MakeSearchEmpty(this, _searchState);
|
_searchEmpty = MakeSearchEmpty(this, _searchState, [=] {
|
||||||
|
_changeSearchFilterRequests.fire(ChatTypeFilter::All);
|
||||||
|
});
|
||||||
if (_controller->session().data().chatsListLoaded()) {
|
if (_controller->session().data().chatsListLoaded()) {
|
||||||
_searchEmpty->animate();
|
_searchEmpty->animate();
|
||||||
}
|
}
|
||||||
|
@ -4288,7 +4364,7 @@ ChosenRow InnerWidget::computeChosenRow() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InnerWidget::isUserpicPress() const {
|
bool InnerWidget::isUserpicPress() const {
|
||||||
return (_lastRowLocalMouseX >= 0)
|
return (_lastRowLocalMouseX >= 0)
|
||||||
&& (_lastRowLocalMouseX < _st->nameLeft)
|
&& (_lastRowLocalMouseX < _st->nameLeft)
|
||||||
&& (_collapsedSelected < 0
|
&& (_collapsedSelected < 0
|
||||||
|| _collapsedSelected >= _collapsedRows.size());
|
|| _collapsedSelected >= _collapsedRows.size());
|
||||||
|
@ -4308,6 +4384,24 @@ bool InnerWidget::chooseRow(
|
||||||
_changeSearchTabRequests.fire(ChatSearchTab::PublicPosts);
|
_changeSearchTabRequests.fire(ChatSearchTab::PublicPosts);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
} else if (_selectedChatTypeFilter) {
|
||||||
|
_menu = base::make_unique_q<Ui::PopupMenu>(
|
||||||
|
this,
|
||||||
|
st::popupMenuWithIcons);
|
||||||
|
for (const auto tab : {
|
||||||
|
ChatTypeFilter::All,
|
||||||
|
ChatTypeFilter::Private,
|
||||||
|
ChatTypeFilter::Groups,
|
||||||
|
ChatTypeFilter::Channels,
|
||||||
|
}) {
|
||||||
|
_menu->addAction(ChatTypeFilterLabel(tab), [=] {
|
||||||
|
_changeSearchFilterRequests.fire_copy(tab);
|
||||||
|
}, (tab == _searchState.filter)
|
||||||
|
? &st::mediaPlayerMenuCheck
|
||||||
|
: nullptr);
|
||||||
|
}
|
||||||
|
_menu->popup(QCursor::pos());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
const auto modifyChosenRow = [&](
|
const auto modifyChosenRow = [&](
|
||||||
ChosenRow row,
|
ChosenRow row,
|
||||||
|
|
|
@ -65,6 +65,7 @@ class SearchEmpty;
|
||||||
class ChatSearchIn;
|
class ChatSearchIn;
|
||||||
enum class HashOrCashtag : uchar;
|
enum class HashOrCashtag : uchar;
|
||||||
struct RightButton;
|
struct RightButton;
|
||||||
|
enum class ChatTypeFilter : uchar;
|
||||||
|
|
||||||
struct ChosenRow {
|
struct ChosenRow {
|
||||||
Key key;
|
Key key;
|
||||||
|
@ -176,6 +177,8 @@ public:
|
||||||
[[nodiscard]] rpl::producer<> listBottomReached() const;
|
[[nodiscard]] rpl::producer<> listBottomReached() const;
|
||||||
[[nodiscard]] auto changeSearchTabRequests() const
|
[[nodiscard]] auto changeSearchTabRequests() const
|
||||||
-> rpl::producer<ChatSearchTab>;
|
-> rpl::producer<ChatSearchTab>;
|
||||||
|
[[nodiscard]] auto changeSearchFilterRequests() const
|
||||||
|
-> rpl::producer<ChatTypeFilter>;
|
||||||
[[nodiscard]] rpl::producer<> cancelSearchRequests() const;
|
[[nodiscard]] rpl::producer<> cancelSearchRequests() const;
|
||||||
[[nodiscard]] rpl::producer<> cancelSearchFromRequests() const;
|
[[nodiscard]] rpl::producer<> cancelSearchFromRequests() const;
|
||||||
[[nodiscard]] rpl::producer<> changeSearchFromRequests() const;
|
[[nodiscard]] rpl::producer<> changeSearchFromRequests() const;
|
||||||
|
@ -308,7 +311,8 @@ private:
|
||||||
|| (_peerSearchPressed >= 0)
|
|| (_peerSearchPressed >= 0)
|
||||||
|| (_previewPressed >= 0)
|
|| (_previewPressed >= 0)
|
||||||
|| (_searchedPressed >= 0)
|
|| (_searchedPressed >= 0)
|
||||||
|| _pressedMorePosts;
|
|| _pressedMorePosts
|
||||||
|
|| _pressedChatTypeFilter;
|
||||||
}
|
}
|
||||||
bool isSelected() const {
|
bool isSelected() const {
|
||||||
return (_collapsedSelected >= 0)
|
return (_collapsedSelected >= 0)
|
||||||
|
@ -318,7 +322,8 @@ private:
|
||||||
|| (_peerSearchSelected >= 0)
|
|| (_peerSearchSelected >= 0)
|
||||||
|| (_previewSelected >= 0)
|
|| (_previewSelected >= 0)
|
||||||
|| (_searchedSelected >= 0)
|
|| (_searchedSelected >= 0)
|
||||||
|| _selectedMorePosts;
|
|| _selectedMorePosts
|
||||||
|
|| _selectedChatTypeFilter;
|
||||||
}
|
}
|
||||||
bool uniqueSearchResults() const;
|
bool uniqueSearchResults() const;
|
||||||
bool hasHistoryInResults(not_null<History*> history) const;
|
bool hasHistoryInResults(not_null<History*> history) const;
|
||||||
|
@ -486,6 +491,8 @@ private:
|
||||||
std::vector<std::unique_ptr<CollapsedRow>> _collapsedRows;
|
std::vector<std::unique_ptr<CollapsedRow>> _collapsedRows;
|
||||||
not_null<const style::DialogRow*> _st;
|
not_null<const style::DialogRow*> _st;
|
||||||
mutable std::unique_ptr<Ui::TopicJumpCache> _topicJumpCache;
|
mutable std::unique_ptr<Ui::TopicJumpCache> _topicJumpCache;
|
||||||
|
bool _selectedChatTypeFilter = false;
|
||||||
|
bool _pressedChatTypeFilter = false;
|
||||||
bool _selectedMorePosts = false;
|
bool _selectedMorePosts = false;
|
||||||
bool _pressedMorePosts = false;
|
bool _pressedMorePosts = false;
|
||||||
int _collapsedSelected = -1;
|
int _collapsedSelected = -1;
|
||||||
|
@ -543,6 +550,7 @@ private:
|
||||||
int _previewSelected = -1;
|
int _previewSelected = -1;
|
||||||
int _previewPressed = -1;
|
int _previewPressed = -1;
|
||||||
int _morePostsWidth = 0;
|
int _morePostsWidth = 0;
|
||||||
|
int _chatTypeFilterWidth = 0;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<FakeRow>> _searchResults;
|
std::vector<std::unique_ptr<FakeRow>> _searchResults;
|
||||||
int _searchedCount = 0;
|
int _searchedCount = 0;
|
||||||
|
@ -554,6 +562,7 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<ChatSearchIn> _searchIn;
|
std::unique_ptr<ChatSearchIn> _searchIn;
|
||||||
rpl::event_stream<ChatSearchTab> _changeSearchTabRequests;
|
rpl::event_stream<ChatSearchTab> _changeSearchTabRequests;
|
||||||
|
rpl::event_stream<ChatTypeFilter> _changeSearchFilterRequests;
|
||||||
rpl::event_stream<> _cancelSearchRequests;
|
rpl::event_stream<> _cancelSearchRequests;
|
||||||
rpl::event_stream<> _cancelSearchFromRequests;
|
rpl::event_stream<> _cancelSearchFromRequests;
|
||||||
rpl::event_stream<> _changeSearchFromRequests;
|
rpl::event_stream<> _changeSearchFromRequests;
|
||||||
|
|
|
@ -129,11 +129,19 @@ struct EntryState {
|
||||||
const EntryState&) = default;
|
const EntryState&) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ChatTypeFilter : uchar {
|
||||||
|
All,
|
||||||
|
Private,
|
||||||
|
Groups,
|
||||||
|
Channels,
|
||||||
|
};
|
||||||
|
|
||||||
struct SearchState {
|
struct SearchState {
|
||||||
Key inChat;
|
Key inChat;
|
||||||
PeerData *fromPeer = nullptr;
|
PeerData *fromPeer = nullptr;
|
||||||
std::vector<Data::ReactionId> tags;
|
std::vector<Data::ReactionId> tags;
|
||||||
ChatSearchTab tab = {};
|
ChatSearchTab tab = {};
|
||||||
|
ChatTypeFilter filter = ChatTypeFilter::All;
|
||||||
QString query;
|
QString query;
|
||||||
|
|
||||||
[[nodiscard]] bool empty() const;
|
[[nodiscard]] bool empty() const;
|
||||||
|
|
|
@ -453,6 +453,15 @@ Widget::Widget(
|
||||||
copy.tab = tab;
|
copy.tab = tab;
|
||||||
applySearchState(std::move(copy));
|
applySearchState(std::move(copy));
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
_inner->changeSearchFilterRequests(
|
||||||
|
) | rpl::filter([=](ChatTypeFilter filter) {
|
||||||
|
return (_searchState.filter != filter)
|
||||||
|
&& (_searchState.tab == ChatSearchTab::MyMessages);
|
||||||
|
}) | rpl::start_with_next([=](ChatTypeFilter filter) {
|
||||||
|
auto copy = _searchState;
|
||||||
|
copy.filter = filter;
|
||||||
|
applySearchState(copy);
|
||||||
|
}, lifetime());
|
||||||
_inner->cancelSearchRequests(
|
_inner->cancelSearchRequests(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
cancelSearch({
|
cancelSearch({
|
||||||
|
@ -2201,6 +2210,7 @@ bool Widget::search(bool inCache, SearchRequestDelay delay) {
|
||||||
const auto fromPeer = searchFromPeer();
|
const auto fromPeer = searchFromPeer();
|
||||||
const auto &inTags = searchInTags();
|
const auto &inTags = searchInTags();
|
||||||
const auto tab = _searchState.tab;
|
const auto tab = _searchState.tab;
|
||||||
|
const auto filter = _searchState.filter;
|
||||||
const auto fromStartType = SearchRequestType{
|
const auto fromStartType = SearchRequestType{
|
||||||
.start = true,
|
.start = true,
|
||||||
.peer = (inPeer != nullptr),
|
.peer = (inPeer != nullptr),
|
||||||
|
@ -2232,6 +2242,7 @@ bool Widget::search(bool inCache, SearchRequestDelay delay) {
|
||||||
_searchQueryFrom = fromPeer;
|
_searchQueryFrom = fromPeer;
|
||||||
_searchQueryTags = inTags;
|
_searchQueryTags = inTags;
|
||||||
_searchQueryTab = tab;
|
_searchQueryTab = tab;
|
||||||
|
_searchQueryFilter = filter;
|
||||||
process->nextRate = 0;
|
process->nextRate = 0;
|
||||||
process->full = false;
|
process->full = false;
|
||||||
_migratedProcess.full = false;
|
_migratedProcess.full = false;
|
||||||
|
@ -2242,12 +2253,14 @@ bool Widget::search(bool inCache, SearchRequestDelay delay) {
|
||||||
} else if (_searchQuery != query
|
} else if (_searchQuery != query
|
||||||
|| _searchQueryFrom != fromPeer
|
|| _searchQueryFrom != fromPeer
|
||||||
|| _searchQueryTags != inTags
|
|| _searchQueryTags != inTags
|
||||||
|| _searchQueryTab != tab) {
|
|| _searchQueryTab != tab
|
||||||
|
|| _searchQueryFilter != filter) {
|
||||||
const auto process = currentSearchProcess();
|
const auto process = currentSearchProcess();
|
||||||
_searchQuery = query;
|
_searchQuery = query;
|
||||||
_searchQueryFrom = fromPeer;
|
_searchQueryFrom = fromPeer;
|
||||||
_searchQueryTags = inTags;
|
_searchQueryTags = inTags;
|
||||||
_searchQueryTab = tab;
|
_searchQueryTab = tab;
|
||||||
|
_searchQueryFilter = filter;
|
||||||
process->nextRate = 0;
|
process->nextRate = 0;
|
||||||
process->full = false;
|
process->full = false;
|
||||||
_migratedProcess.full = false;
|
_migratedProcess.full = false;
|
||||||
|
@ -2326,7 +2339,6 @@ bool Widget::search(bool inCache, SearchRequestDelay delay) {
|
||||||
_peerSearchQuery = peerQuery;
|
_peerSearchQuery = peerQuery;
|
||||||
_peerSearchRequest = 0;
|
_peerSearchRequest = 0;
|
||||||
peerSearchReceived(i->second, 0);
|
peerSearchReceived(i->second, 0);
|
||||||
result = true;
|
|
||||||
}
|
}
|
||||||
} else if (_peerSearchQuery != peerQuery) {
|
} else if (_peerSearchQuery != peerQuery) {
|
||||||
_peerSearchQuery = peerQuery;
|
_peerSearchQuery = peerQuery;
|
||||||
|
@ -2598,9 +2610,18 @@ void Widget::requestMessages(bool fromStart) {
|
||||||
const auto type = SearchRequestType{
|
const auto type = SearchRequestType{
|
||||||
.start = fromStart,
|
.start = fromStart,
|
||||||
};
|
};
|
||||||
const auto flags = session().settings().skipArchiveInSearch()
|
using Flag = MTPmessages_SearchGlobal::Flag;
|
||||||
? MTPmessages_SearchGlobal::Flag::f_folder_id
|
const auto flags = Flag()
|
||||||
: MTPmessages_SearchGlobal::Flag(0);
|
| (session().settings().skipArchiveInSearch()
|
||||||
|
? Flag::f_folder_id
|
||||||
|
: Flag())
|
||||||
|
| (_searchQueryFilter == ChatTypeFilter::Private
|
||||||
|
? Flag::f_users_only
|
||||||
|
: _searchQueryFilter == ChatTypeFilter::Groups
|
||||||
|
? Flag::f_groups_only
|
||||||
|
: _searchQueryFilter == ChatTypeFilter::Channels
|
||||||
|
? Flag::f_broadcasts_only
|
||||||
|
: Flag());
|
||||||
const auto folderId = 0;
|
const auto folderId = 0;
|
||||||
_searchProcess.requestId = session().api().request(
|
_searchProcess.requestId = session().api().request(
|
||||||
MTPmessages_SearchGlobal(
|
MTPmessages_SearchGlobal(
|
||||||
|
@ -3184,6 +3205,10 @@ bool Widget::applySearchState(SearchState state) {
|
||||||
const auto queryEmptyChanged = queryChanged
|
const auto queryEmptyChanged = queryChanged
|
||||||
? (_searchState.query.isEmpty() != state.query.isEmpty())
|
? (_searchState.query.isEmpty() != state.query.isEmpty())
|
||||||
: false;
|
: false;
|
||||||
|
if (queryEmptyChanged || tabChanged) {
|
||||||
|
state.filter = ChatTypeFilter::All;
|
||||||
|
}
|
||||||
|
const auto filterChanged = (_searchState.filter != state.filter);
|
||||||
|
|
||||||
if (forum) {
|
if (forum) {
|
||||||
if (_openedForum == forum) {
|
if (_openedForum == forum) {
|
||||||
|
@ -3245,6 +3270,7 @@ bool Widget::applySearchState(SearchState state) {
|
||||||
if (searchCleared
|
if (searchCleared
|
||||||
|| inChatChanged
|
|| inChatChanged
|
||||||
|| fromPeerChanged
|
|| fromPeerChanged
|
||||||
|
|| filterChanged
|
||||||
|| tagsChanged
|
|| tagsChanged
|
||||||
|| tabChanged) {
|
|| tabChanged) {
|
||||||
clearSearchCache(searchCleared);
|
clearSearchCache(searchCleared);
|
||||||
|
|
|
@ -381,6 +381,7 @@ private:
|
||||||
PeerData *_searchQueryFrom = nullptr;
|
PeerData *_searchQueryFrom = nullptr;
|
||||||
std::vector<Data::ReactionId> _searchQueryTags;
|
std::vector<Data::ReactionId> _searchQueryTags;
|
||||||
ChatSearchTab _searchQueryTab = {};
|
ChatSearchTab _searchQueryTab = {};
|
||||||
|
ChatTypeFilter _searchQueryFilter = {};
|
||||||
|
|
||||||
SearchProcessState _searchProcess;
|
SearchProcessState _searchProcess;
|
||||||
SearchProcessState _migratedProcess;
|
SearchProcessState _migratedProcess;
|
||||||
|
|
|
@ -62,6 +62,13 @@ void SearchEmpty::setup(Icon icon, rpl::producer<TextWithEntities> text) {
|
||||||
label->move((size.width() - label->width()) / 2, top - sub);
|
label->move((size.width() - label->width()) / 2, top - sub);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
label->setClickHandlerFilter([=](
|
||||||
|
const ClickHandlerPtr &handler,
|
||||||
|
Qt::MouseButton) {
|
||||||
|
_handlerActivated.fire_copy(handler);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
_animate = [animate] {
|
_animate = [animate] {
|
||||||
animate(anim::repeat::once);
|
animate(anim::repeat::once);
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,10 +29,15 @@ public:
|
||||||
|
|
||||||
void animate();
|
void animate();
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<ClickHandlerPtr> handlerActivated() const {
|
||||||
|
return _handlerActivated.events();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setup(Icon icon, rpl::producer<TextWithEntities> text);
|
void setup(Icon icon, rpl::producer<TextWithEntities> text);
|
||||||
|
|
||||||
Fn<void()> _animate;
|
Fn<void()> _animate;
|
||||||
|
rpl::event_stream<ClickHandlerPtr> _handlerActivated;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue