diff --git a/CHANGELOG.md b/CHANGELOG.md index 182d67839..a8553d9b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,7 @@ - Bugfix: Fixed avatar in usercard and moderation button triggering when releasing the mouse outside their area. (#5052) - Bugfix: Fixed moderator-only topics being subscribed to for non-moderators. (#5056) - Bugfix: Fixed a bug where buttons would remain in a hovered state after leaving them. (#5077) +- Bugfix: Fixed an issue where you had to click the `reply` button twice if you already had that users @ in your input box. (#5173) - Bugfix: Fixed popup windows not persisting between restarts. (#5081) - Bugfix: Fixed splits not retaining their focus after minimizing. (#5080) - Bugfix: Fixed _Copy message_ copying the channel name in global search. (#5106) diff --git a/src/widgets/splits/SplitInput.cpp b/src/widgets/splits/SplitInput.cpp index 81707a066..d53b4bad9 100644 --- a/src/widgets/splits/SplitInput.cpp +++ b/src/widgets/splits/SplitInput.cpp @@ -1113,16 +1113,32 @@ void SplitInput::setReply(MessagePtr reply, bool showReplyingLabel) // Only enable reply label if inline replying auto replyPrefix = "@" + this->replyThread_->displayName; auto plainText = this->ui_.textEdit->toPlainText().trimmed(); - if (!plainText.startsWith(replyPrefix)) + + // This makes it so if plainText contains "@StreamerFan" and + // we are replying to "@Streamer" we don't just leave "Fan" + // in the text box + if (plainText.startsWith(replyPrefix)) { - if (!plainText.isEmpty()) + if (plainText.length() > replyPrefix.length()) { - replyPrefix.append(' '); + if (plainText.at(replyPrefix.length()) == ',' || + plainText.at(replyPrefix.length()) == ' ') + { + plainText.remove(0, replyPrefix.length() + 1); + } + } + else + { + plainText.remove(0, replyPrefix.length()); } - this->ui_.textEdit->setPlainText(replyPrefix + plainText + " "); - this->ui_.textEdit->moveCursor(QTextCursor::EndOfBlock); - this->ui_.textEdit->resetCompletion(); } + if (!plainText.isEmpty() && !plainText.startsWith(' ')) + { + replyPrefix.append(' '); + } + this->ui_.textEdit->setPlainText(replyPrefix + plainText + " "); + this->ui_.textEdit->moveCursor(QTextCursor::EndOfBlock); + this->ui_.textEdit->resetCompletion(); this->ui_.replyLabel->setText("Replying to @" + this->replyThread_->displayName); } diff --git a/tests/src/SplitInput.cpp b/tests/src/SplitInput.cpp index 8f5667bde..5d542f735 100644 --- a/tests/src/SplitInput.cpp +++ b/tests/src/SplitInput.cpp @@ -76,10 +76,11 @@ public: Emotes emotes; }; -class SplitInputFixture : public ::testing::Test +class SplitInputTest + : public ::testing::TestWithParam> { -protected: - SplitInputFixture() +public: + SplitInputTest() : split(new Split(nullptr)) , input(this->split) { @@ -92,18 +93,79 @@ protected: } // namespace -TEST_F(SplitInputFixture, Reply) +TEST_P(SplitInputTest, Reply) { + std::tuple params = this->GetParam(); + auto [inputText, expected] = params; ASSERT_EQ("", this->input.getInputText()); - this->input.setInputText("forsen"); - ASSERT_EQ("forsen", this->input.getInputText()); + this->input.setInputText(inputText); + ASSERT_EQ(inputText, this->input.getInputText()); + auto *message = new Message(); - message->displayName = "xd"; + message->displayName = "forsen"; auto reply = MessagePtr(message); this->input.setReply(reply); - QString expected("@xd forsen "); QString actual = this->input.getInputText(); ASSERT_EQ(expected, actual) << "Input text after setReply should be '" << qUtf8Printable(expected) << "', but got '" << qUtf8Printable(actual) << "'"; } + +INSTANTIATE_TEST_SUITE_P( + SplitInput, SplitInputTest, + testing::Values( + // Ensure message is retained + std::make_tuple( + // Pre-existing text in the input + "Test message", + // Expected text after replying to forsen + "@forsen Test message "), + + // Ensure mention is stripped, no message + std::make_tuple( + // Pre-existing text in the input + "@forsen", + // Expected text after replying to forsen + "@forsen "), + + // Ensure mention with space is stripped, no message + std::make_tuple( + // Pre-existing text in the input + "@forsen ", + // Expected text after replying to forsen + "@forsen "), + + // Ensure mention is stripped, retain message + std::make_tuple( + // Pre-existing text in the input + "@forsen Test message", + // Expected text after replying to forsen + "@forsen Test message "), + + // Ensure mention with comma is stripped, no message + std::make_tuple( + // Pre-existing text in the input + "@forsen,", + // Expected text after replying to forsen + "@forsen "), + + // Ensure mention with comma is stripped, retain message + std::make_tuple( + // Pre-existing text in the input + "@forsen Test message", + // Expected text after replying to forsen + "@forsen Test message "), + + // Ensure mention with comma and space is stripped, no message + std::make_tuple( + // Pre-existing text in the input + "@forsen, ", + // Expected text after replying to forsen + "@forsen "), + + // Ensure it works with no message + std::make_tuple( + // Pre-existing text in the input + "", + // Expected text after replying to forsen + "@forsen ")));