// ==UserScript== // @name AO3: Tracking // @description Track any filterable listing. // @namespace https://greasyfork.org/en/scripts/8382-ao3-tracking // @author Min // @version 1.5 // @grant none // @require https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js // @include http://*archiveofourown.org/* // @include https://*archiveofourown.org/* // @downloadURL https://update.greasyfork.icu/scripts/8382/AO3%3A%20Tracking.user.js // @updateURL https://update.greasyfork.icu/scripts/8382/AO3%3A%20Tracking.meta.js // ==/UserScript== (function($) { if (typeof(Storage) !== 'undefined') { var tracked_list = ''; var tracked_array = []; loadList(); addCss(); addTrackedMenu(); var main = $('#main'); // if it's a listing of works or bookmarks if (main.hasClass('works-index') || main.hasClass('bookmarks-index')) { var is_tracked = false; var is_first_page = true; // get page url var location_url = location.href; // check if page is already tracked var array_index = tracked_array.indexOf(location_url); if (array_index > -1) { is_tracked = true; checkOpen(); } // make sure it's the first page of the listing var current_page = main.find('ol.pagination:first span.current'); if (current_page.length && current_page.text() !== '1') { is_first_page = false; } if (is_first_page) { addTrackButton(); } } // add "Mark all as vieved" button when all listing get checked $(document).ajaxStop(function() { if ($('#tracked-box').length && !$('#button-check').length) { $('#button-mark').css('visibility', 'visible'); } }); } // load the saved list function loadList() { tracked_list = localStorage.getItem('ao3tracking_list'); if (!tracked_list) { tracked_list = ''; } // make an array of the list if (tracked_list.length) { tracked_array = tracked_list.split(',,,'); } } // add current page to tracked listings function addToTracked() { var added = false; loadList(); // if there's less than 25 tracked if (tracked_array.length < 75) { // ask for name var heading = main.find('h2.heading:first'); var heading_link = heading.find('a'); if (heading_link.length) { var suggest = heading_link.text(); } else { var suggest = heading.text().replace(/\n/g, '').replace(/^\s+/, '').replace(/(.+of )?\d+ /, ''); } var listing_name = prompt('Name for the tracked listing:', suggest); if (listing_name !== '' && listing_name !== null) { // remove characters we don't want in the names listing_name = listing_name.replace(/,,,/g, ' '); var listing_count = heading.text().replace(/\n/g, '').replace(/^\s+/, '').replace(/.*\d+ - \d+ of /, '').replace(/(\d+)(.+)/, '$1'); // add name, url, count tracked_array.push(listing_name, location_url, listing_count); tracked_list = tracked_array.join(',,,'); // save the updated list localStorage.setItem('ao3tracking_list', tracked_list); added = true; } } else { alert("You're already tracking 25 listings. Remove some first."); } return added; } // remove a given url from tracked listings function removeFromTracked(url) { var removed = false; loadList(); var index = tracked_array.indexOf(url); // if the url is on the saved list if (index > -1) { // ask for confirmation var confirmed = confirm('Sure you want to remove "' + tracked_array[index-1] + '"?'); if (confirmed) { // remove name, url, count tracked_array.splice(index-1, 3); tracked_list = tracked_array.join(',,,'); // save the updated list localStorage.setItem('ao3tracking_list', tracked_list); removed = true; } } return removed; } // check open page for new works function checkOpen() { var heading = main.find('h2.heading:first'); // get a count of new works var current_count = getCountFromHeading(heading.text()); var saved_count = parseInt(tracked_array[array_index+1]); var new_count = current_count - saved_count; if (new_count !== 0) { heading.append(' (' + new_count + ' new) [mark viewed]'); $('#mark-viewed').click(function() { loadList(); var array_index = tracked_array.indexOf(location_url); if (array_index > -1) { // update the count tracked_array[array_index+1] = current_count; tracked_list = tracked_array.join(',,,'); // save the updated list localStorage.setItem('ao3tracking_list', tracked_list); } $('#new-works').detach(); $(this).detach(); }); } } // check the tracked listings for new works function checkForNew() { // check if it's more than 8 hours since last check var last_check = localStorage.getItem('ao3tracking_lastcheck'); if (!last_check) { var last_check = 0; } else { last_check = parseInt(last_check); } var now = new Date(); now = now.getTime(); var wait = 28800000 - (now - last_check); if (wait < 0) { localStorage.setItem('ao3tracking_lastcheck', now); // for each tracked listing $('#tracked-box li.tracked-listing').each(function() { var tracked_url = $(this).find('a').attr('href'); var listing_id = $(this).attr('id'); tracked_url += ' #main h2.heading:first'; // load heading of the tracked page $(this).find('span.tracked-current').load(tracked_url, function() { var listing = $('#' + listing_id); // get a count of new works var current_count = getCountFromHeading(listing.find('span.tracked-current').text()); listing.find('span.tracked-current').html(current_count); var saved_count = parseInt(listing.find('span.tracked-saved').text()); var new_count = current_count - saved_count; listing.find('span.tracked-new').text('(' + new_count + ' new)'); if (new_count !== 0) { listing.find('span.tracked-new').addClass('new-stuff'); listing.parent().prepend(listing); } else { listing.find('span.tracked-new').addClass('no-new-stuff'); } }); }); } else { var hours = Math.floor(wait/3600000); var minutes = Math.ceil((wait%3600000)/60000); var warning = $('
'); if (hours > 0) { warning.html('Please be kind to the AO3 servers! Wait ' + hours + ' hour(s) and ' + minutes + ' minute(s) more before another check.'); } else { warning.html('Please be kind to the AO3 servers! Wait ' + minutes + ' more minute(s) before another check.'); } $('#tracked-box p.actions').after(warning); } } // add the 'Track This' button function addTrackButton() { var work_filters = $('form.filters, form.old-filters').find('dd.submit.actions:first'); var track_this_button = $(''); track_this_button.click(function() { var added = addToTracked(); if (added) { track_this_button.detach(); work_filters.prepend(untrack_this_button); } }); var untrack_this_button = $(''); untrack_this_button.click(function() { var removed = removeFromTracked(location_url); if (removed) { untrack_this_button.detach(); work_filters.prepend(track_this_button); } }); // if the page is already tracked if (is_tracked) { work_filters.prepend(untrack_this_button); } // if it's not tracked else { work_filters.prepend(track_this_button); } } // rearrange things on the list function editList() { var box_list = $('#box-list'); box_list.find('li.tracked-listing').each(function() { $(this).prepend('↑ ↓ ✗ '); }); box_list.on('click', 'span.up-arrow', function() { $(this).parent().prev().before($(this).parent()); }); box_list.on('click', 'span.down-arrow', function() { $(this).parent().next().after($(this).parent()); }); box_list.on('click', 'span.cross', function() { $(this).parent().detach(); }); } // save list after edits function saveList() { tracked_array = []; // get name, url, count for all listings $('#tracked-box li.tracked-listing').each(function() { var name = $(this).find('a').text(); var url = $(this).find('a').attr('href'); var count = $(this).find('span.tracked-saved').text(); tracked_array.push(name, url, count); }); // update and save the new list tracked_list = tracked_array.join(',,,'); localStorage.setItem('ao3tracking_list', tracked_list); // reload the box $('#tracked-box').detach(); $('#tracked-bg').detach(); showBox(); } // update the listings counts function markAllViewed() { loadList(); // get the current count for all listings $('#tracked-box li.tracked-listing').each(function() { var url = $(this).find('a').attr('href'); var current_count = $(this).find('span.tracked-current').text(); var index = tracked_array.indexOf(url); if (index > -1) { tracked_array[index+1] = current_count; } }); // update and save the new list tracked_list = tracked_array.join(',,,'); localStorage.setItem('ao3tracking_list', tracked_list); // reload the box $('#tracked-box').detach(); $('#tracked-bg').detach(); showBox(); } // show the box with tracked listings function showBox() { var tracked_bg = $(''); var tracked_box = $(''); var box_buttons = $(''); var box_button_check = $(''); box_button_check.click(function() { box_button_edit.after(box_button_mark); checkForNew(); box_button_edit.detach(); box_button_check.detach(); }); var box_button_edit = $(''); box_button_edit.click(function() { editList(); box_button_edit.after(box_button_save, box_button_cancel); box_button_check.detach(); box_button_edit.detach(); }); var box_button_save = $(''); box_button_save.click(function() { saveList(); }); var box_button_cancel = $(''); box_button_cancel.click(function() { tracked_box.detach(); tracked_bg.detach(); showBox(); }); var box_button_mark = $(''); box_button_mark.click(function() { markAllViewed(); }); var box_button_close = $(''); box_button_close.click(function() { tracked_box.detach(); tracked_bg.detach(); }); var box_header = $('').text('Tracked listings [' + tracked_array.length/3 + '/25]:'); var box_list = $('