From 00df4625e2c0c50210905fb4470e78a7f6153294 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 13 Oct 2022 01:34:46 +0300 Subject: [PATCH] Added support of primary username to FieldAutocomplete. --- .../chat_helpers/field_autocomplete.cpp | 34 +++++++++++-------- .../chat_helpers/field_autocomplete.h | 1 + .../SourceFiles/history/history_widget.cpp | 27 +++++++-------- Telegram/SourceFiles/history/history_widget.h | 1 - .../history_view_compose_controls.cpp | 14 ++++---- 5 files changed, 39 insertions(+), 38 deletions(-) diff --git a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp index b72e2ed36..5417dee12 100644 --- a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp +++ b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp @@ -51,6 +51,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include +[[nodiscard]] QString PrimaryUsername(not_null user) { + const auto &usernames = user->usernames(); + return usernames.empty() ? user->username() : usernames.front(); +} + class FieldAutocomplete::Inner final : public Ui::RpWidget { public: struct ScrollTo { @@ -396,9 +401,9 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) { } auto filterNotPassedByUsername = [this](UserData *user) -> bool { - if (user->username().startsWith(_filter, Qt::CaseInsensitive)) { + if (PrimaryUsername(user).startsWith(_filter, Qt::CaseInsensitive)) { const auto exactUsername = - (user->username().size() == _filter.size()); + (PrimaryUsername(user).size() == _filter.size()); return exactUsername; } return true; @@ -407,7 +412,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) { for (const auto &nameWord : user->nameWords()) { if (nameWord.startsWith(_filter, Qt::CaseInsensitive)) { const auto exactUsername = - (user->username().compare(_filter, Qt::CaseInsensitive) == 0); + (PrimaryUsername(user).compare(_filter, Qt::CaseInsensitive) == 0); return exactUsername; } } @@ -556,7 +561,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) { for (const auto &command : *i->second) { if (!listAllSuggestions) { auto toFilter = (hasUsername || botStatus == 0 || botStatus == 2) - ? command.command + '@' + user->username() + ? command.command + '@' + PrimaryUsername(user) : command.command; if (!toFilter.startsWith(_filter, Qt::CaseInsensitive)/* || toFilter.size() == _filter.size()*/) { continue; @@ -575,7 +580,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) { const auto toFilter = (hasUsername || botStatus == 0 || botStatus == 2) - ? command.command + '@' + user->username() + ? command.command + '@' + PrimaryUsername(user) : command.command; if (!toFilter.startsWith(_filter, Qt::CaseInsensitive)/* || toFilter.size() == _filter.size()*/) continue; } @@ -941,16 +946,16 @@ void FieldAutocomplete::Inner::paintEvent(QPaintEvent *e) { auto &row = _mrows->at(i); const auto user = row.user; auto first = (!filterIsEmpty - && user->username().startsWith( + && PrimaryUsername(user).startsWith( filter, Qt::CaseInsensitive)) - ? ('@' + user->username().mid(0, filterSize)) + ? ('@' + PrimaryUsername(user).mid(0, filterSize)) : QString(); auto second = first.isEmpty() - ? (user->username().isEmpty() - ? QString() - : ('@' + user->username())) - : user->username().mid(filterSize); + ? (PrimaryUsername(user).isEmpty() + ? QString() + : ('@' + PrimaryUsername(user))) + : PrimaryUsername(user).mid(filterSize); auto firstwidth = st::mentionFont->width(first); auto secondwidth = st::mentionFont->width(second); auto unamewidth = firstwidth + secondwidth; @@ -1015,7 +1020,7 @@ void FieldAutocomplete::Inner::paintEvent(QPaintEvent *e) { auto toHighlight = row.command; int32 botStatus = _parent->chat() ? _parent->chat()->botStatus : ((_parent->channel() && _parent->channel()->isMegagroup()) ? _parent->channel()->mgInfo->botStatus : -1); if (hasUsername || botStatus == 0 || botStatus == 2) { - toHighlight += '@' + user->username(); + toHighlight += '@' + PrimaryUsername(user); } user->loadUserpic(); user->paintUserpicLeft(p, row.userpic, st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), width(), st::mentionPhotoSize); @@ -1149,7 +1154,8 @@ bool FieldAutocomplete::Inner::chooseAtIndex( } } else if (!_mrows->empty()) { if (index < _mrows->size()) { - _mentionChosen.fire({ _mrows->at(index).user, method }); + const auto user = _mrows->at(index).user; + _mentionChosen.fire({ user, PrimaryUsername(user), method }); return true; } } else if (!_hrows->empty()) { @@ -1172,7 +1178,7 @@ bool FieldAutocomplete::Inner::chooseAtIndex( || _parent->filter().indexOf('@') > 0); const auto commandString = QString("/%1%2").arg( command, - insertUsername ? ('@' + user->username()) : QString()); + insertUsername ? ('@' + PrimaryUsername(user)) : QString()); _botCommandChosen.fire({ commandString, method }); return true; diff --git a/Telegram/SourceFiles/chat_helpers/field_autocomplete.h b/Telegram/SourceFiles/chat_helpers/field_autocomplete.h index 240547d98..270f59438 100644 --- a/Telegram/SourceFiles/chat_helpers/field_autocomplete.h +++ b/Telegram/SourceFiles/chat_helpers/field_autocomplete.h @@ -76,6 +76,7 @@ public: }; struct MentionChosen { not_null user; + QString mention; ChooseMethod method = ChooseMethod::ByEnter; }; struct HashtagChosen { diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 27c6c0142..68f7e1268 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -389,7 +389,18 @@ HistoryWidget::HistoryWidget( _fieldAutocomplete->mentionChosen( ) | rpl::start_with_next([=](FieldAutocomplete::MentionChosen data) { - insertMention(data.user); + auto replacement = QString(); + auto entityTag = QString(); + if (data.mention.isEmpty()) { + replacement = data.user->firstName; + if (replacement.isEmpty()) { + replacement = data.user->name(); + } + entityTag = PrepareMentionTag(data.user); + } else { + replacement = '@' + data.mention; + } + _field->insertTag(replacement, entityTag); }, lifetime()); _fieldAutocomplete->hashtagChosen( @@ -1331,20 +1342,6 @@ void HistoryWidget::start() { session().data().stickers().notifySavedGifsUpdated(); } -void HistoryWidget::insertMention(UserData *user) { - QString replacement, entityTag; - if (user->username().isEmpty()) { - replacement = user->firstName; - if (replacement.isEmpty()) { - replacement = user->name(); - } - entityTag = PrepareMentionTag(user); - } else { - replacement = '@' + user->username(); - } - _field->insertTag(replacement, entityTag); -} - void HistoryWidget::insertHashtagOrBotCommand( QString str, FieldAutocomplete::ChooseMethod method) { diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 1c1a6876b..625bb1f0d 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -348,7 +348,6 @@ private: void insertHashtagOrBotCommand( QString str, FieldAutocomplete::ChooseMethod method); - void insertMention(UserData *user); void cancelInlineBot(); void saveDraft(bool delayed = false); void saveCloudDraft(); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index 3411eaab5..b0ac36507 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -1496,19 +1496,17 @@ void ComposeControls::initAutocomplete() { _field->insertTag(string); } }; - const auto insertMention = [=](not_null user) { - if (user->username().isEmpty()) { + + _autocomplete->mentionChosen( + ) | rpl::start_with_next([=](FieldAutocomplete::MentionChosen data) { + const auto user = data.user; + if (data.mention.isEmpty()) { _field->insertTag( user->firstName.isEmpty() ? user->name() : user->firstName, PrepareMentionTag(user)); } else { - _field->insertTag('@' + user->username()); + _field->insertTag('@' + data.mention); } - }; - - _autocomplete->mentionChosen( - ) | rpl::start_with_next([=](FieldAutocomplete::MentionChosen data) { - insertMention(data.user); }, _autocomplete->lifetime()); _autocomplete->hashtagChosen(