Files
OpenFrontIO/src/client/graphics/layers/RelationSmiley.ts
T
FloPinguin 66bbbc664b Colored SVG smiley icons next to nation names based on relation 😊 (#3746)
## Description:

Instead of coloring nation names based on diplomatic relation, small
inline SVG face icons are now shown next to the nation name in the
player info overlay:

- 😠 **Hostile** - red angry face (furrowed brows, downturned mouth)
- 😟 **Distrustful** - orange slightly-sad face (flat mouth)
- 😊 **Friendly** - green happy face (upturned smile)
- **Neutral** - no icon shown

<img width="509" height="80" alt="Screenshot 2026-04-23 013151"
src="https://github.com/user-attachments/assets/85dc3f29-0a84-45d1-902e-e75c6cad4a44"
/>
<img width="511" height="82" alt="Screenshot 2026-04-23 012809"
src="https://github.com/user-attachments/assets/7a37c8a3-08d0-448e-9eaa-16f254a296ad"
/>
<img width="511" height="88" alt="Screenshot 2026-04-23 012741"
src="https://github.com/user-attachments/assets/d617f8ca-2315-467a-85f5-63f769bd0341"
/>

No longer conflicts with green text color because of alliance now. 

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

FloPinguin
2026-04-24 08:09:03 -06:00

80 lines
1.8 KiB
TypeScript

import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators.js";
import { Relation } from "../../../core/game/Game";
type FaceData = {
color: string;
eyeCy: number;
mouth: string;
brows?: string[];
};
const RELATION_FACES: Partial<Record<Relation, FaceData>> = {
[Relation.Hostile]: {
color: "#ef4444",
eyeCy: 7.5,
mouth: "M5 12 Q8 9 11 12",
brows: ["M4 5.5 L6.5 7", "M12 5.5 L9.5 7"],
},
[Relation.Distrustful]: {
color: "#f97316",
eyeCy: 6.8,
mouth: "M5.5 11 Q8 9.2 10.5 11",
},
[Relation.Friendly]: {
color: "#22c55e",
eyeCy: 6.5,
mouth: "M5 10 Q8 13 11 10",
},
};
@customElement("relation-smiley")
export class RelationSmiley extends LitElement {
@property({ type: Number })
relation: Relation = Relation.Neutral;
createRenderRoot() {
return this;
}
render() {
const face = RELATION_FACES[this.relation];
if (!face) return html``;
const { color, eyeCy, mouth, brows } = face;
return html`<svg
width="16"
height="16"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
style="flex-shrink:0"
aria-hidden="true"
>
<circle
cx="8"
cy="8"
r="6.5"
stroke="${color}"
stroke-width="1.4"
fill="none"
/>
${brows?.map(
(d) =>
html`<path
d="${d}"
stroke="${color}"
stroke-width="1.4"
stroke-linecap="round"
/>`,
)}
<circle cx="5.8" cy="${eyeCy}" r="0.9" fill="${color}" />
<circle cx="10.2" cy="${eyeCy}" r="0.9" fill="${color}" />
<path
d="${mouth}"
stroke="${color}"
stroke-width="1.4"
fill="none"
stroke-linecap="round"
/>
</svg>`;
}
}