Improve MineGeo UI and application flows
Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 2m37s
Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 2m37s
This commit is contained in:
@@ -9,6 +9,8 @@ import {
|
||||
difficulties,
|
||||
customDifficultySchema,
|
||||
type DifficultyPreset,
|
||||
type ScoringMode,
|
||||
difficultyRuleDefaults,
|
||||
} from "@/shared/protocol";
|
||||
import { api } from "@/lib/client-api";
|
||||
import { mergeDifficultyPresets } from "@/shared/difficulty-presets";
|
||||
@@ -27,6 +29,13 @@ export function StartGame({
|
||||
[difficultyName, setDifficultyName] = useState(""),
|
||||
[difficultySeconds, setDifficultySeconds] = useState(90),
|
||||
[difficultyZoom, setDifficultyZoom] = useState(true),
|
||||
[difficultyRules, setDifficultyRules] = useState<{
|
||||
pan: boolean;
|
||||
compass: boolean;
|
||||
coordinates: boolean;
|
||||
mapZoom: boolean;
|
||||
scoring: ScoringMode;
|
||||
}>(difficultyRuleDefaults),
|
||||
[savingDifficulty, setSavingDifficulty] = useState(false),
|
||||
[mode, setMode] = useState<"solo" | "multiplayer">("solo"),
|
||||
[playerLimit, setPlayerLimit] = useState(4),
|
||||
@@ -67,6 +76,7 @@ export function StartGame({
|
||||
name: difficultyName,
|
||||
seconds: difficultySeconds,
|
||||
zoom: difficultyZoom,
|
||||
...difficultyRules,
|
||||
});
|
||||
if (!parsed.success) {
|
||||
setError(parsed.error.issues[0].message);
|
||||
@@ -85,6 +95,7 @@ export function StartGame({
|
||||
setDifficultyName("");
|
||||
setDifficultySeconds(90);
|
||||
setDifficultyZoom(true);
|
||||
setDifficultyRules(difficultyRuleDefaults);
|
||||
setShowDifficultyForm(false);
|
||||
} catch (failure) {
|
||||
setError((failure as Error).message);
|
||||
@@ -157,6 +168,18 @@ export function StartGame({
|
||||
<ZoomIn size={13} />
|
||||
{option.zoom ? t("Zoom allowed") : t("No zoom")}
|
||||
</span>
|
||||
{!(option.id in difficulties) && (
|
||||
<span>
|
||||
{t(
|
||||
option.scoring === "strict"
|
||||
? "Strict scoring"
|
||||
: option.scoring === "gentle"
|
||||
? "Gentle scoring"
|
||||
: "Normal scoring",
|
||||
)}{" "}
|
||||
· {t(option.pan === false ? "Fixed view" : "Panning allowed")}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -219,6 +242,52 @@ export function StartGame({
|
||||
/>
|
||||
{t("Allow zoom")}
|
||||
</label>
|
||||
{(
|
||||
[
|
||||
["pan", "Allow panorama panning"],
|
||||
["compass", "Show north indicator"],
|
||||
["coordinates", "Show guess coordinates"],
|
||||
["mapZoom", "Allow guess-map zoom"],
|
||||
] as const
|
||||
).map(([key, label]) => (
|
||||
<label className="difficulty-builder-zoom" key={key}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={difficultyRules[key]}
|
||||
disabled={savingDifficulty || loading}
|
||||
onChange={(event) =>
|
||||
setDifficultyRules((previous) => ({
|
||||
...previous,
|
||||
[key]: event.target.checked,
|
||||
}))
|
||||
}
|
||||
/>
|
||||
{t(label)}
|
||||
</label>
|
||||
))}
|
||||
<label htmlFor="custom-difficulty-scoring">
|
||||
{t("Scoring strictness")}
|
||||
</label>
|
||||
<select
|
||||
id="custom-difficulty-scoring"
|
||||
value={difficultyRules.scoring}
|
||||
disabled={savingDifficulty || loading}
|
||||
onChange={(event) =>
|
||||
setDifficultyRules((previous) => ({
|
||||
...previous,
|
||||
scoring: event.target.value as ScoringMode,
|
||||
}))
|
||||
}
|
||||
>
|
||||
<option value="normal">{t("Normal scoring")}</option>
|
||||
<option value="strict">{t("Strict scoring")}</option>
|
||||
<option value="gentle">{t("Gentle scoring")}</option>
|
||||
</select>
|
||||
<p className="muted">
|
||||
{t(
|
||||
"Strict scoring penalizes distance more; gentle scoring gives more credit for nearby guesses. Every game still has five rounds.",
|
||||
)}
|
||||
</p>
|
||||
<button
|
||||
className="button primary"
|
||||
disabled={savingDifficulty || loading}
|
||||
|
||||
Reference in New Issue
Block a user