diff --git a/Telegram/SourceFiles/history/view/history_view_send_action.cpp b/Telegram/SourceFiles/history/view/history_view_send_action.cpp index 2c9440358..e5f26dc8d 100644 --- a/Telegram/SourceFiles/history/view/history_view_send_action.cpp +++ b/Telegram/SourceFiles/history/view/history_view_send_action.cpp @@ -280,22 +280,24 @@ bool SendActionPainter::updateNeedsAnimating(crl::time now, bool force) { return QString(); }; for (const auto &[user, action] : _sendActions) { + const auto isNamed = !_history->peer->isUser(); newTypingString = sendActionString( action.type, - _history->peer->isUser() ? QString() : user->firstName); + isNamed ? user->firstName : QString()); if (!newTypingString.isEmpty()) { _sendActionAnimation.start(action.type); // Add an animation to the middle of text. - using namespace Lang; - if (GetInstance().supportChoosingStickerReplacement() + const auto &lang = Lang::GetInstance(); + if (lang.supportChoosingStickerReplacement() && (action.type == Type::ChooseSticker)) { - - const auto index = newTypingString.lastIndexOf( - Lang::kChoosingStickerReplacement.utf8()); - _animationLeft = (index == -1) - ? 0 - : _st.font->width(newTypingString, 0, index); + const auto index = newTypingString.size() + - lang.rightIndexChoosingStickerReplacement( + isNamed); + _animationLeft = _st.font->width( + newTypingString, + 0, + index); if (!_spacesCount) { _spacesCount = std::ceil( @@ -303,8 +305,10 @@ bool SendActionPainter::updateNeedsAnimating(crl::time now, bool force) { / _st.font->spacew); } newTypingString = newTypingString.replace( - Lang::kChoosingStickerReplacement.utf8(), - QString().fill(' ', _spacesCount)); + index, + Lang::kChoosingStickerReplacement.utf8().size(), + QString().fill(' ', _spacesCount).constData(), + _spacesCount); } else { _animationLeft = 0; } diff --git a/Telegram/SourceFiles/lang/lang_instance.cpp b/Telegram/SourceFiles/lang/lang_instance.cpp index 6701f8aa0..09ae28fe6 100644 --- a/Telegram/SourceFiles/lang/lang_instance.cpp +++ b/Telegram/SourceFiles/lang/lang_instance.cpp @@ -303,7 +303,7 @@ void Instance::reset(const Language &data) { _values[i] = GetOriginalValue(ushort(i)); } ranges::fill(_nonDefaultSet, 0); - updateSupportChoosingStickerReplacement(); + updateChoosingStickerReplacement(); _idChanges.fire_copy(_id); } @@ -549,7 +549,7 @@ void Instance::fillFromSerialized( applyValue(nonDefaultStrings[i], nonDefaultStrings[i + 1]); } updatePluralRules(); - updateSupportChoosingStickerReplacement(); + updateChoosingStickerReplacement(); _idChanges.fire_copy(_id); } @@ -574,7 +574,7 @@ void Instance::fillFromCustomContent( _pluralId = PluralCodeForCustom(absolutePath, relativePath); _name = _nativeName = QString(); loadFromCustomContent(absolutePath, relativePath, content); - updateSupportChoosingStickerReplacement(); + updateChoosingStickerReplacement(); _idChanges.fire_copy(_id); } @@ -605,18 +605,33 @@ bool Instance::loadFromCustomFile(const QString &filePath) { return false; } -void Instance::updateSupportChoosingStickerReplacement() { +void Instance::updateChoosingStickerReplacement() { // A language changing in the runtime is not supported. + const auto replacement = kChoosingStickerReplacement.utf8(); const auto phrase = tr::lng_send_action_choose_sticker(tr::now); - const auto first = phrase.indexOf(kChoosingStickerReplacement.utf8()); - const auto last = phrase.lastIndexOf(kChoosingStickerReplacement.utf8()); - _supportChoosingStickerReplacement = (first == last) - ? (first != -1) - : false; + const auto first = phrase.indexOf(replacement); + const auto support = (first != -1); + const auto phraseNamed = tr::lng_user_action_choose_sticker( + tr::now, + lt_user, + QString()); + const auto firstNamed = phraseNamed.indexOf(replacement); + const auto supportNamed = (firstNamed != -1); + + _choosingStickerReplacement.support = (supportNamed && support); + _choosingStickerReplacement.rightIndex = phrase.size() - first; + _choosingStickerReplacement.rightIndexNamed = phraseNamed.size() + - firstNamed; } bool Instance::supportChoosingStickerReplacement() const { - return _supportChoosingStickerReplacement; + return _choosingStickerReplacement.support; +} + +int Instance::rightIndexChoosingStickerReplacement(bool named) const { + return named + ? _choosingStickerReplacement.rightIndexNamed + : _choosingStickerReplacement.rightIndex; } // SetCallback takes two QByteArrays: key, value. diff --git a/Telegram/SourceFiles/lang/lang_instance.h b/Telegram/SourceFiles/lang/lang_instance.h index 961f17df9..db77c7db5 100644 --- a/Telegram/SourceFiles/lang/lang_instance.h +++ b/Telegram/SourceFiles/lang/lang_instance.h @@ -77,6 +77,7 @@ public: void fillFromSerialized(const QByteArray &data, int dataAppVersion); bool supportChoosingStickerReplacement() const; + int rightIndexChoosingStickerReplacement(bool named) const; void applyDifference( Pack pack, @@ -124,7 +125,7 @@ private: const QString &relativePath, const QByteArray &content); void updatePluralRules(); - void updateSupportChoosingStickerReplacement(); + void updateChoosingStickerReplacement(); Instance *_derived = nullptr; @@ -137,7 +138,11 @@ private: int _version = 0; rpl::event_stream<> _updated; - bool _supportChoosingStickerReplacement; + struct { + bool support = false; + int rightIndex = 0; + int rightIndexNamed = 0; + } _choosingStickerReplacement; mutable QString _systemLanguage;