Skip to content

Commit

Permalink
fix_: add callTime for OnChangeText
Browse files Browse the repository at this point in the history
  • Loading branch information
qfrank committed Sep 12, 2024
1 parent 63e17be commit a1010b3
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 35 deletions.
26 changes: 14 additions & 12 deletions protocol/messenger_mention.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ type ChatMentionContext struct {
NewText string

CallID uint64
CallTime int64
mu *sync.Mutex
LatestCallID uint64
}
Expand Down Expand Up @@ -301,27 +302,28 @@ func (m *MentionManager) ReplaceWithPublicKey(chatID, text string) (string, erro
return newText, nil
}

func withCallID(ctx *ChatMentionContext, callID uint64) *ChatMentionContext {
func withCallID(ctx *ChatMentionContext, callID uint64, callTime int64) *ChatMentionContext {
result := *ctx
result.CallID = callID
result.CallTime = callTime
return &result
}

func (m *MentionManager) OnChangeText(chatID, fullText string, callID uint64) (*ChatMentionContext, error) {
func (m *MentionManager) OnChangeText(chatID, fullText string, callID uint64, callTime int64) (*ChatMentionContext, error) {
ctx := m.getChatMentionContext(chatID)
if callID > 0 {
ctx.mu.Lock()
if callID <= ctx.LatestCallID {
ctx.mu.Unlock()
return withCallID(ctx, callID), fmt.Errorf("callID is less than or equal to latestCallID, callID: %d, maxCallID: %d", callID, ctx.LatestCallID)
return withCallID(ctx, callID, callTime), fmt.Errorf("callID is less than or equal to latestCallID, callID: %d, maxCallID: %d", callID, ctx.LatestCallID)
}
ctx.LatestCallID = callID
ctx.mu.Unlock()
}

diff := diffText(ctx.PreviousText, fullText)
if diff == nil {
return withCallID(ctx, callID), nil
return withCallID(ctx, callID, callTime), nil
}
ctx.PreviousText = fullText
if ctx.MentionState == nil {
Expand All @@ -335,12 +337,12 @@ func (m *MentionManager) OnChangeText(chatID, fullText string, callID uint64) (*

atIndexes, err := calculateAtIndexEntries(ctx.MentionState)
if err != nil {
return withCallID(ctx, callID), err
return withCallID(ctx, callID, callTime), err
}
ctx.MentionState.AtIdxs = atIndexes
m.logger.Debug("OnChangeText", zap.String("chatID", chatID), zap.Any("state", ctx.MentionState))
ctx, err = m.calculateSuggestions(chatID, fullText)
return withCallID(ctx, callID), err
return withCallID(ctx, callID, callTime), err
}

func (m *MentionManager) calculateSuggestions(chatID, fullText string) (*ChatMentionContext, error) {
Expand Down Expand Up @@ -372,8 +374,8 @@ func (m *MentionManager) calculateSuggestionsWithMentionableUsers(chatID string,
}

newAtIndexEntries := checkIdxForMentions(fullText, state.AtIdxs, mentionableUsers)
calculatedInput, success := calculateInput(fullText, newAtIndexEntries)
if !success {
calculatedInput, inputSegmentString := calculateInput(fullText, newAtIndexEntries)
if fullText != inputSegmentString {
m.logger.Warn("calculateSuggestionsWithMentionableUsers: calculateInput failed", zap.String("chatID", chatID), zap.String("fullText", fullText), zap.Any("state", state))
}

Expand Down Expand Up @@ -426,7 +428,7 @@ func (m *MentionManager) SelectMention(chatID, text, primaryName, publicKey stri

ctx.NewText = string(tr[:atSignIdx+1]) + primaryName + space + string(tr[mentionEnd:])

_, err := m.OnChangeText(chatID, ctx.NewText, 0)
_, err := m.OnChangeText(chatID, ctx.NewText, 0, 0)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1013,9 +1015,9 @@ func appendInputSegment(result *[]InputSegment, typ SegmentType, value string, f
}
}

func calculateInput(text string, atIndexEntries []*AtIndexEntry) ([]InputSegment, bool) {
func calculateInput(text string, atIndexEntries []*AtIndexEntry) ([]InputSegment, string) {
if len(atIndexEntries) == 0 {
return []InputSegment{{Type: Text, Value: text}}, true
return []InputSegment{{Type: Text, Value: text}}, text
}
idxCount := len(atIndexEntries)
lastFrom := atIndexEntries[idxCount-1].From
Expand Down Expand Up @@ -1051,7 +1053,7 @@ func calculateInput(text string, atIndexEntries []*AtIndexEntry) ([]InputSegment
}
}

return result, fullText == text
return result, fullText
}

func subs(s string, start int, end ...int) string {
Expand Down
49 changes: 28 additions & 21 deletions protocol/messenger_mention_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"reflect"
"strings"
"testing"
"time"

"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -794,7 +795,7 @@ func TestMentionSuggestionCases(t *testing.T) {

for i, tc := range testCases {
t.Run(fmt.Sprintf("%d", i+1), func(t *testing.T) {
ctx, err := mentionManager.OnChangeText(chatID, tc.inputText, uint64(i+1))
ctx, err := mentionManager.OnChangeText(chatID, tc.inputText, uint64(i+1), now())
require.NoError(t, err)
t.Logf("Input: %+v, MentionState:%+v, InputSegments:%+v\n", tc.inputText, ctx.MentionState, ctx.InputSegments)
require.Equal(t, tc.expectedSize, len(ctx.MentionSuggestions))
Expand All @@ -806,7 +807,7 @@ func TestMentionSuggestionAfterToInputField(t *testing.T) {
mentionableUserMap, chatID, mentionManager := setupMentionSuggestionTest(t, nil)
_, err := mentionManager.ToInputField(chatID, "abc")
require.NoError(t, err)
ctx, err := mentionManager.OnChangeText(chatID, "@", 1)
ctx, err := mentionManager.OnChangeText(chatID, "@", 1, now())
require.NoError(t, err)
require.Equal(t, len(mentionableUserMap), len(ctx.MentionSuggestions))
}
Expand All @@ -826,7 +827,7 @@ func TestMentionSuggestionSpecialInputModeForAndroid(t *testing.T) {

for i, tc := range testCases {
t.Run(fmt.Sprintf("%d", i+1), func(t *testing.T) {
ctx, err := mentionManager.OnChangeText(chatID, tc.inputText, uint64(i+1))
ctx, err := mentionManager.OnChangeText(chatID, tc.inputText, uint64(i+1), now())
require.NoError(t, err)
require.Equal(t, tc.expectedSize, len(ctx.MentionSuggestions))
t.Logf("Input: %+v, MentionState:%+v, InputSegments:%+v\n", tc.inputText, ctx.MentionState, ctx.InputSegments)
Expand All @@ -849,7 +850,7 @@ func TestMentionSuggestionSpecialChars(t *testing.T) {

for i, tc := range testCases {
t.Run(fmt.Sprintf("%d", i+1), func(t *testing.T) {
ctx, err := mentionManager.OnChangeText(chatID, tc.inputText, uint64(i+1))
ctx, err := mentionManager.OnChangeText(chatID, tc.inputText, uint64(i+1), now())
require.NoError(t, err)
t.Logf("Input: %+v, MentionState:%+v, InputSegments:%+v\n", tc.inputText, ctx.MentionState, ctx.InputSegments)
require.Equal(t, tc.expectedSize, len(ctx.MentionSuggestions))
Expand Down Expand Up @@ -879,7 +880,7 @@ func TestMentionSuggestionAtSignSpaceCases(t *testing.T) {
var ctx *ChatMentionContext
var err error
for i, tc := range testCases {
ctx, err = mentionManager.OnChangeText(chatID, tc.inputText, uint64(i+1))
ctx, err = mentionManager.OnChangeText(chatID, tc.inputText, uint64(i+1), now())
require.NoError(t, err)
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))
Expand All @@ -896,12 +897,12 @@ func TestSelectMention(t *testing.T) {

var callID uint64 = 1
text := "@u2 abc"
ctx, err := mentionManager.OnChangeText(chatID, text, callID)
ctx, err := mentionManager.OnChangeText(chatID, text, callID, now())
require.NoError(t, err)
require.Equal(t, 0, len(ctx.MentionSuggestions))

callID++
ctx, err = mentionManager.OnChangeText(chatID, "@u abc", callID)
ctx, err = mentionManager.OnChangeText(chatID, "@u abc", callID, now())
require.NoError(t, err)
require.Equal(t, len(mentionableUsers), len(ctx.MentionSuggestions))

Expand All @@ -912,22 +913,26 @@ func TestSelectMention(t *testing.T) {
require.Equal(t, text, ctx.PreviousText)

callID++
ctx, err = mentionManager.OnChangeText(chatID, text, callID)
ctx, err = mentionManager.OnChangeText(chatID, text, callID, now())
require.NoError(t, err)
require.Equal(t, 0, len(ctx.MentionSuggestions))
}

func now() int64 {
return time.Now().UnixMilli()
}

func TestInputSegments(t *testing.T) {
_, chatID, mentionManager := setupMentionSuggestionTest(t, nil)
var callID uint64 = 1
ctx, err := mentionManager.OnChangeText(chatID, "@u1", callID)
ctx, err := mentionManager.OnChangeText(chatID, "@u1", callID, now())
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)

callID++
ctx, err = mentionManager.OnChangeText(chatID, "@u1 @User Number One", callID)
ctx, err = mentionManager.OnChangeText(chatID, "@u1 @User Number One", callID, now())
require.NoError(t, err)
require.Equal(t, 2, len(ctx.InputSegments))
require.Equal(t, Text, ctx.InputSegments[0].Type)
Expand All @@ -936,14 +941,14 @@ func TestInputSegments(t *testing.T) {
require.Equal(t, "@User Number One", ctx.InputSegments[1].Value)

callID++
ctx, err = mentionManager.OnChangeText(chatID, "@u1 @User Number O", callID)
ctx, err = mentionManager.OnChangeText(chatID, "@u1 @User Number O", callID, now())
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)

callID++
ctx, err = mentionManager.OnChangeText(chatID, "@u2 @User Number One", callID)
ctx, err = mentionManager.OnChangeText(chatID, "@u2 @User Number One", callID, now())
require.NoError(t, err)
require.Equal(t, 3, len(ctx.InputSegments))
require.Equal(t, Mention, ctx.InputSegments[0].Type)
Expand All @@ -954,7 +959,7 @@ func TestInputSegments(t *testing.T) {
require.Equal(t, "@User Number One", ctx.InputSegments[2].Value)

callID++
ctx, err = mentionManager.OnChangeText(chatID, "@u2 @User Number One a ", callID)
ctx, err = mentionManager.OnChangeText(chatID, "@u2 @User Number One a ", callID, now())
require.NoError(t, err)
require.Equal(t, 4, len(ctx.InputSegments))
require.Equal(t, Mention, ctx.InputSegments[2].Type)
Expand All @@ -963,7 +968,7 @@ func TestInputSegments(t *testing.T) {
require.Equal(t, " a ", ctx.InputSegments[3].Value)

callID++
ctx, err = mentionManager.OnChangeText(chatID, "@u2 @User Numbed One a ", callID)
ctx, err = mentionManager.OnChangeText(chatID, "@u2 @User Numbed One a ", callID, now())
require.NoError(t, err)
require.Equal(t, 3, len(ctx.InputSegments))
require.Equal(t, Mention, ctx.InputSegments[0].Type)
Expand All @@ -972,7 +977,7 @@ func TestInputSegments(t *testing.T) {
require.Equal(t, "@User Numbed One a ", ctx.InputSegments[2].Value)

callID++
ctx, err = mentionManager.OnChangeText(chatID, "@ @ ", callID)
ctx, err = mentionManager.OnChangeText(chatID, "@ @ ", callID, now())
require.NoError(t, err)
require.Equal(t, 2, len(ctx.InputSegments))
require.Equal(t, Text, ctx.InputSegments[0].Type)
Expand All @@ -981,7 +986,7 @@ func TestInputSegments(t *testing.T) {
require.Equal(t, "@ ", ctx.InputSegments[1].Value)

callID++
ctx, err = mentionManager.OnChangeText(chatID, "@u3 @ ", callID)
ctx, err = mentionManager.OnChangeText(chatID, "@u3 @ ", callID, now())
require.NoError(t, err)
require.Equal(t, 3, len(ctx.InputSegments))
require.Equal(t, Mention, ctx.InputSegments[0].Type)
Expand All @@ -992,24 +997,26 @@ func TestInputSegments(t *testing.T) {
require.Equal(t, "@ ", ctx.InputSegments[2].Value)

callID++
_, err = mentionManager.OnChangeText(chatID, " @ @User Number Three ", callID)
_, err = mentionManager.OnChangeText(chatID, " @ @User Number Three ", callID, now())
require.NoError(t, err)
callID++
_, err = mentionManager.OnChangeText(chatID, "@U @ @User Number Three ", callID)
_, err = mentionManager.OnChangeText(chatID, "@U @ @User Number Three ", callID, now())
require.NoError(t, err)
ctx, err = mentionManager.SelectMention(chatID, "@U @ @User Number Three ", "User Number Three", "0xpk3")
require.NoError(t, err)
require.Equal(t, 2, mentionTypeNum(ctx.InputSegments))

callID++
ctx, _ = mentionManager.OnChangeText(chatID, "@User Number Threea", callID)
ctx, _ = mentionManager.OnChangeText(chatID, "@User Number Threea", callID, now())
require.Equal(t, 0, mentionTypeNum(ctx.InputSegments))

callID++
ctx, _ = mentionManager.OnChangeText(chatID, "@User Number Threea\n@u2\nabc@u3 asa", callID)
ctx, err = mentionManager.OnChangeText(chatID, "@User Number Threea\n@u2\nabc@u3 asa", callID, now())
require.NoError(t, err)
require.Equal(t, 2, mentionTypeNum(ctx.InputSegments))
callID++
ctx, _ = mentionManager.OnChangeText(chatID, "@User Number Thre\n@u2\nabc@u3 asa", callID)
ctx, err = mentionManager.OnChangeText(chatID, "@User Number Thre\n@u2\nabc@u3 asa", callID, now())
require.NoError(t, err)
require.Equal(t, 2, mentionTypeNum(ctx.InputSegments))
require.Equal(t, "@u2", ctx.InputSegments[1].Value)
require.Equal(t, "@u3", ctx.InputSegments[3].Value)
Expand Down
4 changes: 2 additions & 2 deletions services/ext/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1705,8 +1705,8 @@ func (api *PublicAPI) ChatMentionReplaceWithPublicKey(chatID, text string) (stri
// 2. user input "c", call this function with text "abc"
// whatever, we should ensure ChatMentionOnChangeText know(invoked) the latest full text.
// ChatMentionOnChangeText will maintain state of fulltext and diff between previous/latest full text internally.
func (api *PublicAPI) ChatMentionOnChangeText(chatID, text string, callID uint64) (*protocol.ChatMentionContext, error) {
return api.service.messenger.GetMentionsManager().OnChangeText(chatID, text, callID)
func (api *PublicAPI) ChatMentionOnChangeText(chatID, text string, callID uint64, callTime int64) (*protocol.ChatMentionContext, error) {
return api.service.messenger.GetMentionsManager().OnChangeText(chatID, text, callID, callTime)
}

// ChatMentionSelectMention select mention from mention suggestion list
Expand Down

0 comments on commit a1010b3

Please sign in to comment.