ci / api / api (push) Successful in 19m12s
ci / ts / ts (packages + web) (push) Successful in 2m44s
ci / module boundaries / boundaries (push) Successful in 18m23s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 59s
ci / db / db (push) Failing after 18s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m18s
48 lines
1.6 KiB
Go
48 lines
1.6 KiB
Go
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()
|
|
}
|