feat(web): профиль с аватаром, панель в углу, настройки сервера, скрытые ID
Правки пользователя: - в «Профиль → Основной» сверху квадратный аватар слева, справа от него настройки имени, «О себе», состояния и эмодзи во всю высоту; смена аватара — клик по нему, форматы (JPEG, PNG, WebP, GIF до 8 МБ) — в подсказке; - убраны дубли: часовой пояс только в «Язык и регион», статус — только в мини-профиле панели; - панель пользователя переехала в нижний левый угол под сайдбар, подсказка о выходе из сервера — на её прежнее место; панель ужата под 240 px; - шестерёнка сервера открывает новый пункт настроек «Сервер» (список серверов, общее, участники, роли, опасная зона), а «Профиль → Сервер» оставлен только для ника и «Применить ко всем серверам»; - окно настроек получило статический размер 70% рабочей области со скроллом; - ID пользователей скрыты везде, кроме раздела «Инстанс» у администратора; - список друзей свёрнут под кнопкой «Друзья (N)» и раскрывается снизу вверх; - 249 тестов Vitest (было 239), check/lint/test/build зелёные.
This commit is contained in:
+29
-13
@@ -121,16 +121,15 @@ function saveNear(label: string): HTMLElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* Открывает настройки сервера: приложение → мини-профиль → «Настройки серверов».
|
||||
* Так же их открывает и обычный участник без прав администратора.
|
||||
* Открывает администрирование сервера: приложение → мини-профиль →
|
||||
* «Настройки серверов» → пункт «Сервер». Так же его открывает шестерёнка
|
||||
* в шапке сервера.
|
||||
*/
|
||||
async function openServerSettings(path = '/app/empty', guildName?: string) {
|
||||
const view = renderApp(path);
|
||||
const trigger = await screen.findByLabelText('Открыть меню пользователя');
|
||||
await userEvent.click(trigger);
|
||||
const menu = await screen.findByRole('menu', { name: 'Меню пользователя' });
|
||||
await userEvent.click(within(menu).getByRole('menuitem', { name: 'Настройки серверов' }));
|
||||
await screen.findByRole('dialog', { name: 'Настройки' });
|
||||
const dialog = await openSettingsWindow();
|
||||
const nav = within(dialog).getByTestId('settings-nav');
|
||||
await userEvent.click(await within(nav).findByRole('button', { name: 'Сервер' }));
|
||||
|
||||
if (guildName !== undefined) {
|
||||
const picker = await openGuildPicker();
|
||||
@@ -139,7 +138,24 @@ async function openServerSettings(path = '/app/empty', guildName?: string) {
|
||||
return view;
|
||||
}
|
||||
|
||||
/** Раскрывает выпадающий список серверов во вкладке «Профиль → Сервер». */
|
||||
/**
|
||||
* Открывает «Профиль → Сервер»: личный ник и «Применить ко всем серверам».
|
||||
* Доступно и обычному участнику без прав администратора.
|
||||
*/
|
||||
async function openProfileServerTab(path = '/app/empty') {
|
||||
const view = renderApp(path);
|
||||
await openSettingsWindow();
|
||||
await userEvent.click(await screen.findByRole('tab', { name: 'Сервер' }));
|
||||
return view;
|
||||
}
|
||||
|
||||
/** Окно настроек открывается шестерёнкой в панели пользователя. */
|
||||
async function openSettingsWindow(): Promise<HTMLElement> {
|
||||
await userEvent.click(await screen.findByLabelText('Настройки пользователя'));
|
||||
return screen.findByRole('dialog', { name: 'Настройки' });
|
||||
}
|
||||
|
||||
/** Раскрывает выпадающий список серверов в настройках. */
|
||||
async function openGuildPicker(): Promise<HTMLElement> {
|
||||
await userEvent.click(await screen.findByLabelText('Выбрать сервер'));
|
||||
return screen.findByRole('menu', { name: 'Мои серверы' });
|
||||
@@ -210,7 +226,7 @@ describe('настройки серверов', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('сохраняет свой никнейм через PATCH /guilds/{id}/members/{me}', async () => {
|
||||
it('сохраняет свой никнейм в «Профиль → Сервер» через PATCH /guilds/{id}/members/{me}', async () => {
|
||||
const fetchMock = installFetch(
|
||||
serversRoutes([
|
||||
{
|
||||
@@ -221,7 +237,7 @@ describe('настройки серверов', () => {
|
||||
]),
|
||||
);
|
||||
|
||||
await openServerSettings();
|
||||
await openProfileServerTab();
|
||||
|
||||
const nickname = await screen.findByLabelText('Никнейм');
|
||||
await waitFor(() => {
|
||||
@@ -239,7 +255,7 @@ describe('настройки серверов', () => {
|
||||
expect(patch?.body).toEqual({ nickname: 'Алиса' });
|
||||
});
|
||||
|
||||
it('применяет введённый ник ко всем серверам по очереди', async () => {
|
||||
it('применяет введённый ник ко всем серверам по очереди (вкладка профиля)', async () => {
|
||||
const fetchMock = installFetch(
|
||||
serversRoutes([
|
||||
{
|
||||
@@ -255,7 +271,7 @@ describe('настройки серверов', () => {
|
||||
]),
|
||||
);
|
||||
|
||||
await openServerSettings();
|
||||
await openProfileServerTab();
|
||||
|
||||
const nickname = await screen.findByLabelText('Никнейм');
|
||||
await userEvent.clear(nickname);
|
||||
@@ -387,7 +403,7 @@ describe('настройки серверов', () => {
|
||||
{ match: '/api/v1/instance', response: () => json({ instance: { name: 'glchat-test' } }) },
|
||||
]);
|
||||
|
||||
await openServerSettings();
|
||||
await openProfileServerTab();
|
||||
|
||||
const content = screen.getByTestId('settings-content');
|
||||
expect(await within(content).findByText('Пока нет ни одного сервера')).toBeVisible();
|
||||
|
||||
Reference in New Issue
Block a user