@@ -206,7 +206,7 @@ type queries struct {
206206 UpdateConversationFirstReplyAt * sqlx.Stmt `query:"update-conversation-first-reply-at"`
207207 UpdateConversationLastReplyAt * sqlx.Stmt `query:"update-conversation-last-reply-at"`
208208 UpdateConversationWaitingSince * sqlx.Stmt `query:"update-conversation-waiting-since"`
209- UpdateConversationAssigneeLastSeen * sqlx.Stmt `query:"update-conversation-assignee -last-seen"`
209+ UpsertUserLastSeen * sqlx.Stmt `query:"upsert-user -last-seen"`
210210 UpdateConversationAssignedUser * sqlx.Stmt `query:"update-conversation-assigned-user"`
211211 UpdateConversationAssignedTeam * sqlx.Stmt `query:"update-conversation-assigned-team"`
212212 UpdateConversationCustomAttributes * sqlx.Stmt `query:"update-conversation-custom-attributes"`
@@ -300,15 +300,12 @@ func (c *Manager) GetConversationsCreatedAfter(time time.Time) ([]models.Convers
300300 return conversations , nil
301301}
302302
303- // UpdateConversationAssigneeLastSeen updates the last seen timestamp of assignee .
304- func (c * Manager ) UpdateConversationAssigneeLastSeen (uuid string ) error {
305- if _ , err := c .q .UpdateConversationAssigneeLastSeen .Exec (uuid ); err != nil {
306- c .lo .Error ("error updating conversation" , "error" , err )
303+ // UpdateUserLastSeen updates the last seen timestamp for a specific user on a conversation .
304+ func (c * Manager ) UpdateUserLastSeen (uuid string , userID int ) error {
305+ if _ , err := c .q .UpsertUserLastSeen .Exec (userID , uuid ); err != nil {
306+ c .lo .Error ("error upserting user last seen" , "user_id" , userID , "conversation_uuid" , uuid , "error" , err )
307307 return envelope .NewError (envelope .GeneralError , c .i18n .Ts ("globals.messages.errorUpdating" , "name" , "{globals.terms.conversation}" ), nil )
308308 }
309-
310- // Broadcast the property update to all subscribers.
311- c .BroadcastConversationUpdate (uuid , "assignee_last_seen_at" , time .Now ().Format (time .RFC3339 ))
312309 return nil
313310}
314311
@@ -348,35 +345,36 @@ func (c *Manager) GetConversationUUID(id int) (string, error) {
348345}
349346
350347// GetAllConversationsList retrieves all conversations with optional filtering, ordering, and pagination.
351- func (c * Manager ) GetAllConversationsList (order , orderBy , filters string , page , pageSize int ) ([]models.ConversationListItem , error ) {
352- return c .GetConversations (0 , []int {}, []string {models .AllConversations }, order , orderBy , filters , page , pageSize )
348+ func (c * Manager ) GetAllConversationsList (viewingUserID int , order , orderBy , filters string , page , pageSize int ) ([]models.ConversationListItem , error ) {
349+ return c .GetConversations (viewingUserID , 0 , []int {}, []string {models .AllConversations }, order , orderBy , filters , page , pageSize )
353350}
354351
355352// GetAssignedConversationsList retrieves conversations assigned to a specific user with optional filtering, ordering, and pagination.
356- func (c * Manager ) GetAssignedConversationsList (userID int , order , orderBy , filters string , page , pageSize int ) ([]models.ConversationListItem , error ) {
357- return c .GetConversations (userID , []int {}, []string {models .AssignedConversations }, order , orderBy , filters , page , pageSize )
353+ func (c * Manager ) GetAssignedConversationsList (viewingUserID , userID int , order , orderBy , filters string , page , pageSize int ) ([]models.ConversationListItem , error ) {
354+ return c .GetConversations (viewingUserID , userID , []int {}, []string {models .AssignedConversations }, order , orderBy , filters , page , pageSize )
358355}
359356
360357// GetUnassignedConversationsList retrieves conversations assigned to a team the user is part of with optional filtering, ordering, and pagination.
361- func (c * Manager ) GetUnassignedConversationsList (order , orderBy , filters string , page , pageSize int ) ([]models.ConversationListItem , error ) {
362- return c .GetConversations (0 , []int {}, []string {models .UnassignedConversations }, order , orderBy , filters , page , pageSize )
358+ func (c * Manager ) GetUnassignedConversationsList (viewingUserID int , order , orderBy , filters string , page , pageSize int ) ([]models.ConversationListItem , error ) {
359+ return c .GetConversations (viewingUserID , 0 , []int {}, []string {models .UnassignedConversations }, order , orderBy , filters , page , pageSize )
363360}
364361
365362// GetTeamUnassignedConversationsList retrieves conversations assigned to a team with optional filtering, ordering, and pagination.
366- func (c * Manager ) GetTeamUnassignedConversationsList (teamID int , order , orderBy , filters string , page , pageSize int ) ([]models.ConversationListItem , error ) {
367- return c .GetConversations (0 , []int {teamID }, []string {models .TeamUnassignedConversations }, order , orderBy , filters , page , pageSize )
363+ func (c * Manager ) GetTeamUnassignedConversationsList (viewingUserID , teamID int , order , orderBy , filters string , page , pageSize int ) ([]models.ConversationListItem , error ) {
364+ return c .GetConversations (viewingUserID , 0 , []int {teamID }, []string {models .TeamUnassignedConversations }, order , orderBy , filters , page , pageSize )
368365}
369366
370- func (c * Manager ) GetViewConversationsList (userID int , teamIDs []int , listType []string , order , orderBy , filters string , page , pageSize int ) ([]models.ConversationListItem , error ) {
371- return c .GetConversations (userID , teamIDs , listType , order , orderBy , filters , page , pageSize )
367+ func (c * Manager ) GetViewConversationsList (viewingUserID , userID int , teamIDs []int , listType []string , order , orderBy , filters string , page , pageSize int ) ([]models.ConversationListItem , error ) {
368+ return c .GetConversations (viewingUserID , userID , teamIDs , listType , order , orderBy , filters , page , pageSize )
372369}
373370
374371// GetConversations retrieves conversations list based on user ID, type, and optional filtering, ordering, and pagination.
375- func (c * Manager ) GetConversations (userID int , teamIDs []int , listTypes []string , order , orderBy , filters string , page , pageSize int ) ([]models.ConversationListItem , error ) {
372+ // viewingUserID is used to calculate per-agent unread counts.
373+ func (c * Manager ) GetConversations (viewingUserID , userID int , teamIDs []int , listTypes []string , order , orderBy , filters string , page , pageSize int ) ([]models.ConversationListItem , error ) {
376374 var conversations = make ([]models.ConversationListItem , 0 )
377375
378376 // Make the query.
379- query , qArgs , err := c .makeConversationsListQuery (userID , teamIDs , listTypes , c .q .GetConversations , order , orderBy , page , pageSize , filters )
377+ query , qArgs , err := c .makeConversationsListQuery (viewingUserID , userID , teamIDs , listTypes , c .q .GetConversations , order , orderBy , page , pageSize , filters )
380378 if err != nil {
381379 c .lo .Error ("error making conversations query" , "error" , err )
382380 return conversations , envelope .NewError (envelope .GeneralError , c .i18n .Ts ("globals.messages.errorFetching" , "name" , "{globals.terms.conversation}" ), nil )
@@ -1068,8 +1066,9 @@ func (c *Manager) getConversationTags(uuid string) ([]string, error) {
10681066}
10691067
10701068// makeConversationsListQuery prepares a SQL query string for conversations list
1071- func (c * Manager ) makeConversationsListQuery (userID int , teamIDs []int , listTypes []string , baseQuery , order , orderBy string , page , pageSize int , filtersJSON string ) (string , []interface {}, error ) {
1072- var qArgs []interface {}
1069+ // viewingUserID is used as $1 for per-agent unread count calculation
1070+ func (c * Manager ) makeConversationsListQuery (viewingUserID , userID int , teamIDs []int , listTypes []string , baseQuery , order , orderBy string , page , pageSize int , filtersJSON string ) (string , []interface {}, error ) {
1071+ qArgs := []any {viewingUserID }
10731072
10741073 // Set defaults
10751074 if orderBy == "" {
0 commit comments