From: Marius Gavrilescu <marius@ieval.ro> Date: Fri, 12 Dec 2014 14:55:20 +0000 (+0200) Subject: Add user tracking X-Git-Url: http://git.ieval.ro/?a=commitdiff_plain;h=d31924ef2cb534377b73a3e0f9a6612678474afc;p=plack-app-gruntmaster.git Add user tracking --- diff --git a/css/custom.css b/css/custom.css index 429955b..4239ab8 100644 --- a/css/custom.css +++ b/css/custom.css @@ -78,4 +78,12 @@ ul.inline li:after { ul.inline li:last-child:after { content: ""; +} + +.tracker-mark.tick { + color: green; +} + +.tracker-mark.x{ + color: red; } \ No newline at end of file diff --git a/js/80-sidebar.js b/js/80-sidebar.js new file mode 100644 index 0000000..cf729ec --- /dev/null +++ b/js/80-sidebar.js @@ -0,0 +1,10 @@ +(function(){ + 'use strict'; + + $( document ).ready(function() { + if(!$('#sidebar').size()) { + var content = $('#content'); + content.wrapInner('<div class="col-md-9">').append('<div id="sidebar" class="col-md-3">').addClass('row'); + } + }); +})(); diff --git a/js/90-tracker.js b/js/90-tracker.js new file mode 100644 index 0000000..5c71e12 --- /dev/null +++ b/js/90-tracker.js @@ -0,0 +1,94 @@ +(function(){ + 'use strict'; + + function tick() { return $('<span class="tick tracker-mark">â</span>') } + function xmark() { return $('<span class="x tracker-mark">â</span>') } + + function update_tracker(){ + var data = localStorage.getItem('tracker_data'); + var user = localStorage.getItem('tracker_username'); + if(!data) + return; + data = JSON.parse(data); + var solved = {}; + var attempted = {}; + var solvednr = 0; + var attemptednr = 0; + data.problems.forEach(function(e){ + if(e.solved){ + solved[e.problem] = 1; + solvednr++; + } else { + attempted[e.problem] = 1; + attemptednr++; + } + }); + + var contests = {}; + data.contests.forEach(function(e){ + contests[e.contest] = 1; + }); + + $('#tracker_userlink').html(data.name); + $('#tracker_solved').html(solvednr); + $('#tracker_attempted').html(attemptednr); + $('#tracker_contests').html(data.contests.length); + + $('.tracker-mark').detach(); + if(location.pathname == '/pb/') + $('table').find('.name').find('a').each(function() { + var id = $(this).attr('href').split('?', 2)[0]; + if(solved[id]) + $(this).parent().append(tick()); + else if(attempted[id]) + $(this).parent().append(xmark()); + }); + + if(location.pathname == '/ct/') + $('table').find('.name').find('a').each(function() { + var id = $(this).attr('href').substr(4); + if(contests[id]) + $(this).parent().append(tick()); + }); + + if(location.pathname == '/log/') + $('table').find('tbody').find('tr').each(function() { + if($(this).find('.owner').find('a').attr('href') != "/us/" + user) + return; + $(this).find('.id').append($(this).find('.r0').size() ? tick() : xmark()); + }); + } + + function start_tracking(user){ + localStorage.setItem('tracker_username', user); + $('#tracker_userlink').attr('href', '/us/' + user).html(user); + $('#tracker_tracking').removeClass('hidden'); + $('#tracker_form').addClass('hidden'); + update_tracker(); + var xhr = new XMLHttpRequest(); + xhr.open('GET', '/us/' + user); + xhr.setRequestHeader('Accept', 'application/json'); + xhr.onload = function () { + localStorage.setItem('tracker_data', this.responseText); + update_tracker(); + }; + xhr.send(); + } + + function stop_tracking(){ + $('.tracker-mark').detach(); + localStorage.removeItem('tracker_username'); + localStorage.removeItem('tracker_data'); + $('#tracker_tracking').addClass('hidden'); + $('#tracker_form').removeClass('hidden'); + } + + $( document ).ready(function(){ + $('#tracker').detach().prependTo($('#sidebar')).removeClass('hidden'); + $('#tracker_button').on('click', function() { start_tracking($('#tracker_username').val()) }); + $('#tracker_stop').on('click', stop_tracking); + + if(localStorage.getItem('tracker_username')) + start_tracking(localStorage.getItem('tracker_username')); + }); +})(); diff --git a/tmpl/skel.en b/tmpl/skel.en index 1e20c87..4d1e73e 100644 --- a/tmpl/skel.en +++ b/tmpl/skel.en @@ -37,6 +37,27 @@ <div id="content">Content goes here</div> +<div id="tracker"> +<h1>Track user</h1> +<div id="tracker_form"> +<div class="form-group"> +<label for="tracker_username">Username</label> +<input type="text" id="tracker_username" class="form-control"> +</div> +<button id="tracker_button" class="btn">Start tracking</button> +</div> + +<div id="tracker_tracking" class="hidden"> +Tracking <a href="#" id="tracker_userlink"></a>.<br> +<a href="#" id="tracker_stop">Stop tracking</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> +</div> + <footer> Dilmom: Why don't you call your product the Gruntmaster 6000?<br> Dilbert: What kind of product do you see when you imagine a Gruntmaster 6000?<br>