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  }