Simplify: общий загрузчик файлов и единые ключи на фронте
- Четыре копии «ресайз → FormData → CSRF из cookie → fetch → разбор конверта ошибки» (аватар, фото партии, фото из админки, иконка ачивки) сведены в lib/upload.ts. Иконка по-прежнему уходит оригиналом: ресайз в JPEG убил бы прозрачность герба. - Три копии readCsrfToken и вторая копия resizeImage удалены — берём readCookie из api/client.ts и resizeImage из lib/image.ts с параметром размера. - Ключи, протухающие от партии, собраны в matchAffectedKeys: раньше они были написаны строками мимо реестра qk в двух местах, и переименование ключа сломало бы инвалидацию молча. - Различение «нет сессии» и «нет связи» вынесено в authProbeRetry и применено к обеим пробам. Прошлый заход чинил только игроцкие гварды, и RequireAdmin по-прежнему выкидывал админа на страницу входа при обрыве связи. - ToastContext больше не пересоздаёт значение контекста: провайдер обёрнут вокруг всего приложения, и каждый тост перерисовывал всех потребителей. - PlaceEditor не трогает DOM, пока цель подсветки не изменилась (было querySelectorAll на каждый pointermove). #8 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BoiJK9ux8peeyjLb8TYjFf
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { useEffect } from "react";
|
||||
|
||||
import { qk } from "../api/queryKeys";
|
||||
import { matchAffectedKeys, qk } from "../api/queryKeys";
|
||||
|
||||
interface ServerEvent {
|
||||
type: "match" | "group" | "invitations" | "notifications";
|
||||
@@ -38,13 +38,8 @@ export function useServerEvents(enabled: boolean) {
|
||||
qc.invalidateQueries({ queryKey: qk.groupMatches(ev.group_id) });
|
||||
qc.invalidateQueries({ queryKey: qk.groupStats(ev.group_id) });
|
||||
}
|
||||
qc.invalidateQueries({ queryKey: qk.home });
|
||||
qc.invalidateQueries({ queryKey: qk.leaderboard });
|
||||
// История игр и публичный профиль тоже меняются от чужой партии: без этих
|
||||
// двух ключей открытый профиль показывал бы состав до завершения.
|
||||
qc.invalidateQueries({ queryKey: ["userMatches"] });
|
||||
qc.invalidateQueries({ queryKey: ["publicProfile"] });
|
||||
qc.invalidateQueries({ queryKey: qk.myStats });
|
||||
// История игр и публичные профили тоже меняются от чужой партии.
|
||||
for (const key of matchAffectedKeys) qc.invalidateQueries({ queryKey: key });
|
||||
} else if (ev.type === "group") {
|
||||
if (ev.group_id != null) {
|
||||
qc.invalidateQueries({ queryKey: qk.group(ev.group_id) });
|
||||
|
||||
Reference in New Issue
Block a user