feat(cosmetics): оформление профиля — галерея, роли и личные стили

- миграция 00013: guild_cosmetics (рамки и иконки) и user_styles («для друзей»
  и пер-серверные стили) (AGENT.md 7.2, 7.4)
- store: CRUD галереи, личные стили и вычисление оформления поэлементно
  (роль → пер-серверный стиль → «для друзей» → дефолт) с откатом, когда роль
  больше не выдаёт элемент
- API: галерея сервера под MANAGE_ROLES, оформление роли в create/update,
  GET/PUT/DELETE /users/@me/styles с доступными элементами по областям
- клиент: редактор личного стиля с предпросмотром, галерея оформления в
  настройках сервера, оформление роли в разделе «Роли»
- рендер: рамка под аватаром, иконка рядом с ником, цвет и встроенные эффекты
  ника (CSS, при reduced-motion статично) в ленте и списке участников
This commit is contained in:
2026-09-21 01:28:48 +03:00
parent 2e038a1d3f
commit 48e30a1897
25 changed files with 3542 additions and 41 deletions
+46 -1
View File
@@ -676,6 +676,31 @@
"hint": "Profile badges and frames.",
"empty": "No decorations yet.",
"stub": "Badges, frames and profile effects are coming later."
},
"style": {
"title": "Profile decoration",
"description": "Frame, icon, nick colour and effect. You can only pick what your roles grant: on a server the role wins, then the per-server style, then the friends style.",
"scope": "Where to apply",
"scopeGlobal": "For friends (DMs and global places)",
"preview": "preview",
"frame": "Avatar frame",
"badge": "Icon next to the nick",
"color": "Nick colour",
"colorDefault": "Same as role",
"effect": "Nick effect",
"none": "No element",
"noFrames": "No frames granted by roles yet — a server admin grants them.",
"noBadges": "No icons granted by roles yet.",
"reset": "Reset style",
"priorityHint": "Changes apply immediately.",
"effects": {
"none": "No effect",
"gradient": "Gradient",
"glow": "Glow",
"fire": "Fire",
"shimmer": "Shimmer",
"glitch": "Glitch"
}
}
},
"security": {
@@ -842,7 +867,12 @@
"description": "Role colour and position. Role management arrives in the next phases.",
"empty": "This server has no roles yet.",
"position": "Position {{position}}",
"default": "default"
"default": "default",
"frame": "Frame",
"badge": "Icon",
"nickColor": "Nick colour",
"nickEffect": "Nick effect",
"decorationSaved": "Role decoration saved."
},
"danger": {
"title": "Danger zone",
@@ -986,6 +1016,21 @@
"empty": "none",
"notImage": "An image file is required (PNG, JPEG, GIF, WebP).",
"tooLarge": "The file is larger than 8 MB."
},
"cosmetics": {
"title": "Decoration gallery",
"description": "Avatar frames and icons next to the nick. Uploaded items are granted to roles in the Roles section; animated GIF and WebP keep their animation.",
"upload": "Upload",
"empty": "Nothing uploaded yet.",
"limit": "{{used}} of {{total}} used",
"name": "Item name",
"notImage": "An image file is required",
"tooLarge": "File is larger than 5 MB",
"deleteConfirm": "Delete the item? It disappears from all roles and personal styles.",
"kind": {
"frame": "Frames",
"badge": "Icons"
}
}
},
"navLabel": "Settings sections",
+46 -1
View File
@@ -676,6 +676,31 @@
"hint": "Бейджи и рамки профиля.",
"empty": "Украшений пока нет.",
"stub": "Бейджи, рамки и эффекты профиля появятся позже."
},
"style": {
"title": "Оформление профиля",
"description": "Рамка, иконка, цвет и эффект ника. Выбирать можно только то, что выдали роли: на сервере приоритет у роли, затем у пер-серверного стиля, затем у стиля «для друзей».",
"scope": "Где применять",
"scopeGlobal": "Для друзей (DM и глобальные места)",
"preview": "предпросмотр",
"frame": "Рамка аватара",
"badge": "Иконка рядом с ником",
"color": "Цвет ника",
"colorDefault": "Как у роли",
"effect": "Эффект ника",
"none": "Без элемента",
"noFrames": "Роли пока не выдали ни одной рамки — их выдаёт администратор сервера.",
"noBadges": "Роли пока не выдали ни одной иконки.",
"reset": "Сбросить стиль",
"priorityHint": "Изменения применяются сразу.",
"effects": {
"none": "Без эффекта",
"gradient": "Градиент",
"glow": "Свечение",
"fire": "Огонь",
"shimmer": "Блик",
"glitch": "Глитч"
}
}
},
"security": {
@@ -842,7 +867,12 @@
"description": "Цвет и позиция ролей. Управление ролями появится в следующих фазах.",
"empty": "На сервере пока нет ролей.",
"position": "Позиция {{position}}",
"default": "по умолчанию"
"default": "по умолчанию",
"frame": "Рамка",
"badge": "Иконка",
"nickColor": "Цвет ника",
"nickEffect": "Эффект ника",
"decorationSaved": "Оформление роли сохранено."
},
"danger": {
"title": "Опасная зона",
@@ -986,6 +1016,21 @@
"empty": "нет",
"notImage": "Нужен файл изображения (PNG, JPEG, GIF, WebP).",
"tooLarge": "Файл больше 8 МБ."
},
"cosmetics": {
"title": "Галерея оформления",
"description": "Рамки аватара и иконки рядом с ником. Загруженные элементы выдаются ролям в разделе «Роли»; анимированные GIF и WebP сохраняют анимацию.",
"upload": "Загрузить",
"empty": "Пока ничего не загружено.",
"limit": "занято {{used}} из {{total}}",
"name": "Имя элемента",
"notImage": "Нужен файл изображения",
"tooLarge": "Файл больше 5 МБ",
"deleteConfirm": "Удалить элемент? Он исчезнет у всех ролей и в личных стилях.",
"kind": {
"frame": "Рамки",
"badge": "Иконки"
}
}
},
"navLabel": "Пункты настроек",