Add discord-user-header (#2084)

## Description:
This PR adds a component to display a Discord user’s avatar and name.
It will not be directly visible in this PR, but in other PRs it will be
shown together with the modal for viewing stats.

It should look like this:
<img width="145" height="67" alt="スクリーンショット 2025-09-23 9 48 04"
src="https://github.com/user-attachments/assets/dd1b3abe-66e5-4961-8e7a-66c1f968a9a6"
/>

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

aotumuri

---------

Co-authored-by: evanpelle <evanpelle@gmail.com>
This commit is contained in:
Aotumuri
2025-09-26 08:58:01 +09:00
committed by GitHub
parent 5d9b62da4d
commit d3fb7544b8
2 changed files with 81 additions and 0 deletions
+3
View File
@@ -648,6 +648,9 @@
"delete_unit_title": "Delete Unit",
"delete_unit_description": "Click to delete the nearest unit"
},
"discord_user_header": {
"avatar_alt": "Avatar"
},
"player_stats_table": {
"building_stats": "Building Statistics",
"ship_arrivals": "Ship Arrivals",
@@ -0,0 +1,78 @@
import { LitElement, css, html } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import type { DiscordUser } from "../../../../core/ApiSchemas";
import { translateText } from "../../../Utils";
@customElement("discord-user-header")
export class DiscordUserHeader extends LitElement {
static styles = css`
.wrap {
display: flex;
align-items: center;
gap: 0.5rem;
}
.avatarFrame {
padding: 3px;
border-radius: 9999px;
background: #6b7280; /* bg-gray-500 */
}
.avatar {
width: 48px;
height: 48px;
border-radius: 9999px;
display: block;
}
.name {
font-weight: 600;
color: white;
}
`;
@state() private _data: DiscordUser | null = null;
@property({ attribute: false })
get data(): DiscordUser | null {
return this._data;
}
set data(v: DiscordUser | null) {
this._data = v;
this.requestUpdate();
}
private get avatarUrl(): string | null {
const u = this._data;
if (!u) return null;
if (u.avatar) {
const ext = u.avatar.startsWith("a_") ? "gif" : "png";
return `https://cdn.discordapp.com/avatars/${u.id}/${u.avatar}.${ext}`;
}
if (u.discriminator !== undefined) {
const idx = Number(u.discriminator) % 5;
return `https://cdn.discordapp.com/embed/avatars/${idx}.png`;
}
return null;
}
private get discordDisplayName(): string {
return this._data?.username ?? "";
}
render() {
return html`
<div class="wrap">
${this.avatarUrl
? html`
<div class="avatarFrame">
<img
class="avatar"
src="${this.avatarUrl}"
alt="${translateText("discord_user_header.avatar_alt")}"
/>
</div>
`
: null}
<span class="name">${this.discordDisplayName}</span>
</div>
`;
}
}