Add live account appeal updates and restricted status settings
This commit is contained in:
@@ -8,6 +8,7 @@ import type {
|
||||
AccountAppealRecord,
|
||||
} from "@/shared/account-controls";
|
||||
import styles from "@/app/ban/appeal/page.module.css";
|
||||
import { useAppealRealtime } from "./useAppealRealtime";
|
||||
|
||||
export function AccountControls({
|
||||
administrator,
|
||||
@@ -28,6 +29,7 @@ export function AccountControls({
|
||||
const [message, setMessage] = useState("");
|
||||
const [busy, setBusy] = useState(false);
|
||||
const lock = useRef(false);
|
||||
const appealReads = useRef(0);
|
||||
const [selected, setSelected] = useState<{
|
||||
account: ManagedAccount;
|
||||
action: "deactivate" | "ban" | "restore" | "delete";
|
||||
@@ -37,19 +39,38 @@ export function AccountControls({
|
||||
const [reviewReasons, setReviewReasons] = useState<Record<string, string>>(
|
||||
{},
|
||||
);
|
||||
const realtime = useAppealRealtime({
|
||||
enabled: showAppeals,
|
||||
refresh: async () => {
|
||||
const version = ++appealReads.current;
|
||||
const result = await api<{ appeals: AccountAppealRecord[] }>(
|
||||
"moderation/account-appeals",
|
||||
);
|
||||
if (version === appealReads.current) {
|
||||
setAppeals(result.appeals);
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
setError((error as Error).message);
|
||||
setLoading(false);
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!showAppeals) return;
|
||||
let active = true;
|
||||
const version = ++appealReads.current;
|
||||
api<{ appeals: AccountAppealRecord[] }>("moderation/account-appeals")
|
||||
.then((data) => {
|
||||
if (active) setAppeals(data.appeals);
|
||||
if (active && version === appealReads.current) setAppeals(data.appeals);
|
||||
})
|
||||
.catch((e) => {
|
||||
if (active) setError((e as Error).message);
|
||||
if (active && version === appealReads.current)
|
||||
setError((e as Error).message);
|
||||
})
|
||||
.finally(() => {
|
||||
if (active) setLoading(false);
|
||||
if (active && version === appealReads.current) setLoading(false);
|
||||
});
|
||||
return () => {
|
||||
active = false;
|
||||
@@ -81,16 +102,14 @@ export function AccountControls({
|
||||
async function refreshAppeals() {
|
||||
if (!showAppeals) return;
|
||||
setLoading(true);
|
||||
const version = ++appealReads.current;
|
||||
try {
|
||||
setAppeals(
|
||||
(
|
||||
await api<{ appeals: AccountAppealRecord[] }>(
|
||||
"moderation/account-appeals",
|
||||
)
|
||||
).appeals,
|
||||
const result = await api<{ appeals: AccountAppealRecord[] }>(
|
||||
"moderation/account-appeals",
|
||||
);
|
||||
if (version === appealReads.current) setAppeals(result.appeals);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
if (version === appealReads.current) setLoading(false);
|
||||
}
|
||||
}
|
||||
async function save(event: React.FormEvent) {
|
||||
@@ -320,14 +339,29 @@ export function AccountControls({
|
||||
"Модераторы и администраторы могут рассматривать апелляции. Одобрение восстанавливает доступ после этой блокировки. Деактивация и удаление доступны только администраторам.",
|
||||
)}
|
||||
</p>
|
||||
<button
|
||||
className="button"
|
||||
disabled={busy || loading}
|
||||
onClick={() => void run(refreshAppeals)}
|
||||
>
|
||||
<RefreshCw size={16} aria-hidden="true" />
|
||||
{l("Refresh appeals", "Обновить апелляции")}
|
||||
</button>
|
||||
<div className={styles.refreshActions}>
|
||||
<button
|
||||
className="button"
|
||||
disabled={busy || loading}
|
||||
onClick={() => void run(refreshAppeals)}
|
||||
>
|
||||
<RefreshCw size={16} aria-hidden="true" />
|
||||
{l("Refresh appeals", "Обновить апелляции")}
|
||||
</button>
|
||||
<span className="muted">
|
||||
{realtime === "live"
|
||||
? l(
|
||||
"Live updates connected",
|
||||
"Обновления в реальном времени подключены",
|
||||
)
|
||||
: realtime === "offline"
|
||||
? l(
|
||||
"Reconnecting… Refresh remains available.",
|
||||
"Переподключение… Можно обновить вручную.",
|
||||
)
|
||||
: l("Connecting live updates…", "Подключение обновлений…")}
|
||||
</span>
|
||||
</div>
|
||||
{loading && (
|
||||
<p role="status">{l("Loading appeals…", "Загрузка апелляций…")}</p>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user