feat(dm): иконка групповой беседы в хранилище и API (Фаза 7)
D-070: у групповой беседы не было своей иконки — показывались имя и первая
буква аватара, как у 1:1 без аватара. Колонки под файл у канала не было.
Миграция 00024 добавляет `channels.icon_file_id` (REFERENCES files ON DELETE
SET NULL): NULL у 1:1 и комнат сервера, файл — у группы. Store читает и пишет
поле через `Channel`/`UpdateChannelParams` (`IconFileID`/`ClearIcon`), отдаёт
его в `ListDMChannels` и в READY, а уборка сирот больше не считает иконку
беседы мусором. Когда в группе остаётся два участника, беседа снова обычная
личная — иконка сбрасывается вместе с именем и владельцем.
Ручки `POST/DELETE /channels/{id}/icon` принимают multipart (назначение файла
`dm_icon`, аватарный лимит, проверка `image/`) и доступны только владельцу
беседы: участнику-не-владельцу 403 `perm.denied`, посторонним 404 (существование
чужой беседы не подтверждаем), у 1:1 своей иконки нет — 422 `dm.not_group`.
Файл иконки отдаётся только участникам беседы. После изменения участникам
уходит `DM_CHANNEL_UPDATE`, поэтому иконка меняется без перезагрузки
(AGENT.md 7.7, 7.8, 8.3, 11.6; D-042, D-070).
This commit is contained in:
@@ -93,7 +93,8 @@ func (s *Snapshot) Build(ctx context.Context, user *store.User) (*Ready, error)
|
||||
Status: visibleStatus(summary.Status, summary.LastSeenAt),
|
||||
}
|
||||
if summary.IsGroup {
|
||||
// Групповая беседа: имя и состав вместо собеседника.
|
||||
// Групповая беседа: имя и состав вместо собеседника, иконка — своя
|
||||
// загрузка (D-070), а не аватар участника.
|
||||
channel.IsGroup = true
|
||||
channel.Name = summary.GroupName
|
||||
channel.MemberCount = summary.MemberCount
|
||||
@@ -104,8 +105,11 @@ func (s *Snapshot) Build(ctx context.Context, user *store.User) (*Ready, error)
|
||||
if summary.OwnerID != nil {
|
||||
channel.OwnerID = formatID(*summary.OwnerID)
|
||||
}
|
||||
}
|
||||
if summary.AvatarFileID != nil {
|
||||
if summary.Channel.IconFileID != nil {
|
||||
channel.IconFileID = formatID(*summary.Channel.IconFileID)
|
||||
}
|
||||
} else if summary.AvatarFileID != nil {
|
||||
// У 1:1 иконка беседы — аватар собеседника (AGENT.md 7.8).
|
||||
channel.IconFileID = formatID(*summary.AvatarFileID)
|
||||
}
|
||||
if summary.LastMessageID != 0 {
|
||||
|
||||
Reference in New Issue
Block a user