mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 11:30:43 +00:00
Created ModalHeader and moved/unified all modal headers (#2882)
If this PR fixes an issue, link it below. If not, delete these two lines. Resolves #(issue number) ## Description: Moved the Modal Headers into its own class ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced ## Please put your Discord username so you can be contacted if a bug or regression is found: w.o.n
This commit is contained in:
@@ -14,6 +14,7 @@ import "./components/baseComponents/stats/PlayerStatsTree";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import "./components/Difficulties";
|
||||
import "./components/PatternButton";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
import { copyToClipboard, translateText } from "./Utils";
|
||||
|
||||
@customElement("account-modal")
|
||||
@@ -109,37 +110,11 @@ export class AccountModal extends BaseModal {
|
||||
<div
|
||||
class="h-full flex flex-col bg-black/60 backdrop-blur-md rounded-2xl border border-white/10 overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="flex items-center mb-6 pb-2 border-b border-white/10 gap-2 shrink-0 p-6"
|
||||
>
|
||||
<div class="flex items-center gap-4 flex-1">
|
||||
<button
|
||||
@click=${() => this.close()}
|
||||
class="group flex items-center justify-center w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 transition-all border border-white/10"
|
||||
aria-label="${translateText("common.back")}"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span
|
||||
class="text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase tracking-widest break-words hyphens-auto"
|
||||
>
|
||||
${title}
|
||||
</span>
|
||||
</div>
|
||||
${isLoggedIn
|
||||
${modalHeader({
|
||||
title,
|
||||
onBack: () => this.close(),
|
||||
ariaLabel: translateText("common.back"),
|
||||
rightContent: isLoggedIn
|
||||
? html`
|
||||
<div class="flex items-center gap-2">
|
||||
<span
|
||||
@@ -158,8 +133,8 @@ export class AccountModal extends BaseModal {
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
</div>
|
||||
: undefined,
|
||||
})}
|
||||
|
||||
<div class="flex-1 overflow-y-auto custom-scrollbar mr-1">
|
||||
${isLoggedIn ? this.renderAccountInfo() : this.renderLoginOptions()}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { customElement, query, state } from "lit/decorators.js";
|
||||
import Countries from "resources/countries.json" with { type: "json" };
|
||||
import { translateText } from "./Utils";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
|
||||
@customElement("flag-input-modal")
|
||||
export class FlagInputModal extends BaseModal {
|
||||
@@ -21,53 +22,31 @@ export class FlagInputModal extends BaseModal {
|
||||
class="h-full flex flex-col bg-black/60 backdrop-blur-md rounded-2xl border border-white/10 overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="flex items-center mb-4 pb-2 border-b border-white/10 gap-2 shrink-0 p-6"
|
||||
class="relative flex flex-col border-b border-white/10 pb-4 shrink-0"
|
||||
>
|
||||
<div class="flex items-center gap-4 flex-1">
|
||||
<button
|
||||
@click=${() => this.close()}
|
||||
class="group flex items-center justify-center w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 transition-all border border-white/10"
|
||||
aria-label="${translateText("common.back")}"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span
|
||||
class="text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase tracking-widest break-words hyphens-auto"
|
||||
>
|
||||
${translateText("flag_input.title")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
${modalHeader({
|
||||
title: translateText("flag_input.title"),
|
||||
onBack: () => this.close(),
|
||||
ariaLabel: translateText("common.back"),
|
||||
})}
|
||||
|
||||
<div class="flex justify-center w-full px-6 pb-4 shrink-0">
|
||||
<input
|
||||
class="h-12 w-full max-w-md border border-white/10 bg-black/60
|
||||
rounded-xl shadow-inner text-xl text-center focus:outline-none
|
||||
focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500 text-white placeholder-white/30 transition-all"
|
||||
type="text"
|
||||
placeholder=${translateText("flag_input.search_flag")}
|
||||
@change=${this.handleSearch}
|
||||
@keyup=${this.handleSearch}
|
||||
/>
|
||||
<div class="md:flex items-center gap-2 justify-center mt-4">
|
||||
<input
|
||||
class="h-12 w-full max-w-md border border-white/10 bg-black/60
|
||||
rounded-xl shadow-inner text-xl text-center focus:outline-none
|
||||
focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500 text-white placeholder-white/30 transition-all"
|
||||
type="text"
|
||||
placeholder=${translateText("flag_input.search_flag")}
|
||||
@change=${this.handleSearch}
|
||||
@keyup=${this.handleSearch}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex-1 overflow-y-auto px-6 pb-6 scrollbar-thin scrollbar-thumb-white/20 scrollbar-track-transparent mr-1"
|
||||
>
|
||||
<div class="flex flex-wrap justify-center gap-4 min-h-min">
|
||||
<div class="pt-2 flex flex-wrap justify-center gap-4 min-h-min">
|
||||
${Countries.filter(
|
||||
(country) =>
|
||||
!country.restricted && this.includedInSearch(country),
|
||||
|
||||
+6
-31
@@ -4,6 +4,7 @@ import { translateText } from "../client/Utils";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import "./components/Difficulties";
|
||||
import "./components/Maps";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
|
||||
@customElement("help-modal")
|
||||
export class HelpModal extends BaseModal {
|
||||
@@ -101,37 +102,11 @@ export class HelpModal extends BaseModal {
|
||||
? "bg-black/60 backdrop-blur-md rounded-2xl border border-white/10"
|
||||
: ""}"
|
||||
>
|
||||
<div
|
||||
class="flex items-center mb-4 pb-2 border-b border-white/10 gap-2 shrink-0 p-6"
|
||||
>
|
||||
<div class="flex items-center gap-4 flex-1">
|
||||
<button
|
||||
@click=${this.close}
|
||||
class="group flex items-center justify-center w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 transition-all border border-white/10"
|
||||
aria-label="${translateText("common.back")}"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span
|
||||
class="text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase tracking-widest break-words hyphens-auto"
|
||||
>
|
||||
${translateText("main.instructions")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
${modalHeader({
|
||||
title: translateText("main.instructions"),
|
||||
onBack: this.close,
|
||||
ariaLabel: translateText("common.back"),
|
||||
})}
|
||||
|
||||
<div
|
||||
class="prose prose-invert prose-sm max-w-none overflow-y-auto px-6 pb-6 mr-1
|
||||
|
||||
+93
-115
@@ -29,6 +29,7 @@ import "./components/Difficulties";
|
||||
import "./components/FluentSlider";
|
||||
import "./components/LobbyTeamView";
|
||||
import "./components/Maps";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
import { crazyGamesSDK } from "./CrazyGamesSDK";
|
||||
import { JoinLobbyEvent } from "./Main";
|
||||
import { terrainMapFileLoader } from "./TerrainMapFileLoader";
|
||||
@@ -105,124 +106,101 @@ export class HostLobbyModal extends BaseModal {
|
||||
class="h-full flex flex-col bg-black/60 backdrop-blur-md rounded-2xl border border-white/10 overflow-hidden select-none"
|
||||
>
|
||||
<!-- Header -->
|
||||
<div
|
||||
class="flex items-center mb-6 pb-2 border-b border-white/10 gap-2 shrink-0 p-6"
|
||||
>
|
||||
<div class="flex items-center gap-4 flex-1">
|
||||
<button
|
||||
@click=${() => {
|
||||
this.leaveLobby();
|
||||
this.close();
|
||||
}}
|
||||
class="group flex items-center justify-center w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 transition-all border border-white/10"
|
||||
aria-label="${translateText("common.back")}"
|
||||
${modalHeader({
|
||||
title: translateText("host_modal.title"),
|
||||
onBack: () => {
|
||||
this.leaveLobby();
|
||||
this.close();
|
||||
},
|
||||
ariaLabel: translateText("common.back"),
|
||||
rightContent: html`
|
||||
<!-- Lobby ID Box -->
|
||||
<div
|
||||
class="flex items-center gap-0.5 bg-white/5 rounded-lg px-2 py-1 border border-white/10 max-w-[220px] flex-nowrap"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
<button
|
||||
@click=${() => {
|
||||
this.lobbyIdVisible = !this.lobbyIdVisible;
|
||||
this.requestUpdate();
|
||||
}}
|
||||
class="p-1.5 rounded-md hover:bg-white/10 text-white/60 hover:text-white transition-colors"
|
||||
title="${translateText("user_setting.toggle_visibility")}"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span
|
||||
class="text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase tracking-widest break-words hyphens-auto"
|
||||
>
|
||||
${translateText("host_modal.title")}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Lobby ID Box -->
|
||||
<div
|
||||
class="flex items-center gap-0.5 bg-white/5 rounded-lg px-2 py-1 border border-white/10 max-w-[220px] flex-nowrap"
|
||||
>
|
||||
<button
|
||||
@click=${() => {
|
||||
this.lobbyIdVisible = !this.lobbyIdVisible;
|
||||
this.requestUpdate();
|
||||
}}
|
||||
class="p-1.5 rounded-md hover:bg-white/10 text-white/60 hover:text-white transition-colors"
|
||||
title="Toggle Visibility"
|
||||
>
|
||||
${this.lobbyIdVisible
|
||||
? html`<svg
|
||||
viewBox="0 0 512 512"
|
||||
height="16px"
|
||||
width="16px"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M256 105c-101.8 0-188.4 62.7-224 151 35.6 88.3 122.2 151 224 151s188.4-62.7 224-151c-35.6-88.3-122.2-151-224-151zm0 251.7c-56 0-101.7-45.7-101.7-101.7S200 153.3 256 153.3 357.7 199 357.7 255 312 356.7 256 356.7zm0-161.1c-33 0-59.4 26.4-59.4 59.4s26.4 59.4 59.4 59.4 59.4-26.4 59.4-59.4-26.4-59.4-59.4-59.4z"
|
||||
></path>
|
||||
</svg>`
|
||||
: html`<svg
|
||||
viewBox="0 0 512 512"
|
||||
height="16px"
|
||||
width="16px"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M448 256s-64-128-192-128S64 256 64 256c32 64 96 128 192 128s160-64 192-128z"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="32"
|
||||
></path>
|
||||
<path
|
||||
d="M144 256l224 0"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="32"
|
||||
stroke-linecap="round"
|
||||
></path>
|
||||
</svg>`}
|
||||
</button>
|
||||
<button
|
||||
@click=${this.copyToClipboard}
|
||||
@dblclick=${(e: Event) => {
|
||||
(e.currentTarget as HTMLElement).classList.add("select-all");
|
||||
}}
|
||||
@mouseleave=${(e: Event) => {
|
||||
(e.currentTarget as HTMLElement).classList.remove("select-all");
|
||||
}}
|
||||
class="font-mono text-xs font-bold text-white px-2 cursor-pointer select-none min-w-[80px] text-center truncate tracking-wider bg-transparent border-0"
|
||||
title="${translateText("common.click_to_copy")}"
|
||||
aria-label="${translateText("common.click_to_copy")}"
|
||||
type="button"
|
||||
>
|
||||
${this.copySuccess
|
||||
? translateText("common.copied")
|
||||
: this.lobbyIdVisible
|
||||
? this.lobbyId
|
||||
: "••••••••"}
|
||||
</button>
|
||||
<button
|
||||
@click=${this.copyToClipboard}
|
||||
class="p-1.5 rounded-md hover:bg-white/10 text-white/60 hover:text-white transition-colors"
|
||||
title="${translateText("common.click_to_copy")}"
|
||||
aria-label="${translateText("common.click_to_copy")}"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
height="16px"
|
||||
width="16px"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
${this.lobbyIdVisible
|
||||
? html`<svg
|
||||
viewBox="0 0 512 512"
|
||||
height="16px"
|
||||
width="16px"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M256 105c-101.8 0-188.4 62.7-224 151 35.6 88.3 122.2 151 224 151s188.4-62.7 224-151c-35.6-88.3-122.2-151-224-151zm0 251.7c-56 0-101.7-45.7-101.7-101.7S200 153.3 256 153.3 357.7 199 357.7 255 312 356.7 256 356.7zm0-161.1c-33 0-59.4 26.4-59.4 59.4s26.4 59.4 59.4 59.4 59.4-26.4 59.4-59.4-26.4-59.4-59.4-59.4z"
|
||||
></path>
|
||||
</svg>`
|
||||
: html`<svg
|
||||
viewBox="0 0 512 512"
|
||||
height="16px"
|
||||
width="16px"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M448 256s-64-128-192-128S64 256 64 256c32 64 96 128 192 128s160-64 192-128z"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="32"
|
||||
></path>
|
||||
<path
|
||||
d="M144 256l224 0"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="32"
|
||||
stroke-linecap="round"
|
||||
></path>
|
||||
</svg>`}
|
||||
</button>
|
||||
<button
|
||||
@click=${this.copyToClipboard}
|
||||
@dblclick=${(e: Event) => {
|
||||
(e.currentTarget as HTMLElement).classList.add("select-all");
|
||||
}}
|
||||
@mouseleave=${(e: Event) => {
|
||||
(e.currentTarget as HTMLElement).classList.remove(
|
||||
"select-all",
|
||||
);
|
||||
}}
|
||||
class="font-mono text-xs font-bold text-white px-2 cursor-pointer select-none min-w-[80px] text-center truncate tracking-wider bg-transparent border-0"
|
||||
title="${translateText("common.click_to_copy")}"
|
||||
aria-label="${translateText("common.click_to_copy")}"
|
||||
type="button"
|
||||
>
|
||||
<path
|
||||
d="M16 1H4c-1.1 0-2 .9-2 2v12h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
${this.copySuccess
|
||||
? translateText("common.copied")
|
||||
: this.lobbyIdVisible
|
||||
? this.lobbyId
|
||||
: "••••••••"}
|
||||
</button>
|
||||
<button
|
||||
@click=${this.copyToClipboard}
|
||||
class="p-1.5 rounded-md hover:bg-white/10 text-white/60 hover:text-white transition-colors"
|
||||
title="${translateText("common.click_to_copy")}"
|
||||
aria-label="${translateText("common.click_to_copy")}"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
height="16px"
|
||||
width="16px"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M16 1H4c-1.1 0-2 .9-2 2v12h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
`,
|
||||
})}
|
||||
|
||||
<!-- Scrollable Content -->
|
||||
<div class="flex-1 overflow-y-auto custom-scrollbar p-6 mr-1">
|
||||
|
||||
@@ -16,6 +16,7 @@ import { JoinLobbyEvent } from "./Main";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import "./components/Difficulties";
|
||||
import "./components/LobbyTeamView";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
@customElement("join-private-lobby-modal")
|
||||
export class JoinPrivateLobbyModal extends BaseModal {
|
||||
@query("#lobbyIdInput") private lobbyIdInput!: HTMLInputElement;
|
||||
@@ -40,125 +41,100 @@ export class JoinPrivateLobbyModal extends BaseModal {
|
||||
<div
|
||||
class="h-full flex flex-col bg-black/60 backdrop-blur-md rounded-2xl border border-white/10 overflow-hidden select-none"
|
||||
>
|
||||
<div
|
||||
class="flex items-center mb-6 pb-2 border-b border-white/10 gap-2 shrink-0 p-6"
|
||||
>
|
||||
<div class="flex items-center gap-4 flex-1">
|
||||
<button
|
||||
@click=${this.closeAndLeave}
|
||||
class="group flex items-center justify-center w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 transition-all border border-white/10"
|
||||
aria-label=${translateText("common.close")}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span
|
||||
class="text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase tracking-widest break-words hyphens-auto"
|
||||
>
|
||||
${translateText("private_lobby.title")}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Lobby ID Box -->
|
||||
${this.hasJoined
|
||||
? html`<div
|
||||
class="flex items-center gap-0.5 bg-white/5 rounded-lg px-2 py-1 border border-white/10 max-w-[220px] flex-nowrap"
|
||||
>
|
||||
<button
|
||||
@click=${() => {
|
||||
this.lobbyIdVisible = !this.lobbyIdVisible;
|
||||
this.requestUpdate();
|
||||
}}
|
||||
class="p-1.5 rounded-md hover:bg-white/10 text-white/60 hover:text-white transition-colors"
|
||||
title=${translateText("toggle_visibility")}
|
||||
>
|
||||
${this.lobbyIdVisible
|
||||
? html`<svg
|
||||
viewBox="0 0 512 512"
|
||||
height="16px"
|
||||
width="16px"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M256 105c-101.8 0-188.4 62.7-224 151 35.6 88.3 122.2 151 224 151s188.4-62.7 224-151c-35.6-88.3-122.2-151-224-151zm0 251.7c-56 0-101.7-45.7-101.7-101.7S200 153.3 256 153.3 357.7 199 357.7 255 312 356.7 256 356.7zm0-161.1c-33 0-59.4 26.4-59.4 59.4s26.4 59.4 59.4 59.4 59.4-26.4 59.4-59.4-26.4-59.4-59.4-59.4z"
|
||||
></path>
|
||||
</svg>`
|
||||
: html`<svg
|
||||
viewBox="0 0 512 512"
|
||||
height="16px"
|
||||
width="16px"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M448 256s-64-128-192-128S64 256 64 256c32 64 96 128 192 128s160-64 192-128z"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="32"
|
||||
></path>
|
||||
<path
|
||||
d="M144 256l224 0"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="32"
|
||||
stroke-linecap="round"
|
||||
></path>
|
||||
</svg>`}
|
||||
</button>
|
||||
${modalHeader({
|
||||
title: translateText("private_lobby.title"),
|
||||
onBack: this.closeAndLeave,
|
||||
ariaLabel: translateText("common.close"),
|
||||
rightContent: this.hasJoined
|
||||
? html`
|
||||
<!-- Lobby ID Box -->
|
||||
<div
|
||||
@click=${this.copyToClipboard}
|
||||
@dblclick=${(e: Event) => {
|
||||
(e.currentTarget as HTMLElement).classList.add(
|
||||
"select-all",
|
||||
);
|
||||
}}
|
||||
@mouseleave=${(e: Event) => {
|
||||
(e.currentTarget as HTMLElement).classList.remove(
|
||||
"select-all",
|
||||
);
|
||||
}}
|
||||
class="font-mono text-xs font-bold text-white px-2 cursor-pointer select-none min-w-[80px] text-center truncate tracking-wider"
|
||||
title="${translateText("common.click_to_copy")}"
|
||||
class="flex items-center gap-0.5 bg-white/5 rounded-lg px-2 py-1 border border-white/10 max-w-[220px] flex-nowrap"
|
||||
>
|
||||
${this.copySuccess
|
||||
? translateText("common.copied")
|
||||
: this.lobbyIdVisible
|
||||
? this.currentLobbyId
|
||||
: "••••••••"}
|
||||
</div>
|
||||
<button
|
||||
@click=${this.copyToClipboard}
|
||||
class="p-1.5 rounded-md hover:bg-white/10 text-white/60 hover:text-white transition-colors"
|
||||
title="${translateText("common.click_to_copy")}"
|
||||
aria-label="${translateText("common.click_to_copy")}"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
height="16px"
|
||||
width="16px"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
<button
|
||||
@click=${() => {
|
||||
this.lobbyIdVisible = !this.lobbyIdVisible;
|
||||
this.requestUpdate();
|
||||
}}
|
||||
class="p-1.5 rounded-md hover:bg-white/10 text-white/60 hover:text-white transition-colors"
|
||||
title="${translateText("user_setting.toggle_visibility")}"
|
||||
>
|
||||
<path
|
||||
d="M16 1H4c-1.1 0-2 .9-2 2v12h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>`
|
||||
: ""}
|
||||
</div>
|
||||
${this.lobbyIdVisible
|
||||
? html`<svg
|
||||
viewBox="0 0 512 512"
|
||||
height="16px"
|
||||
width="16px"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M256 105c-101.8 0-188.4 62.7-224 151 35.6 88.3 122.2 151 224 151s188.4-62.7 224-151c-35.6-88.3-122.2-151-224-151zm0 251.7c-56 0-101.7-45.7-101.7-101.7S200 153.3 256 153.3 357.7 199 357.7 255 312 356.7 256 356.7zm0-161.1c-33 0-59.4 26.4-59.4 59.4s26.4 59.4 59.4 59.4 59.4-26.4 59.4-59.4-26.4-59.4-59.4-59.4z"
|
||||
></path>
|
||||
</svg>`
|
||||
: html`<svg
|
||||
viewBox="0 0 512 512"
|
||||
height="16px"
|
||||
width="16px"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M448 256s-64-128-192-128S64 256 64 256c32 64 96 128 192 128s160-64 192-128z"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="32"
|
||||
></path>
|
||||
<path
|
||||
d="M144 256l224 0"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="32"
|
||||
stroke-linecap="round"
|
||||
></path>
|
||||
</svg>`}
|
||||
</button>
|
||||
<div
|
||||
@click=${this.copyToClipboard}
|
||||
@dblclick=${(e: Event) => {
|
||||
(e.currentTarget as HTMLElement).classList.add(
|
||||
"select-all",
|
||||
);
|
||||
}}
|
||||
@mouseleave=${(e: Event) => {
|
||||
(e.currentTarget as HTMLElement).classList.remove(
|
||||
"select-all",
|
||||
);
|
||||
}}
|
||||
class="font-mono text-xs font-bold text-white px-2 cursor-pointer select-none min-w-[80px] text-center truncate tracking-wider"
|
||||
title="${translateText("common.click_to_copy")}"
|
||||
>
|
||||
${this.copySuccess
|
||||
? translateText("common.copied")
|
||||
: this.lobbyIdVisible
|
||||
? this.currentLobbyId
|
||||
: "••••••••"}
|
||||
</div>
|
||||
<button
|
||||
@click=${this.copyToClipboard}
|
||||
class="p-1.5 rounded-md hover:bg-white/10 text-white/60 hover:text-white transition-colors"
|
||||
title="${translateText("common.click_to_copy")}"
|
||||
aria-label="${translateText("common.click_to_copy")}"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
height="16px"
|
||||
width="16px"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M16 1H4c-1.1 0-2 .9-2 2v12h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
: undefined,
|
||||
})}
|
||||
<div class="flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4 mr-1">
|
||||
${!this.hasJoined
|
||||
? html`<div class="flex flex-col gap-3">
|
||||
|
||||
@@ -3,6 +3,7 @@ import { customElement, property } from "lit/decorators.js";
|
||||
import { translateText } from "../client/Utils";
|
||||
import "./components/baseComponents/Modal";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
|
||||
interface LanguageOption {
|
||||
code: string;
|
||||
@@ -30,47 +31,17 @@ export class LanguageModal extends BaseModal {
|
||||
render() {
|
||||
const content = html`
|
||||
<div
|
||||
class="h-full flex flex-col ${
|
||||
this.inline
|
||||
? "bg-black/60 backdrop-blur-md rounded-2xl border border-white/10 p-6"
|
||||
: "bg-[#232323] text-white"
|
||||
}"
|
||||
class="h-full flex flex-col bg-black/60 backdrop-blur-md rounded-2xl border border-white/10 overflow-hidden select-none"
|
||||
>
|
||||
<!-- Header -->
|
||||
<div
|
||||
class="flex items-center mb-6 pb-2 border-b border-white/10 gap-2 shrink-0"
|
||||
>
|
||||
<div class="flex items-center gap-4">
|
||||
<button
|
||||
@click=${this.close}
|
||||
class="group flex items-center justify-center w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 transition-all border border-white/10"
|
||||
aria-label="${translateText("common.back")}"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span
|
||||
class="text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase tracking-widest break-words hyphens-auto"
|
||||
>
|
||||
${translateText("select_lang.title")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
${modalHeader({
|
||||
title: translateText("select_lang.title"),
|
||||
onBack: this.close,
|
||||
ariaLabel: translateText("common.back"),
|
||||
})}
|
||||
|
||||
<div
|
||||
class="flex-1 overflow-y-auto custom-scrollbar pr-2 mr-1"
|
||||
class="flex-1 overflow-y-auto custom-scrollbar p-2"
|
||||
>
|
||||
<div
|
||||
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3"
|
||||
@@ -86,8 +57,7 @@ export class LanguageModal extends BaseModal {
|
||||
buttonClasses +=
|
||||
" animate-pulse font-bold text-white border-2 border-dashed border-cyan-400 shadow-[0_0_15px_rgba(34,211,238,0.2)] bg-gradient-to-r from-red-600 via-yellow-600 via-green-600 via-blue-600 to-purple-600";
|
||||
} else if (isActive) {
|
||||
buttonClasses +=
|
||||
" bg-blue-500/20 border-blue-500/50 shadow-[0_0_15px_rgba(59,130,246,0.2)]";
|
||||
buttonClasses += " bg-blue-500/20 border-blue-500/50";
|
||||
} else {
|
||||
buttonClasses +=
|
||||
" bg-white/5 border-white/10 hover:bg-white/10 hover:border-white/20";
|
||||
|
||||
@@ -8,6 +8,7 @@ import { getPlayToken } from "./Auth";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import "./components/Difficulties";
|
||||
import "./components/PatternButton";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
import { JoinLobbyEvent } from "./Main";
|
||||
import { translateText } from "./Utils";
|
||||
|
||||
@@ -51,37 +52,11 @@ export class MatchmakingModal extends BaseModal {
|
||||
? "bg-black/60 backdrop-blur-md rounded-2xl border border-white/10"
|
||||
: ""}"
|
||||
>
|
||||
<div
|
||||
class="flex items-center mb-4 pb-2 border-b border-white/10 gap-2 shrink-0 p-6"
|
||||
>
|
||||
<div class="flex items-center gap-4 flex-1">
|
||||
<button
|
||||
@click=${this.close}
|
||||
class="group flex items-center justify-center w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 transition-all border border-white/10"
|
||||
aria-label="${translateText("common.back")}"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span
|
||||
class="text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase tracking-widest break-words hyphens-auto"
|
||||
>
|
||||
${translateText("matchmaking_modal.title")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
${modalHeader({
|
||||
title: translateText("matchmaking_modal.title"),
|
||||
onBack: this.close,
|
||||
ariaLabel: translateText("common.back"),
|
||||
})}
|
||||
<div class="flex-1 flex flex-col items-center justify-center gap-6 p-6">
|
||||
${eloDisplay} ${this.renderInner()}
|
||||
</div>
|
||||
|
||||
+7
-32
@@ -5,6 +5,7 @@ import version from "resources/version.txt?raw";
|
||||
import { translateText } from "../client/Utils";
|
||||
import "./components/baseComponents/Modal";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
import changelog from "/changelog.md?url";
|
||||
import megaphone from "/images/Megaphone.svg?url";
|
||||
|
||||
@@ -21,39 +22,13 @@ export class NewsModal extends BaseModal {
|
||||
? "bg-black/60 backdrop-blur-md rounded-2xl border border-white/10"
|
||||
: ""}"
|
||||
>
|
||||
${modalHeader({
|
||||
title: translateText("news.title"),
|
||||
onBack: this.close,
|
||||
ariaLabel: translateText("common.back"),
|
||||
})}
|
||||
<div
|
||||
class="flex items-center mb-4 pb-2 border-b border-white/10 gap-2 shrink-0 p-6"
|
||||
>
|
||||
<div class="flex items-center gap-4 flex-1">
|
||||
<button
|
||||
@click=${this.close}
|
||||
class="group flex items-center justify-center w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 transition-all border border-white/10"
|
||||
aria-label="${translateText("common.back")}"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span
|
||||
class="text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase tracking-widest break-words hyphens-auto"
|
||||
>
|
||||
${translateText("news.title")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="prose prose-invert prose-sm max-w-none overflow-y-auto px-6 pb-6 mr-1
|
||||
class="pt-2 prose prose-invert prose-sm max-w-none overflow-y-auto px-6 pb-6 mr-1
|
||||
[&_a]:text-blue-400 [&_a:hover]:text-blue-300 transition-colors
|
||||
[&_h1]:text-2xl [&_h1]:font-bold [&_h1]:mb-4 [&_h1]:text-white [&_h1]:border-b [&_h1]:border-white/10 [&_h1]:pb-2
|
||||
[&_h2]:text-xl [&_h2]:font-bold [&_h2]:mt-6 [&_h2]:mb-3 [&_h2]:text-blue-200
|
||||
|
||||
@@ -25,6 +25,7 @@ import { BaseModal } from "./components/BaseModal";
|
||||
import "./components/Difficulties";
|
||||
import "./components/FluentSlider";
|
||||
import "./components/Maps";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
import { fetchCosmetics } from "./Cosmetics";
|
||||
import { FlagInput } from "./FlagInput";
|
||||
import { JoinLobbyEvent } from "./Main";
|
||||
@@ -132,36 +133,11 @@ export class SinglePlayerModal extends BaseModal {
|
||||
class="h-full flex flex-col bg-black/60 backdrop-blur-md rounded-2xl border border-white/10 overflow-hidden"
|
||||
>
|
||||
<!-- Header -->
|
||||
<div
|
||||
class="flex items-center pb-2 border-b border-white/10 gap-4 shrink-0 px-6 pt-6"
|
||||
>
|
||||
<button
|
||||
@click=${this.close}
|
||||
class="group flex items-center justify-center w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 transition-all border border-white/10 shrink-0"
|
||||
aria-label="${translateText("common.back")}"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span
|
||||
class="text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase tracking-widest flex-1 break-words hyphens-auto"
|
||||
>
|
||||
${translateText("main.solo") || "Solo"}
|
||||
</span>
|
||||
|
||||
${hasLinkedAccount(this.userMeResponse)
|
||||
${modalHeader({
|
||||
title: translateText("main.solo") || "Solo",
|
||||
onBack: this.close,
|
||||
ariaLabel: translateText("common.back"),
|
||||
rightContent: hasLinkedAccount(this.userMeResponse)
|
||||
? html`<button
|
||||
@click=${this.toggleAchievements}
|
||||
class="flex items-center gap-2 px-3 py-2 rounded-xl border border-white/10 bg-white/5 hover:bg-white/10 transition-all shrink-0 ${this
|
||||
@@ -181,8 +157,8 @@ export class SinglePlayerModal extends BaseModal {
|
||||
>${translateText("single_modal.toggle_achievements")}</span
|
||||
>
|
||||
</button>`
|
||||
: this.renderNotLoggedInBanner()}
|
||||
</div>
|
||||
: this.renderNotLoggedInBanner(),
|
||||
})}
|
||||
|
||||
<!-- Scrollable Content -->
|
||||
<div class="flex-1 overflow-y-auto custom-scrollbar px-6 pb-6 mr-1">
|
||||
|
||||
+10
-30
@@ -8,6 +8,7 @@ import {
|
||||
import { getApiBase } from "./Api";
|
||||
import { translateText } from "./Utils";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
|
||||
@customElement("stats-modal")
|
||||
export class StatsModal extends BaseModal {
|
||||
@@ -195,7 +196,7 @@ export class StatsModal extends BaseModal {
|
||||
const maxGames = Math.max(...clans.map((c) => c.games), 1);
|
||||
|
||||
return html`
|
||||
<div class="w-full">
|
||||
<div class="w-full pt-2">
|
||||
<div
|
||||
class="overflow-x-auto rounded-xl border border-white/5 bg-black/20"
|
||||
>
|
||||
@@ -371,34 +372,10 @@ export class StatsModal extends BaseModal {
|
||||
|
||||
const content = html`
|
||||
<div
|
||||
class="h-full flex flex-col ${this.inline
|
||||
? "bg-black/60 backdrop-blur-md rounded-2xl border border-white/10"
|
||||
: ""}"
|
||||
class="h-full flex flex-col bg-black/60 backdrop-blur-md rounded-2xl border border-white/10 overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="flex flex-wrap items-center mb-6 pb-2 border-b border-white/10 gap-2 shrink-0 p-6"
|
||||
>
|
||||
<div class="flex flex-wrap items-center gap-4 flex-1">
|
||||
<button
|
||||
@click=${this.close}
|
||||
class="group flex items-center justify-center w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 transition-all border border-white/10"
|
||||
aria-label=${translateText("common.close")}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
${modalHeader({
|
||||
titleContent: html`
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<span
|
||||
class="text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase tracking-widest break-words hyphens-auto"
|
||||
@@ -407,8 +384,11 @@ export class StatsModal extends BaseModal {
|
||||
</span>
|
||||
${dateRange}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
onBack: this.close,
|
||||
ariaLabel: translateText("common.close"),
|
||||
leftClassName: "flex flex-wrap items-center gap-4 flex-1",
|
||||
})}
|
||||
|
||||
<div
|
||||
class="flex-1 overflow-y-auto scrollbar-thin scrollbar-thumb-white/20 scrollbar-track-transparent px-6 pb-6 mr-1"
|
||||
|
||||
@@ -9,6 +9,7 @@ import { hasLinkedAccount } from "./Api";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import "./components/Difficulties";
|
||||
import "./components/PatternButton";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
import {
|
||||
fetchCosmetics,
|
||||
handlePurchase,
|
||||
@@ -84,69 +85,37 @@ export class TerritoryPatternsModal extends BaseModal {
|
||||
|
||||
private renderTabNavigation(): TemplateResult {
|
||||
return html`
|
||||
<div
|
||||
class="flex items-center mb-4 pb-2 border-b border-white/10 gap-2 shrink-0 p-6"
|
||||
>
|
||||
<div class="flex items-center gap-4 flex-1">
|
||||
<button
|
||||
@click=${this.close}
|
||||
class="group flex items-center justify-center w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 transition-all border border-white/10 shrink-0"
|
||||
aria-label="${translateText("common.back")}"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span
|
||||
class="text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase tracking-widest break-words hyphens-auto"
|
||||
>
|
||||
${translateText("territory_patterns.title")}
|
||||
</span>
|
||||
|
||||
${
|
||||
!hasLinkedAccount(this.userMeResponse)
|
||||
? html`<div class="ml-auto flex items-center">
|
||||
${this.renderNotLoggedInWarning()}
|
||||
</div>`
|
||||
: html``
|
||||
}
|
||||
</div>
|
||||
<!-- TEMP DISABlE TAB SWITCHING
|
||||
${modalHeader({
|
||||
title: translateText("territory_patterns.title"),
|
||||
onBack: this.close,
|
||||
ariaLabel: translateText("common.back"),
|
||||
rightContent: !hasLinkedAccount(this.userMeResponse)
|
||||
? html`<div class="flex items-center">
|
||||
${this.renderNotLoggedInWarning()}
|
||||
</div>`
|
||||
: undefined,
|
||||
})}
|
||||
<!-- TEMP DISABlE TAB SWITCHING
|
||||
<div class="flex items-center gap-2 justify-center">
|
||||
<button
|
||||
class="px-6 py-2 text-xs font-bold transition-all duration-200 rounded-lg uppercase tracking-widest ${
|
||||
this.activeTab === "patterns"
|
||||
? "bg-blue-500/20 text-blue-400 border border-blue-500/30 shadow-[0_0_15px_rgba(59,130,246,0.2)]"
|
||||
: "text-white/40 hover:text-white hover:bg-white/5 border border-transparent"
|
||||
}"
|
||||
class="px-6 py-2 text-xs font-bold transition-all duration-200 rounded-lg uppercase tracking-widest ${this
|
||||
.activeTab === "patterns"
|
||||
? "bg-blue-500/20 text-blue-400 border border-blue-500/30 shadow-[0_0_15px_rgba(59,130,246,0.2)]"
|
||||
: "text-white/40 hover:text-white hover:bg-white/5 border border-transparent"}"
|
||||
@click=${() => (this.activeTab = "patterns")}
|
||||
>
|
||||
${translateText("territory_patterns.title")}
|
||||
</button>
|
||||
<button
|
||||
class="px-6 py-2 text-xs font-bold transition-all duration-200 rounded-lg uppercase tracking-widest ${
|
||||
this.activeTab === "colors"
|
||||
? "bg-blue-500/20 text-blue-400 border border-blue-500/30 shadow-[0_0_15px_rgba(59,130,246,0.2)]"
|
||||
: "text-white/40 hover:text-white hover:bg-white/5 border border-transparent"
|
||||
}"
|
||||
class="px-6 py-2 text-xs font-bold transition-all duration-200 rounded-lg uppercase tracking-widest ${this
|
||||
.activeTab === "colors"
|
||||
? "bg-blue-500/20 text-blue-400 border border-blue-500/30 shadow-[0_0_15px_rgba(59,130,246,0.2)]"
|
||||
: "text-white/40 hover:text-white hover:bg-white/5 border border-transparent"}"
|
||||
@click=${() => (this.activeTab = "colors")}
|
||||
>
|
||||
${translateText("territory_patterns.colors")}
|
||||
</button>
|
||||
TEMP DISABlE TAB SWITCHING -->
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import "./components/baseComponents/setting/SettingNumber";
|
||||
import "./components/baseComponents/setting/SettingSlider";
|
||||
import "./components/baseComponents/setting/SettingToggle";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
import "./FlagInputModal";
|
||||
|
||||
interface FlagInputModalElement extends HTMLElement {
|
||||
@@ -388,40 +389,17 @@ export class UserSettingModal extends BaseModal {
|
||||
|
||||
const content = html`
|
||||
<div
|
||||
class="h-full flex flex-col ${this.inline
|
||||
? "bg-black/60 backdrop-blur-md rounded-2xl border border-white/10"
|
||||
: ""}"
|
||||
class="h-full flex flex-col bg-black/60 backdrop-blur-md rounded-2xl border border-white/10 overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="relative flex flex-col mb-6 border-b border-white/10 pb-4 shrink-0 p-6"
|
||||
class="relative flex flex-col border-b border-white/10 pb-4 shrink-0"
|
||||
>
|
||||
<div class="flex items-center gap-4 flex-1 flex-wrap">
|
||||
<button
|
||||
@click=${this.close}
|
||||
class="group flex items-center justify-center w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 transition-all border border-white/10 shrink-0"
|
||||
aria-label="${translateText("common.back")}"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<span
|
||||
class="text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase tracking-widest break-all hyphens-auto min-w-0"
|
||||
>
|
||||
${translateText("user_setting.title")}
|
||||
</span>
|
||||
</div>
|
||||
${modalHeader({
|
||||
title: translateText("user_setting.title"),
|
||||
onBack: this.close,
|
||||
ariaLabel: translateText("common.back"),
|
||||
showDivider: true,
|
||||
})}
|
||||
|
||||
<div class="hidden md:flex items-center gap-2 justify-center mt-4">
|
||||
<button
|
||||
@@ -446,7 +424,7 @@ export class UserSettingModal extends BaseModal {
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex-1 overflow-y-auto scrollbar-thin scrollbar-thumb-white/20 scrollbar-track-transparent px-6 pb-6 mr-1"
|
||||
class="pt-2 flex-1 overflow-y-auto scrollbar-thin scrollbar-thumb-white/20 scrollbar-track-transparent px-6 pb-6 mr-1"
|
||||
>
|
||||
<div class="flex flex-col gap-2">${activeContent}</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import { html, TemplateResult } from "lit";
|
||||
|
||||
export interface ModalHeaderProps {
|
||||
title?: string | TemplateResult;
|
||||
titleContent?: TemplateResult;
|
||||
onBack: (event: MouseEvent) => void;
|
||||
ariaLabel?: string;
|
||||
rightContent?: TemplateResult;
|
||||
leftClassName?: string;
|
||||
buttonClassName?: string;
|
||||
titleClassName?: string;
|
||||
padded?: boolean;
|
||||
showDivider?: boolean;
|
||||
}
|
||||
|
||||
const DEFAULT_WRAPPER_CLASS = "flex flex-wrap items-center gap-2 shrink-0";
|
||||
const DEFAULT_DIVIDER_CLASS = "border-b border-white/10";
|
||||
const DEFAULT_PADDING_CLASS = "p-6";
|
||||
const DEFAULT_LEFT_CLASS = "flex items-center gap-4 flex-1";
|
||||
const DEFAULT_BUTTON_CLASS =
|
||||
"group flex items-center justify-center w-10 h-10 rounded-full shrink-0 " +
|
||||
"bg-white/5 hover:bg-white/10 transition-all border border-white/10";
|
||||
const DEFAULT_TITLE_CLASS =
|
||||
"text-white text-xl sm:text-2xl md:text-3xl font-bold uppercase " +
|
||||
"tracking-widest break-words hyphens-auto";
|
||||
|
||||
const withClasses = (...classes: Array<string | undefined>) =>
|
||||
classes.filter(Boolean).join(" ");
|
||||
|
||||
export const modalHeader = ({
|
||||
title,
|
||||
titleContent,
|
||||
onBack,
|
||||
ariaLabel = "Back",
|
||||
rightContent,
|
||||
leftClassName,
|
||||
buttonClassName,
|
||||
titleClassName,
|
||||
padded = true,
|
||||
showDivider = true,
|
||||
}: ModalHeaderProps): TemplateResult => {
|
||||
const wrapperClass = withClasses(
|
||||
DEFAULT_WRAPPER_CLASS,
|
||||
showDivider ? DEFAULT_DIVIDER_CLASS : undefined,
|
||||
padded ? DEFAULT_PADDING_CLASS : undefined,
|
||||
);
|
||||
const leftClass = withClasses(DEFAULT_LEFT_CLASS, leftClassName);
|
||||
const buttonClass = withClasses(DEFAULT_BUTTON_CLASS, buttonClassName);
|
||||
const resolvedTitleClass = withClasses(DEFAULT_TITLE_CLASS, titleClassName);
|
||||
|
||||
return html`
|
||||
<div class="${wrapperClass}">
|
||||
<div class="${leftClass}">
|
||||
<button
|
||||
@click=${onBack}
|
||||
class="${buttonClass}"
|
||||
aria-label="${ariaLabel}"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
${titleContent ??
|
||||
html`<span class="${resolvedTitleClass}">${title}</span>`}
|
||||
</div>
|
||||
${rightContent ?? ""}
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
Reference in New Issue
Block a user