diff --git a/src/client/ClanModal.ts b/src/client/ClanModal.ts index d5c2c468e..e4b1b0886 100644 --- a/src/client/ClanModal.ts +++ b/src/client/ClanModal.ts @@ -16,6 +16,7 @@ import "./components/clan/ClanTransferView"; import "./components/ConfirmDialog"; import "./components/CopyButton"; import { modalHeader } from "./components/ui/ModalHeader"; +import { modalRouter } from "./ModalRouter"; import { translateText } from "./Utils"; type View = @@ -153,6 +154,7 @@ export class ClanModal extends BaseModal { this.selectedClanTag = ""; this.myRole = null; this.detailCache = null; + modalRouter.syncArgs("clan", { clan: null }); }, ariaLabel, rightContent: clan ? this.tagPill(clan.tag) : undefined, @@ -399,6 +401,7 @@ export class ClanModal extends BaseModal { private openDetail(tag: string) { this.selectedClanTag = tag; this.view = "detail"; + modalRouter.syncArgs("clan", { clan: tag }); } private renderMyClans() { diff --git a/src/client/ModalRouter.ts b/src/client/ModalRouter.ts index a2224f86e..377827db2 100644 --- a/src/client/ModalRouter.ts +++ b/src/client/ModalRouter.ts @@ -123,6 +123,24 @@ class ModalRouter { this.replaceHash("#" + params.toString()); } + /** Called when a router-managed modal changes non-tab route state. */ + syncArgs(name: string, args: Record): void { + if (this.routingFromUrl) return; + if (this.currentName !== name) return; + const params = this.currentHashParams(); + params.set("modal", name); + for (const [key, value] of Object.entries(args)) { + if (key === "modal") continue; + if (value === undefined || value === null || value === "") { + params.delete(key); + continue; + } + if (typeof value === "object") continue; + params.set(key, String(value)); + } + this.replaceHash("#" + params.toString()); + } + /** True if the current hash is `#modal=...`. */ isHashRouted(): boolean { const hash = window.location.hash;