Mark chat as read on conversation events

This commit is contained in:
Tulir Asokan 2023-08-09 16:30:02 +03:00
parent 0169f2140a
commit 3df8296d9f
2 changed files with 23 additions and 13 deletions

View file

@ -24,7 +24,6 @@ import (
"time" "time"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"maunium.net/go/mautrix" "maunium.net/go/mautrix"
"maunium.net/go/mautrix/event" "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id" "maunium.net/go/mautrix/id"
@ -51,16 +50,19 @@ type pendingBackfill struct {
lastMessageTS time.Time lastMessageTS time.Time
} }
func (portal *Portal) missedForwardBackfill(user *User, lastMessageTS time.Time, lastMessageID string, markRead bool) bool { func (portal *Portal) missedForwardBackfill(user *User, lastMessageTS time.Time, lastMessageID string, markRead, markReadIfNoBackfill bool) {
if portal.bridge.Config.Bridge.Backfill.MissedLimit == 0 { if portal.bridge.Config.Bridge.Backfill.MissedLimit == 0 {
return false if markRead && markReadIfNoBackfill {
user.markSelfReadFull(portal, lastMessageID)
}
return
} }
log := portal.zlog.With(). log := portal.zlog.With().
Str("action", "missed forward backfill"). Str("action", "missed forward backfill").
Str("latest_message_id", lastMessageID). Str("latest_message_id", lastMessageID).
Logger() Logger()
ctx := log.WithContext(context.TODO()) ctx := log.WithContext(context.TODO())
if time.Since(lastMessageTS) < 5*time.Minute { if !lastMessageTS.IsZero() && time.Since(lastMessageTS) < 5*time.Minute && portal.lastMessageTS.Before(lastMessageTS) {
var cancel context.CancelFunc var cancel context.CancelFunc
ctx, cancel = context.WithCancel(ctx) ctx, cancel = context.WithCancel(ctx)
prev := portal.pendingRecentBackfill.Swap(&pendingBackfill{cancel: cancel, lastMessageID: lastMessageID, lastMessageTS: lastMessageTS}) prev := portal.pendingRecentBackfill.Swap(&pendingBackfill{cancel: cancel, lastMessageID: lastMessageID, lastMessageTS: lastMessageTS})
@ -72,7 +74,7 @@ func (portal *Portal) missedForwardBackfill(user *User, lastMessageTS time.Time,
case <-time.After(recentBackfillDelay): case <-time.After(recentBackfillDelay):
case <-ctx.Done(): case <-ctx.Done():
log.Debug().Msg("Backfill was cancelled by a newer backfill") log.Debug().Msg("Backfill was cancelled by a newer backfill")
return false return
} }
} }
@ -83,7 +85,7 @@ func (portal *Portal) missedForwardBackfill(user *User, lastMessageTS time.Time,
lastMsg, err := portal.bridge.DB.Message.GetLastInChat(ctx, portal.Key) lastMsg, err := portal.bridge.DB.Message.GetLastInChat(ctx, portal.Key)
if err != nil { if err != nil {
log.Err(err).Msg("Failed to get last message in chat") log.Err(err).Msg("Failed to get last message in chat")
return false return
} else if lastMsg == nil { } else if lastMsg == nil {
log.Debug().Msg("No messages in chat") log.Debug().Msg("No messages in chat")
} else { } else {
@ -96,7 +98,10 @@ func (portal *Portal) missedForwardBackfill(user *User, lastMessageTS time.Time,
Str("latest_message_id", lastMessageID). Str("latest_message_id", lastMessageID).
Time("last_bridged_ts", portal.lastMessageTS). Time("last_bridged_ts", portal.lastMessageTS).
Msg("Nothing to backfill") Msg("Nothing to backfill")
return false if markRead && markReadIfNoBackfill {
user.markSelfReadFull(portal, lastMessageID)
}
return
} }
} }
log.Info(). log.Info().
@ -104,7 +109,7 @@ func (portal *Portal) missedForwardBackfill(user *User, lastMessageTS time.Time,
Str("latest_message_id", lastMessageID). Str("latest_message_id", lastMessageID).
Time("last_bridged_ts", portal.lastMessageTS). Time("last_bridged_ts", portal.lastMessageTS).
Msg("Backfilling missed messages") Msg("Backfilling missed messages")
return portal.forwardBackfill(ctx, user, portal.lastMessageTS, portal.bridge.Config.Bridge.Backfill.MissedLimit, markRead) portal.forwardBackfill(ctx, user, portal.lastMessageTS, portal.bridge.Config.Bridge.Backfill.MissedLimit, markRead)
} }
func (portal *Portal) deterministicEventID(messageID string, part int) id.EventID { func (portal *Portal) deterministicEventID(messageID string, part int) id.EventID {

15
user.go
View file

@ -832,11 +832,13 @@ func (user *User) syncConversation(v *gmproto.Conversation, source string) {
log.Debug().Msg("Syncing existing portal") log.Debug().Msg("Syncing existing portal")
portal.UpdateMetadata(user, v) portal.UpdateMetadata(user, v)
user.syncChatDoublePuppetDetails(portal, v, false) user.syncChatDoublePuppetDetails(portal, v, false)
didBackfill := portal.missedForwardBackfill(user, time.UnixMicro(v.LastMessageTimestamp), v.LatestMessageID, !v.GetUnread()) go portal.missedForwardBackfill(
if !didBackfill && !v.GetUnread() && v.LatestMessageID != "" && user.DoublePuppetIntent != nil { user,
// TODO this would spam a lot of read receipts on startup time.UnixMicro(v.LastMessageTimestamp),
//user.markSelfReadFull(portal, v.LatestMessageID) v.LatestMessageID,
} !v.GetUnread(),
source == "event",
)
} }
} else if updateType == gmproto.ConversationStatus_ACTIVE || updateType == gmproto.ConversationStatus_ARCHIVED { } else if updateType == gmproto.ConversationStatus_ACTIVE || updateType == gmproto.ConversationStatus_ARCHIVED {
if v.Participants == nil { if v.Participants == nil {
@ -912,6 +914,9 @@ type CustomReadMarkers struct {
} }
func (user *User) markSelfReadFull(portal *Portal, lastMessageID string) { func (user *User) markSelfReadFull(portal *Portal, lastMessageID string) {
if user.DoublePuppetIntent == nil {
return
}
ctx := context.TODO() ctx := context.TODO()
lastMessage, err := user.bridge.DB.Message.GetByID(ctx, portal.Key, lastMessageID) lastMessage, err := user.bridge.DB.Message.GetByID(ctx, portal.Key, lastMessageID)
if err == nil && lastMessage == nil { if err == nil && lastMessage == nil {