feat(cosmetics): оформление «для друзей» в друзьях и личных беседах

- API: список друзей отдаёт вычисленное оформление «для друзей» одним запросом
  на весь список (AGENT.md 7.2)
- клиент: рамка, иконка, цвет и эффект ника в списке друзей, в ленте личных
  бесед — из профиля собеседника
- тесты: Go на список друзей, Vitest на отрисовку в друзьях
This commit is contained in:
2026-09-21 01:48:56 +03:00
parent 75b71da7b7
commit a36ee9527b
8 changed files with 192 additions and 5 deletions
+15 -1
View File
@@ -29,6 +29,9 @@ type relationshipUser struct {
Timezone string `json:"timezone"`
// Relationship: friend | incoming | outgoing | blocked | none
Relationship string `json:"relationship"`
// Cosmetics — оформление «для друзей»: в DM и списке друзей применяется
// именно оно (AGENT.md 7.2).
Cosmetics *cosmeticsPayload `json:"cosmetics,omitempty"`
}
type relationshipListOutput struct {
@@ -398,9 +401,20 @@ func (s *Server) relationshipProfiles(ctx context.Context, userID uint64, kind s
if err != nil {
return nil, humaError(err)
}
// Оформление «для друзей» (AGENT.md 7.2) — одним запросом на весь список.
ids := make([]uint64, 0, len(profiles))
for i := range profiles {
ids = append(ids, profiles[i].UserID)
}
cosmetics, err := s.store.EffectiveCosmeticsForUsers(ctx, ids)
if err != nil {
return nil, humaError(err)
}
result := make([]relationshipUser, 0, len(profiles))
for i := range profiles {
result = append(result, s.relationshipPayload(userID, &profiles[i], string(kind)))
payload := s.relationshipPayload(userID, &profiles[i], string(kind))
payload.Cosmetics = cosmeticsFromEffective(cosmetics[profiles[i].UserID])
result = append(result, payload)
}
return result, nil
}