diff --git a/internal/text/common.go b/internal/text/common.go
index a3ec15e46b..d57e577543 100644
--- a/internal/text/common.go
+++ b/internal/text/common.go
@@ -90,26 +90,38 @@ func (f *formatter) ReplaceTags(ctx context.Context, in string, tags []*gtsmodel
}
func (f *formatter) ReplaceMentions(ctx context.Context, in string, mentions []*gtsmodel.Mention) string {
- for _, menchie := range mentions {
- // make sure we have a target account, either by getting one pinned on the mention,
- // or by pulling it from the database
- var targetAccount *gtsmodel.Account
- if menchie.OriginAccount != nil {
- // got it from the mention
- targetAccount = menchie.OriginAccount
- } else {
- a, err := f.db.GetAccountByID(ctx, menchie.TargetAccountID)
- if err == nil {
- // got it from the db
- targetAccount = a
- } else {
- // couldn't get it so we can't do replacement
- return in
+ return regexes.MentionFinder.ReplaceAllStringFunc(in, func(match string) string {
+ // we have a match
+ matchTrimmed := strings.TrimSpace(match)
+ // check through mentions to find what we're matching
+ for _, menchie := range mentions {
+ if strings.EqualFold(matchTrimmed, menchie.NameString) {
+ // make sure we have an account attached to this mention
+ if menchie.TargetAccount == nil {
+ a, err := f.db.GetAccountByID(ctx, menchie.TargetAccountID)
+ if err != nil {
+ f.log.Errorf("error getting account with id %s from the db: %s", menchie.TargetAccountID, err)
+ return match
+ }
+ menchie.TargetAccount = a
+ }
+ targetAccount := menchie.TargetAccount
+
+ // replace the mention with the formatted mention content
+ mentionContent := fmt.Sprintf(`@%s`, targetAccount.URL, targetAccount.Username)
+
+ // in case the match picked up any previous space or newlines (thanks to the regex), include them as well
+ if strings.HasPrefix(match, " ") {
+ mentionContent = " " + mentionContent
+ } else if strings.HasPrefix(match, "\n") {
+ mentionContent = "\n" + mentionContent
+ }
+
+ // done
+ return mentionContent
}
}
-
- mentionContent := fmt.Sprintf(`@%s`, targetAccount.URL, targetAccount.Username)
- in = strings.ReplaceAll(in, menchie.NameString, mentionContent)
- }
- return in
+ // the match wasn't in the list of mentions for whatever reason, so just return the match as we found it so nothing changes
+ return match
+ })
}
diff --git a/internal/text/common_test.go b/internal/text/common_test.go
index 174b791771..6d21a07191 100644
--- a/internal/text/common_test.go
+++ b/internal/text/common_test.go
@@ -21,8 +21,8 @@ package text_test
import (
"context"
"testing"
+ "time"
- "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/text"
@@ -52,6 +52,22 @@ Text`
#Hashtag
Text`
+
+ replaceMentionsWithLinkString = `Another test @foss_satan@fossbros-anonymous.io
+
+https://fossbros-anonymous.io/@foss_satan/statuses/6675ee73-fccc-4562-a46a-3e8cd9798060`
+
+ replaceMentionsWithLinkStringExpected = `Another test @foss_satan
+
+https://fossbros-anonymous.io/@foss_satan/statuses/6675ee73-fccc-4562-a46a-3e8cd9798060`
+
+ replaceMentionsWithLinkSelfString = `Mentioning myself: @the_mighty_zork
+
+and linking to my own status: https://localhost:8080/@the_mighty_zork/statuses/01FGXKJRX2PMERJQ9EQF8Y6HCR`
+
+ replaceMemtionsWithLinkSelfExpected = `Mentioning myself: @the_mighty_zork
+
+and linking to my own status: https://localhost:8080/@the_mighty_zork/statuses/01FGXKJRX2PMERJQ9EQF8Y6HCR`
)
type CommonTestSuite struct {
@@ -89,7 +105,7 @@ func (suite *CommonTestSuite) TestReplaceMentions() {
}
f := suite.formatter.ReplaceMentions(context.Background(), replaceMentionsString, foundMentions)
- assert.Equal(suite.T(), replaceMentionsExpected, f)
+ suite.Equal(replaceMentionsExpected, f)
}
func (suite *CommonTestSuite) TestReplaceHashtags() {
@@ -99,7 +115,7 @@ func (suite *CommonTestSuite) TestReplaceHashtags() {
f := suite.formatter.ReplaceTags(context.Background(), replaceMentionsString, foundTags)
- assert.Equal(suite.T(), replaceHashtagsExpected, f)
+ suite.Equal(replaceHashtagsExpected, f)
}
func (suite *CommonTestSuite) TestReplaceHashtagsAfterReplaceMentions() {
@@ -109,7 +125,37 @@ func (suite *CommonTestSuite) TestReplaceHashtagsAfterReplaceMentions() {
f := suite.formatter.ReplaceTags(context.Background(), replaceMentionsExpected, foundTags)
- assert.Equal(suite.T(), replaceHashtagsAfterMentionsExpected, f)
+ suite.Equal(replaceHashtagsAfterMentionsExpected, f)
+}
+
+func (suite *CommonTestSuite) TestReplaceMentionsWithLink() {
+ foundMentions := []*gtsmodel.Mention{
+ suite.testMentions["zork_mention_foss_satan"],
+ }
+
+ f := suite.formatter.ReplaceMentions(context.Background(), replaceMentionsWithLinkString, foundMentions)
+ suite.Equal(replaceMentionsWithLinkStringExpected, f)
+}
+
+func (suite *CommonTestSuite) TestReplaceMentionsWithLinkSelf() {
+ mentioningAccount := suite.testAccounts["local_account_1"]
+
+ foundMentions := []*gtsmodel.Mention{
+ {
+ ID: "01FGXKN5F815DVFVD53PN9NYM6",
+ CreatedAt: time.Now(),
+ UpdatedAt: time.Now(),
+ StatusID: "01FGXKP0S5THQXFC1D9R141DDR",
+ OriginAccountID: mentioningAccount.ID,
+ TargetAccountID: mentioningAccount.ID,
+ NameString: "@the_mighty_zork",
+ TargetAccountURI: mentioningAccount.URI,
+ TargetAccountURL: mentioningAccount.URL,
+ },
+ }
+
+ f := suite.formatter.ReplaceMentions(context.Background(), replaceMentionsWithLinkSelfString, foundMentions)
+ suite.Equal(replaceMemtionsWithLinkSelfExpected, f)
}
func TestCommonTestSuite(t *testing.T) {