Suggest global search of cashtags.

This commit is contained in:
John Preston 2024-06-27 16:55:19 +04:00
parent 631d6abb06
commit 09e6077e97
6 changed files with 52 additions and 28 deletions

View file

@ -2655,7 +2655,7 @@ void InnerWidget::applySearchState(SearchState state) {
onHashtagFilterUpdate(QStringView());
}
_searchState = std::move(state);
_searchingHashtag = IsHashtagSearchQuery(_searchState.query);
_searchHashOrCashtag = IsHashOrCashtagSearchQuery(_searchState.query);
updateSearchIn();
moveSearchIn();
@ -3332,7 +3332,8 @@ auto InnerWidget::searchTagsChanges() const
}
void InnerWidget::updateSearchIn() {
if (!_searchState.inChat && !_searchingHashtag) {
if (!_searchState.inChat
&& _searchHashOrCashtag == HashOrCashtag::None) {
_searchIn = nullptr;
return;
} else if (!_searchIn) {
@ -3381,7 +3382,7 @@ void InnerWidget::updateSearchIn() {
? Ui::MakeUserpicThumbnail(sublist->peer())
: nullptr;
const auto myIcon = Ui::MakeIconThumbnail(st::menuIconChats);
const auto publicIcon = _searchingHashtag
const auto publicIcon = (_searchHashOrCashtag != HashOrCashtag::None)
? Ui::MakeIconThumbnail(st::menuIconChannel)
: nullptr;
const auto peerTabType = (peer && peer->isBroadcast())

View file

@ -62,6 +62,7 @@ class IndexedList;
class SearchTags;
class SearchEmpty;
class ChatSearchIn;
enum class HashOrCashtag : uchar;
struct ChosenRow {
Key key;
@ -514,7 +515,7 @@ private:
Ui::DraggingScrollManager _draggingScroll;
SearchState _searchState;
bool _searchingHashtag = false;
HashOrCashtag _searchHashOrCashtag = {};
History *_searchInMigrated = nullptr;
PeerData *_searchFromShown = nullptr;
Ui::Text::String _searchFromUserText;

View file

@ -2125,14 +2125,14 @@ bool Widget::searchForPeersRequired(const QString &query) const {
return _searchState.filterChatsList()
&& !_openedForum
&& !query.isEmpty()
&& !IsHashtagSearchQuery(query);
&& (IsHashOrCashtagSearchQuery(query) == HashOrCashtag::None);
}
bool Widget::searchForTopicsRequired(const QString &query) const {
return _searchState.filterChatsList()
&& _openedForum
&& !query.isEmpty()
&& !IsHashtagSearchQuery(query)
&& (IsHashOrCashtagSearchQuery(query) == HashOrCashtag::None)
&& !_openedForum->topicsList()->loaded();
}
@ -2654,16 +2654,19 @@ void Widget::updateCancelSearch() {
QString Widget::validateSearchQuery() {
const auto query = currentSearchQuery();
if (_searchState.tab == ChatSearchTab::PublicPosts) {
_searchingHashtag = true;
if (_searchHashOrCashtag == HashOrCashtag::None) {
_searchHashOrCashtag = HashOrCashtag::Hashtag;
}
const auto fixed = FixHashtagSearchQuery(
query,
currentSearchQueryCursorPosition());
currentSearchQueryCursorPosition(),
_searchHashOrCashtag);
if (fixed.text != query) {
setSearchQuery(fixed.text, fixed.cursorPosition);
}
return fixed.text;
} else {
_searchingHashtag = IsHashtagSearchQuery(query);
_searchHashOrCashtag = IsHashOrCashtagSearchQuery(query);
}
return query;
}
@ -2860,11 +2863,12 @@ bool Widget::applySearchState(SearchState state) {
state.fromPeer = nullptr;
}
if (state.tab == ChatSearchTab::PublicPosts
&& !IsHashtagSearchQuery(state.query)) {
&& IsHashOrCashtagSearchQuery(state.query) == HashOrCashtag::None) {
state.tab = (_openedForum && !state.inChat)
? ChatSearchTab::ThisPeer
: ChatSearchTab::MyMessages;
} else if (!state.inChat && !_searchingHashtag) {
} else if (!state.inChat
&& _searchHashOrCashtag == HashOrCashtag::None) {
state.tab = (forum || _openedForum)
? ChatSearchTab::ThisPeer
: ChatSearchTab::MyMessages;
@ -2904,7 +2908,7 @@ bool Widget::applySearchState(SearchState state) {
&& !state.inChat
&& !_openedForum)
|| (state.tab == ChatSearchTab::PublicPosts
&& !_searchingHashtag)) {
&& _searchHashOrCashtag == HashOrCashtag::None)) {
state.tab = state.inChat.topic()
? ChatSearchTab::ThisTopic
: (state.inChat.owningHistory() || state.inChat.sublist())

View file

@ -79,6 +79,7 @@ enum class SearchRequestDelay : uchar;
class Suggestions;
class ChatSearchIn;
enum class ChatSearchTab : uchar;
enum class HashOrCashtag : uchar;
class Widget final : public Window::AbstractSectionWidget {
public:
@ -314,7 +315,7 @@ private:
object_ptr<Ui::JumpDownButton> _scrollToTop;
bool _scrollToTopIsShown = false;
bool _forumSearchRequested = false;
bool _searchingHashtag = false;
HashOrCashtag _searchHashOrCashtag = {};
Data::Folder *_openedFolder = nullptr;
Data::Forum *_openedForum = nullptr;

View file

@ -199,12 +199,14 @@ void Action::handleKeyPress(not_null<QKeyEvent*> e) {
FixedHashtagSearchQuery FixHashtagSearchQuery(
const QString &query,
int cursorPosition) {
int cursorPosition,
HashOrCashtag tag) {
const auto trimmed = query.trimmed();
const auto hash = int(trimmed.isEmpty()
? query.size()
: query.indexOf(trimmed));
const auto start = std::min(cursorPosition, hash);
const auto first = QChar(tag == HashOrCashtag::Cashtag ? '$' : '#');
auto result = query.mid(0, start);
for (const auto &ch : query.mid(start)) {
if (ch.isSpace()) {
@ -213,33 +215,41 @@ FixedHashtagSearchQuery FixHashtagSearchQuery(
}
continue;
} else if (result.size() == start) {
result += '#';
if (ch != '#') {
result += first;
if (ch != first) {
++cursorPosition;
}
}
if (ch != '#') {
if (ch != first) {
result += ch;
}
}
if (result.size() == start) {
result += '#';
result += first;
++cursorPosition;
}
return { result, cursorPosition };
}
bool IsHashtagSearchQuery(const QString &query) {
HashOrCashtag IsHashOrCashtagSearchQuery(const QString &query) {
const auto trimmed = query.trimmed();
if (trimmed.isEmpty() || trimmed[0] != '#') {
return false;
}
for (const auto &ch : trimmed) {
if (ch.isSpace()) {
return false;
const auto first = trimmed.isEmpty() ? QChar() : trimmed[0];
if (first == '#') {
for (const auto &ch : trimmed) {
if (ch.isSpace()) {
return HashOrCashtag::None;
}
}
return HashOrCashtag::Hashtag;
} else if (first == '$') {
for (const auto &ch : trimmed.midRef(1)) {
if (ch < 'A' || ch > 'Z') {
return HashOrCashtag::None;
}
}
return HashOrCashtag::Cashtag;
}
return true;
return HashOrCashtag::None;
}
void ChatSearchIn::Section::update() {

View file

@ -87,14 +87,21 @@ private:
};
enum class HashOrCashtag : uchar {
None,
Hashtag,
Cashtag,
};
struct FixedHashtagSearchQuery {
QString text;
int cursorPosition = 0;
};
[[nodiscard]] FixedHashtagSearchQuery FixHashtagSearchQuery(
const QString &query,
int cursorPosition);
int cursorPosition,
HashOrCashtag tag);
[[nodiscard]] bool IsHashtagSearchQuery(const QString &query);
[[nodiscard]] HashOrCashtag IsHashOrCashtagSearchQuery(const QString &query);
} // namespace Dialogs