github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/chat/activitynotifier.go (about) 1 package chat 2 3 import ( 4 "context" 5 "sync" 6 7 "github.com/keybase/client/go/chat/globals" 8 "github.com/keybase/client/go/chat/utils" 9 "github.com/keybase/client/go/libkb" 10 "github.com/keybase/client/go/protocol/chat1" 11 "github.com/keybase/client/go/protocol/gregor1" 12 "github.com/keybase/client/go/protocol/keybase1" 13 ) 14 15 type NotifyRouterActivityRouter struct { 16 utils.DebugLabeler 17 globals.Contextified 18 sync.Mutex 19 20 notifyCh chan func() 21 shutdownCh chan struct{} 22 } 23 24 func NewNotifyRouterActivityRouter(g *globals.Context) *NotifyRouterActivityRouter { 25 n := &NotifyRouterActivityRouter{ 26 Contextified: globals.NewContextified(g), 27 DebugLabeler: utils.NewDebugLabeler(g.ExternalG(), "NotifyRouterActivityRouter", false), 28 notifyCh: make(chan func(), 5000), 29 shutdownCh: make(chan struct{}), 30 } 31 go n.notifyLoop() 32 g.PushShutdownHook(func(mctx libkb.MetaContext) error { 33 close(n.shutdownCh) 34 return nil 35 }) 36 return n 37 } 38 39 func (n *NotifyRouterActivityRouter) notifyLoop() { 40 for { 41 select { 42 case f := <-n.notifyCh: 43 f() 44 case <-n.shutdownCh: 45 return 46 } 47 } 48 } 49 50 func (n *NotifyRouterActivityRouter) kuid(uid gregor1.UID) keybase1.UID { 51 return keybase1.UID(uid.String()) 52 } 53 54 func (n *NotifyRouterActivityRouter) Activity(ctx context.Context, uid gregor1.UID, 55 topicType chat1.TopicType, activity *chat1.ChatActivity, source chat1.ChatActivitySource) { 56 defer n.Trace(ctx, nil, "Activity(%v,%v)", topicType, source)() 57 ctx = globals.BackgroundChatCtx(ctx, n.G()) 58 if activity == nil { 59 return 60 } 61 switch topicType { 62 case chat1.TopicType_KBFSFILEEDIT: 63 if libkb.IsMobilePlatform() { 64 n.Debug(ctx, "skipping file edit notify on mobile") 65 return 66 } 67 default: 68 } 69 typ, err := activity.ActivityType() 70 if err != nil { 71 n.Debug(ctx, "invalid activity type: %v", err) 72 return 73 } 74 75 var canSkip bool 76 // If the conversation is not being actively viewed, we can optionally skip 77 // notifications to the UI. 78 if typ == chat1.ChatActivityType_INCOMING_MESSAGE { 79 act := activity.IncomingMessage() 80 if !act.DisplayDesktopNotification && act.Conv != nil && 81 act.Conv.TeamType == chat1.TeamType_COMPLEX && 82 !n.G().Syncer.IsSelectedConversation(act.ConvID) && 83 act.Conv.ReadMsgID+100 < act.Conv.MaxVisibleMsgID { 84 n.Debug(ctx, "canSkip UI notification %v for %v", typ, act.ConvID) 85 canSkip = true 86 } 87 } 88 n.notifyCh <- func() { 89 n.G().NotifyRouter.HandleNewChatActivity(ctx, n.kuid(uid), topicType, activity, source, canSkip) 90 } 91 } 92 93 func (n *NotifyRouterActivityRouter) TypingUpdate(ctx context.Context, updates []chat1.ConvTypingUpdate) { 94 ctx = globals.BackgroundChatCtx(ctx, n.G()) 95 n.notifyCh <- func() { 96 n.G().NotifyRouter.HandleChatTypingUpdate(ctx, updates) 97 } 98 } 99 100 func (n *NotifyRouterActivityRouter) JoinedConversation(ctx context.Context, uid gregor1.UID, 101 convID chat1.ConversationID, topicType chat1.TopicType, conv *chat1.InboxUIItem) { 102 defer n.Trace(ctx, nil, "JoinedConversation(%s,%v)", convID, topicType)() 103 ctx = globals.BackgroundChatCtx(ctx, n.G()) 104 n.notifyCh <- func() { 105 n.G().NotifyRouter.HandleChatJoinedConversation(ctx, n.kuid(uid), convID, topicType, conv) 106 } 107 } 108 109 func (n *NotifyRouterActivityRouter) LeftConversation(ctx context.Context, uid gregor1.UID, 110 convID chat1.ConversationID, topicType chat1.TopicType) { 111 defer n.Trace(ctx, nil, "LeftConversation(%s,%v)", convID, topicType)() 112 ctx = globals.BackgroundChatCtx(ctx, n.G()) 113 n.notifyCh <- func() { 114 n.G().NotifyRouter.HandleChatLeftConversation(ctx, n.kuid(uid), convID, topicType) 115 } 116 } 117 118 func (n *NotifyRouterActivityRouter) ResetConversation(ctx context.Context, uid gregor1.UID, 119 convID chat1.ConversationID, topicType chat1.TopicType) { 120 defer n.Trace(ctx, nil, "ResetConversation(%s,%v)", convID, topicType)() 121 ctx = globals.BackgroundChatCtx(ctx, n.G()) 122 n.notifyCh <- func() { 123 n.G().NotifyRouter.HandleChatResetConversation(ctx, n.kuid(uid), convID, topicType) 124 } 125 } 126 127 func (n *NotifyRouterActivityRouter) KBFSToImpteamUpgrade(ctx context.Context, uid gregor1.UID, 128 convID chat1.ConversationID, topicType chat1.TopicType) { 129 defer n.Trace(ctx, nil, "KBFSToImpteamUpgrade(%s,%v)", convID, topicType)() 130 ctx = globals.BackgroundChatCtx(ctx, n.G()) 131 n.notifyCh <- func() { 132 n.G().NotifyRouter.HandleChatKBFSToImpteamUpgrade(ctx, n.kuid(uid), convID, topicType) 133 } 134 } 135 136 func (n *NotifyRouterActivityRouter) SetConvRetention(ctx context.Context, uid gregor1.UID, 137 convID chat1.ConversationID, topicType chat1.TopicType, conv *chat1.InboxUIItem) { 138 defer n.Trace(ctx, nil, "SetConvRetention(%s,%v)", convID, topicType)() 139 ctx = globals.BackgroundChatCtx(ctx, n.G()) 140 n.notifyCh <- func() { 141 n.G().NotifyRouter.HandleChatSetConvRetention(ctx, n.kuid(uid), convID, topicType, conv) 142 } 143 } 144 145 func (n *NotifyRouterActivityRouter) SetTeamRetention(ctx context.Context, uid gregor1.UID, 146 teamID keybase1.TeamID, topicType chat1.TopicType, convs []chat1.InboxUIItem) { 147 defer n.Trace(ctx, nil, "SetTeamRetention(%s,%v)", teamID, topicType)() 148 ctx = globals.BackgroundChatCtx(ctx, n.G()) 149 n.notifyCh <- func() { 150 n.G().NotifyRouter.HandleChatSetTeamRetention(ctx, n.kuid(uid), teamID, topicType, convs) 151 } 152 } 153 154 func (n *NotifyRouterActivityRouter) SetConvSettings(ctx context.Context, uid gregor1.UID, 155 convID chat1.ConversationID, topicType chat1.TopicType, conv *chat1.InboxUIItem) { 156 defer n.Trace(ctx, nil, "SetConvSettings(%s,%v)", convID, topicType)() 157 ctx = globals.BackgroundChatCtx(ctx, n.G()) 158 n.notifyCh <- func() { 159 n.G().NotifyRouter.HandleChatSetConvSettings(ctx, n.kuid(uid), convID, topicType, conv) 160 } 161 } 162 163 func (n *NotifyRouterActivityRouter) SubteamRename(ctx context.Context, uid gregor1.UID, 164 convIDs []chat1.ConversationID, topicType chat1.TopicType, convs []chat1.InboxUIItem) { 165 defer n.Trace(ctx, nil, "SubteamRename(%v,%d convs)", topicType, len(convs))() 166 ctx = globals.BackgroundChatCtx(ctx, n.G()) 167 n.notifyCh <- func() { 168 n.G().NotifyRouter.HandleChatSubteamRename(ctx, n.kuid(uid), convIDs, topicType, convs) 169 } 170 } 171 172 func (n *NotifyRouterActivityRouter) InboxSyncStarted(ctx context.Context, uid gregor1.UID) { 173 defer n.Trace(ctx, nil, "InboxSyncStarted")() 174 ctx = globals.BackgroundChatCtx(ctx, n.G()) 175 n.notifyCh <- func() { 176 n.G().NotifyRouter.HandleChatInboxSyncStarted(ctx, n.kuid(uid)) 177 } 178 } 179 180 func (n *NotifyRouterActivityRouter) InboxSynced(ctx context.Context, uid gregor1.UID, 181 topicType chat1.TopicType, syncRes chat1.ChatSyncResult) { 182 defer n.Trace(ctx, nil, "InboxSynced(%v)", topicType)() 183 ctx = globals.BackgroundChatCtx(ctx, n.G()) 184 n.notifyCh <- func() { 185 n.G().NotifyRouter.HandleChatInboxSynced(ctx, n.kuid(uid), topicType, syncRes) 186 } 187 } 188 189 func (n *NotifyRouterActivityRouter) InboxStale(ctx context.Context, uid gregor1.UID) { 190 defer n.Trace(ctx, nil, "InboxStale")() 191 ctx = globals.BackgroundChatCtx(ctx, n.G()) 192 n.notifyCh <- func() { 193 n.G().NotifyRouter.HandleChatInboxStale(ctx, n.kuid(uid)) 194 } 195 } 196 197 func (n *NotifyRouterActivityRouter) ThreadsStale(ctx context.Context, uid gregor1.UID, 198 updates []chat1.ConversationStaleUpdate) { 199 defer n.Trace(ctx, nil, "ThreadsStale")() 200 ctx = globals.BackgroundChatCtx(ctx, n.G()) 201 n.notifyCh <- func() { 202 n.G().NotifyRouter.HandleChatThreadsStale(ctx, n.kuid(uid), updates) 203 } 204 } 205 206 func (n *NotifyRouterActivityRouter) TLFFinalize(ctx context.Context, uid gregor1.UID, 207 convID chat1.ConversationID, topicType chat1.TopicType, finalizeInfo chat1.ConversationFinalizeInfo, conv *chat1.InboxUIItem) { 208 defer n.Trace(ctx, nil, "TLFFinalize(%s,%v)", convID, topicType)() 209 ctx = globals.BackgroundChatCtx(ctx, n.G()) 210 n.notifyCh <- func() { 211 n.G().NotifyRouter.HandleChatTLFFinalize(ctx, n.kuid(uid), convID, topicType, finalizeInfo, conv) 212 } 213 } 214 215 func (n *NotifyRouterActivityRouter) TLFResolve(ctx context.Context, uid gregor1.UID, 216 convID chat1.ConversationID, topicType chat1.TopicType, resolveInfo chat1.ConversationResolveInfo) { 217 defer n.Trace(ctx, nil, "TLFResolve(%s,%v)", convID, topicType)() 218 ctx = globals.BackgroundChatCtx(ctx, n.G()) 219 n.notifyCh <- func() { 220 n.G().NotifyRouter.HandleChatTLFResolve(ctx, n.kuid(uid), convID, topicType, resolveInfo) 221 } 222 } 223 224 func (n *NotifyRouterActivityRouter) AttachmentUploadStart(ctx context.Context, uid gregor1.UID, 225 convID chat1.ConversationID, outboxID chat1.OutboxID) { 226 defer n.Trace(ctx, nil, "AttachmentUploadStart(%s,%s)", convID, outboxID)() 227 ctx = globals.BackgroundChatCtx(ctx, n.G()) 228 n.notifyCh <- func() { 229 n.G().NotifyRouter.HandleChatAttachmentUploadStart(ctx, n.kuid(uid), convID, outboxID) 230 } 231 } 232 233 func (n *NotifyRouterActivityRouter) AttachmentUploadProgress(ctx context.Context, uid gregor1.UID, 234 convID chat1.ConversationID, outboxID chat1.OutboxID, bytesComplete, bytesTotal int64) { 235 defer n.Trace(ctx, nil, "AttachmentUploadProgress(%s,%s)", convID, outboxID)() 236 ctx = globals.BackgroundChatCtx(ctx, n.G()) 237 n.notifyCh <- func() { 238 n.G().NotifyRouter.HandleChatAttachmentUploadProgress(ctx, n.kuid(uid), convID, outboxID, 239 bytesComplete, bytesTotal) 240 } 241 } 242 243 func (n *NotifyRouterActivityRouter) PromptUnfurl(ctx context.Context, uid gregor1.UID, 244 convID chat1.ConversationID, msgID chat1.MessageID, domain string) { 245 defer n.Trace(ctx, nil, "PromptUnfurl(%s,%s)", convID, msgID)() 246 ctx = globals.BackgroundChatCtx(ctx, n.G()) 247 n.notifyCh <- func() { 248 n.G().NotifyRouter.HandleChatPromptUnfurl(ctx, n.kuid(uid), convID, msgID, domain) 249 } 250 } 251 252 func (n *NotifyRouterActivityRouter) ConvUpdate(ctx context.Context, uid gregor1.UID, 253 convID chat1.ConversationID, topicType chat1.TopicType, conv *chat1.InboxUIItem) { 254 defer n.Trace(ctx, nil, "ConvUpdate(%s,%v)", convID, topicType)() 255 ctx = globals.BackgroundChatCtx(ctx, n.G()) 256 n.notifyCh <- func() { 257 n.G().NotifyRouter.HandleChatConvUpdate(ctx, n.kuid(uid), convID, topicType, conv) 258 } 259 }