MLS for Quick Chat (#686)

## Description:
<img width="842" alt="スクリーンショット 2025-05-09 17 51 27"
src="https://github.com/user-attachments/assets/b9a2cb5b-74d2-4c07-aed2-01d719de6eb4"
/>

MLS
## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
This commit is contained in:
Aotumuri
2025-05-10 13:50:56 +09:00
committed by GitHub
parent 47f76b5b29
commit d6170f67ab
9 changed files with 272 additions and 93 deletions
+35 -21
View File
@@ -7,10 +7,10 @@ import { GameView, PlayerView } from "../../../core/game/GameView";
import quickChatData from "../../../../resources/QuickChat.json";
import { EventBus } from "../../../core/EventBus";
import { SendQuickChatEvent } from "../../Transport";
import { translateText } from "../../Utils";
type QuickChatPhrase = {
key: string;
text: string;
requiresPlayer: boolean;
};
@@ -58,12 +58,12 @@ export class ChatModal extends LitElement {
};
private categories = [
{ id: "help", name: "Help" },
{ id: "attack", name: "Attack" },
{ id: "defend", name: "Defend" },
{ id: "greet", name: "Greetings" },
{ id: "misc", name: "Miscellaneous" },
{ id: "warnings", name: "Warnings" },
{ id: "help" },
{ id: "attack" },
{ id: "defend" },
{ id: "greet" },
{ id: "misc" },
{ id: "warnings" },
];
private getPhrasesForCategory(categoryId: string) {
@@ -83,10 +83,10 @@ export class ChatModal extends LitElement {
const displayPlayers = [...filteredPlayers, ...otherPlayers];
return html`
<o-modal title="Quick Chat">
<o-modal title="${translateText("chat.title")}">
<div class="chat-columns">
<div class="chat-column">
<div class="column-title">Category</div>
<div class="column-title">${translateText("chat.category")}</div>
${this.categories.map(
(category) => html`
<button
@@ -96,7 +96,7 @@ export class ChatModal extends LitElement {
: ""}"
@click=${() => this.selectCategory(category.id)}
>
${category.name}
${translateText(`chat.cat.${category.id}`)}
</button>
`,
)}
@@ -105,13 +105,18 @@ export class ChatModal extends LitElement {
${this.selectedCategory
? html`
<div class="chat-column">
<div class="column-title">Phrase</div>
<div class="column-title">
${translateText("chat.phrase")}
</div>
<div class="phrase-scroll-area">
${this.getPhrasesForCategory(this.selectedCategory).map(
(phrase) => html`
<button
class="chat-option-button ${this
.selectedPhraseText === phrase.text
.selectedPhraseText ===
translateText(
`chat.${this.selectedCategory}.${phrase.key}`,
)
? "selected"
: ""}"
@click=${() => this.selectPhrase(phrase)}
@@ -127,12 +132,14 @@ export class ChatModal extends LitElement {
${this.requiresPlayerSelection || this.selectedPlayer
? html`
<div class="chat-column">
<div class="column-title">Player</div>
<div class="column-title">
${translateText("chat.player")}
</div>
<input
class="player-search-input"
type="text"
placeholder="Search player..."
placeholder="${translateText("chat.search")}"
.value=${this.playerSearchQuery}
@input=${this.onPlayerSearchInput}
/>
@@ -158,7 +165,9 @@ export class ChatModal extends LitElement {
</div>
<div class="chat-preview">
${this.previewText || "Build your message..."}
${this.previewText
? translateText(this.previewText)
: translateText("chat.build")}
</div>
<div class="chat-send">
<button
@@ -166,7 +175,7 @@ export class ChatModal extends LitElement {
@click=${this.sendChatMessage}
?disabled=${!this.previewText}
>
Send
${translateText("chat.send")}
</button>
</div>
</o-modal>
@@ -183,20 +192,24 @@ export class ChatModal extends LitElement {
}
private selectPhrase(phrase: QuickChatPhrase) {
this.selectedPhraseTemplate = phrase.text;
this.selectedPhraseText = phrase.text;
this.selectedQuickChatKey = this.getFullQuickChatKey(
this.selectedCategory!,
phrase.key,
);
this.previewText = phrase.text;
this.selectedPhraseTemplate = translateText(
`chat.${this.selectedCategory}.${phrase.key}`,
);
this.selectedPhraseText = translateText(
`chat.${this.selectedCategory}.${phrase.key}`,
);
this.previewText = `chat.${this.selectedCategory}.${phrase.key}`;
this.requiresPlayerSelection = phrase.requiresPlayer;
this.selectedPlayer = null;
this.requestUpdate();
}
private renderPhrasePreview(phrase: { text: string }) {
return phrase.text.replace("[P1]", "___"); // 仮表示
private renderPhrasePreview(phrase: { key: string }) {
return translateText(`chat.${this.selectedCategory}.${phrase.key}`);
}
private selectPlayer(player: string) {
@@ -270,6 +283,7 @@ export class ChatModal extends LitElement {
this.recipient = recipient;
this.sender = sender;
}
this.requestUpdate();
this.modalEl?.open();
}
@@ -16,6 +16,7 @@ import {
AllianceRequestUpdate,
AttackUpdate,
BrokeAllianceUpdate,
DisplayChatMessageUpdate,
DisplayMessageUpdate,
EmojiUpdate,
GameUpdateType,
@@ -33,6 +34,8 @@ import { onlyImages } from "../../../core/Util";
import { renderTroops } from "../../Utils";
import { GoToPlayerEvent, GoToUnitEvent } from "./Leaderboard";
import { translateText } from "../../Utils";
interface Event {
description: string;
unsafeDescription?: boolean;
@@ -77,6 +80,7 @@ export class EventsDisplay extends LitElement implements Layer {
private updateMap = new Map([
[GameUpdateType.DisplayEvent, (u) => this.onDisplayMessageEvent(u)],
[GameUpdateType.DisplayChatEvent, (u) => this.onDisplayChatEvent(u)],
[GameUpdateType.AllianceRequest, (u) => this.onAllianceRequestEvent(u)],
[
GameUpdateType.AllianceRequestReply,
@@ -187,6 +191,34 @@ export class EventsDisplay extends LitElement implements Layer {
});
}
onDisplayChatEvent(event: DisplayChatMessageUpdate) {
const myPlayer = this.game.playerByClientID(this.clientID);
if (
event.playerID === null ||
!myPlayer ||
myPlayer.smallID() !== event.playerID
) {
return;
}
const baseMessage = translateText(`chat.${event.category}.${event.key}`);
const translatedMessage = baseMessage.replace(
/\[([^\]]+)\]/g,
(_, key) => event.variables?.[key] || `[${key}]`,
);
this.addEvent({
description: translateText(event.isFrom ? "chat.from" : "chat.to", {
user: event.recipient,
msg: translatedMessage,
}),
createdAt: this.game.ticks(),
highlight: true,
type: MessageType.CHAT,
unsafeDescription: false,
});
}
onAllianceRequestEvent(update: AllianceRequestUpdate) {
const myPlayer = this.game.playerByClientID(this.clientID);
if (!myPlayer || update.recipientID !== myPlayer.smallID()) {