| 1 | const TICK = '<span class="tick tracker-mark">✔</span>'; |
| 2 | const XMARK = '<span class="x tracker-mark">✘</span>'; |
| 3 | |
| 4 | function clean_tracker(){ |
| 5 | $('.tracker-mark').each(e => e.parentNode.removeChild(e)); |
| 6 | $('.tracker-info').each(e => { |
| 7 | e.classList.remove('tracker-info'); |
| 8 | e.classList.remove('info'); |
| 9 | }); |
| 10 | } |
| 11 | |
| 12 | let tracker; |
| 13 | |
| 14 | function update_tracker(){ |
| 15 | if(!localStorage.getItem('tracker_data')) |
| 16 | return; |
| 17 | const data = JSON.parse(localStorage.getItem('tracker_data')); |
| 18 | const user = localStorage.getItem('tracker_username'); |
| 19 | const contests = {}, solved = {}, attempted = {}; |
| 20 | let solvednr = 0, attemptednr = 0; |
| 21 | data.problems.forEach(e => { |
| 22 | if(e.solved) { |
| 23 | solved[e.problem] = 1; |
| 24 | solvednr++; |
| 25 | } else { |
| 26 | attempted[e.problem] = 1; |
| 27 | attemptednr++; |
| 28 | } |
| 29 | }); |
| 30 | |
| 31 | data.contests.forEach(e => contests[e.contest] = 1); |
| 32 | |
| 33 | clean_tracker(); |
| 34 | $('#tracker_userlink')[0].innerHTML = data.name; |
| 35 | $('#tracker_solved')[0].innerHTML = solvednr; |
| 36 | $('#tracker_attempted')[0].innerHTML = attemptednr; |
| 37 | $('#tracker_contests')[0].innerHTML = data.contests.length; |
| 38 | $('#tracker_log')[0].setAttribute('href', '/log/?owner=' + user); |
| 39 | |
| 40 | if(location.pathname == '/pb/') |
| 41 | $('table .name a').each(el => { |
| 42 | const id = el.getAttribute('href').split('?', 2)[0]; |
| 43 | if(solved[id]) |
| 44 | el.insertAdjacentHTML('beforebegin', TICK); |
| 45 | else if(attempted[id]) |
| 46 | el.insertAdjacentHTML('beforebegin', XMARK); |
| 47 | }); |
| 48 | |
| 49 | if(location.pathname == '/ct/') |
| 50 | $('table .name a').each(el => { |
| 51 | const id = el.getAttribute('href').substr(4); |
| 52 | if(contests[id]) |
| 53 | el.insertAdjacentHTML('beforebegin', TICK); |
| 54 | }); |
| 55 | |
| 56 | if(location.pathname == '/log/') |
| 57 | $('table tbody tr').each(el => { |
| 58 | const owner = el.querySelector('.owner a'); |
| 59 | if(!owner || owner.getAttribute('href') != '/us/' + user) |
| 60 | return; |
| 61 | const state = el.getElementsByClassName('r0').length ? TICK : XMARK; |
| 62 | el.getElementsByClassName('id')[0].innerHTML += state; |
| 63 | }); |
| 64 | |
| 65 | if(location.pathname.match(/^\/st\//) || location.pathname == '/us/') |
| 66 | $('table tbody tr').each(el => { |
| 67 | if(el.querySelector('.user a').getAttribute('href') == '/us/' + user){ |
| 68 | el.classList.add('info'); |
| 69 | el.classList.add('tracker-info'); |
| 70 | } |
| 71 | }); |
| 72 | } |
| 73 | |
| 74 | function start_tracking(user){ |
| 75 | localStorage.setItem('tracker_username', user); |
| 76 | $('#tracker_userlink')[0].setAttribute('href', '/us/' + user); |
| 77 | $('#tracker_userlink')[0].innerHTML = user; |
| 78 | tracker.classList.remove('hidden'); |
| 79 | update_tracker(); |
| 80 | const lastfetch = localStorage.getItem('tracker_lastfetch'); |
| 81 | if(Date.now() - lastfetch > 60 * 10 * 1000) |
| 82 | refresh_tracker(); |
| 83 | } |
| 84 | |
| 85 | function refresh_tracker(){ |
| 86 | const user = localStorage.getItem('tracker_username'); |
| 87 | const xhr = new XMLHttpRequest(); |
| 88 | xhr.open('GET', '/us/' + user + '?format=json'); |
| 89 | xhr.onload = () => { |
| 90 | localStorage.setItem('tracker_data', xhr.responseText); |
| 91 | localStorage.setItem('tracker_lastfetch', Date.now()); |
| 92 | update_tracker(); |
| 93 | }; |
| 94 | xhr.send(); |
| 95 | } |
| 96 | |
| 97 | function stop_tracking(){ |
| 98 | clean_tracker(); |
| 99 | localStorage.removeItem('tracker_username'); |
| 100 | localStorage.removeItem('tracker_data'); |
| 101 | localStorage.removeItem('tracker_lastfetch'); |
| 102 | tracker.classList.add('hidden'); |
| 103 | } |
| 104 | |
| 105 | $(function(){ |
| 106 | tracker = m('<div id="tracker" class="hidden">Tracking <a id="tracker_userlink"></a>.<br><a id="tracker_stop" role="button">Stop tracking</a><br><a id="tracker_log">Job log</a><dl class="dl-horizontal"><dt>Solved</dt> <dd id="tracker_solved">?</dd><dt>Attempted</dt> <dd id="tracker_attempted">?</dd><dt>Contests</dt> <dd id="tracker_contests">?</dd></dl></div>'); |
| 107 | const sidebar = $('#sidebar')[0]; |
| 108 | sidebar.insertBefore(tracker, sidebar.firstChild); |
| 109 | $('#tracker_stop').on('click', stop_tracking); |
| 110 | $('#track_user').on('click', function() { stop_tracking(); start_tracking(this.dataset.user) }); |
| 111 | $('#submitform').on('submit', () => localStorage.removeItem('tracker_lastfetch')); |
| 112 | |
| 113 | if(localStorage.getItem('tracker_username')) |
| 114 | start_tracking(localStorage.getItem('tracker_username')); |
| 115 | }); |