add not logged in warning to flags modal, refactored to its own lit component (#3521)

## Description:

So players know they are logged out and don't think their purchased
flags dissappeared.

## 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:

evan
This commit is contained in:
Evan
2026-03-26 16:45:13 -07:00
committed by GitHub
parent d99359c456
commit 1c2bd5df31
5 changed files with 56 additions and 37 deletions
+1 -1
View File
@@ -6,6 +6,7 @@
"lang_code": "en"
},
"common": {
"not_logged_in": "Not logged in",
"close": "Close",
"copy": "Copy",
"paste": "Paste",
@@ -912,7 +913,6 @@
"territory_patterns": {
"title": "Skins",
"purchase": "Purchase",
"not_logged_in": "Not logged in",
"pattern": {
"default": "Default"
},
+2
View File
@@ -9,6 +9,7 @@ import { fetchCosmetics, flagRelationship } from "./Cosmetics";
import { translateText } from "./Utils";
import { BaseModal } from "./components/BaseModal";
import "./components/FlagButton";
import "./components/NotLoggedInWarning";
import { modalHeader } from "./components/ui/ModalHeader";
@customElement("flag-input-modal")
@@ -103,6 +104,7 @@ export class FlagInputModal extends BaseModal {
title: translateText("flag_input.title"),
onBack: () => this.close(),
ariaLabel: translateText("common.back"),
rightContent: html`<not-logged-in-warning></not-logged-in-warning>`,
})}
<div class="md:flex items-center gap-2 justify-center mt-4">
+2 -18
View File
@@ -5,9 +5,9 @@ import { UserMeResponse } from "../core/ApiSchemas";
import { ColorPalette, Cosmetics, Pattern } from "../core/CosmeticSchemas";
import { UserSettings } from "../core/game/UserSettings";
import { PlayerPattern } from "../core/Schemas";
import { hasLinkedAccount } from "./Api";
import { BaseModal } from "./components/BaseModal";
import "./components/FlagButton";
import "./components/NotLoggedInWarning";
import "./components/PatternButton";
import { modalHeader } from "./components/ui/ModalHeader";
import {
@@ -77,11 +77,7 @@ export class StoreModal extends BaseModal {
title: translateText("store.title"),
onBack: () => this.close(),
ariaLabel: translateText("common.back"),
rightContent: !hasLinkedAccount(this.userMeResponse)
? html`<div class="flex items-center">
${this.renderNotLoggedInWarning()}
</div>`
: undefined,
rightContent: html`<not-logged-in-warning></not-logged-in-warning>`,
})}
<div class="flex items-center gap-2 justify-center pt-2">
<button
@@ -214,18 +210,6 @@ export class StoreModal extends BaseModal {
`;
}
private renderNotLoggedInWarning(): TemplateResult {
return html`<button
class="px-4 py-2 text-xs font-bold uppercase tracking-wider transition-colors duration-200 rounded-lg bg-red-500/20 text-red-400 border border-red-500/30 cursor-pointer hover:bg-red-500/30"
@click=${() => {
this.close();
window.showPage?.("page-account");
}}
>
${translateText("territory_patterns.not_logged_in")}
</button>`;
}
render() {
if (!this.isActive && !this.inline) return html``;
+2 -18
View File
@@ -5,8 +5,8 @@ import { UserMeResponse } from "../core/ApiSchemas";
import { Cosmetics, Pattern } from "../core/CosmeticSchemas";
import { UserSettings } from "../core/game/UserSettings";
import { PlayerPattern } from "../core/Schemas";
import { hasLinkedAccount } from "./Api";
import { BaseModal } from "./components/BaseModal";
import "./components/NotLoggedInWarning";
import "./components/PatternButton";
import { modalHeader } from "./components/ui/ModalHeader";
import {
@@ -123,18 +123,6 @@ export class TerritoryPatternsModal extends BaseModal {
`;
}
private renderNotLoggedInWarning(): TemplateResult {
return html`<button
class="px-4 py-2 text-xs font-bold uppercase tracking-wider transition-colors duration-200 rounded-lg bg-red-500/20 text-red-400 border border-red-500/30 cursor-pointer hover:bg-red-500/30"
@click=${() => {
this.close();
window.showPage?.("page-account");
}}
>
${translateText("territory_patterns.not_logged_in")}
</button>`;
}
render() {
const content = html`
<div class="${this.modalContainerClass}">
@@ -145,11 +133,7 @@ export class TerritoryPatternsModal extends BaseModal {
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,
rightContent: html`<not-logged-in-warning></not-logged-in-warning>`,
})}
</div>
<div class="flex justify-center py-3 shrink-0">
@@ -0,0 +1,49 @@
import { LitElement, html } from "lit";
import { customElement, state } from "lit/decorators.js";
import { UserMeResponse } from "../../core/ApiSchemas";
import { hasLinkedAccount } from "../Api";
@customElement("not-logged-in-warning")
export class NotLoggedInWarning extends LitElement {
@state() private linked = false;
private _onUserMe = (event: CustomEvent<UserMeResponse | false>) => {
this.linked = hasLinkedAccount(event.detail);
};
createRenderRoot() {
return this;
}
connectedCallback() {
super.connectedCallback();
document.addEventListener(
"userMeResponse",
this._onUserMe as EventListener,
);
}
disconnectedCallback() {
super.disconnectedCallback();
document.removeEventListener(
"userMeResponse",
this._onUserMe as EventListener,
);
}
render() {
if (this.linked) return html``;
return html`<div class="flex items-center">
<button
class="px-4 py-2 text-xs font-bold uppercase tracking-wider transition-colors duration-200 rounded-lg bg-red-500/20 text-red-400 border border-red-500/30 cursor-pointer hover:bg-red-500/30"
data-i18n="common.not_logged_in"
@click=${() => {
window.showPage?.("page-account");
}}
>
Not logged in
</button>
</div>`;
}
}