package social import ( "context" "github.com/google/uuid" "pipu/api/internal/api/gen" ) // Read all previews in one query. Recheck friendship and both block directions // here so a removed relationship cannot expose history through the inbox. func (s *Store) attachLastMessages(ctx context.Context, viewer uuid.UUID, people []gen.SocialPerson) error { positions := map[uuid.UUID]int{} ids := []uuid.UUID{} for i, p := range people { if p.Relationship == "friend" { positions[p.Id] = i ids = append(ids, p.Id) } } if len(ids) == 0 { return nil } rows, e := s.pool.Query(ctx, `SELECT p.peer_id,m.id,m.sender_id, CASE WHEN m.deleted_at IS NULL THEN left(m.text,160) ELSE '' END, m.attachment_kind,m.created_at,m.deleted_at IS NOT NULL FROM unnest($2::uuid[]) AS p(peer_id) JOIN friendships f ON f.low_id=LEAST($1::uuid,p.peer_id) AND f.high_id=GREATEST($1::uuid,p.peer_id) AND f.accepted JOIN LATERAL (SELECT * FROM direct_messages WHERE LEAST(sender_id,recipient_id)=LEAST($1::uuid,p.peer_id) AND GREATEST(sender_id,recipient_id)=GREATEST($1::uuid,p.peer_id) ORDER BY seq DESC LIMIT 1) m ON true WHERE NOT EXISTS(SELECT 1 FROM social_blocks b WHERE (b.user_id=$1 AND b.peer_id=p.peer_id) OR (b.peer_id=$1 AND b.user_id=p.peer_id))`, viewer, ids) if e != nil { return e } defer rows.Close() for rows.Next() { var peer uuid.UUID var preview gen.SocialMessagePreview if e = rows.Scan(&peer, &preview.Id, &preview.SenderId, &preview.Text, &preview.AttachmentKind, &preview.CreatedAt, &preview.Deleted); e != nil { return e } people[positions[peer]].LastMessage = &preview } return rows.Err() }