// ==UserScript==
// @name AO3: Kudosed and seen history
// @description Highlight or hide works you kudosed/marked as seen.
// @namespace
// @author Min
// @version 1.0
// @grant none
// @include http://archiveofourown.org/*
// @include https://archiveofourown.org/*
// ==/UserScript==
// STUFF HAPPENS BELOW //
(function($) {
if (typeof(Storage) !== 'undefined') {
var username = localStorage.getItem('kudoshistory_username');
// if there's no saved username, look for it on the page or ask
if (!username) {
var userlink = $('#greeting').find('[href^="/users/"]');
if (userlink.length) {
var userlink_parts = userlink.attr('href').split('/');
var username = userlink_parts[2];
localStorage.setItem('kudoshistory_username', username);
}
else {
var username = prompt('AO3: Kudosed and seen history\n\nYour AO3 username:');
localStorage.setItem('kudoshistory_username', username);
}
}
// check the 'hide seen works' setting
var hide_seen = false;
var hide_seen_set = localStorage.getItem('kudoshistory_hide');
if (hide_seen_set == 'yes') {
hide_seen = true;
}
// uncomment the next three lines if you need to clear your local lists (then comment them again after refreshing the page once)
// localStorage.removeItem('kudoshistory_kudosed');
// localStorage.removeItem('kudoshistory_checked');
// localStorage.removeItem('kudoshistory_seen');
var list_kudosed = localStorage.getItem('kudoshistory_kudosed');
var list_checked = localStorage.getItem('kudoshistory_checked');
var list_seen = localStorage.getItem('kudoshistory_seen');
if (!list_kudosed) {
var list_kudosed = ',';
}
if (!list_checked) {
var list_checked = ',';
}
if (!list_seen) {
var list_seen = ',';
}
$(document).ajaxStop(function() {
localStorage.setItem('kudoshistory_kudosed', list_kudosed);
localStorage.setItem('kudoshistory_checked', list_checked);
localStorage.setItem('kudoshistory_seen', list_seen);
});
// add css rules for kudosed works
addCss();
// if there's a list of works or bookmarks, add menu
var work_blurbs = $('li.work.blurb');
var bookmark_blurbs = $('li.bookmark.blurb');
if (work_blurbs.length || bookmark_blurbs.length) {
addSeenMenu();
}
// for each work blurb
$('li.work.blurb').each(function() {
// get work id
var work_id = $(this).attr('id').replace('work_', '');
// if work id is on the kudosed list
if (list_kudosed.indexOf(',' + work_id + ',') > -1) {
$(this).addClass('has-kudos');
list_kudosed = ',' + work_id + list_kudosed.replace(',' + work_id + ',', ',');
}
// if work id is on the seen list
else if (list_seen.indexOf(',' + work_id + ',') > -1) {
$(this).addClass('marked-seen');
list_seen = ',' + work_id + list_seen.replace(',' + work_id + ',', ',');
}
// if work id is on the checked list
else if (list_checked.indexOf(',' + work_id + ',') > -1) {
list_checked = ',' + work_id + list_checked.replace(',' + work_id + ',', ',');
}
else {
// add a div to the blurb that will house the kudos
$(this).append('<div id="kudos_' + work_id + '" style="display: none"></div>');
// retrieve a list of kudos from the work
var work_url = 'http://archiveofourown.org/works/' + work_id + '/kudos #kudos';
$('#kudos_' + work_id).load(work_url, function() {
// check if there are kudos from the user
var user_kudos = $('#kudos_' + work_id).find('[href="/users/' + username + '"]');
if (user_kudos.length) {
// highlight blurb and add work id to kudosed list
$('#work_' + work_id).addClass('has-kudos');
list_kudosed = ',' + work_id + list_kudosed;
}
else {
// add work id to checked list
list_checked = ',' + work_id + list_checked;
}
});
}
});
// for each bookmark blurb
$('li.bookmark.blurb').each(function() {
// get bookmark and work ids
var bookmark_id = $(this).attr('id').replace('bookmark_', '');
var work_id = $(this).find('h4 a:first').attr('href').replace('/works/', '');
// if work id is on the kudosed list
if (list_kudosed.indexOf(',' + work_id + ',') > -1) {
$(this).addClass('has-kudos');
list_kudosed = ',' + work_id + list_kudosed.replace(',' + work_id + ',', ',');
}
// if work id is on the seen list
else if (list_seen.indexOf(',' + work_id + ',') > -1) {
$(this).addClass('marked-seen');
list_seen = ',' + work_id + list_seen.replace(',' + work_id + ',', ',');
}
// if work id is on the checked list
else if (list_checked.indexOf(',' + work_id + ',') > -1) {
list_checked = ',' + work_id + list_checked.replace(',' + work_id + ',', ',');
}
else {
// add a div to the blurb that will house the kudos
$(this).append('<div id="kudos_' + work_id + '" style="display: none"></div>');
// retrieve a list of kudos from the work
var work_url = 'http://archiveofourown.org/works/' + work_id + '/kudos #kudos';
$('#kudos_' + work_id).load(work_url, function() {
// check if there are kudos from the user
var user_kudos = $('#kudos_' + work_id).find('[href="/users/' + username + '"]');
if (user_kudos.length) {
// highlight blurb and add work id to kudosed list
$('#bookmark_' + bookmark_id).addClass('has-kudos');
list_kudosed = ',' + work_id + list_kudosed;
}
else {
// add work id to checked list
list_checked = ',' + work_id + list_checked;
}
});
}
});
// if it's a work page
if ($('#workskin').length) {
// get work id
var url_parts = location.pathname.split('/');
var work_id = url_parts[2];
// check if work id is on the seen list
var is_seen = list_seen.indexOf(',' + work_id + ',');
addSeenButtons();
if (is_seen > -1) {
$('dl.work.meta.group').addClass('marked-seen');
}
// if work id is on the kudosed list
if (list_kudosed.indexOf(',' + work_id + ',') > -1) {
$('dl.work.meta.group').addClass('has-kudos');
}
else {
var found_kudos = false;
// check if there are kudos from the user
var user_kudos = $('#kudos').find('[href="/users/' + username + '"]');
if (user_kudos.length) {
// highlight blurb and add work id to kudosed list
list_kudosed = ',' + work_id + list_kudosed;
list_checked = list_checked.replace(',' + work_id + ',', ',');
$('dl.work.meta.group').addClass('has-kudos');
found_kudos = true;
}
else if (list_checked.indexOf(',' + work_id + ',') == -1) {
// add work id to checked list
list_checked = ',' + work_id + list_checked;
}
if (!found_kudos) {
$('#new_kudo').click(function() {
list_kudosed = ',' + work_id + list_kudosed;
list_checked = list_checked.replace(',' + work_id + ',', ',');
$('dl.work.meta.group').addClass('has-kudos');
localStorage.setItem('kudoshistory_kudosed', list_kudosed);
localStorage.setItem('kudoshistory_checked', list_checked);
});
}
}
}
// keep the kudos and checked lists under 200k characters (~25k works)
if (list_kudosed.length > 200000) {
list_kudosed = list_kudosed.slice(0,180000);
localStorage.setItem('kudoshistory_kudosed', list_kudosed);
}
if (list_checked.length > 200000) {
list_checked = list_checked.slice(0,180000);
localStorage.setItem('kudoshistory_checked', list_checked);
}
// keep the seen list under 1mil characters (~125k works)
if (list_seen.length > 1000000) {
list_seen = list_seen.slice(0,900000);
localStorage.setItem('kudoshistory_seen', list_seen);
}
// save all lists
localStorage.setItem('kudoshistory_kudosed', list_kudosed);
localStorage.setItem('kudoshistory_checked', list_checked);
localStorage.setItem('kudoshistory_seen', list_seen);
}
// mark all works on the page as seen
function markPageSeen() {
// for each work blurb
$('li.work.blurb').each(function() {
var work_id = $(this).attr('id').replace('work_', '');
if (list_seen.indexOf(',' + work_id + ',') == -1) {
$(this).addClass('marked-seen');
list_seen = ',' + work_id + list_seen;
}
});
// for each bookmark blurb
$('li.bookmark.blurb').each(function() {
var work_id = $(this).find('h4 a:first').attr('href').replace('/works/', '');
if (list_seen.indexOf(',' + work_id + ',') == -1) {
$(this).addClass('marked-seen');
list_seen = ',' + work_id + list_seen;
}
});
localStorage.setItem('kudoshistory_seen', list_seen);
}
// mark all works on the page as unseen
function markPageUnseen() {
// for each work blurb
$('li.work.blurb').each(function() {
var work_id = $(this).attr('id').replace('work_', '');
if (list_seen.indexOf(',' + work_id + ',') > -1) {
$(this).removeClass('marked-seen');
list_seen = list_seen.replace(',' + work_id + ',', ',');
}
});
// for each bookmark blurb
$('li.bookmark.blurb').each(function() {
var work_id = $(this).find('h4 a:first').attr('href').replace('/works/', '');
if (list_seen.indexOf(',' + work_id + ',') > -1) {
$(this).removeClass('marked-seen');
list_seen = list_seen.replace(',' + work_id + ',', ',');
}
});
localStorage.setItem('kudoshistory_seen', list_seen);
}
// add the seen/unseen buttons
function addSeenButtons() {
var seen_button1 = $('<li class="mark-seen"></li>').html('<a>Seen ✓</a>');
var seen_button2 = seen_button1.clone();
$('ul.actions').on('click', 'li.mark-seen', function() {
list_seen = ',' + work_id + list_seen;
localStorage.setItem('kudoshistory_seen', list_seen);
$('dl.work.meta.group').addClass('marked-seen');
seen_button1.replaceWith(unseen_button1);
seen_button2.replaceWith(unseen_button2);
});
var unseen_button1 = $('<li class="mark-unseen"></li>').html('<a>Unseen ✗</a>');
var unseen_button2 = unseen_button1.clone();
$('ul.actions').on('click', 'li.mark-unseen', function() {
list_seen = list_seen.replace(',' + work_id + ',', ',');
localStorage.setItem('kudoshistory_seen', list_seen);
$('dl.work.meta.group').removeClass('marked-seen');
unseen_button1.replaceWith(seen_button1);
unseen_button2.replaceWith(seen_button2);
});
if (is_seen == -1) {
$('li.bookmark').after(seen_button1);
$('#new_kudo').parent().after(seen_button2);
}
else {
$('li.bookmark').after(unseen_button1);
$('#new_kudo').parent().after(unseen_button2);
}
}
// attach the menu
function addSeenMenu() {
// get the header menu
var header_menu = $('ul.primary.navigation.actions');
// create and insert menu button
var seen_menu = $('<li class="dropdown"></li>').html('<a>Seen works</a>');
header_menu.find('li.search').before(seen_menu);
// create and append dropdown menu
var drop_menu = $('<ul class="menu dropdown-menu"></li>');
seen_menu.append(drop_menu);
// create button - mark page as seen
var button_page_seen = $('<li></li>').html('<a>Mark this page as seen</a>');
button_page_seen.click(function() {markPageSeen();});
// create button - mark page as unseen
var button_page_unseen = $('<li></li>').html('<a>Mark this page as unseen</a>');
button_page_unseen.click(function() {markPageUnseen();});
// create button - hide seen works
var button_hide_yes = $('<li class="hide-yes"></li>').html('<a>Hide seen works: YES</a>');
drop_menu.on('click', 'li.hide-yes', function() {
localStorage.setItem('kudoshistory_hide', 'no');
button_hide_yes.replaceWith(button_hide_no);
});
// create button - don't hide seen works
var button_hide_no = $('<li class="hide-no"></li>').html('<a>Hide seen works: NO</a>');
drop_menu.on('click', 'li.hide-no', function() {
localStorage.setItem('kudoshistory_hide', 'yes');
hide_seen = true;
addCss();
button_hide_no.replaceWith(button_hide_yes);
});
// append buttons to the dropdown menu
drop_menu.append(button_page_seen);
drop_menu.append(button_page_unseen);
if (hide_seen) {
drop_menu.append(button_hide_yes);
}
else {
drop_menu.append(button_hide_no);
}
}
// add css rules to page head
function addCss() {
var style = $('style');
var css_highlight = '.has-kudos, .has-kudos.marked-seen {background: url("http://i.imgur.com/Rmyf262.png") left repeat-y; padding-left: 70px !important;}\
.marked-seen {background: url("http://i.imgur.com/qdA6ylN.png") left repeat-y; padding-left: 70px !important;}';
var css_hide = 'dl.has-kudos, dl.has-kudos.marked-seen {background: url("http://i.imgur.com/Rmyf262.png") left repeat-y; padding-left: 70px !important;}\
dl.marked-seen {background: url("http://i.imgur.com/qdA6ylN.png") left repeat-y; padding-left: 70px !important;}\
li.has-kudos, li.marked-seen {display: none !important;}';
if (!style.length) {
style = $('<style type="text/css"></style>').appendTo($('head'));
}
if (!hide_seen) {
style.append(css_highlight);
}
else {
style.append(css_hide);
}
}
})(jQuery);