codeforces-problem-queue

You can queue the problems you want to revenge!

Versão de: 28/02/2021. Veja: a última versão.

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name         codeforces-problem-queue
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  You can queue the problems you want to revenge!
// @author       itohdak
// @license      MIT
// @match        https://codeforces.com/contest/*/problem/*
// @match        https://codeforces.com/profile/*
// @grant        none
// ==/UserScript==

var max_problem_count = 50;
function getProblemQueue () {
    return JSON.parse(localStorage.getItem('problemQueue') || '{}');
}
function setProblemQueue (problemQueue) {
    localStorage.setItem('problemQueue', JSON.stringify(problemQueue));
}
function addProblem (problemTitle, problemContent) {
    var problemQueue = getProblemQueue();
    if(problemTitle in problemQueue) {
        return "Already in queue.";
    } else if(Object.keys(problemQueue).length >= max_problem_count) {
        return "Reached the maximum number of problems you can queue.</br>Let\'s solve the problems!:)";
    } else {
        problemQueue[problemTitle] = problemContent;
        setProblemQueue(problemQueue);
        return "Added successfully.";
    }
}
function deleteProblem (problemTitle) {
    var problemQueue = getProblemQueue();
    delete problemQueue[problemTitle];
    setProblemQueue(problemQueue);
}

function setAddProblemButton () {
    // Create a button in a container div.
    var div = document.createElement('div');
    div.setAttribute('style', 'margin:1em;font-size:0.8em;');
    div.setAttribute('id', 'addProblemContainer');
    var btn = document.createElement('input');
    btn.setAttribute('type', 'submit');
    btn.setAttribute('value', 'Add this problem to my problem queue');
    btn.setAttribute('style', 'padding:0 0.5em;');
    btn.setAttribute('id', 'addProblemButton');
    div.appendChild(btn);
    document.getElementsByClassName('header')[0].appendChild(div);

    // Activate the newly added button.
    document.getElementById('addProblemButton').addEventListener(
        'click', buttonClickAction, false
    );
}

function buttonClickAction (event) {
    var problemTitle = document.getElementsByClassName('title')[0].innerHTML
    var contestName = document.getElementsByClassName('left')[0].querySelectorAll('a')[0].text
    var msg = addProblem(problemTitle, {'contestName': contestName, 'problemLink': location.href});

    var p = document.createElement('p');
    p.innerHTML = '<font color="red">' + msg + '</font>';
    var cntr = document.getElementById('addProblemContainer');
    if(cntr.children.length > 1) cntr.removeChild(cntr.childNodes[1]);
    cntr.appendChild(p);
}

function createCodeforcesLikeRoundBox () {
    var roundBox = document.createElement('div');
    roundBox.setAttribute('class', 'roundbox sidebox top-contributed');
    roundBox.setAttribute('style', 'margin-top:1em;');
    var roundBoxLT = document.createElement('div');
    roundBoxLT.setAttribute('class', 'roundbox-lt');
    roundBoxLT.innerHTML = '&nbsp;';
    var roundBoxRT = document.createElement('div');
    roundBoxRT.setAttribute('class', 'roundbox-rt');
    roundBoxRT.innerHTML = '&nbsp;';
    var roundBoxLB = document.createElement('div');
    roundBoxLB.setAttribute('class', 'roundbox-lb');
    roundBoxLB.innerHTML = '&nbsp;';
    var roundBoxRB = document.createElement('div');
    roundBoxRB.setAttribute('class', 'roundbox-rb');
    roundBoxRB.innerHTML = '&nbsp;';
    roundBox.appendChild(roundBoxLT);
    roundBox.appendChild(roundBoxRT);
    // roundBox.appendChild(roundBoxLB);
    // roundBox.appendChild(roundBoxRB);
    return roundBox;
}

function createCodeforcesLikeDeleteButton (problemTitle) {
    var deleteBtn = document.createElement('a');
    deleteBtn.setAttribute('class', 'delete-virtual-contest');
    deleteBtn.setAttribute('title', 'delete [' + problemTitle + ']');
    deleteBtn.setAttribute('href', '#');
    var img = document.createElement('img');
    img.setAttribute('width', '12px;');
    img.setAttribute('src', '//sta.codeforces.com/s/!/images/delete.png');
    deleteBtn.appendChild(img);
    return deleteBtn;
}

function setProblemList () {
    var userPage = document.getElementsByClassName('avatar')[0].querySelectorAll('a')[1];
    if(userPage == null || (userPage != location.href && userPage + "#" != location.href)) return;

    var roundBox = createCodeforcesLikeRoundBox();

    var title = document.createElement('div');
    title.setAttribute('class', 'caption titled');
    title.innerHTML = '→ Problem queue';
    roundBox.appendChild(title);

    var table = document.createElement('table');
    table.setAttribute('class', 'rtable ');
    table.setAttribute('id', 'problemQueue');
    roundBox.appendChild(table);
    var tbody = document.createElement('tbody');
    table.appendChild(tbody);

    var header = document.createElement('tr');
    var thIdx = document.createElement('th');
    thIdx.textContent = '#';
    var thPblm = document.createElement('th');
    thPblm.textContent = 'Problem';
    header.appendChild(thIdx);
    header.appendChild(thPblm);
    header.appendChild(document.createElement('th'));
    tbody.appendChild(header);

    var num = 1;
    var problemQueue = getProblemQueue();
    for (let key in problemQueue) {
        var tr = document.createElement('tr');
        // add index
        var tdIdx = document.createElement('td');
        tdIdx.innerText = num;
        if(num%2) tdIdx.setAttribute('class', 'dark');
        // add problem link
        var tdLink = document.createElement('td');
        if(num%2) tdLink.setAttribute('class', 'dark');
        tdLink.innerHTML = '<a href="' + problemQueue[key].problemLink + '" title="' + problemQueue[key].contestName + '" target="_blank" rel="noopener noreferrer">' + key + '</a>';
        // add delete button
        var tdBtn = document.createElement('td');
        if(num%2) tdBtn.setAttribute('class', 'dark');
        tdBtn.appendChild(createCodeforcesLikeDeleteButton(key));
        tr.appendChild(tdIdx);
        tr.appendChild(tdLink);
        tr.appendChild(tdBtn);
        tbody.appendChild(tr);
        num++;
    }
    document.getElementById('pageContent').appendChild(roundBox);

    document.querySelectorAll('.delete-virtual-contest').forEach ( (btn) => btn.addEventListener (
        'click', {obj: btn, handleEvent: deleteAction}, false
    ));
}

function deleteAction (event) {
    var tr = this.obj.parentNode.parentNode;
    var problemTitle = tr.querySelectorAll('a')[0].text;
    deleteProblem(problemTitle);
    tr.parentNode.deleteRow(tr.sectionRowIndex);
}

(function() {
    var url = window.location.href;

    if( url.match(new RegExp('/codeforces.com\/contest\/(.*)\/problem\/(.*)')) != null ) {
        setAddProblemButton();
    } else if ( url.match(new RegExp('/codeforces.com\/profile\/(.*)')) != null) {
        setProblemList();
    }
})();