Support hashtags with mentions.

This commit is contained in:
John Preston 2024-10-11 09:31:03 +04:00
parent f89aeb6ad4
commit 7ee2e3d8bc
6 changed files with 42 additions and 1 deletions

View file

@ -40,6 +40,25 @@ std::vector<ReactionId> SearchTagsFromQuery(
return result;
}
HashtagWithUsername HashtagWithUsernameFromQuery(QStringView query) {
const auto match = TextUtilities::RegExpHashtag(true).match(query);
if (match.hasMatch()) {
const auto username = match.capturedView(2).mid(1).toString();
const auto offset = int(match.capturedLength(1));
const auto full = int(query.size());
const auto length = full
- int(username.size())
- 1
- offset
- int(match.capturedLength(3));
if (!username.isEmpty() && length > 0 && offset + length <= full) {
const auto hashtag = query.mid(offset, length).toString();
return { hashtag, username };
}
}
return {};
}
QString ReactionEntityData(const ReactionId &id) {
if (id.empty()) {
return {};

View file

@ -65,6 +65,13 @@ struct MessageReaction {
[[nodiscard]] std::vector<ReactionId> SearchTagsFromQuery(
const QString &query);
struct HashtagWithUsername {
QString hashtag;
QString username;
};
[[nodiscard]] HashtagWithUsername HashtagWithUsernameFromQuery(
QStringView query);
[[nodiscard]] QString ReactionEntityData(const ReactionId &id);
[[nodiscard]] ReactionId ReactionFromMTP(const MTPReaction &reaction);

View file

@ -43,6 +43,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_history_hider.h"
#include "window/window_controller.h"
#include "window/window_peer_menu.h"
#include "window/window_session_controller_link_info.h"
#include "window/themes/window_theme.h"
#include "chat_helpers/bot_command.h"
#include "chat_helpers/tabbed_selector.h" // TabbedSelector::refreshStickers
@ -744,6 +745,15 @@ void MainWidget::hideSingleUseKeyboard(FullMsgId replyToId) {
}
void MainWidget::searchMessages(const QString &query, Dialogs::Key inChat) {
const auto complex = Data::HashtagWithUsernameFromQuery(query);
if (!complex.username.isEmpty()) {
_controller->showPeerByLink(Window::PeerByLinkInfo{
.usernameOrId = complex.username,
.text = complex.hashtag,
.resolveType = Window::ResolveType::HashtagSearch,
});
return;
}
auto tags = Data::SearchTagsFromQuery(query);
if (_dialogs) {
auto state = Dialogs::SearchState{

View file

@ -2722,7 +2722,9 @@ std::optional<RecentHashtagPack> Account::saveRecentHashtags(
auto found = false;
auto m = QRegularExpressionMatch();
auto recent = getPack();
for (auto i = 0, next = 0; (m = TextUtilities::RegExpHashtag(false).match(text, i)).hasMatch(); i = next) {
for (auto i = 0, next = 0
; (m = TextUtilities::RegExpHashtag(false).match(text, i)).hasMatch()
; i = next) {
i = m.capturedStart();
next = m.capturedEnd();
if (m.hasMatch()) {

View file

@ -580,6 +580,8 @@ void SessionNavigation::showPeerByLinkResolved(
params);
} else if (resolveType == ResolveType::Profile) {
showPeerInfo(peer, params);
} else if (resolveType == ResolveType::HashtagSearch) {
searchMessages(info.text, peer->owner().history(peer));
} else if (peer->isForum() && resolveType != ResolveType::Boost) {
const auto itemId = info.messageId;
if (!itemId) {

View file

@ -19,6 +19,7 @@ enum class ResolveType {
BotStart,
AddToGroup,
AddToChannel,
HashtagSearch,
ShareGame,
Mention,
Boost,