fix: chat UI

This commit is contained in:
Krispire Admin
2026-08-29 17:30:14 +05:30
parent 7a730cd42e
commit 44120efdec
7 changed files with 513 additions and 19 deletions
+54
View File
@@ -1157,6 +1157,60 @@ func (r *ChatRepo) ReportMessage(ctx context.Context, reporterID, messageID, con
return nil
}
// PushCandidate is a participant plus the state that decides whether a new
// message should reach them out-of-band.
type PushCandidate struct {
UserID string
MutedUntil *time.Time
LastReadSeq int64
}
// PushCandidates lists everyone still in the thread except the sender.
func (r *ChatRepo) PushCandidates(ctx context.Context, conversationID, senderID string) ([]PushCandidate, error) {
rows, err := r.pg.Pool.Query(ctx, `
SELECT user_id, muted_until, last_read_seq
FROM conversation_participants
WHERE conversation_id = $1 AND user_id <> $2 AND left_at IS NULL`,
conversationID, senderID)
if err != nil {
return nil, fmt.Errorf("push candidates: %w", err)
}
defer rows.Close()
out := []PushCandidate{}
for rows.Next() {
var c PushCandidate
if err := rows.Scan(&c.UserID, &c.MutedUntil, &c.LastReadSeq); err != nil {
return nil, fmt.Errorf("scan push candidate: %w", err)
}
out = append(out, c)
}
return out, rows.Err()
}
// UnreadConversations counts the caller's threads holding unread messages.
//
// Counts THREADS, not messages: the badge answers "is anything waiting for
// me?", and one chatty group shouldn't dominate it.
//
// Muted threads are excluded. Unread still accrues on them and the inbox still
// shows it — mute silences the alert, and a badge is an alert.
func (r *ChatRepo) UnreadConversations(ctx context.Context, userID string) (int, error) {
var n int
err := r.pg.Pool.QueryRow(ctx, `
SELECT count(*)
FROM conversation_participants p
JOIN conversations c ON c.id = p.conversation_id
WHERE p.user_id = $1
AND p.left_at IS NULL
AND c.last_seq > p.last_read_seq
AND (p.muted_until IS NULL OR p.muted_until <= now())`, userID).Scan(&n)
if err != nil {
return 0, fmt.Errorf("count unread conversations: %w", err)
}
return n, nil
}
// SetMute sets or clears the caller's mute on a thread. A nil until unmutes.
//
// Mute is per participant, not per conversation: muting a group silences it for