Skip to content

Instantly share code, notes, and snippets.

@badp
Created October 17, 2010 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save badp/631092 to your computer and use it in GitHub Desktop.
Save badp/631092 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name SO Live!
// @namespace tag://badp/
// @description Bring Live reputation requirement updates to the StackExchange™ EgoEmpowering HumanWorth™ counter.
// @include http://stackoverflow.com/*
// @include http://meta.stackoverflow.com/*
// @include http://superuser.com/*
// @include http://meta.superuser.com/*
// @include http://serverfault.com/*
// @include http://meta.serverfault.com/*
// @include http://askubuntu.com/*
// @include http://meta.askubuntu.com/*
// @include http://answers.onstartups.com/*
// @include http://meta.answers.onstartups.com/*
// @include http://nothingtoinstall.com/*
// @include http://meta.nothingtoinstall.com/*
// @include http://seasonedadvice.com/*
// @include http://meta.seasonedadvice.com/*
// @include http://stackapps.com/*
// @include http://*.stackexchange.com/*
// @exclude http://chat.stackexchange.com/*
// @exclude http://chat.*.stackexchange.com/*
// @exclude http://api.*.stackexchange.com/*
// @exclude http://odata.stackexchange.com/*
// @exclude http://area51.stackexchange.com/*
// @exclude http://*/reputation
// ==/UserScript==
//balpha <3
function with_plugin(url, callback) {
var script = document.createElement("script");
script.setAttribute("src", url);
script.addEventListener("load", function () {
var script = document.createElement("script");
script.type = "text/javascript";
script.textContent = "(" + callback.toString() + ")(jQuery)";
document.body.appendChild(script);
}, false);
document.body.appendChild(script);
}
with_plugin("http://soapi.info/code/js/stable/scripts/Soapi.js", SO_Live)
function SO_Live($){
var api = Soapi.RouteFactory("api." + site);
var last_update = now();
function update_reputation_since(date){
if(date === undefined)
throw new Error("Please specify a date object.")
last_update = now();
api.UsersByIdReputation( { id: user_id,
fromdate: date
} ).getResponse( function(data) {
$.each(data.items, _parse_api_result);
window.console.debug("Updates received: " + data.items);
_schedule_next_update();
} );
}
function _schedule_next_update(){
window.console.debug("Scheduling next update in 30 seconds, checking activity since " + last_update)
setTimeout( function(){update_reputation_since(last_update) },
30000)
}
_schedule_next_update();
}
//for the I can't believe I had to write this™ series
function now(){
return new Date();
}
function to_num(val){
var number = parseInt(val, 10);
if( isNaN(number) )
throw new Error(val + " is not a number");
return number;
}
//http://www.mredkj.com/javascript/numberFormat.html
function add_commas(nStr)
{
if(nStr > 999999) //this function breaks above one million.
throw new Error("Sorry, you are too awesome for this mere function.");
nStr += '';
var x = nStr.split('.');
var x1 = x[0];
var x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
//actual stuff
var site = window.location.hostname;
if(site !== "meta.stackoverflow.com") // metas do not count
site = site.replace("meta.", ""); //get rep updates from parent instead.
var user_id = $("#hlinks-user a").first().attr("href").match(/[0-9]+/)[0];
// get the URL address of the link to the user page; the sequence of digits is the user number, right? Right?
var rep_number_obj = $("#hlinks-user .reputation-score").first();
var debug_change = {
positive_rep: 5000,
negative_rep: 2000,
title: "How do I move the paddle in Pong?",
post_id: 42
};
function get_current_reputation(){
return to_num(rep_number_obj.text().replace(",", ""));
}
function _change_rep_number_by(difference){
var prev_rep = get_current_reputation();
var new_rep = prev_rep + difference;
rep_number_obj.text(add_commas(new_rep));
return new_rep;
}
function lightweight_notify(show_this_message, duration){
/*
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0
|---'---'---|---'---'---|---'---'---'---'---'---'---'---|---'---'---|---'---'---|
| fade out | fade in | display message | fade out | fade in |
| #hlinks | message | | message | #hlinks |
|<---300--->|<---300--->|<-------------800------------->|<---300--->|<---300--->|
|<---300--->|<------------------------1,400------------------------>|<---300--->|
*/
if(duration === undefined){
duration = 800
}
var fade_time = 300
if( $(".lightweight_notify").length ) { //delay -- TODO: handle this better
throw new Error("lightweight notifies overlap")
}
$("#hlinks")
.fadeOut(fade_time)
.delay(fade_time + duration + fade_time) //give the time for the message to appaear
.fadeIn(fade_time);
$("<span />")
.css({'float': 'left',
'text-align': 'right',
'margin-right': 20,
'width': '500px', //960-340=620-20=600 on SO, let's take less space for SE sites
'overflow': 'hidden',
'text-overflow': 'ellipsis',
'-o-text-overflow': 'ellipsis',
'white-space': 'nowrap',
'font-weight': 'bold'
})
.addClass('hot transient-notification')
.insertBefore("#hsearch")
.hide()
.delay(fade_time) //give the time for #links to fade out
.fadeIn(fade_time)
.delay(duration)
.fadeOut(fade_time)
[0] //get DOM object
.innerHTML = show_this_message;
setTimeout("$(\".transient-notification\").remove()", fade_time*3 + duration);
}
//http://stackoverflow.com/q/3953746/13992
function _schedule_rep_number_change(diff, step, number){
setTimeout( function(){ _change_rep_number_by(diff) },
4200 + step*25 + number*5000);
}
function _schedule_lightweight_notify(message, number){
setTimeout( function(){ lightweight_notify(message, 3000)},
number*5000
)
}
function linkify(change){
return $("<a/>").text(change.title)
.attr("href", "http://" + site + "/questions/" + change.post_id + "/-1") //give Community some love
[0] //get dom object
.outerHTML //cringe
}
function _parse_api_result(number, change){
//lit up the envelope
$(".envelope-off").toggleClass(".envelope-on")
.toggleClass(".envelope-off")
.attr("title", "You have new replies");
var rep_net_change = change.positive_rep - change.negative_rep;
var step = 1;
var message = rep_net_change > 0 ? "Gained " : "Spent "
message += Math.abs(rep_net_change)
message += " reputation for "
message += linkify(change)
_schedule_lightweight_notify(message, number)
while(rep_net_change){
if(rep_net_change > 0)
var diff = Math.ceil(rep_net_change / 10);
else
var diff = Math.floor(rep_net_change / 10);
_schedule_rep_number_change(diff, step, number);
rep_net_change -= diff;
step++;
}
}
@badp
Copy link
Author

badp commented Oct 17, 2010

How to try revision 6ab9d

  1. Paste it in, get error SoApi is not defined
  2. Paste it in again
  3. update_reputation_since(new Date("2010-09-01 00:00:00Z"))

Following updates are actually functional.

@badp
Copy link
Author

badp commented Oct 17, 2010

How to try revision 7c5cb

  1. Paste it in the javascript console.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment