Files
OpenFrontIO/src/client/graphics/layers/ChatIntegration.ts
T
Aotumuri e68d48c3a8 Fixed quick chat text injection (#1144)
## Description:
https://github.com/openfrontio/OpenFrontIO/issues/1035
Fixes #1035 
## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

## Please put your Discord username so you can be contacted if a bug or
regression is found:

.w.

---------

Co-authored-by: Scott Anderson <scottanderson@users.noreply.github.com>
Co-authored-by: evanpelle <evanpelle@gmail.com>
2025-06-13 09:21:22 -07:00

103 lines
3.1 KiB
TypeScript

import { EventBus } from "../../../core/EventBus";
import { GameView, PlayerView } from "../../../core/game/GameView";
import { SendQuickChatEvent } from "../../Transport";
import { translateText } from "../../Utils";
import { ChatModal, QuickChatPhrase, quickChatPhrases } from "./ChatModal";
import { COLORS, MenuElement, MenuElementParams } from "./RadialMenuElements";
export class ChatIntegration {
private ctModal: ChatModal;
constructor(
private game: GameView,
private eventBus: EventBus,
) {
this.ctModal = document.querySelector("chat-modal") as ChatModal;
if (!this.ctModal) {
throw new Error(
"Chat modal element not found. Ensure chat-modal element exists in DOM before initializing ChatIntegration",
);
}
}
setupChatModal(sender: PlayerView, recipient: PlayerView) {
this.ctModal.setSender(sender);
this.ctModal.setRecipient(recipient);
}
createQuickChatMenu(recipient: PlayerView): MenuElement[] {
if (!this.ctModal) {
throw new Error("Chat modal not set");
}
const myPlayer = this.game.myPlayer();
if (!myPlayer) {
throw new Error("Current player not found");
}
return this.ctModal.categories.map((category) => {
const categoryTranslation = translateText(`chat.cat.${category.id}`);
const categoryColor =
COLORS.chat[category.id as keyof typeof COLORS.chat] ||
COLORS.chat.default;
const phrases = quickChatPhrases[category.id] || [];
const phraseItems: MenuElement[] = phrases.map(
(phrase: QuickChatPhrase) => {
const phraseText = translateText(`chat.${category.id}.${phrase.key}`);
return {
id: `phrase-${category.id}-${phrase.key}`,
name: phraseText,
disabled: () => false,
text: this.shortenText(phraseText),
fontSize: "10px",
color: categoryColor,
tooltipItems: [
{
text: phraseText,
className: "description",
},
],
action: (params: MenuElementParams) => {
if (phrase.requiresPlayer) {
this.ctModal.openWithSelection(
category.id,
phrase.key,
myPlayer,
recipient,
);
} else {
this.eventBus.emit(
new SendQuickChatEvent(
recipient,
`${category.id}.${phrase.key}`,
undefined,
),
);
}
},
};
},
);
return {
id: `chat-category-${category.id}`,
name: categoryTranslation,
disabled: () => false,
text: categoryTranslation,
color: categoryColor,
_action: () => {}, // Empty action placeholder for RadialMenu
subMenu: () => phraseItems,
};
});
}
shortenText(text: string, maxLength = 15): string {
if (text.length <= maxLength) return text;
return text.substring(0, maxLength - 3) + "...";
}
}