UI: рандом фракции — убрана подпись «случайная», добавлена анимация-барабан названий в строке
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,8 @@ export function CreateMatchPage() {
|
||||
|
||||
const [rows, setRows] = useState<Draft[]>([emptyDraft(), emptyDraft()]);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
// Анимация-«барабан» рандома: для крутящейся строки — текущее мелькающее название.
|
||||
const [spin, setSpin] = useState<Record<number, string | null>>({});
|
||||
|
||||
if (lm || lf) return <Spinner />;
|
||||
if (!groupId) return <div className="muted">Нет активной группы.</div>;
|
||||
@@ -51,13 +53,25 @@ export function CreateMatchPage() {
|
||||
const removeRow = (idx: number) => setRows((rs) => rs.filter((_, i) => i !== idx));
|
||||
|
||||
const randomizeRow = async (idx: number) => {
|
||||
const pool = factions ?? [];
|
||||
if (pool.length === 0) return;
|
||||
// Запускаем «барабан»: быстро мелькаем названиями фракций.
|
||||
const ticker = setInterval(() => {
|
||||
const name = pool[Math.floor(Math.random() * pool.length)].name_ru;
|
||||
setSpin((s) => ({ ...s, [idx]: name }));
|
||||
}, 60);
|
||||
try {
|
||||
const faction = await randomize.mutateAsync({
|
||||
group_id: groupId,
|
||||
exclude_faction_ids: takenFactionIds(idx),
|
||||
});
|
||||
await new Promise((r) => setTimeout(r, 700)); // даём барабану покрутиться
|
||||
clearInterval(ticker);
|
||||
setSpin((s) => ({ ...s, [idx]: null }));
|
||||
update(idx, { faction_id: faction.id, was_random: true });
|
||||
} catch (e) {
|
||||
clearInterval(ticker);
|
||||
setSpin((s) => ({ ...s, [idx]: null }));
|
||||
toast.show(e instanceof ApiError ? e.message : "Ошибка рандома");
|
||||
}
|
||||
};
|
||||
@@ -137,28 +151,36 @@ export function CreateMatchPage() {
|
||||
</select>
|
||||
|
||||
<div className="row">
|
||||
<select
|
||||
value={row.faction_id}
|
||||
onChange={(e) =>
|
||||
update(idx, {
|
||||
faction_id: e.target.value ? Number(e.target.value) : "",
|
||||
was_random: false,
|
||||
})
|
||||
}
|
||||
style={{ flex: 1 }}
|
||||
{spin[idx] != null ? (
|
||||
<div className="faction-spin" style={{ flex: 1 }}>{spin[idx]}</div>
|
||||
) : (
|
||||
<select
|
||||
value={row.faction_id}
|
||||
onChange={(e) =>
|
||||
update(idx, {
|
||||
faction_id: e.target.value ? Number(e.target.value) : "",
|
||||
was_random: false,
|
||||
})
|
||||
}
|
||||
style={{ flex: 1 }}
|
||||
>
|
||||
<option value="">— фракция —</option>
|
||||
{(factions ?? []).map((f) => (
|
||||
<option key={f.id} value={f.id}>
|
||||
{f.name_ru}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
)}
|
||||
<button
|
||||
className="btn"
|
||||
onClick={() => randomizeRow(idx)}
|
||||
disabled={spin[idx] != null}
|
||||
title="Случайная фракция"
|
||||
>
|
||||
<option value="">— фракция —</option>
|
||||
{(factions ?? []).map((f) => (
|
||||
<option key={f.id} value={f.id}>
|
||||
{f.name_ru}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<button className="btn" onClick={() => randomizeRow(idx)} title="Случайная фракция">
|
||||
<Dices size={18} />
|
||||
</button>
|
||||
</div>
|
||||
{row.was_random && row.faction_id !== "" && <span className="badge">🎲 случайная</span>}
|
||||
</div>
|
||||
))}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user