diff --git a/src/client/ChatModal.ts b/src/client/ChatModal.ts index f26d7d88e..f6a29c985 100644 --- a/src/client/ChatModal.ts +++ b/src/client/ChatModal.ts @@ -5,11 +5,25 @@ const quickChatPhrases: Record< string, Array<{ text: string; requiresPlayer: boolean }> > = { - help: [{ text: "Please give me troops!", requiresPlayer: false }], - attack: [{ text: "Attack [P1]!", requiresPlayer: true }], + help: [ + { text: "Please give me troops!", requiresPlayer: false }, + { text: "Please give me golds!", requiresPlayer: false }, + { text: "Please don't attack me!", requiresPlayer: false }, + ], + attack: [ + { text: "Attack [P1]!", requiresPlayer: true }, + { text: "Launch a MIRV at [P1]!", requiresPlayer: true }, + { text: "Focus fire on [P1]!", requiresPlayer: true }, + { text: "Let's finish off [P1]!", requiresPlayer: true }, + ], defend: [{ text: "Defend [P1]!", requiresPlayer: true }], greet: [{ text: "Hello!", requiresPlayer: false }], - misc: [{ text: "Let’s go!", requiresPlayer: false }], + misc: [ + { text: "Let’s go!", requiresPlayer: false }, + { text: "Nice strategy!", requiresPlayer: false }, + { text: "This game is fun!", requiresPlayer: false }, + { text: "When will my PR finally get merged...?", requiresPlayer: false }, + ], }; @customElement("chat-modal") @@ -23,10 +37,30 @@ export class ChatModal extends LitElement { return this; } + private players: string[] = [ + "Slovakia", + "Germany", + "Japan", + "Anon", + "Anon1", + "Anon2", + "Anon3", + "Anon4", + "Anon5", + "Anon6", + "Anon7", + "Anon8", + "Anon9", + "Anon10", + ]; + + private playerSearchQuery: string = ""; private previewText: string | null = null; private requiresPlayerSelection: boolean = false; - private players: string[] = ["Slovakia", "Germany", "Japan"]; private selectedCategory: string | null = null; + private selectedPhraseText: string | null = null; + private selectedPlayer: string | null = null; + private selectedPhraseTemplate: string | null = null; quickChatPhrases: Record< string, @@ -52,65 +86,78 @@ export class ChatModal extends LitElement { } render() { + const sortedPlayers = [...this.players].sort((a, b) => a.localeCompare(b)); + + const filteredPlayers = sortedPlayers.filter((player) => + player.toLowerCase().includes(this.playerSearchQuery), + ); + + const otherPlayers = sortedPlayers.filter( + (player) => !player.toLowerCase().includes(this.playerSearchQuery), + ); + + const displayPlayers = [...filteredPlayers, ...otherPlayers]; return html` -
- -
- ${this.previewText || "Select a phrase"} +
+
+
Category
+ ${this.categories.map( + (category) => html` + + `, + )}
- -
-
Categories
-
- ${this.categories.map( - (category) => html` - - `, - )} -
-
- - ${this.selectedCategory ? html` -
-
Phrases
-
- ${this.getPhrasesForCategory(this.selectedCategory).map( - (phrase) => html` - - `, - )} -
+
+
Phrase
+ ${this.getPhrasesForCategory(this.selectedCategory).map( + (phrase) => html` + + `, + )}
` : null} - - - ${this.requiresPlayerSelection + ${this.requiresPlayerSelection || this.selectedPlayer ? html` -
-
Select Player
-
- ${this.players.map( +
+
Player
+ + + +
+ ${this.getSortedFilteredPlayers().map( (player) => html`
` : null} +
- -
- -
+
+ ${this.previewText || "Build your message..."} +
+
+
`; @@ -139,14 +188,19 @@ export class ChatModal extends LitElement { private selectCategory(categoryId: string) { this.selectedCategory = categoryId; + this.selectedPhraseText = null; this.previewText = null; this.requiresPlayerSelection = false; + this.selectedPlayer = null; this.requestUpdate(); } private selectPhrase(phrase: { text: string; requiresPlayer: boolean }) { + this.selectedPhraseTemplate = phrase.text; + this.selectedPhraseText = phrase.text; this.previewText = phrase.text; this.requiresPlayerSelection = phrase.requiresPlayer; + this.selectedPlayer = null; this.requestUpdate(); } @@ -156,7 +210,8 @@ export class ChatModal extends LitElement { private selectPlayer(player: string) { if (this.previewText) { - this.previewText = this.previewText.replace("[P1]", player); + this.previewText = this.selectedPhraseTemplate.replace("[P1]", player); + this.selectedPlayer = player; this.requiresPlayerSelection = false; this.requestUpdate(); } @@ -167,7 +222,24 @@ export class ChatModal extends LitElement { this.previewText = null; this.selectedCategory = null; this.requiresPlayerSelection = false; - this.close(); // モーダルを閉じる + this.close(); + } + + private onPlayerSearchInput(e: Event) { + const target = e.target as HTMLInputElement; + this.playerSearchQuery = target.value.toLowerCase(); + this.requestUpdate(); + } + + private getSortedFilteredPlayers(): string[] { + const sorted = [...this.players].sort((a, b) => a.localeCompare(b)); + const filtered = sorted.filter((p) => + p.toLowerCase().includes(this.playerSearchQuery), + ); + const others = sorted.filter( + (p) => !p.toLowerCase().includes(this.playerSearchQuery), + ); + return [...filtered, ...others]; } public open() { diff --git a/src/client/styles.css b/src/client/styles.css index 6204d8c50..8bfe816ca 100644 --- a/src/client/styles.css +++ b/src/client/styles.css @@ -492,65 +492,88 @@ label.option-card:hover { border: 1px solid rgba(255, 255, 255, 0.2); } -.chat-modal-content { +/* .w. */ + +.chat-columns { display: flex; - flex-direction: column; - gap: 12px; + gap: 16px; + padding: 12px; + overflow-x: auto; } -.chat-preview { - background: #222; - padding: 10px; - border-radius: 6px; +.chat-column { + display: flex; + flex-direction: column; + gap: 8px; + min-width: 120px; +} + +.column-title { font-weight: bold; - text-align: center; -} - -.chat-section { - display: flex; - flex-direction: column; -} - -.chat-section-title { - font-size: 14px; - margin-bottom: 6px; -} - -.chat-options { - display: flex; - flex-wrap: wrap; - gap: 6px; + margin-bottom: 4px; } .chat-option-button { - background: #444; + background: #333; + color: white; border: none; + padding: 8px 12px; border-radius: 4px; - padding: 6px 10px; + text-align: left; cursor: pointer; } .chat-option-button.selected { - background: #66c; + background-color: #66c; +} + +.chat-preview { + margin: 10px 12px; + padding: 10px; + background: #222; color: white; + border-radius: 6px; + text-align: center; } .chat-send { display: flex; - justify-content: space-between; - margin-top: 10px; + justify-content: flex-end; + padding: 0 12px 12px; } .chat-send-button { background: #4caf50; color: white; - padding: 8px 14px; + padding: 8px 16px; + border: none; border-radius: 4px; + cursor: pointer; } -.chat-cancel-button { - background: #aaa; - color: black; - padding: 8px 14px; - border-radius: 4px; +.chat-column { + display: flex; + flex-direction: column; + gap: 8px; + min-width: 140px; +} + +.player-search-input { + padding: 6px 8px; + border-radius: 4px; + border: 1px solid #666; + font-size: 14px; + outline: none; + + background-color: #fff; + color: #000; +} + +.player-scroll-area { + max-height: 200px; + overflow-y: auto; + display: flex; + flex-direction: column; + gap: 6px; + padding-right: 4px; }