Ticket #4069: chathistory_wip1.patch

File chathistory_wip1.patch, 13.6 KB (added by elexis, 8 years ago)

Filtering logic not implemented yet. Gamesetup chat should be preserved too.

  • binaries/data/mods/public/gui/session/chat_window.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22
    3 <object name="chatDialogPanel" size="50%-180 50%-66 50%+180 50%+54" type="image" hidden="true" sprite="genericPanel">
     3<object name="chatDialogPanel" type="image" size="50%-180 50%-60 50%+180 50%+60" hidden="true" sprite="genericPanel">
    44
    5     <!-- Message addressee -->
    6     <object size="16 14 50 38" type="text" style="chatPanel">
    7         <translatableAttribute id="caption" context="chat input">To:</translatableAttribute>
    8     </object>
    9     <object size="75 12 100%-16 36" name="chatAddressee" type="dropdown" style="ModernDropDown" tooltip_style="sessionToolTipBold">
    10         <translatableAttribute id="tooltip" context="chat input">Select chatmessage addressee</translatableAttribute>
    11     </object>
    12 
    13     <!-- Message text -->
    14     <object size="16 46 50 70" type="text" style="chatPanel">
    15         <translatableAttribute id="caption" context="chat input">Text:</translatableAttribute>
    16     </object>
    17     <object name="chatInput" size="75 44 100%-16 68" type="input" style="ModernInput" max_length="80">
    18         <translatableAttribute id="tooltip" context="chat input">Type the message to send.</translatableAttribute>
    19         <action on="Press">submitChatInput();</action>
    20         <action on="Tab">
    21             let playernames = [];
    22             for (let player in g_PlayerAssignments)
    23                 playernames.push(g_PlayerAssignments[player].name);
    24             autoCompleteNick(this, playernames);
    25         </action>
    26     </object>
     5    <object name="chatExtended" size="0 0 100% 350" hidden="true">
    276
    28     <!-- Cancel Button -->
    29     <object size="16 100%-40 30%+16 100%-12" type="button" style="StoneButton">
    30         <translatableAttribute id="caption">Cancel</translatableAttribute>
    31         <action on="Press">closeChat();</action>
    32     </object>
     7        <!-- Tab buttons: Chat, Filter, possibly a page for preformatted, translated messages -->
     8        <object type="image" name="chatPageButtons" size="10 10 100%-10 55">
     9            <object name="chatPageButtonHistory" type="button" size="0 5 140 100%-10" style="StoneButton" textcolor_disabled="245 208 96">
     10                <translatableAttribute id="caption">Chat</translatableAttribute>
     11                <action on="Press">showChatPage("History");</action>
     12            </object>
     13            <object  name="chatPageButtonFilter" type="button" size="150 5 270 100%-10" style="StoneButton" textcolor_disabled="245 208 96">
     14                <translatableAttribute id="caption" context="chatWindow">Filter</translatableAttribute>
     15                <action on="Press">showChatPage("Filter");</action>
     16            </object>
     17        </object>
     18
     19        <object type="image" name="chatPages" size="10 60 100%-10 100%" sprite="ModernDarkBoxGold">
     20
     21            <!-- History page -->
     22            <object name="pageChatHistory" size="0 0 100% 100%">
     23                <object name="chatHistory" type="text" size="0 0 100% 100%" style="chatHistory"/>
     24            </object>
     25
     26            <!-- Filter page -->
     27            <object name="pageChatFilter" size="0 0 100% 100%">
     28                <object name="chatFilterInfo" type="text" size="0 0 100% 25" textcolor="white">
     29                    <translatableAttribute id="caption">Specify which messages should be shown:</translatableAttribute>
     30                </object>
     31                <repeat count="7" var="i">
     32                    <object name="chatFilter[i]" type="checkbox" style="ModernTickBox"/>
     33                    <object name="chatFilterLabel[i]" type="text" textcolor="white"/>
     34                </repeat>
     35            </object>
     36
     37        </object>
     38    </object>
     39
     40    <object name="chatSimple" size="0 0 100% 120">
     41
     42        <!-- Message addressee -->
     43        <object type="text" size="16 14 50 38" style="chatPanel">
     44            <translatableAttribute id="caption" context="chat input">To:</translatableAttribute>
     45        </object>
     46        <object type="dropdown" size="75 12 100%-16 36" name="chatAddressee" style="ModernDropDown" tooltip_style="sessionToolTipBold">
     47            <translatableAttribute id="tooltip" context="chat input">Select chatmessage addressee</translatableAttribute>
     48        </object>
     49
     50        <!-- Message text -->
     51        <object type="text" size="16 46 50 70" style="chatPanel">
     52            <translatableAttribute id="caption" context="chat input">Text:</translatableAttribute>
     53        </object>
     54        <object name="chatInput" type="input" size="75 44 100%-16 68" style="ModernInput" max_length="80">
     55            <translatableAttribute id="tooltip" context="chat input">Type the message to send.</translatableAttribute>
     56            <action on="Press">submitChatInput();</action>
     57            <action on="Tab">
     58                let playernames = [];
     59                for (let player in g_PlayerAssignments)
     60                    playernames.push(g_PlayerAssignments[player].name);
     61
     62                autoCompleteNick(this, playernames);
     63            </action>
     64        </object>
     65
     66        <!-- Close Button -->
     67        <object size="16 100%-40 30%+16 100%-12" type="button" style="StoneButton">
     68            <translatableAttribute id="caption">Close</translatableAttribute>
     69            <action on="Press">closeChat();</action>
     70        </object>
     71
     72        <!-- Extended Chat Checkbox -->
     73        <object name="extendedChat" type="checkbox" checked="false" style="ModernTickBox" size="50%-50 100%-38 50%-24 100%-12">
     74            <action on="Press">toggleExtendedChat();</action>
     75        </object>
     76
     77        <!-- Extended Chat Label -->
     78        <object type="text" size="50%-24 100%-38 50%+40 100%-12" text_align="left" textcolor="white">
     79            <translatableAttribute id="caption" context="extended chat">Extended</translatableAttribute>
     80        </object>
     81
     82        <!-- Send Button -->
     83        <object size="60%+16 100%-40 100%-16 100%-12" type="button" style="StoneButton">
     84            <translatableAttribute id="caption">Send</translatableAttribute>
     85            <action on="Press">submitChatInput();</action>
     86        </object>
    3387
    34     <!-- Send Button -->
    35     <object size="60%+16 100%-40 100%-16 100%-12" type="button" style="StoneButton">
    36         <translatableAttribute id="caption">Send</translatableAttribute>
    37         <action on="Press">submitChatInput();</action>
    3888    </object>
    3989
    4090</object>
  • binaries/data/mods/public/gui/session/menu.js

    function openChat(teamChat = false)  
    214214
    215215    let chatAddressee = Engine.GetGUIObjectByName("chatAddressee");
    216216    let command = teamChat ? (g_IsObserver ? "/observers" : "/allies") : "";
    217217    chatAddressee.selected = chatAddressee.list_data.indexOf(command);
    218218
    219     Engine.GetGUIObjectByName("chatInput").focus();
    220219    Engine.GetGUIObjectByName("chatDialogPanel").hidden = false;
     220
     221    resizeChatWindow();
    221222}
    222223
    223224function closeChat()
    224225{
    225226    Engine.GetGUIObjectByName("chatInput").caption = "";
    226227    Engine.GetGUIObjectByName("chatInput").blur(); // Remove focus
    227228    Engine.GetGUIObjectByName("chatDialogPanel").hidden = true;
    228229}
    229230
     231/**
     232 * The extended part is shown above the simple one.
     233 * So move the simple to the top if extended part is hidden.
     234 */
     235function resizeChatWindow()
     236{
     237    let chatSimple = Engine.GetGUIObjectByName("chatSimple");
     238    let chatSimpleHeight = chatSimple.size.bottom - chatSimple.size.top;
     239
     240    let chatExtended = Engine.GetGUIObjectByName("chatExtended");
     241    let chatExtendedHeight = chatExtended.size.bottom - chatExtended.size.top;
     242
     243    // Move simple part to the top if extended is hidden
     244    let size = chatSimple.size;
     245    size.top = chatExtended.hidden ? 0 : chatExtendedHeight;
     246    size.bottom = size.top + chatSimpleHeight;
     247    chatSimple.size = size;
     248
     249    // Resize window to show the extended part
     250    let width = chatExtended.hidden ? 360 : 480;
     251    let height = chatSimpleHeight + (chatExtended.hidden ? 0 : chatExtendedHeight);
     252
     253    // Don't center the window vertically
     254    let topOffset = 60;
     255
     256    let chatDialogPanel = Engine.GetGUIObjectByName("chatDialogPanel");
     257    let size = chatDialogPanel.size;
     258    size.top = -height / 2 - topOffset;
     259    size.bottom = height / 2 - topOffset;
     260    size.left = -width / 2;
     261    size.right = width / 2;
     262    chatDialogPanel.size = size;
     263
     264    Engine.GetGUIObjectByName("chatInput").focus();
     265}
     266
     267function initChatFilters()
     268{
     269    const checkboxSize = 20;
     270    const spacing = 5;
     271    const offset = Engine.GetGUIObjectByName("chatFilterInfo").size.bottom;
     272
     273    for (let i=0; i < g_ChatFilter.length; ++i)
     274    {
     275        let top = offset + i * (checkboxSize + spacing);
     276        let bottom = offset + (i+1) * checkboxSize + i * spacing;
     277
     278        let chatFilter = Engine.GetGUIObjectByName("chatFilter[" + i + "]");
     279        chatFilter.size = [0, top, checkboxSize, bottom].join(" ");
     280        chatFilter.hidden = false;
     281        chatFilter.checked = true;
     282        chatFilter.onPress = function() {
     283            updateChatHistory();
     284        };
     285
     286        let chatFilterLabel = Engine.GetGUIObjectByName("chatFilterLabel[" + i + "]");
     287        chatFilterLabel.caption = g_ChatFilter[i].caption;
     288        chatFilterLabel.size = [checkboxSize, top, "100%", bottom].join(" ");
     289        chatFilterLabel.hidden = false;
     290    }
     291}
     292
     293function showChatPage(pageName)
     294{
     295    for (let button of Engine.GetGUIObjectByName("chatPageButtons").children)
     296        button.enabled = button.name != "chatPageButton" + pageName
     297
     298    for (let page of Engine.GetGUIObjectByName("chatPages").children)
     299        page.hidden = page.name != "pageChat" + pageName;
     300}
     301
     302function toggleExtendedChat()
     303{
     304    let chatExtended = Engine.GetGUIObjectByName("chatExtended");
     305    chatExtended.hidden = !chatExtended.hidden;
     306
     307    if (!chatExtended.hidden)
     308        updateChatHistory();
     309
     310    resizeChatWindow();
     311}
     312
     313function updateChatHistory()
     314{
     315    let filteredTypes = [];
     316
     317    for (let i=0; i < g_ChatFilter.length; ++i)
     318    {
     319        //if (Engine.GetGUIObjectByName("chatFilter[" + i + "]").checked)
     320        // TODO: filters
     321    }
     322
     323    Engine.GetGUIObjectByName("chatHistory").caption =
     324        g_ChatHistory.filter(msg => {
     325            return msg.txt; // && filteredTypes.indexOf(msg.type) != -1;
     326        }).map(msg => msg.txt).join("\n");
     327}
     328
    230329function openDiplomacy()
    231330{
    232331    closeOpenDialogs();
    233332
    234333    if (g_ViewedPlayer < 1)
  • binaries/data/mods/public/gui/session/messages.js

    const g_ChatTimeout = 30;  
    1313 * Maximum number of lines to display simultaneously.
    1414 */
    1515const g_ChatLines = 20;
    1616
    1717/**
    18  * The strings to be displayed including sender and formating.
     18 * The currently displayed strings, limited by the given timeframe and limit above.
    1919 */
    2020var g_ChatMessages = [];
    2121
    2222/**
     23 * All unparsed chat messages received since connect, including timestamp.
     24 */
     25var g_ChatHistory = [];
     26
     27/**
    2328 * Holds the timer-IDs used for hiding the chat after g_ChatTimeout seconds.
    2429 */
    2530var g_ChatTimers = [];
    2631
    2732/**
    var g_DiplomacyMessages = {  
    191196        "neutral": translate("%(player)s is now neutral with %(player2)s.")
    192197    }
    193198};
    194199
    195200/**
     201 * TODO: Should include an entry for every client once scrolling is implemented.
     202 */
     203var g_ChatFilter = [
     204    {
     205        "caption": translate("Public"),
     206        "key": "public"
     207    },
     208    {
     209        "caption": translate("Allies"),
     210        "key": "allies"
     211    },
     212    {
     213        "caption": translate("Enemies"),
     214        "key": "enemies"
     215    },
     216    {
     217        "caption": translate("Private"),
     218        "key": "private"
     219    },
     220    {
     221        "caption": translate("Observer"),
     222        "key": "observer"
     223    },
     224    {
     225        "caption": translate("Connection Status"),
     226        "key": "connection"
     227    },
     228    {
     229        "caption": translate("Game Notifications"),
     230        "key": "game"
     231    }
     232];
     233
     234/**
    196235 * Defines how the GUI reacts to notifications that are sent by the simulation.
    197236 */
    198237var g_NotificationsTypes =
    199238{
    200239    "chat": function(notification, player)
    function submitChatDirectly(text)  
    655694
    656695/**
    657696 * Loads the text from the GUI window, checks if it is a local command
    658697 * or cheat and executes it. Otherwise sends it as chat.
    659698 */
    660 function submitChatInput()
     699function submitChatInput(window)
    661700{
    662701    let text = Engine.GetGUIObjectByName("chatInput").caption;
    663702
    664703    closeChat();
     704    Engine.GetGUIObjectByName("chatInput").caption = "";
    665705
    666706    if (!text.length)
    667707        return;
    668708
    669709    if (executeNetworkCommand(text))
    function addChatMessage(msg)  
    691731
    692732    let formatted = g_FormatChatMessage[msg.type](msg);
    693733    if (!formatted)
    694734        return;
    695735
     736    // Remember the original text as it depends on g_PlayerAssignments
     737    g_ChatHistory.push({
     738        "type": msg.type,
     739        "txt": formatted
     740    });
     741    updateChatHistory();
     742
    696743    g_ChatMessages.push(formatted);
    697744    g_ChatTimers.push(setTimeout(removeOldChatMessage, g_ChatTimeout * 1000));
    698745
    699746    if (g_ChatMessages.length > g_ChatLines)
    700747        removeOldChatMessage();
  • binaries/data/mods/public/gui/session/session.js

    function init(initData, hotloadData)  
    288288
    289289    // If in Atlas editor, disable the exit button
    290290    if (Engine.IsAtlasRunning())
    291291        Engine.GetGUIObjectByName("menuExitButton").enabled = false;
    292292
     293    showChatPage("History");
     294    initChatFilters();
     295
    293296    initHotkeyTooltips();
    294297
    295298    if (hotloadData)
    296299        g_Selection.selected = hotloadData.selection;
    297300
  • binaries/data/mods/public/gui/session/styles.xml

     
    239239        sprite_selectarea="chatInputHighlight"
    240240        textcolor="white"
    241241        textcolor_selected="darkgray"
    242242    />
    243243
     244    <style name="chatHistory"
     245        buffer_zone="5"
     246        font="sans-13"
     247        scrollbar="true"
     248        scrollbar_style="ModernScrollBar"
     249        scroll_bottom="true"
     250        textcolor="white"
     251        textcolor_selected="gold"
     252        text_align="left"
     253        text_valign="center"
     254    />
     255
    244256    <style name="notificationPanel"
    245257       buffer_zone="5"
    246258       font="sans-bold-stroke-14"
    247259       textcolor="white"
    248260       text_align="center"