fix: chat UI
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user