mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-09-05 00:46:08 +00:00
Add global search chat type filter.
This commit is contained in:
@@ -79,6 +79,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_color_indices.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "styles/style_media_player.h"
|
||||
#include "styles/style_menu_icons.h"
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
@@ -143,7 +144,8 @@ constexpr auto kPreviewPostsLimit = 3;
|
||||
|
||||
[[nodiscard]] object_ptr<SearchEmpty> MakeSearchEmpty(
|
||||
QWidget *parent,
|
||||
SearchState state) {
|
||||
SearchState state,
|
||||
Fn<void()> resetChatTypeFilter) {
|
||||
const auto query = state.query.trimmed();
|
||||
const auto hashtag = !query.isEmpty() && (query[0] == '#');
|
||||
const auto trimmed = hashtag ? query.mid(1).trimmed() : query;
|
||||
@@ -157,6 +159,9 @@ constexpr auto kPreviewPostsLimit = 3;
|
||||
const auto waiting = trimmed.isEmpty()
|
||||
&& state.tags.empty()
|
||||
&& !fromPeer;
|
||||
const auto suggestAllChats = !waiting
|
||||
&& state.tab == ChatSearchTab::MyMessages
|
||||
&& state.filter != ChatTypeFilter::All;
|
||||
const auto icon = waiting
|
||||
? SearchEmptyIcon::Search
|
||||
: SearchEmptyIcon::NoResults;
|
||||
@@ -180,7 +185,10 @@ constexpr auto kPreviewPostsLimit = 3;
|
||||
tr::now,
|
||||
lt_query,
|
||||
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(
|
||||
tr::lng_search_tab_no_results_retry(tr::now));
|
||||
}
|
||||
@@ -190,11 +198,29 @@ constexpr auto kPreviewPostsLimit = 3;
|
||||
parent,
|
||||
icon,
|
||||
rpl::single(std::move(text)));
|
||||
if (suggestAllChats) {
|
||||
result->handlerActivated(
|
||||
) | rpl::start_with_next(resetChatTypeFilter, result->lifetime());
|
||||
}
|
||||
result->show();
|
||||
result->resizeToWidth(parent->width());
|
||||
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
|
||||
|
||||
struct InnerWidget::CollapsedRow {
|
||||
@@ -1184,6 +1210,25 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||
p.setFont(st::searchedBarFont);
|
||||
p.setPen(st::searchedBarFg);
|
||||
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);
|
||||
|
||||
auto skip = searchedOffset();
|
||||
@@ -1701,6 +1746,20 @@ void InnerWidget::selectByMouse(QPoint globalPosition) {
|
||||
_searchedSelected = searchedSelected;
|
||||
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()) {
|
||||
setCursor(wasSelected ? style::cur_default : style::cur_pointer);
|
||||
@@ -1742,6 +1801,7 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) {
|
||||
setPreviewPressed(_previewSelected);
|
||||
setSearchedPressed(_searchedSelected);
|
||||
_pressedMorePosts = _selectedMorePosts;
|
||||
_pressedChatTypeFilter = _selectedChatTypeFilter;
|
||||
|
||||
const auto alt = (e->modifiers() & Qt::AltModifier);
|
||||
if (alt && showChatPreview()) {
|
||||
@@ -2139,6 +2199,8 @@ void InnerWidget::mousePressReleased(
|
||||
setSearchedPressed(-1);
|
||||
const auto pressedMorePosts = _pressedMorePosts;
|
||||
_pressedMorePosts = false;
|
||||
const auto pressedChatTypeFilter = _pressedChatTypeFilter;
|
||||
_pressedChatTypeFilter = false;
|
||||
if (wasDragging) {
|
||||
selectByMouse(globalPosition);
|
||||
}
|
||||
@@ -2163,7 +2225,9 @@ void InnerWidget::mousePressReleased(
|
||||
|| (searchedPressed >= 0
|
||||
&& searchedPressed == _searchedSelected)
|
||||
|| (pressedMorePosts
|
||||
&& pressedMorePosts == _selectedMorePosts)) {
|
||||
&& pressedMorePosts == _selectedMorePosts)
|
||||
|| (pressedChatTypeFilter
|
||||
&& pressedChatTypeFilter == _selectedChatTypeFilter)) {
|
||||
if (pressedBotApp && (pressed || filteredPressed >= 0)) {
|
||||
const auto &row = pressed
|
||||
? pressed
|
||||
@@ -2690,6 +2754,7 @@ void InnerWidget::clearSelection() {
|
||||
updateSelectedRow();
|
||||
_collapsedSelected = -1;
|
||||
_selectedMorePosts = false;
|
||||
_selectedChatTypeFilter = false;
|
||||
_selected = nullptr;
|
||||
_filteredSelected
|
||||
= _searchedSelected
|
||||
@@ -3001,6 +3066,10 @@ void InnerWidget::applySearchState(SearchState state) {
|
||||
if (state.inChat) {
|
||||
onHashtagFilterUpdate(QStringView());
|
||||
}
|
||||
if (state.filter != _searchState.filter) {
|
||||
_chatTypeFilterWidth = 0;
|
||||
update();
|
||||
}
|
||||
_searchState = std::move(state);
|
||||
_searchHashOrCashtag = IsHashOrCashtagSearchQuery(_searchState.query);
|
||||
_searchWithPostsPreview = computeSearchWithPostsPreview();
|
||||
@@ -3269,6 +3338,11 @@ rpl::producer<ChatSearchTab> InnerWidget::changeSearchTabRequests() const {
|
||||
return _changeSearchTabRequests.events();
|
||||
}
|
||||
|
||||
auto InnerWidget::changeSearchFilterRequests() const
|
||||
-> rpl::producer<ChatTypeFilter>{
|
||||
return _changeSearchFilterRequests.events();
|
||||
}
|
||||
|
||||
rpl::producer<> InnerWidget::cancelSearchRequests() const {
|
||||
return _cancelSearchRequests.events();
|
||||
}
|
||||
@@ -3557,7 +3631,9 @@ void InnerWidget::refreshEmpty() {
|
||||
}
|
||||
} else if (_searchEmptyState != _searchState) {
|
||||
_searchEmptyState = _searchState;
|
||||
_searchEmpty = MakeSearchEmpty(this, _searchState);
|
||||
_searchEmpty = MakeSearchEmpty(this, _searchState, [=] {
|
||||
_changeSearchFilterRequests.fire(ChatTypeFilter::All);
|
||||
});
|
||||
if (_controller->session().data().chatsListLoaded()) {
|
||||
_searchEmpty->animate();
|
||||
}
|
||||
@@ -4288,7 +4364,7 @@ ChosenRow InnerWidget::computeChosenRow() const {
|
||||
}
|
||||
|
||||
bool InnerWidget::isUserpicPress() const {
|
||||
return (_lastRowLocalMouseX >= 0)
|
||||
return (_lastRowLocalMouseX >= 0)
|
||||
&& (_lastRowLocalMouseX < _st->nameLeft)
|
||||
&& (_collapsedSelected < 0
|
||||
|| _collapsedSelected >= _collapsedRows.size());
|
||||
@@ -4308,6 +4384,24 @@ bool InnerWidget::chooseRow(
|
||||
_changeSearchTabRequests.fire(ChatSearchTab::PublicPosts);
|
||||
}
|
||||
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 = [&](
|
||||
ChosenRow row,
|
||||
|
Reference in New Issue
Block a user