feat(social): блокировка пользователей
- PUT/DELETE /users/@me/blocks/{id}: блокировка снимает дружбу и заявки в обе
стороны, разблокировка возвращает возможность писать (AGENT.md 7.2)
- блокировка запрещает личные сообщения (ошибка dm.blocked), открытие беседы и
заявки в друзья с любой стороны
- клиент: раздел «Заблокированные» в друзьях со снятием блокировки, действие
«Заблокировать» в меню строки друга и в меню модерации участника
- тесты: Go (блокировка, заявки, беседа, сообщение) и Vitest (список, снятие,
блокировка из меню)
This commit is contained in:
@@ -9,7 +9,9 @@ import {
|
||||
kickGuildMember,
|
||||
timeoutGuildMember,
|
||||
} from '@/api/moderation';
|
||||
import { blockUser } from '@/api/friends';
|
||||
import { Menu, MenuGroupLabel, MenuItem, MenuSeparator } from '@/components/ui/Menu';
|
||||
import { useFriendsStore } from '@/stores/friends';
|
||||
import { useApiErrorMessage } from '@/lib/useApiErrorMessage';
|
||||
|
||||
/** Пресеты тайм-аута в минутах: 0 — снять ограничение. */
|
||||
@@ -64,6 +66,17 @@ export function MemberModerationMenu({
|
||||
close();
|
||||
},
|
||||
});
|
||||
const reloadRelationships = useFriendsStore((state) => state.reload);
|
||||
const blockedUsers = useFriendsStore((state) => state.blocked);
|
||||
const blocked = blockedUsers.some((entry) => entry.user_id === userId);
|
||||
|
||||
const block = useMutation({
|
||||
mutationFn: () => blockUser(userId),
|
||||
onSuccess: () => {
|
||||
void reloadRelationships();
|
||||
},
|
||||
});
|
||||
|
||||
const kick = useMutation({
|
||||
mutationFn: () => kickGuildMember(guildId, userId),
|
||||
onSuccess: () => {
|
||||
@@ -162,6 +175,16 @@ export function MemberModerationMenu({
|
||||
</MenuItem>
|
||||
) : null}
|
||||
|
||||
{/* Личная блокировка не зависит от прав на сервере (AGENT.md 7.2). */}
|
||||
<MenuItem
|
||||
danger
|
||||
disabled={pending || blocked}
|
||||
data-testid={`member-block-${userId}`}
|
||||
onClick={() => block.mutate()}
|
||||
>
|
||||
{t(blocked ? 'friends.blocked.alreadyBlocked' : 'friends.list.block')}
|
||||
</MenuItem>
|
||||
|
||||
{error === null || error === undefined ? null : (
|
||||
<p className="px-2 py-1 text-xs text-danger">{describeError(error)}</p>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user