From 14cbd63412eb4f1d85c4c7df34abfe8d2cc5c16d Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 8 Jul 2022 16:55:29 +0200 Subject: [PATCH] Send MARKREAD push notifications Allows clients to dismiss notifications when another client marks the conversation as read. --- downstream.go | 12 ++++++++++++ irc.go | 6 ++++++ upstream.go | 10 +++++----- user.go | 27 +++++++++++++++------------ 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/downstream.go b/downstream.go index f0e9c61..dea8ca5 100644 --- a/downstream.go +++ b/downstream.go @@ -2004,6 +2004,8 @@ func (dc *downstreamConn) handleMessageRegistered(ctx context.Context, msg *irc. if err := uc.network.deleteChannel(ctx, upstreamName); err != nil { dc.logger.Printf("failed to delete channel %q: %v", upstreamName, err) } + + uc.network.pushTargets.Del(upstreamName) } } case "KICK": @@ -2994,6 +2996,16 @@ func (dc *downstreamConn) handleMessageRegistered(ctx context.Context, msg *irc. }) } }) + + if broadcast && network.pushTargets.Has(entity) { + // TODO: only broadcast if draft/read-marker has been negotiated + // TODO: use lower priority + network.pushTargets.Del(entity) + network.broadcastWebPush(ctx, &irc.Message{ + Command: "MARKREAD", + Params: []string{entity, timestampStr}, + }) + } case "SEARCH": store, ok := dc.user.msgStore.(msgstore.SearchStore) if !ok { diff --git a/irc.go b/irc.go index a75b914..2afd8ad 100644 --- a/irc.go +++ b/irc.go @@ -464,6 +464,12 @@ func (cm *monitorCasemapMap) ForEach(f func(name string, online bool)) { } } +type casemapSet struct{ casemapMap } + +func (cs *casemapSet) Add(name string) { + cs.set(name, nil) +} + func isWordBoundary(r rune) bool { switch r { case '-', '_', '|': // inspired from weechat.look.highlight_regex diff --git a/upstream.go b/upstream.go index 32da315..3ed8b85 100644 --- a/upstream.go +++ b/upstream.go @@ -522,21 +522,21 @@ func (uc *upstreamConn) handleMessage(ctx context.Context, msg *irc.Message) err self := uc.isOurNick(msg.Prefix.Name) ch := uc.network.channels.Get(bufferName) + highlight := false if ch != nil && msg.Command != "TAGMSG" && !self { if ch.Detached { uc.handleDetachedMessage(ctx, ch, msg) } - highlight := uc.network.isHighlight(msg) + highlight = uc.network.isHighlight(msg) if ch.DetachOn == database.FilterMessage || ch.DetachOn == database.FilterDefault || (ch.DetachOn == database.FilterHighlight && highlight) { uc.updateChannelAutoDetach(bufferName) } - if highlight { - uc.network.broadcastWebPush(ctx, msg) - } } - if ch == nil && uc.isOurNick(target) { + + if highlight || uc.isOurNick(target) { uc.network.broadcastWebPush(ctx, msg) + uc.network.pushTargets.Add(bufferName) } uc.produce(bufferName, msg, downstreamID) diff --git a/user.go b/user.go index bc7bbd9..2ab3bbf 100644 --- a/user.go +++ b/user.go @@ -131,11 +131,12 @@ type network struct { logger Logger stopped chan struct{} - conn *upstreamConn - channels channelCasemapMap - delivered deliveredStore - lastError error - casemap casemapping + conn *upstreamConn + channels channelCasemapMap + delivered deliveredStore + pushTargets casemapSet + lastError error + casemap casemapping } func newNetwork(user *user, record *database.Network, channels []database.Channel) *network { @@ -148,13 +149,14 @@ func newNetwork(user *user, record *database.Network, channels []database.Channe } return &network{ - Network: *record, - user: user, - logger: logger, - stopped: make(chan struct{}), - channels: m, - delivered: newDeliveredStore(), - casemap: casemapRFC1459, + Network: *record, + user: user, + logger: logger, + stopped: make(chan struct{}), + channels: m, + delivered: newDeliveredStore(), + pushTargets: casemapSet{newCasemapMap()}, + casemap: casemapRFC1459, } } @@ -377,6 +379,7 @@ func (net *network) updateCasemapping(newCasemap casemapping) { net.casemap = newCasemap net.channels.SetCasemapping(newCasemap) net.delivered.m.SetCasemapping(newCasemap) + net.pushTargets.SetCasemapping(newCasemap) if uc := net.conn; uc != nil { uc.channels.SetCasemapping(newCasemap) uc.channels.ForEach(func(uch *upstreamChannel) {