mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Fix some bugs in new chats search.
This commit is contained in:
parent
dd5643ac67
commit
6a8edefc87
6 changed files with 188 additions and 231 deletions
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "dialogs/dialogs_inner_widget.h"
|
||||
|
||||
#include "dialogs/dialogs_three_state_icon.h"
|
||||
#include "dialogs/ui/chat_search_tabs.h"
|
||||
#include "dialogs/ui/dialogs_layout.h"
|
||||
#include "dialogs/ui/dialogs_stories_content.h"
|
||||
#include "dialogs/ui/dialogs_video_userpic.h"
|
||||
|
@ -747,6 +748,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
p.fillRect(dialogsClip, currentBg());
|
||||
}
|
||||
} else if (_state == WidgetState::Filtered) {
|
||||
auto top = 0;
|
||||
if (!_hashtagResults.empty()) {
|
||||
auto from = floorclamp(r.y(), st::mentionHeight, 0, _hashtagResults.size());
|
||||
auto to = ceilclamp(r.y() + r.height(), st::mentionHeight, 0, _hashtagResults.size());
|
||||
|
@ -791,6 +793,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
p.drawText(htagleft + firstwidth, st::mentionTop + st::mentionFont->ascent, second);
|
||||
}
|
||||
p.translate(0, st::mentionHeight);
|
||||
top += st::mentionHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -800,7 +803,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
auto to = std::min(
|
||||
filteredIndex(r.y() + r.height() - skip) + 1,
|
||||
int(_filterResults.size()));
|
||||
p.translate(0, filteredHeight(from));
|
||||
const auto height = filteredHeight(from);
|
||||
p.translate(0, height);
|
||||
top += height;
|
||||
for (; from < to; ++from) {
|
||||
const auto selected = isPressed()
|
||||
? (from == _filteredPressed)
|
||||
|
@ -808,6 +813,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
const auto row = _filterResults[from].row;
|
||||
paintRow(row, selected, !activeEntry.fullId);
|
||||
p.translate(0, row->height());
|
||||
top += row->height();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -817,11 +823,13 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
p.setPen(st::searchedBarFg);
|
||||
p.drawTextLeft(st::searchedBarPosition.x(), st::searchedBarPosition.y(), width(), tr::lng_search_global_results(tr::now));
|
||||
p.translate(0, st::searchedBarHeight);
|
||||
top += st::searchedBarHeight;
|
||||
|
||||
auto skip = peerSearchOffset();
|
||||
auto from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _peerSearchResults.size());
|
||||
auto to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _peerSearchResults.size());
|
||||
p.translate(0, from * st::dialogsRowHeight);
|
||||
top += from * st::dialogsRowHeight;
|
||||
if (from < _peerSearchResults.size()) {
|
||||
const auto activePeer = activeEntry.key.peer();
|
||||
for (; from < to; ++from) {
|
||||
|
@ -844,6 +852,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
.paused = videoPaused,
|
||||
});
|
||||
p.translate(0, st::dialogsRowHeight);
|
||||
top += st::dialogsRowHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -857,29 +866,15 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
.paused = videoPaused,
|
||||
});
|
||||
p.translate(0, searchInChatSkip());
|
||||
if (_waitingForSearch && _searchResults.empty()) {
|
||||
p.fillRect(
|
||||
0,
|
||||
0,
|
||||
fullWidth,
|
||||
st::searchedBarHeight,
|
||||
st::searchedBarBg);
|
||||
p.setFont(st::searchedBarFont);
|
||||
p.setPen(st::searchedBarFg);
|
||||
p.drawTextLeft(
|
||||
st::searchedBarPosition.x(),
|
||||
st::searchedBarPosition.y(),
|
||||
width(),
|
||||
tr::lng_dlg_search_for_messages(tr::now));
|
||||
p.translate(0, st::searchedBarHeight);
|
||||
top += searchInChatSkip();
|
||||
if (_searchResults.empty()) {
|
||||
p.fillRect(0, 0, fullWidth, st::lineWidth, st::shadowFg);
|
||||
}
|
||||
}
|
||||
|
||||
const auto showUnreadInSearchResults = uniqueSearchResults();
|
||||
if (!_waitingForSearch || !_searchResults.empty()) {
|
||||
const auto text = _searchResults.empty()
|
||||
? tr::lng_search_no_results(tr::now)
|
||||
: showUnreadInSearchResults
|
||||
if (!_searchResults.empty()) {
|
||||
const auto text = showUnreadInSearchResults
|
||||
? u"Search results"_q
|
||||
: tr::lng_search_found_results(
|
||||
tr::now,
|
||||
|
@ -890,11 +885,13 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
p.setPen(st::searchedBarFg);
|
||||
p.drawTextLeft(st::searchedBarPosition.x(), st::searchedBarPosition.y(), width(), text);
|
||||
p.translate(0, st::searchedBarHeight);
|
||||
top += st::searchedBarHeight;
|
||||
|
||||
auto skip = searchedOffset();
|
||||
auto from = floorclamp(r.y() - skip, _st->height, 0, _searchResults.size());
|
||||
auto to = ceilclamp(r.y() + r.height() - skip, _st->height, 0, _searchResults.size());
|
||||
p.translate(0, from * _st->height);
|
||||
top += from * _st->height;
|
||||
if (from < _searchResults.size()) {
|
||||
for (; from < to; ++from) {
|
||||
const auto &result = _searchResults[from];
|
||||
|
@ -920,6 +917,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
.displayUnreadInfo = showUnreadInSearchResults,
|
||||
});
|
||||
p.translate(0, _st->height);
|
||||
top += _st->height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1127,10 +1125,11 @@ void InnerWidget::paintSearchInChat(
|
|||
auto top = 0;
|
||||
if (_searchTags) {
|
||||
const auto height = _searchTags->height();
|
||||
top += st::dialogsSearchTagBottom;
|
||||
p.fillRect(0, top, width(), height, currentBg());
|
||||
const auto position = QPoint(_searchTagsLeft, 0);
|
||||
const auto position = QPoint(_searchTagsLeft, top);
|
||||
_searchTags->paint(p, position, context.now, context.paused);
|
||||
top += height;
|
||||
top += height - st::dialogsSearchTagBottom;
|
||||
}
|
||||
p.setFont(st::searchedBarFont);
|
||||
auto fullRect = QRect(0, top, width(), height - top);
|
||||
|
@ -1279,7 +1278,9 @@ void InnerWidget::selectByMouse(QPoint globalPosition) {
|
|||
_lastMousePosition = globalPosition;
|
||||
_lastRowLocalMouseX = local.x();
|
||||
|
||||
const auto tagBase = QPoint(_searchTagsLeft, searchInChatOffset());
|
||||
const auto tagBase = QPoint(
|
||||
_searchTagsLeft,
|
||||
searchInChatOffset() + st::dialogsSearchTagBottom);
|
||||
const auto tagPoint = local - tagBase;
|
||||
const auto inTags = _searchTags
|
||||
&& QRect(
|
||||
|
@ -1895,7 +1896,7 @@ void InnerWidget::moveCancelSearchButtons() {
|
|||
st::columnMinimalWidthLeft - _narrowWidth);
|
||||
const auto left = widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchFromUser->width();
|
||||
const auto top = (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2;
|
||||
const auto skip = st::searchedBarHeight + (_searchTags ? _searchTags->height() : 0);
|
||||
const auto skip = (_searchTags ? _searchTags->height() : 0);
|
||||
_cancelSearchFromUser->moveToLeft(left, skip + top);
|
||||
}
|
||||
|
||||
|
@ -2460,6 +2461,74 @@ void InnerWidget::applySearchState(SearchState state) {
|
|||
withSameQuery.query = _searchState.query;
|
||||
const auto otherChanged = (_searchState != withSameQuery);
|
||||
|
||||
const auto ignoreInChat = (state.tab == ChatSearchTab::MyMessages)
|
||||
|| (state.tab == ChatSearchTab::PublicPosts);
|
||||
const auto sublist = ignoreInChat ? nullptr : state.inChat.sublist();
|
||||
const auto peer = ignoreInChat
|
||||
? nullptr
|
||||
: sublist
|
||||
? session().user().get()
|
||||
: state.inChat.peer();
|
||||
if (const auto migrateFrom = peer ? peer->migrateFrom() : nullptr) {
|
||||
_searchInMigrated = peer->owner().history(migrateFrom);
|
||||
} else {
|
||||
_searchInMigrated = nullptr;
|
||||
}
|
||||
if (peer && peer->isSelf()) {
|
||||
const auto reactions = &peer->owner().reactions();
|
||||
_searchTags = std::make_unique<SearchTags>(
|
||||
&peer->owner(),
|
||||
reactions->myTagsValue(sublist),
|
||||
state.tags);
|
||||
|
||||
_searchTags->selectedChanges(
|
||||
) | rpl::start_with_next([=](std::vector<Data::ReactionId> &&list) {
|
||||
_searchState.tags = std::move(list);
|
||||
}, _searchTags->lifetime());
|
||||
|
||||
_searchTags->repaintRequests() | rpl::start_with_next([=] {
|
||||
const auto height = _searchTags->height();
|
||||
update(0, searchInChatOffset(), width(), height);
|
||||
}, _searchTags->lifetime());
|
||||
|
||||
_searchTags->menuRequests(
|
||||
) | rpl::start_with_next([=](Data::ReactionId id) {
|
||||
HistoryView::ShowTagInListMenu(
|
||||
&_menu,
|
||||
_lastMousePosition.value_or(QCursor::pos()),
|
||||
this,
|
||||
id,
|
||||
_controller);
|
||||
}, _searchTags->lifetime());
|
||||
|
||||
_searchTags->heightValue() | rpl::skip(
|
||||
1
|
||||
) | rpl::start_with_next([=] {
|
||||
refresh();
|
||||
moveCancelSearchButtons();
|
||||
}, _searchTags->lifetime());
|
||||
} else {
|
||||
_searchTags = nullptr;
|
||||
state.tags.clear();
|
||||
}
|
||||
_searchFromShown = ignoreInChat
|
||||
? nullptr
|
||||
: sublist
|
||||
? sublist->peer().get()
|
||||
: state.fromPeer;
|
||||
if (state.inChat) {
|
||||
onHashtagFilterUpdate(QStringView());
|
||||
}
|
||||
if (_searchFromShown) {
|
||||
_cancelSearchFromUser->show();
|
||||
_searchFromUserUserpic = _searchFromShown->createUserpicView();
|
||||
} else {
|
||||
_cancelSearchFromUser->hide();
|
||||
_searchFromUserUserpic = {};
|
||||
}
|
||||
refreshSearchInChatLabel();
|
||||
moveCancelSearchButtons();
|
||||
|
||||
_searchState = std::move(state);
|
||||
auto newFilter = _searchState.query;
|
||||
const auto mentionsSearch = (newFilter == u"@"_q);
|
||||
|
@ -2569,7 +2638,9 @@ InnerWidget::~InnerWidget() {
|
|||
}
|
||||
|
||||
void InnerWidget::clearSearchResults(bool clearPeerSearchResults) {
|
||||
if (clearPeerSearchResults) _peerSearchResults.clear();
|
||||
if (clearPeerSearchResults) {
|
||||
_peerSearchResults.clear();
|
||||
}
|
||||
_searchResults.clear();
|
||||
_searchResultsLifetime.destroy();
|
||||
_searchResultsHistories.clear();
|
||||
|
@ -2807,7 +2878,8 @@ void InnerWidget::searchReceived(
|
|||
SearchRequestType type,
|
||||
int fullCount) {
|
||||
const auto uniquePeers = uniqueSearchResults();
|
||||
if (type == SearchRequestType::FromStart || type == SearchRequestType::PeerFromStart) {
|
||||
if (type == SearchRequestType::FromStart
|
||||
|| type == SearchRequestType::PeerFromStart) {
|
||||
clearSearchResults(false);
|
||||
}
|
||||
const auto isMigratedSearch = (type == SearchRequestType::MigratedFromStart)
|
||||
|
@ -3066,81 +3138,6 @@ bool InnerWidget::hasFilteredResults() const {
|
|||
return !_filterResults.empty() && _hashtagResults.empty();
|
||||
}
|
||||
|
||||
void InnerWidget::searchInChat(
|
||||
Key key,
|
||||
PeerData *from,
|
||||
std::vector<Data::ReactionId> tags) {
|
||||
_searchInMigrated = nullptr;
|
||||
const auto sublist = key.sublist();
|
||||
const auto peer = sublist ? session().user().get() : key.peer();
|
||||
if (peer) {
|
||||
if (const auto migrateTo = peer->migrateTo()) {
|
||||
const auto to = peer->owner().history(migrateTo);
|
||||
return searchInChat(to, from, tags);
|
||||
} else if (const auto migrateFrom = peer->migrateFrom()) {
|
||||
_searchInMigrated = peer->owner().history(migrateFrom);
|
||||
}
|
||||
|
||||
if (peer->isSelf()) {
|
||||
const auto reactions = &peer->owner().reactions();
|
||||
_searchTags = std::make_unique<SearchTags>(
|
||||
&peer->owner(),
|
||||
reactions->myTagsValue(sublist),
|
||||
tags);
|
||||
|
||||
_searchTags->selectedChanges(
|
||||
) | rpl::start_with_next([=](std::vector<Data::ReactionId> &&list) {
|
||||
_searchState.tags = std::move(list);
|
||||
}, _searchTags->lifetime());
|
||||
|
||||
_searchTags->repaintRequests() | rpl::start_with_next([=] {
|
||||
const auto height = _searchTags->height();
|
||||
update(0, searchInChatOffset(), width(), height);
|
||||
}, _searchTags->lifetime());
|
||||
|
||||
_searchTags->menuRequests(
|
||||
) | rpl::start_with_next([=](Data::ReactionId id) {
|
||||
HistoryView::ShowTagInListMenu(
|
||||
&_menu,
|
||||
_lastMousePosition.value_or(QCursor::pos()),
|
||||
this,
|
||||
id,
|
||||
_controller);
|
||||
}, _searchTags->lifetime());
|
||||
|
||||
_searchTags->heightValue() | rpl::skip(
|
||||
1
|
||||
) | rpl::start_with_next([=] {
|
||||
refresh();
|
||||
moveCancelSearchButtons();
|
||||
}, _searchTags->lifetime());
|
||||
} else {
|
||||
_searchTags = nullptr;
|
||||
_searchState.tags.clear();
|
||||
}
|
||||
} else {
|
||||
_searchTags = nullptr;
|
||||
_searchState.tags.clear();
|
||||
}
|
||||
_searchState.inChat = key;
|
||||
_searchState.fromPeer = from;
|
||||
_searchFromShown = key.sublist() ? key.sublist()->peer().get() : from;
|
||||
if (_searchState.inChat) {
|
||||
onHashtagFilterUpdate(QStringView());
|
||||
}
|
||||
if (_searchFromShown) {
|
||||
_cancelSearchFromUser->show();
|
||||
_searchFromUserUserpic = _searchFromShown->createUserpicView();
|
||||
} else {
|
||||
_cancelSearchFromUser->hide();
|
||||
_searchFromUserUserpic = {};
|
||||
}
|
||||
if (_searchState.inChat || _searchState.fromPeer) {
|
||||
refreshSearchInChatLabel();
|
||||
}
|
||||
moveCancelSearchButtons();
|
||||
}
|
||||
|
||||
auto InnerWidget::searchTagsChanges() const
|
||||
-> rpl::producer<std::vector<Data::ReactionId>> {
|
||||
return _searchTags
|
||||
|
|
|
@ -146,10 +146,6 @@ public:
|
|||
[[nodiscard]] bool hasFilteredResults() const;
|
||||
|
||||
void applySearchState(SearchState state);
|
||||
void searchInChat(
|
||||
Key key,
|
||||
PeerData *from,
|
||||
std::vector<Data::ReactionId> tags);
|
||||
[[nodiscard]] auto searchTagsChanges() const
|
||||
-> rpl::producer<std::vector<Data::ReactionId>>;
|
||||
|
||||
|
@ -386,6 +382,7 @@ private:
|
|||
const Ui::Text::String &text) const;
|
||||
void refreshSearchInChatLabel();
|
||||
void repaintSearchResult(int index);
|
||||
void paintEmpty(QPainter &p, int top);
|
||||
|
||||
Ui::VideoUserpic *validateVideoUserpic(not_null<Row*> row);
|
||||
Ui::VideoUserpic *validateVideoUserpic(not_null<History*> history);
|
||||
|
|
|
@ -375,7 +375,7 @@ Widget::Widget(
|
|||
|
||||
_search->changes(
|
||||
) | rpl::start_with_next([=] {
|
||||
applySearchUpdate();
|
||||
crl::on_main(this, [=] { applySearchUpdate(); });
|
||||
}, _search->lifetime());
|
||||
|
||||
_search->submits(
|
||||
|
@ -524,7 +524,7 @@ Widget::Widget(
|
|||
void Widget::chosenRow(const ChosenRow &row) {
|
||||
storiesToggleExplicitExpand(false);
|
||||
|
||||
if (!currentSearchQuery().isEmpty()) {
|
||||
if (!_searchState.query.isEmpty()) {
|
||||
if (const auto history = row.key.history()) {
|
||||
session().recentPeers().bump(history->peer);
|
||||
}
|
||||
|
@ -1240,6 +1240,7 @@ void Widget::updateSearchTabs() {
|
|||
applySearchState(std::move(copy));
|
||||
}, _searchTabs->lifetime());
|
||||
}
|
||||
const auto sublist = _searchState.inChat.sublist();
|
||||
const auto topic = _searchState.inChat.topic();
|
||||
const auto peer = _searchState.inChat.owningHistory()
|
||||
? _searchState.inChat.owningHistory()->peer.get()
|
||||
|
@ -1258,6 +1259,10 @@ void Widget::updateSearchTabs() {
|
|||
? Ui::Text::SingleCustomEmoji(
|
||||
session().data().customEmojiManager().peerUserpicEmojiData(
|
||||
peer))
|
||||
: sublist
|
||||
? Ui::Text::SingleCustomEmoji(
|
||||
session().data().customEmojiManager().peerUserpicEmojiData(
|
||||
sublist->peer()))
|
||||
: TextWithEntities();
|
||||
const auto myShortLabel = DefaultShortLabel(ChatSearchTab::MyMessages);
|
||||
const auto publicShortLabel = _searchingHashtag
|
||||
|
@ -1275,12 +1280,17 @@ void Widget::updateSearchTabs() {
|
|||
? ChatSearchTab::ThisPeer
|
||||
: ChatSearchTab::MyMessages;
|
||||
}
|
||||
const auto peerTabType = (peer && peer->isBroadcast())
|
||||
? ChatSearchPeerTabType::Channel
|
||||
: (peer && (peer->isChat() || peer->isMegagroup()))
|
||||
? ChatSearchPeerTabType::Group
|
||||
: ChatSearchPeerTabType::Chat;
|
||||
_searchTabs->setTabShortLabels({
|
||||
{ ChatSearchTab::ThisTopic, topicShortLabel },
|
||||
{ ChatSearchTab::ThisPeer, peerShortLabel },
|
||||
{ ChatSearchTab::MyMessages, myShortLabel },
|
||||
{ ChatSearchTab::PublicPosts, publicShortLabel },
|
||||
}, _searchState.tab);
|
||||
}, _searchState.tab, peerTabType);
|
||||
|
||||
updateControlsGeometry();
|
||||
}
|
||||
|
@ -1611,7 +1621,7 @@ void Widget::jumpToTop(bool belowPinned) {
|
|||
if (session().supportMode()) {
|
||||
return;
|
||||
}
|
||||
if ((currentSearchQuery().trimmed().isEmpty() && !_searchState.inChat)) {
|
||||
if ((_searchState.query.trimmed().isEmpty() && !_searchState.inChat)) {
|
||||
auto to = 0;
|
||||
if (belowPinned) {
|
||||
const auto list = _openedForum
|
||||
|
@ -1749,7 +1759,7 @@ void Widget::updateStoriesVisibility() {
|
|||
|| _childList
|
||||
|| _searchHasFocus
|
||||
|| _searchSuggestionsLocked
|
||||
|| !currentSearchQuery().isEmpty()
|
||||
|| !_searchState.query.isEmpty()
|
||||
|| _searchState.inChat
|
||||
|| _stories->empty();
|
||||
if (_stories->isHidden() != hidden) {
|
||||
|
@ -1952,16 +1962,22 @@ void Widget::loadMoreBlockedByDate() {
|
|||
|
||||
bool Widget::search(bool inCache) {
|
||||
auto result = false;
|
||||
const auto query = currentSearchQuery().trimmed();
|
||||
const auto query = _searchState.query.trimmed();
|
||||
const auto inPeer = searchInPeer();
|
||||
const auto fromPeer = searchFromPeer();
|
||||
const auto &inTags = searchInTags();
|
||||
const auto tab = _searchState.tab;
|
||||
const auto fromStartType = inPeer
|
||||
? SearchRequestType::PeerFromStart
|
||||
: SearchRequestType::FromStart;
|
||||
const auto skipRequest = (query.isEmpty() && !fromPeer && inTags.empty())
|
||||
|| (tab == ChatSearchTab::PublicPosts && query.size() < 2);
|
||||
if (skipRequest) {
|
||||
cancelSearchRequest();
|
||||
searchApplyEmpty(fromStartType, 0);
|
||||
_api.request(base::take(_peerSearchRequest)).cancel();
|
||||
_peerSearchQuery = QString();
|
||||
peerSearchApplyEmpty(0);
|
||||
_api.request(base::take(_topicSearchRequest)).cancel();
|
||||
return true;
|
||||
} else if (inCache) {
|
||||
|
@ -1981,9 +1997,7 @@ bool Widget::search(bool inCache) {
|
|||
_searchFull = _searchFullMigrated = false;
|
||||
cancelSearchRequest();
|
||||
searchReceived(
|
||||
(inPeer
|
||||
? SearchRequestType::PeerFromStart
|
||||
: SearchRequestType::FromStart),
|
||||
fromStartType,
|
||||
i->second,
|
||||
0);
|
||||
result = true;
|
||||
|
@ -2109,21 +2123,14 @@ bool Widget::search(bool inCache) {
|
|||
)).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) {
|
||||
peerSearchReceived(result, requestId);
|
||||
}).fail([=](const MTP::Error &error, mtpRequestId requestId) {
|
||||
peopleFailed(error, requestId);
|
||||
peerSearchFailed(error, requestId);
|
||||
}).send();
|
||||
_peerSearchQueries.emplace(_peerSearchRequest, _peerSearchQuery);
|
||||
}
|
||||
} else {
|
||||
_api.request(base::take(_peerSearchRequest)).cancel();
|
||||
_peerSearchQuery = peerQuery;
|
||||
_peerSearchFull = true;
|
||||
peerSearchReceived(
|
||||
MTP_contacts_found(
|
||||
MTP_vector<MTPPeer>(0),
|
||||
MTP_vector<MTPPeer>(0),
|
||||
MTP_vector<MTPChat>(0),
|
||||
MTP_vector<MTPUser>(0)),
|
||||
0);
|
||||
peerSearchApplyEmpty(0);
|
||||
}
|
||||
if (searchForTopicsRequired(peerQuery)) {
|
||||
if (inCache) {
|
||||
|
@ -2170,64 +2177,7 @@ void Widget::showMainMenu() {
|
|||
|
||||
void Widget::searchMessages(SearchState state) {
|
||||
applySearchState(std::move(state));
|
||||
session().local().saveRecentSearchHashtags(state.query);
|
||||
//if (_childList) {
|
||||
// const auto forum = controller()->shownForum().current();
|
||||
// const auto topic = inChat.topic();
|
||||
// if ((forum && forum->channel() == inChat.peer())
|
||||
// || (topic && topic->forum() == forum)) {
|
||||
// _childList->searchMessages(query, inChat);
|
||||
// return;
|
||||
// }
|
||||
// hideChildList();
|
||||
//}
|
||||
//if (_openedFolder) {
|
||||
// controller()->closeFolder();
|
||||
//}
|
||||
|
||||
//auto tags = Data::SearchTagsFromQuery(query);
|
||||
//if (!tags.empty()) {
|
||||
// if (!inChat.sublist()) {
|
||||
// inChat = session().data().history(session().user());
|
||||
// }
|
||||
// query = QString();
|
||||
//}
|
||||
//const auto inChatChanged = [&] {
|
||||
// const auto inPeer = inChat.peer();
|
||||
// const auto inTopic = inChat.topic();
|
||||
// if (!inTopic
|
||||
// && _openedForum
|
||||
// && inPeer == _openedForum->channel()
|
||||
// && _subsectionTopBar
|
||||
// && _subsectionTopBar->searchMode()) {
|
||||
// return false;
|
||||
// } else if ((inTopic || (inPeer && !inPeer->isForum()))
|
||||
// && (inChat == _searchState.inChat)) {
|
||||
// return false;
|
||||
// } else if (inPeer) {
|
||||
// if (const auto to = inPeer->migrateTo()) {
|
||||
// if (to == _searchState.inChat.peer()
|
||||
// && !_searchState.inChat.topic()) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
//}();
|
||||
//if ((currentSearchQuery() != query)
|
||||
// || inChatChanged
|
||||
// || _searchState.tags != tags) {
|
||||
// if (inChat) {
|
||||
// cancelSearch();
|
||||
// setSearchInChat(inChat, nullptr, tags);
|
||||
// }
|
||||
// setSearchQuery(query);
|
||||
// applySearchUpdate(true);
|
||||
// _searchTimer.cancel();
|
||||
// searchMessages();
|
||||
|
||||
// session().local().saveRecentSearchHashtags(query);
|
||||
//}
|
||||
session().local().saveRecentSearchHashtags(_searchState.query);
|
||||
}
|
||||
|
||||
void Widget::searchTopics() {
|
||||
|
@ -2574,18 +2524,34 @@ void Widget::peerSearchReceived(
|
|||
}
|
||||
}
|
||||
|
||||
void Widget::searchApplyEmpty(SearchRequestType type, mtpRequestId id) {
|
||||
_searchFull = _searchFullMigrated = true;
|
||||
searchReceived(
|
||||
type,
|
||||
MTP_messages_messages(
|
||||
MTP_vector<MTPMessage>(),
|
||||
MTP_vector<MTPChat>(),
|
||||
MTP_vector<MTPUser>()),
|
||||
id);
|
||||
}
|
||||
|
||||
void Widget::peerSearchApplyEmpty(mtpRequestId id) {
|
||||
_peerSearchFull = true;
|
||||
peerSearchReceived(
|
||||
MTP_contacts_found(
|
||||
MTP_vector<MTPPeer>(0),
|
||||
MTP_vector<MTPPeer>(0),
|
||||
MTP_vector<MTPChat>(0),
|
||||
MTP_vector<MTPUser>(0)),
|
||||
id);
|
||||
}
|
||||
|
||||
void Widget::searchFailed(
|
||||
SearchRequestType type,
|
||||
const MTP::Error &error,
|
||||
mtpRequestId requestId) {
|
||||
if (error.type() == u"SEARCH_QUERY_EMPTY"_q) {
|
||||
searchReceived(
|
||||
type,
|
||||
MTP_messages_messages(
|
||||
MTP_vector<MTPMessage>(),
|
||||
MTP_vector<MTPChat>(),
|
||||
MTP_vector<MTPUser>()),
|
||||
requestId);
|
||||
searchApplyEmpty(type, requestId);
|
||||
} else if (_searchRequest == requestId) {
|
||||
_searchRequest = 0;
|
||||
if (type == SearchRequestType::MigratedFromStart || type == SearchRequestType::MigratedFromOffset) {
|
||||
|
@ -2596,8 +2562,8 @@ void Widget::searchFailed(
|
|||
}
|
||||
}
|
||||
|
||||
void Widget::peopleFailed(const MTP::Error &error, mtpRequestId requestId) {
|
||||
if (_peerSearchRequest == requestId) {
|
||||
void Widget::peerSearchFailed(const MTP::Error &error, mtpRequestId id) {
|
||||
if (_peerSearchRequest == id) {
|
||||
_peerSearchRequest = 0;
|
||||
_peerSearchFull = true;
|
||||
}
|
||||
|
@ -2702,40 +2668,33 @@ void Widget::listScrollUpdated() {
|
|||
}
|
||||
|
||||
void Widget::updateCancelSearch() {
|
||||
const auto shown = !_search->getLastText().isEmpty()
|
||||
const auto shown = !_searchState.query.isEmpty()
|
||||
|| (!_searchState.inChat
|
||||
&& (_searchHasFocus || _searchSuggestionsLocked));
|
||||
_cancelSearch->toggle(shown, anim::type::normal);
|
||||
}
|
||||
|
||||
bool Widget::fixSearchQuery() {
|
||||
if (_fixingSearchQuery) {
|
||||
return false;
|
||||
}
|
||||
_fixingSearchQuery = true;
|
||||
QString Widget::validateSearchQuery() {
|
||||
const auto query = currentSearchQuery();
|
||||
if (_searchState.tab == ChatSearchTab::PublicPosts) {
|
||||
_searchingHashtag = true;
|
||||
const auto fixed = FixHashtagSearchQuery(
|
||||
query,
|
||||
currentSearchQueryCursorPosition());
|
||||
if (fixed.text != query) {
|
||||
setSearchQuery(fixed.text, fixed.cursorPosition);
|
||||
}
|
||||
_searchingHashtag = true;
|
||||
return fixed.text;
|
||||
} else if (_searchingHashtag != IsHashtagSearchQuery(query)) {
|
||||
_searchingHashtag = !_searchingHashtag;
|
||||
updateSearchTabs();
|
||||
}
|
||||
_fixingSearchQuery = false;
|
||||
return true;
|
||||
return query;
|
||||
}
|
||||
|
||||
void Widget::applySearchUpdate() {
|
||||
if (!fixSearchQuery()) {
|
||||
return;
|
||||
}
|
||||
auto copy = _searchState;
|
||||
copy.query = currentSearchQuery();
|
||||
copy.query = validateSearchQuery();
|
||||
applySearchState(std::move(copy));
|
||||
|
||||
if (_chooseFromUser->toggled()
|
||||
|
@ -2755,7 +2714,7 @@ void Widget::updateForceDisplayWide() {
|
|||
controller()->setChatsForceDisplayWide(_searchHasFocus
|
||||
|| (_subsectionTopBar && _subsectionTopBar->searchHasFocus())
|
||||
|| _searchSuggestionsLocked
|
||||
|| !currentSearchQuery().isEmpty()
|
||||
|| !_searchState.query.isEmpty()
|
||||
|| _searchState.inChat);
|
||||
}
|
||||
|
||||
|
@ -2961,12 +2920,10 @@ bool Widget::applySearchState(SearchState state) {
|
|||
updateSearchTabs();
|
||||
}
|
||||
if (queryChanged || inChatChanged) {
|
||||
updateJumpToDateVisibility();
|
||||
updateStoriesVisibility();
|
||||
}
|
||||
if (fromPeerChanged) {
|
||||
updateSearchFromVisibility();
|
||||
}
|
||||
updateJumpToDateVisibility();
|
||||
updateSearchFromVisibility();
|
||||
updateLockUnlockPosition();
|
||||
|
||||
if ((state.query.isEmpty() && !state.fromPeer && state.tags.empty())
|
||||
|
@ -2988,6 +2945,7 @@ bool Widget::applySearchState(SearchState state) {
|
|||
controller()->closeFolder();
|
||||
}
|
||||
|
||||
setSearchQuery(_searchState.query);
|
||||
_inner->applySearchState(_searchState);
|
||||
|
||||
if (!_postponeProcessSearchFocusChange) {
|
||||
|
@ -3009,7 +2967,7 @@ bool Widget::applySearchState(SearchState state) {
|
|||
&& _lastSearchText == HistoryView::SwitchToChooseFromQuery()) {
|
||||
cancelSearch();
|
||||
}
|
||||
if (_searchState.inChat || !_search->getLastText().isEmpty()) {
|
||||
if (_searchState.inChat || !_searchState.query.isEmpty()) {
|
||||
_search->setFocus();
|
||||
} else {
|
||||
setInnerFocus();
|
||||
|
@ -3138,7 +3096,7 @@ void Widget::updateLockUnlockVisibility(anim::type animated) {
|
|||
|| _searchHasFocus
|
||||
|| _searchSuggestionsLocked
|
||||
|| _searchState.inChat
|
||||
|| !_search->getLastText().isEmpty();
|
||||
|| !_searchState.query.isEmpty();
|
||||
if (_lockUnlock->toggled() == hidden) {
|
||||
const auto stories = _stories && !_stories->empty();
|
||||
_lockUnlock->toggle(
|
||||
|
@ -3157,7 +3115,7 @@ void Widget::updateLoadMoreChatsVisibility() {
|
|||
}
|
||||
const auto hidden = (_openedFolder != nullptr)
|
||||
|| (_openedForum != nullptr)
|
||||
|| !currentSearchQuery().isEmpty();
|
||||
|| !_searchState.query.isEmpty();
|
||||
if (_loadMoreChats->isHidden() != hidden) {
|
||||
_loadMoreChats->setVisible(!hidden);
|
||||
updateControlsGeometry();
|
||||
|
@ -3170,7 +3128,7 @@ void Widget::updateJumpToDateVisibility(bool fast) {
|
|||
}
|
||||
|
||||
_jumpToDate->toggle(
|
||||
(_searchState.inChat && _search->getLastText().isEmpty()),
|
||||
(searchInPeer() && _searchState.query.isEmpty()),
|
||||
fast ? anim::type::instant : anim::type::normal);
|
||||
}
|
||||
|
||||
|
@ -3617,6 +3575,10 @@ void Widget::clearSearchField() {
|
|||
}
|
||||
|
||||
void Widget::setSearchQuery(const QString &query, int cursorPosition) {
|
||||
if (query.isEmpty()) {
|
||||
clearSearchField();
|
||||
return;
|
||||
}
|
||||
if (cursorPosition < 0) {
|
||||
cursorPosition = query.size();
|
||||
}
|
||||
|
@ -3666,7 +3628,6 @@ bool Widget::cancelSearch() {
|
|||
_lastSearchPeer = nullptr;
|
||||
_lastSearchId = _lastSearchMigratedId = 0;
|
||||
_inner->clearFilter();
|
||||
clearSearchField();
|
||||
applySearchState(std::move(updatedState));
|
||||
if (_suggestions && clearSearchFocus) {
|
||||
setInnerFocus(true);
|
||||
|
|
|
@ -232,7 +232,7 @@ private:
|
|||
|
||||
void fullSearchRefreshOn(rpl::producer<> events);
|
||||
void updateCancelSearch();
|
||||
bool fixSearchQuery();
|
||||
[[nodiscard]] QString validateSearchQuery();
|
||||
void applySearchUpdate();
|
||||
void refreshLoadMoreButton(bool mayBlock, bool isBlocked);
|
||||
void loadMoreBlockedByDate();
|
||||
|
@ -241,7 +241,9 @@ private:
|
|||
SearchRequestType type,
|
||||
const MTP::Error &error,
|
||||
mtpRequestId requestId);
|
||||
void peopleFailed(const MTP::Error &error, mtpRequestId requestId);
|
||||
void peerSearchFailed(const MTP::Error &error, mtpRequestId requestId);
|
||||
void searchApplyEmpty(SearchRequestType type, mtpRequestId id);
|
||||
void peerSearchApplyEmpty(mtpRequestId id);
|
||||
|
||||
void updateForceDisplayWide();
|
||||
void scrollToDefault(bool verytop = false);
|
||||
|
@ -307,7 +309,6 @@ private:
|
|||
object_ptr<Ui::JumpDownButton> _scrollToTop;
|
||||
bool _scrollToTopIsShown = false;
|
||||
bool _forumSearchRequested = false;
|
||||
bool _fixingSearchQuery = false;
|
||||
bool _searchingHashtag = false;
|
||||
|
||||
Data::Folder *_openedFolder = nullptr;
|
||||
|
|
|
@ -77,6 +77,10 @@ FixedHashtagSearchQuery FixHashtagSearchQuery(
|
|||
result += ch;
|
||||
}
|
||||
}
|
||||
if (result.size() == start) {
|
||||
result += '#';
|
||||
++cursorPosition;
|
||||
}
|
||||
return { result, cursorPosition };
|
||||
}
|
||||
|
||||
|
@ -123,23 +127,17 @@ ChatSearchTabs::ChatSearchTabs(QWidget *parent, ChatSearchTab active)
|
|||
|
||||
ChatSearchTabs::~ChatSearchTabs() = default;
|
||||
|
||||
void ChatSearchTabs::setPeerTabType(ChatSearchPeerTabType type) {
|
||||
_type = type;
|
||||
const auto i = ranges::find(_list, ChatSearchTab::ThisPeer, &Tab::value);
|
||||
Assert(i != end(_list));
|
||||
i->label = TabLabel(ChatSearchTab::ThisPeer, type);
|
||||
if (!i->shortLabel.empty()) {
|
||||
refreshTabs(_active.current());
|
||||
}
|
||||
}
|
||||
|
||||
void ChatSearchTabs::setTabShortLabels(
|
||||
std::vector<ShortLabel> labels,
|
||||
ChatSearchTab active) {
|
||||
ChatSearchTab active,
|
||||
ChatSearchPeerTabType peerTabType) {
|
||||
for (const auto &label : labels) {
|
||||
const auto i = ranges::find(_list, label.tab, &Tab::value);
|
||||
Assert(i != end(_list));
|
||||
i->shortLabel = std::move(label.label);
|
||||
if (i->value == ChatSearchTab::ThisPeer) {
|
||||
i->label = TabLabel(label.tab, peerTabType);
|
||||
}
|
||||
}
|
||||
refreshTabs(active);
|
||||
}
|
||||
|
@ -175,4 +173,8 @@ int ChatSearchTabs::resizeGetHeight(int newWidth) {
|
|||
return _tabs->height();
|
||||
}
|
||||
|
||||
void ChatSearchTabs::paintEvent(QPaintEvent *e) {
|
||||
QPainter(this).fillRect(e->rect(), st::dialogsBg);
|
||||
}
|
||||
|
||||
} // namespace Dialogs
|
|
@ -37,8 +37,6 @@ public:
|
|||
ChatSearchTabs(QWidget *parent, ChatSearchTab active);
|
||||
~ChatSearchTabs();
|
||||
|
||||
void setPeerTabType(ChatSearchPeerTabType type);
|
||||
|
||||
// A [custom] emoji to use when there is not enough space for text.
|
||||
// Only tabs with available short labels are shown.
|
||||
struct ShortLabel {
|
||||
|
@ -47,7 +45,8 @@ public:
|
|||
};
|
||||
void setTabShortLabels(
|
||||
std::vector<ShortLabel> labels,
|
||||
ChatSearchTab active);
|
||||
ChatSearchTab active,
|
||||
ChatSearchPeerTabType peerTabType);
|
||||
|
||||
[[nodiscard]] rpl::producer<ChatSearchTab> tabChanges() const;
|
||||
|
||||
|
@ -60,13 +59,13 @@ private:
|
|||
|
||||
void refreshTabs(ChatSearchTab active);
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
const std::unique_ptr<Ui::SettingsSlider> _tabs;
|
||||
const std::unique_ptr<Ui::PlainShadow> _shadow;
|
||||
|
||||
std::vector<Tab> _list;
|
||||
rpl::variable<ChatSearchTab> _active;
|
||||
ChatSearchPeerTabType _type = {};
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue