/**
* This class is concerned with building and propagating the chat addressee selection.
*/
class ChatAddressees
{
constructor(alignmentHelper)
{
this.selectionChangeHandlers = [];
this.chatAddresseeCaption = Engine.GetGUIObjectByName("chatAddresseeCaption");
resizeGUIObjectToCaption(this.chatAddresseeCaption, { "horizontal": "right" });
this.chatAddressee = Engine.GetGUIObjectByName("chatAddressee");
this.chatAddressee.onSelectionChange = this.onSelectionChange.bind(this);
alignmentHelper.setObject(this.chatAddressee, "left", this.chatAddresseeCaption.size.right + this.DropdownMargin);
}
registerSelectionChangeHandler(handler)
{
this.selectionChangeHandlers.push(handler);
}
onSelectionChange()
{
let selection = this.getSelection();
for (let handler of this.selectionChangeHandlers)
handler(selection);
}
getSelection()
{
return this.chatAddressee.list_data[this.chatAddressee.selected] || "";
}
select(command)
{
this.chatAddressee.selected = this.chatAddressee.list_data.indexOf(command);
}
onUpdatePlayers()
{
// Remember previously selected item
let selectedName = this.getSelection();
selectedName = selectedName.startsWith("/msg ") && selectedName.substr("/msg ".length);
let addressees = this.AddresseeTypes.filter(
addresseeType => addresseeType.isSelectable()).map(
addresseeType => ({
"label": translateWithContext("chat addressee", addresseeType.label),
"cmd": addresseeType.command
}));
// Add playernames for private messages
let guids = sortGUIDsByPlayerID();
for (let guid of guids)
{
if (guid == Engine.GetPlayerGUID())
continue;
let playerID = g_PlayerAssignments[guid].player;
// Don't provide option for PM from observer to player
if (g_IsObserver && !isPlayerObserver(playerID))
continue;
let colorBox = isPlayerObserver(playerID) ? "" : colorizePlayernameHelper("■", playerID) + " ";
addressees.push({
"cmd": "/msg " + g_PlayerAssignments[guid].name,
"label": colorBox + g_PlayerAssignments[guid].name
});
}
// Select mock item if the selected addressee went offline
if (selectedName && guids.every(guid => g_PlayerAssignments[guid].name != selectedName))
addressees.push({
"cmd": "/msg " + selectedName,
"label": sprintf(translate("\\[OFFLINE] %(player)s"), { "player": selectedName })
});
let oldChatAddressee = this.getSelection();
this.chatAddressee.list = addressees.map(adressee => adressee.label);
this.chatAddressee.list_data = addressees.map(adressee => adressee.cmd);
this.chatAddressee.selected = Math.max(0, this.chatAddressee.list_data.indexOf(oldChatAddressee));
}
}
ChatAddressees.prototype.AddresseeTypes = [
{
"command": "",
"isSelectable": () => true,
"label": markForTranslationWithContext("chat addressee", "Everyone"),
"isAddressee": () => true
},
{
"command": "/allies",
"isSelectable": () => !g_IsObserver,
"label": markForTranslationWithContext("chat addressee", "Allies"),
"context": markForTranslationWithContext("chat message context", "Ally"),
"isAddressee":
senderID =>
g_Players[senderID] &&
g_Players[Engine.GetPlayerID()] &&
g_Players[senderID].isMutualAlly[Engine.GetPlayerID()],
},
{
"command": "/enemies",
"isSelectable": () => !g_IsObserver,
"label": markForTranslationWithContext("chat addressee", "Enemies"),
"context": markForTranslationWithContext("chat message context", "Enemy"),
"isAddressee":
senderID =>
g_Players[senderID] &&
g_Players[Engine.GetPlayerID()] &&
g_Players[senderID].isEnemy[Engine.GetPlayerID()],
},
{
"command": "/observers",
"isSelectable": () => true,
"label": markForTranslationWithContext("chat addressee", "Observers"),
"context": markForTranslationWithContext("chat message context", "Observer"),
"isAddressee": senderID => g_IsObserver
},
{
"command": "/msg",
"isSelectable": () => false,
"label": undefined,
"context": markForTranslationWithContext("chat message context", "Private"),
"isAddressee": (senderID, addresseeGUID) => addresseeGUID == Engine.GetPlayerGUID()
}
];
ChatAddressees.prototype.DropdownMargin = 5;