Profile Info

Stores and displays information on player profile pages

Устаревшая версия за 24.09.2017. Перейдите к последней версии.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         Profile Info
// @namespace    sullenProfileInfo
// @version      0.2
// @description  Stores and displays information on player profile pages
// @author       sullengenie [1946152]
// @match        *://*.torn.com/profiles.php?XID=*
// ==/UserScript==

(function() {
    'use strict';

    const tag_colors = {
        tbd: 'inherited',
        easy: 'rgba(161, 248, 161, 1)',
        medium: 'rgba(231, 231, 104, 1)',
        impossible: 'rgba(242, 140, 140, 0.7)'
    };

    const create_html = (html) => document.createRange().createContextualFragment(html);
    const insert_before = (nodes, target) => target.parentNode.insertBefore(nodes, target);
    const insert_after  = (nodes, target) => target.parentNode.insertBefore(nodes, target.nextSibling);

    const button_style = (color) => `.profile-button-attack { background: linear-gradient(180deg, #ebebeb, ${color}) !important; }`;
    document.body.appendChild(create_html('<style id="difficulty-profile-button-style"></style>'));
    const color_button = function(color) {
        document.getElementById('difficulty-profile-button-style').innerText = button_style(color);
    };

    function update_button() {
        //console.log('Update button clicked');
        const difficulty = get_player_difficulty();
        let dropdown = document.getElementById('difficulty-dropdown');
        if (dropdown) {
            dropdown.value = difficulty;
        }
        color_button(tag_colors[difficulty]);
    }

    // Create a button which other scripts can click to update
    const invis_elt = create_html('<div id="sullen-update-button" style="display:none"></div>');
    document.body.appendChild(invis_elt);
    document.getElementById('sullen-update-button').onclick = update_button;

    const automatic_tags = JSON.parse(localStorage.automaticProfileInfo || '{}');
    const initial_tags = JSON.parse(localStorage.sullenProfileInfo || '{}');
    const player_id = parseInt(window.location.href.match(/XID=(\d+)/)[1]);
    const initial_player_info = Object.assign({}, automatic_tags, initial_tags)[player_id] || {};
    //console.log(automatic_tags);
    //console.log(initial_tags);
    //console.log(initial_player_info);

    if (initial_tags.hasOwnProperty(player_id)) {
        color_button(tag_colors[initial_player_info.difficulty || 'tbd']);
    }

    function update_tags(f) {
        let tags = JSON.parse(localStorage.sullenProfileInfo || '{}');
        f(tags);
        localStorage.sullenProfileInfo = JSON.stringify(tags);
    }

    function update_player(vals) {
        update_tags(tags => tags[player_id] = Object.assign({}, tags[player_id], vals));
    }

    function update_hidden(val) {
        update_tags(tags => tags.hidden = val);
    }

    function player_info() {
        const auto_tags = JSON.parse(localStorage.automaticProfileInfo || '{}');
        const manual_tags = JSON.parse(localStorage.sullenProfileInfo || '{}');
        return Object.assign({}, auto_tags[player_id], manual_tags[player_id]);
    }

    function get_player_difficulty() {
        return (player_info().difficulty) || 'tbd';
    }

    function get_player_notes() {
        return player_info().notes;
    }

    function update_difficulty(menu) {
        const difficulty = menu.value;
        update_player({difficulty: difficulty});
        color_button(tag_colors[difficulty]);
    }

    function update_notes(notes) {
        update_player({notes: notes.value});
    }

    const initial_difficulty = initial_player_info.difficulty || 'tbd';
    const initial_notes = initial_player_info.notes || 'Write player notes here. They will automatically save!';

    const test_container = create_html(`
<div class="profile-wrapper m-top10">
<div>
<div class="title-black top-round${initial_tags.hidden ? ' all-round' : ''}" id="difficulty-profile-title">Profile Info - Click to ${initial_tags.hidden ? 'Display' : 'Hide'}</div>
<div class="cont bottom-round">
<div class="profile-container basic-info bottom-round" id="difficulty-profile-body" style="display:${initial_tags.hidden ? 'none' : 'block'}">
<div style="padding: 10px">
<select id="difficulty-dropdown" style="margin: 0px 10px 0px 0px" onchange="update_difficulty(this)">
<option ${initial_difficulty === 'tbd' ? 'selected="selected"' : ''} value="tbd">Difficulty</option>
<option ${initial_difficulty === 'easy' ? 'selected="selected"' : ''} value="easy">Easy</option>
<option ${initial_difficulty === 'medium' ? 'selected="selected"' : ''} value="medium">Medium</option>
<option ${initial_difficulty === 'impossible' ? 'selected="selected"' : ''} value="impossible">Impossible</option>
</select>
<textarea id="difficulty-notes" rows="10" cols="50">${initial_notes}</textarea>
</div>
</div>
</div>
</div>
</div>`);

    function add_title_toggle_onclick() {
        const title_node = document.getElementById('difficulty-profile-title');
        const body_node = document.getElementById('difficulty-profile-body');
        title_node.onclick = function() {
            if (body_node.style.display !== 'none') {
                title_node.innerText = 'Profile Difficulty - Click to Display';
                body_node.style.display = 'none';
                update_hidden(true);
                title_node.classList.add('all-round');
            } else {
                title_node.innerText = 'Profile Difficulty - Click to Hide';
                body_node.style.display = 'block';
                update_hidden(false);
                title_node.classList.remove('all-round');
            }
        };
    }

    function add_difficulty_onchange() {
        const dropdown = document.getElementById('difficulty-dropdown');
        dropdown.onchange = () => update_difficulty(dropdown);
    }

    function add_notes_oninput() {
        const notes = document.getElementById('difficulty-notes');
        notes.oninput = () => update_notes(notes);
    }

    function add_info_panel(medal_wrapper) {
        insert_before(test_container, medal_wrapper);
        add_title_toggle_onclick();
        add_difficulty_onchange();
        add_notes_oninput();
    }

    const is_medals_wrapper = (node) => node.classList !== undefined && node.classList.contains('medals-wrapper');

    function wait_for_medals_wrapper() {
        let target = document.querySelector('div.user-profile');
        let observer = new MutationObserver(function(mutations) {
            mutations.forEach(function(mutation) {
                for (let i = 0; i < mutation.addedNodes.length; i++) {
                    const node = mutation.addedNodes.item(i);
                    if (is_medals_wrapper(node)) {
                        add_info_panel(node);
                        this.disconnect();
                        break;
                    }
                }
            }.bind(this));
        });
        // configuration of the observer:
        let config = { attributes: true, childList: true, characterData: true };
        // pass in the target node, as well as the observer options
        observer.observe(target, config);
    }

    function wait_for_page_load() {
        let target = document.getElementById('profileroot').firstElementChild;
        let observer = new MutationObserver(function(mutations) {
            wait_for_medals_wrapper();
            this.disconnect();
        });
        // configuration of the observer:
        let config = { attributes: true, childList: true, characterData: true };
        // pass in the target node, as well as the observer options
        observer.observe(target, config);
    }
    wait_for_page_load();

    const global_css = create_html(`<style>
#difficulty-profile-title { cursor: pointer; }
#difficulty-profile-body * { vertical-align:top; }
.all-round { border-radius: 5px !important; }
</style>`);
    document.body.appendChild(global_css);
})();