naz7 / Grepolis Command List Fix

// ==UserScript==
// @name         Grepolis Command List Fix
// @namespace    Naz
// @version      0.2.2
// @description  Fixes the problem of command window disappearing on click
// @author       naz
// @updateURL    https://openuserjs.org/meta/naz7/Grepolis_Command_List_Fix.meta.js
// @downloadURL  https://openuserjs.org/src/scripts/naz7/Grepolis_Command_List_Fix.user.js
// @include      http://*.grepolis.*/game*
// @include      https://*.grepolis.*/game*
// @grant        none
// ==/UserScript==
function GPCLF() {
    var head = document.getElementsByTagName('head')[0];

    function addStyle(css) {
        if (!head) return;
        var style = document.createElement('style');
        style.type = 'text/css';
        style.innerHTML = css;
        head.insertBefore(style, head.firstChild);
    }

    // Set the visibility of the command list and the cancel buttons to visible,
    // because they're set to hidden when clicking anywhere in the commands window,
    // and when cancelling a movement the window disappears, which is quite annoying
    addStyle(`
#toolbar_activity_commands_list.fast .js-dropdown-item-list > div { visibility: visible !important }
#toolbar_activity_commands_list.fast .remove { visibility: visible !important }
`);

    // Hide cancel button for commands that can't be cancelled (colonizations, incoming movements, movements launched +10 minutes ago...)
    function updateCommands() {
        // Iterate the commands/movements
        $("#toolbar_activity_commands_list").find('.content.js-dropdown-item-list').children("div").each(function() {
            $(this).attr("class", "visible");

            if ($(this).attr("data-starttime") == "-1") {
                // This command can't be cancelled, so just hide the cancel button (red cross)
                var crossToHide = $(this).find('.remove').first().attr("style", "visibility: hidden !important");
            }
        });
    }

    function showWindowOnRemove(removeBtn) {
        //console.log($(removeBtn).attr('class'));
        if ($(removeBtn.parentElement).hasClass("command")) {
            if ($("#toolbar_activity_commands_list").css("display") == "none") {
                updateCommands();
                $("#toolbar_activity_commands_list").css("display", "block");
            }
            //console.log("command removal");
        } else if ($(removeBtn.parentElement).hasClass("trade")) {
            if ($("#toolbar_activity_trades_list").css("display") == "none") {
                $("#toolbar_activity_trades_list").css("display", "block");
            }
            //console.log("trade removal");
        } else {
            if ($("#toolbar_activity_recruits_list").css("display") == "none") {
                $("#toolbar_activity_recruits_list").css("display", "block");
            }
            //console.log("recruitment removal");
        }
    }

    // Remove the commands of the window
    function removeCommands() {
        // Get the command list and remove all the divs corresponding to commands
        $("#toolbar_activity_commands_list").find('.content.js-dropdown-item-list').children("div").remove();
    }

    // Make the window appear again, because by default it's being hidden when leaving the area of the window
    $(document.body).on("mouseleave", "#toolbar_activity_commands_list", function() {
        setTimeout(function () {
            updateCommands();
            $("#toolbar_activity_commands_list").css("display", "block");
        }, 50);

        // If it didn't work, try again a bit later
        setTimeout(function () {
            updateCommands();
            if ($("#toolbar_activity_commands_list").css("display") == "none") {
                $("#toolbar_activity_commands_list").css("display", "block");
            }
        }, 200);
    });

    // Make the window appear again, because by default it's being hidden when cancelling a command
    $(document.body).on("mousedown", ".remove", function() {
        var removeBtn = this;
        setTimeout(function () {
            if ($(removeBtn.parentElement).hasClass("command")) {
                updateCommands();
                $("#toolbar_activity_commands_list").css("display", "block");
            }
        }, 50);

        // If it didn't work, try again a bit later
        setTimeout(function () {
            showWindowOnRemove(removeBtn);
        }, 200);
    });

    $(document.body).on("mouseover", ".commands", function() {
        // In case there's some other script that allows to drag the window
        if ($("#toolbar_activity_commands_list").hasClass("ui-draggable")) {
            if ($("#toolbar_activity_commands_list").css("display") == "none") {

                // Remove style top and left properties and leave only the display property
                // so it goes back to default position, right below the sword icon,
                // otherwise if the window is far away from the icon, it will disappear
                // when mouseleaving the icon and won't be able to reach to window with the mouse
                $("#toolbar_activity_commands_list").attr("style", "display: none");
            }
        }
    });

    // When hovering the sword icon that shows the command window, update the window,
    // (remove cancel buttons that shouldn't be there)
    $(document.body).on("mouseenter", ".commands", function() {
        setTimeout(function () {
            updateCommands();
        }, 100);
    });

    // When hovering the trading icon that shows the active trades, bring the window to the front,
    // because you may want to see the trades but the overlapping command window won't let you see,
    // and it's also likely that you didn't really want to hover the trading icon, so the window won't
    // stay active like the command window
    $(document.body).on("mouseover", ".trades", function() {
        var currZ = $("#toolbar_activity_commands_list").css("z-index");
        $("#toolbar_activity_trades_list").css("z-index", ((currZ * 1) + 1));
    });

    // Back to its normal state, just in case...
    $(document.body).on("mouseleave", "#toolbar_activity_trades_list", function() {
        $("#toolbar_activity_trades_list").css("z-index", 900);
    });

    // Same for recruiting window
    $(document.body).on("mouseover", ".recruits", function() {
        var currZ = $("#toolbar_activity_commands_list").css("z-index");
        $("#toolbar_activity_recruits_list").css("z-index", ((currZ * 1) + 1));
    });

    // Back to its normal state, just in case...
    $(document.body).on("mouseleave", "#toolbar_activity_recruits_list", function() {
        $("#toolbar_activity_recruits_list").css("z-index", 900);
    });

    $(document.body).on("mouseover", ".js-queue-item", function() {
        setTimeout(function () {
            var currZ = $("#toolbar_activity_recruits_list").css("z-index");
            $(".tooltip_with_arrow.arrow-right-top").css("z-index", (currZ * 1) + 1);
        }, 200);
    });

    // Not really sure whether this is actually needed, I think the tooltipgets destroyed on mouseleave
    /*$(document.body).on("mouseleave", "#toolbar_activity_recruits_list", function() {
        $(".tooltip_with_arrow.arrow-right-top").css("z-index", 900);
    });*/

    // When sending or cancelling commands, update the command window by hiding wrong cancel buttons
    $(document).ajaxComplete(function(event, xhr, settings) {
        var isCommandsUpdate = (settings.url).indexOf("frontend_bridge"); // returns -1 if it isn't a frontend_bridge AJAX response
        var isTownChanged = (settings.url).indexOf("town_info");
        if (isCommandsUpdate >= 0 || isTownChanged >= 0) {
            setTimeout(function () {
                $(".commands").trigger("mouseover");
            }, 50);
            updateCommands();
        }
    });

}
GPCLF();