Improve/mention input segments (#3631)
* improve calculate input segments relate to mention feature * bump version * rename variable
This commit is contained in:
parent
1eb92a19a2
commit
0fcf3abd83
|
@ -309,12 +309,16 @@ func (m *MentionManager) OnChangeText(chatID, fullText string) (*ChatMentionCont
|
||||||
ctx.MentionState.End = diff.end
|
ctx.MentionState.End = diff.end
|
||||||
ctx.MentionState.operation = diff.operation
|
ctx.MentionState.operation = diff.operation
|
||||||
|
|
||||||
ctx.MentionState.AtIdxs = calcAtIdxs(ctx.MentionState)
|
atIndexes, err := calculateAtIndexEntries(ctx.MentionState)
|
||||||
|
if err != nil {
|
||||||
|
return ctx, err
|
||||||
|
}
|
||||||
|
ctx.MentionState.AtIdxs = atIndexes
|
||||||
m.logger.Debug("OnChangeText", zap.String("chatID", chatID), zap.Any("state", ctx.MentionState))
|
m.logger.Debug("OnChangeText", zap.String("chatID", chatID), zap.Any("state", ctx.MentionState))
|
||||||
return m.calculateSuggestions(chatID, fullText)
|
return m.calculateSuggestions(chatID, fullText)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MentionManager) recheckAtIdxs(chatID string, text string, publicKey string) (*ChatMentionContext, error) {
|
func (m *MentionManager) recheckAtIdxs(chatID string, fullText string, publicKey string) (*ChatMentionContext, error) {
|
||||||
user, err := m.mentionableUserGetter.getMentionableUser(chatID, publicKey)
|
user, err := m.mentionableUserGetter.getMentionableUser(chatID, publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -322,8 +326,12 @@ func (m *MentionManager) recheckAtIdxs(chatID string, text string, publicKey str
|
||||||
ctx := m.getChatMentionContext(chatID)
|
ctx := m.getChatMentionContext(chatID)
|
||||||
state := ctx.MentionState
|
state := ctx.MentionState
|
||||||
mentionableUsers := map[string]*MentionableUser{user.ID: user}
|
mentionableUsers := map[string]*MentionableUser{user.ID: user}
|
||||||
newAtIdxs := checkIdxForMentions(text, state.AtIdxs, mentionableUsers)
|
newAtIdxs := checkIdxForMentions(fullText, state.AtIdxs, mentionableUsers)
|
||||||
ctx.InputSegments = calculateInput(text, newAtIdxs)
|
inputSegments, success := calculateInput(fullText, newAtIdxs)
|
||||||
|
if !success {
|
||||||
|
m.logger.Warn("recheckAtIdxs: calculateInput failed", zap.String("chatID", chatID), zap.String("fullText", fullText), zap.Any("state", ctx.MentionState))
|
||||||
|
}
|
||||||
|
ctx.InputSegments = inputSegments
|
||||||
state.AtIdxs = newAtIdxs
|
state.AtIdxs = newAtIdxs
|
||||||
return ctx, nil
|
return ctx, nil
|
||||||
}
|
}
|
||||||
|
@ -357,7 +365,10 @@ func (m *MentionManager) calculateSuggestionsWithMentionableUsers(chatID string,
|
||||||
}
|
}
|
||||||
|
|
||||||
newAtIndexEntries := checkIdxForMentions(fullText, state.AtIdxs, mentionableUsers)
|
newAtIndexEntries := checkIdxForMentions(fullText, state.AtIdxs, mentionableUsers)
|
||||||
calculatedInput := calculateInput(fullText, newAtIndexEntries)
|
calculatedInput, success := calculateInput(fullText, newAtIndexEntries)
|
||||||
|
if !success {
|
||||||
|
m.logger.Warn("calculateSuggestionsWithMentionableUsers: calculateInput failed", zap.String("chatID", chatID), zap.String("fullText", fullText), zap.Any("state", state))
|
||||||
|
}
|
||||||
|
|
||||||
var end int
|
var end int
|
||||||
switch state.operation {
|
switch state.operation {
|
||||||
|
@ -704,6 +715,9 @@ func hasMatchingPrefix(text, searchedText string) bool {
|
||||||
func isMentioned(user *MentionableUser, text string) bool {
|
func isMentioned(user *MentionableUser, text string) bool {
|
||||||
regexStr := ""
|
regexStr := ""
|
||||||
for i, name := range user.names() {
|
for i, name := range user.names() {
|
||||||
|
if name == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
name = strings.ToLower(name)
|
name = strings.ToLower(name)
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
regexStr += "|"
|
regexStr += "|"
|
||||||
|
@ -738,6 +752,7 @@ func matchMention(text string, users map[string]*MentionableUser, mentionKeyIdx
|
||||||
return nil
|
return nil
|
||||||
case userSuggestionsCnt == 1:
|
case userSuggestionsCnt == 1:
|
||||||
user := getFirstUser(userSuggestions)
|
user := getFirstUser(userSuggestions)
|
||||||
|
// maybe len(users) == 1 and user input `@` so we need to recheck if the user is really mentioned
|
||||||
if isMentioned(user, string(tr[mentionKeyIdx+1:])) {
|
if isMentioned(user, string(tr[mentionKeyIdx+1:])) {
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
@ -839,55 +854,59 @@ func (e *AtIndexEntry) String() string {
|
||||||
return fmt.Sprintf("{From: %d, To: %d, Checked: %t, Mentioned: %t, NextAtIdx: %d}", e.From, e.To, e.Checked, e.Mentioned, e.NextAtIdx)
|
return fmt.Sprintf("{From: %d, To: %d, Checked: %t, Mentioned: %t, NextAtIdx: %d}", e.From, e.To, e.Checked, e.Mentioned, e.NextAtIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// implementation reference: https://github.com/status-im/status-react/blob/04d0252e013d9c67862e77a3467dd32c3abde934/src/status_im/chat/models/mentions.cljs#L433
|
func calculateAtIndexEntries(state *MentionState) ([]*AtIndexEntry, error) {
|
||||||
func calcAtIdxs(state *MentionState) []*AtIndexEntry {
|
var keptAtIndexEntries []*AtIndexEntry
|
||||||
|
var oldRunes []rune
|
||||||
|
var newRunes []rune
|
||||||
|
var previousRunes = []rune(state.PreviousText)
|
||||||
|
switch state.operation {
|
||||||
|
case textOperationAdd:
|
||||||
|
newRunes = []rune(state.NewText)
|
||||||
|
case textOperationDelete:
|
||||||
|
oldRunes = previousRunes[state.Start : state.End+1]
|
||||||
|
case textOperationReplace:
|
||||||
|
oldRunes = previousRunes[state.Start : state.End+1]
|
||||||
|
newRunes = []rune(state.NewText)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown text operation: %d", state.operation)
|
||||||
|
}
|
||||||
|
|
||||||
|
oldLen := len(oldRunes)
|
||||||
|
newLen := len(newRunes)
|
||||||
|
diff := newLen - oldLen
|
||||||
|
oldAtSignIndexes := getAtSignIdxs(string(oldRunes), state.Start)
|
||||||
newAtSignIndexes := getAtSignIdxs(state.NewText, state.Start)
|
newAtSignIndexes := getAtSignIdxs(state.NewText, state.Start)
|
||||||
newAtSignIndexesCount := len(newAtSignIndexes)
|
for _, entry := range state.AtIdxs {
|
||||||
if len(state.AtIdxs) == 0 {
|
deleted := false
|
||||||
result := make([]*AtIndexEntry, newAtSignIndexesCount)
|
for _, idx := range oldAtSignIndexes {
|
||||||
for i, idx := range newAtSignIndexes {
|
if idx == entry.From {
|
||||||
result[i] = &AtIndexEntry{
|
deleted = true
|
||||||
From: idx,
|
|
||||||
Checked: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
if !deleted {
|
||||||
}
|
if entry.From >= state.Start { // update range with diff
|
||||||
|
entry.From += diff
|
||||||
newTextLen := len([]rune(state.NewText))
|
entry.To += diff
|
||||||
oldTextLen := len([]rune(state.PreviousText))
|
}
|
||||||
oldEnd := state.Start + oldTextLen
|
if entry.From < state.Start && entry.To >= state.Start { // impacted after user edit so need to be rechecked
|
||||||
diff := newTextLen - oldTextLen
|
entry.Checked = false
|
||||||
var keptAtIdxs []*AtIndexEntry
|
}
|
||||||
for _, entry := range state.AtIdxs {
|
keptAtIndexEntries = append(keptAtIndexEntries, entry)
|
||||||
from := entry.From
|
|
||||||
to := entry.To
|
|
||||||
toPlus1 := to + 1
|
|
||||||
if from >= oldEnd {
|
|
||||||
entry.From = from + diff
|
|
||||||
entry.To = to + diff
|
|
||||||
keptAtIdxs = append(keptAtIdxs, entry)
|
|
||||||
} else if from < state.Start && toPlus1 < state.Start {
|
|
||||||
// NOTE: (not to+1) means is not checked yet, but (not to+1) seems always false, so we ignore it here temporarily
|
|
||||||
// https://github.com/status-im/status-mobile/blob/04d0252e013d9c67862e77a3467dd32c3abde934/src/status_im/chat/models/mentions.cljs#L454
|
|
||||||
keptAtIdxs = append(keptAtIdxs, entry)
|
|
||||||
} else if from < state.Start && toPlus1 >= state.Start {
|
|
||||||
keptAtIdxs = append(keptAtIdxs, &AtIndexEntry{
|
|
||||||
From: from,
|
|
||||||
Checked: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return addNewAtSignIndexes(keptAtIndexEntries, newAtSignIndexes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func addNewAtSignIndexes(keptAtIdxs []*AtIndexEntry, newAtSignIndexes []int) []*AtIndexEntry {
|
||||||
var newAtIndexEntries []*AtIndexEntry
|
var newAtIndexEntries []*AtIndexEntry
|
||||||
var added bool
|
var added bool
|
||||||
var lastNewIdx *int
|
var lastNewIdx int
|
||||||
|
newAtSignIndexesCount := len(newAtSignIndexes)
|
||||||
if newAtSignIndexesCount > 0 {
|
if newAtSignIndexesCount > 0 {
|
||||||
idx := newAtSignIndexes[newAtSignIndexesCount-1]
|
lastNewIdx = newAtSignIndexes[newAtSignIndexesCount-1]
|
||||||
lastNewIdx = &idx
|
|
||||||
}
|
}
|
||||||
for _, entry := range keptAtIdxs {
|
for _, entry := range keptAtIdxs {
|
||||||
if lastNewIdx != nil && entry.From > *lastNewIdx && !added {
|
if newAtSignIndexesCount > 0 && !added && entry.From > lastNewIdx {
|
||||||
newAtIndexEntries = append(newAtIndexEntries, makeAtIdxs(newAtSignIndexes)...)
|
newAtIndexEntries = append(newAtIndexEntries, makeAtIdxs(newAtSignIndexes)...)
|
||||||
newAtIndexEntries = append(newAtIndexEntries, entry)
|
newAtIndexEntries = append(newAtIndexEntries, entry)
|
||||||
added = true
|
added = true
|
||||||
|
@ -933,7 +952,7 @@ func checkAtIndexEntry(fullText string, entry *AtIndexEntry, mentionableUsers ma
|
||||||
if entry.Checked {
|
if entry.Checked {
|
||||||
return entry
|
return entry
|
||||||
}
|
}
|
||||||
result := MatchMention(fullText+charAtSign, mentionableUsers, entry.From)
|
result := MatchMention(fullText, mentionableUsers, entry.From)
|
||||||
if result != nil && result.Match != "" {
|
if result != nil && result.Match != "" {
|
||||||
return &AtIndexEntry{
|
return &AtIndexEntry{
|
||||||
From: entry.From,
|
From: entry.From,
|
||||||
|
@ -977,37 +996,52 @@ func checkIdxForMentions(fullText string, currentAtIndexEntries []*AtIndexEntry,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func calculateInput(text string, idxs []*AtIndexEntry) []InputSegment {
|
func appendInputSegment(result *[]InputSegment, typ SegmentType, value string, fullText *string) {
|
||||||
if len(idxs) == 0 {
|
if value != "" {
|
||||||
return []InputSegment{{Type: Text, Value: text}}
|
*result = append(*result, InputSegment{Type: typ, Value: value})
|
||||||
|
*fullText += value
|
||||||
}
|
}
|
||||||
idxCount := len(idxs)
|
}
|
||||||
lastFrom := idxs[idxCount-1].From
|
|
||||||
|
func calculateInput(text string, atIndexEntries []*AtIndexEntry) ([]InputSegment, bool) {
|
||||||
|
if len(atIndexEntries) == 0 {
|
||||||
|
return []InputSegment{{Type: Text, Value: text}}, true
|
||||||
|
}
|
||||||
|
idxCount := len(atIndexEntries)
|
||||||
|
lastFrom := atIndexEntries[idxCount-1].From
|
||||||
|
|
||||||
var result []InputSegment
|
var result []InputSegment
|
||||||
|
fullText := ""
|
||||||
if idxs[0].From != 0 {
|
if atIndexEntries[0].From != 0 {
|
||||||
result = append(result, InputSegment{Type: Text, Value: subs(text, 0, idxs[0].From)})
|
t := subs(text, 0, atIndexEntries[0].From)
|
||||||
|
appendInputSegment(&result, Text, t, &fullText)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, entry := range idxs {
|
for _, entry := range atIndexEntries {
|
||||||
from := entry.From
|
from := entry.From
|
||||||
to := entry.To
|
to := entry.To
|
||||||
nextAtIdx := entry.NextAtIdx
|
nextAtIdx := entry.NextAtIdx
|
||||||
mentioned := entry.Mentioned
|
mentioned := entry.Mentioned
|
||||||
|
|
||||||
if mentioned && nextAtIdx != intUnknown {
|
if mentioned && nextAtIdx != intUnknown {
|
||||||
result = append(result, InputSegment{Type: Mention, Value: subs(text, from, to+1)})
|
t := subs(text, from, to+1)
|
||||||
result = append(result, InputSegment{Type: Text, Value: subs(text, to+1, nextAtIdx)})
|
appendInputSegment(&result, Mention, t, &fullText)
|
||||||
|
|
||||||
|
t = subs(text, to+1, nextAtIdx)
|
||||||
|
appendInputSegment(&result, Text, t, &fullText)
|
||||||
} else if mentioned && lastFrom == from {
|
} else if mentioned && lastFrom == from {
|
||||||
result = append(result, InputSegment{Type: Mention, Value: subs(text, from, to+1)})
|
t := subs(text, from, to+1)
|
||||||
result = append(result, InputSegment{Type: Text, Value: subs(text, to+1)})
|
appendInputSegment(&result, Mention, t, &fullText)
|
||||||
|
|
||||||
|
t = subs(text, to+1)
|
||||||
|
appendInputSegment(&result, Text, t, &fullText)
|
||||||
} else {
|
} else {
|
||||||
result = append(result, InputSegment{Type: Text, Value: subs(text, from, to+1)})
|
t := subs(text, from, to+1)
|
||||||
|
appendInputSegment(&result, Text, t, &fullText)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result, fullText == text
|
||||||
}
|
}
|
||||||
|
|
||||||
func subs(s string, start int, end ...int) string {
|
func subs(s string, start int, end ...int) string {
|
||||||
|
|
|
@ -251,27 +251,6 @@ func TestGetAtSignIdxs(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCalcAtIdxs(t *testing.T) {
|
|
||||||
state := MentionState{
|
|
||||||
AtIdxs: []*AtIndexEntry{
|
|
||||||
{From: 0, To: 3, Checked: false},
|
|
||||||
},
|
|
||||||
NewText: "@abc",
|
|
||||||
PreviousText: "",
|
|
||||||
Start: 0,
|
|
||||||
}
|
|
||||||
want := []*AtIndexEntry{
|
|
||||||
{From: 0, To: 0, Checked: false},
|
|
||||||
{From: 4, To: 7, Checked: false},
|
|
||||||
}
|
|
||||||
|
|
||||||
got := calcAtIdxs(&state)
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(got, want) {
|
|
||||||
t.Errorf("calcAtIdxs() = %v, want %v", got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestToInfo(t *testing.T) {
|
func TestToInfo(t *testing.T) {
|
||||||
newText := " "
|
newText := " "
|
||||||
t.Run("toInfo base case", func(t *testing.T) {
|
t.Run("toInfo base case", func(t *testing.T) {
|
||||||
|
@ -891,13 +870,11 @@ func TestMentionSuggestionAtSignSpaceCases(t *testing.T) {
|
||||||
t.Logf("After OnChangeText, Input: %+v, MentionState:%+v, InputSegments:%+v\n", tc.inputText, ctx.MentionState, ctx.InputSegments)
|
t.Logf("After OnChangeText, Input: %+v, MentionState:%+v, InputSegments:%+v\n", tc.inputText, ctx.MentionState, ctx.InputSegments)
|
||||||
require.Equal(t, tc.expectedSize, len(ctx.MentionSuggestions))
|
require.Equal(t, tc.expectedSize, len(ctx.MentionSuggestions))
|
||||||
}
|
}
|
||||||
require.Len(t, ctx.InputSegments, 3)
|
require.Len(t, ctx.InputSegments, 2)
|
||||||
require.Equal(t, Mention, ctx.InputSegments[0].Type)
|
require.Equal(t, Text, ctx.InputSegments[0].Type)
|
||||||
require.Equal(t, "@ @", ctx.InputSegments[0].Value)
|
require.Equal(t, "@ ", ctx.InputSegments[0].Value)
|
||||||
require.Equal(t, Text, ctx.InputSegments[1].Type)
|
require.Equal(t, Text, ctx.InputSegments[1].Type)
|
||||||
require.Equal(t, "@", ctx.InputSegments[1].Value)
|
require.Equal(t, "@", ctx.InputSegments[1].Value)
|
||||||
require.Equal(t, Text, ctx.InputSegments[2].Type)
|
|
||||||
require.Equal(t, "@", ctx.InputSegments[2].Value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSelectMention(t *testing.T) {
|
func TestSelectMention(t *testing.T) {
|
||||||
|
@ -923,6 +900,73 @@ func TestSelectMention(t *testing.T) {
|
||||||
require.Equal(t, 0, len(ctx.MentionSuggestions))
|
require.Equal(t, 0, len(ctx.MentionSuggestions))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInputSegments(t *testing.T) {
|
||||||
|
_, chatID, mentionManager := setupMentionSuggestionTest(t, nil)
|
||||||
|
ctx, err := mentionManager.OnChangeText(chatID, "@u1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, len(ctx.InputSegments))
|
||||||
|
require.Equal(t, Text, ctx.InputSegments[0].Type)
|
||||||
|
require.Equal(t, "@u1", ctx.InputSegments[0].Value)
|
||||||
|
|
||||||
|
ctx, err = mentionManager.OnChangeText(chatID, "@u1 @User Number One")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 2, len(ctx.InputSegments))
|
||||||
|
require.Equal(t, Text, ctx.InputSegments[0].Type)
|
||||||
|
require.Equal(t, "@u1 ", ctx.InputSegments[0].Value)
|
||||||
|
require.Equal(t, Mention, ctx.InputSegments[1].Type)
|
||||||
|
require.Equal(t, "@User Number One", ctx.InputSegments[1].Value)
|
||||||
|
|
||||||
|
ctx, err = mentionManager.OnChangeText(chatID, "@u1 @User Number O")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 2, len(ctx.InputSegments))
|
||||||
|
require.Equal(t, Text, ctx.InputSegments[1].Type)
|
||||||
|
require.Equal(t, "@User Number O", ctx.InputSegments[1].Value)
|
||||||
|
|
||||||
|
ctx, err = mentionManager.OnChangeText(chatID, "@u2 @User Number One")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 3, len(ctx.InputSegments))
|
||||||
|
require.Equal(t, Mention, ctx.InputSegments[0].Type)
|
||||||
|
require.Equal(t, "@u2", ctx.InputSegments[0].Value)
|
||||||
|
require.Equal(t, Text, ctx.InputSegments[1].Type)
|
||||||
|
require.Equal(t, " ", ctx.InputSegments[1].Value)
|
||||||
|
require.Equal(t, Mention, ctx.InputSegments[2].Type)
|
||||||
|
require.Equal(t, "@User Number One", ctx.InputSegments[2].Value)
|
||||||
|
|
||||||
|
ctx, err = mentionManager.OnChangeText(chatID, "@u2 @User Number One a ")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 4, len(ctx.InputSegments))
|
||||||
|
require.Equal(t, Mention, ctx.InputSegments[2].Type)
|
||||||
|
require.Equal(t, "@User Number One", ctx.InputSegments[2].Value)
|
||||||
|
require.Equal(t, Text, ctx.InputSegments[3].Type)
|
||||||
|
require.Equal(t, " a ", ctx.InputSegments[3].Value)
|
||||||
|
|
||||||
|
ctx, err = mentionManager.OnChangeText(chatID, "@u2 @User Numbed One a ")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 3, len(ctx.InputSegments))
|
||||||
|
require.Equal(t, Mention, ctx.InputSegments[0].Type)
|
||||||
|
require.Equal(t, "@u2", ctx.InputSegments[0].Value)
|
||||||
|
require.Equal(t, Text, ctx.InputSegments[2].Type)
|
||||||
|
require.Equal(t, "@User Numbed One a ", ctx.InputSegments[2].Value)
|
||||||
|
|
||||||
|
ctx, err = mentionManager.OnChangeText(chatID, "@ @ ")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 2, len(ctx.InputSegments))
|
||||||
|
require.Equal(t, Text, ctx.InputSegments[0].Type)
|
||||||
|
require.Equal(t, "@ ", ctx.InputSegments[0].Value)
|
||||||
|
require.Equal(t, Text, ctx.InputSegments[1].Type)
|
||||||
|
require.Equal(t, "@ ", ctx.InputSegments[1].Value)
|
||||||
|
|
||||||
|
ctx, err = mentionManager.OnChangeText(chatID, "@u3 @ ")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 3, len(ctx.InputSegments))
|
||||||
|
require.Equal(t, Mention, ctx.InputSegments[0].Type)
|
||||||
|
require.Equal(t, "@u3", ctx.InputSegments[0].Value)
|
||||||
|
require.Equal(t, Text, ctx.InputSegments[1].Type)
|
||||||
|
require.Equal(t, " ", ctx.InputSegments[1].Value)
|
||||||
|
require.Equal(t, Text, ctx.InputSegments[2].Type)
|
||||||
|
require.Equal(t, "@ ", ctx.InputSegments[2].Value)
|
||||||
|
}
|
||||||
|
|
||||||
func setupMentionSuggestionTest(t *testing.T, mentionableUserMapInput map[string]*MentionableUser) (map[string]*MentionableUser, string, *MentionManager) {
|
func setupMentionSuggestionTest(t *testing.T, mentionableUserMapInput map[string]*MentionableUser) (map[string]*MentionableUser, string, *MentionManager) {
|
||||||
mentionableUserMap := mentionableUserMapInput
|
mentionableUserMap := mentionableUserMapInput
|
||||||
if mentionableUserMap == nil {
|
if mentionableUserMap == nil {
|
||||||
|
|
Loading…
Reference in New Issue