AO3: Estimated Reading Time v2

Add an estimated reading time to a fic description in hours and minutes.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        AO3: Estimated Reading Time v2
// @description Add an estimated reading time to a fic description in hours and minutes.
// @author      lomky
// @version	1.0
// @grant       none
// @require     https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js
// @include     http://archiveofourown.org/*
// @include     https://archiveofourown.org/*
// @namespace https://greasyfork.org/users/718789
// ==/UserScript==

// This script adapted from oulfis' original Estimated Reading Time https://greasyfork.org/en/scripts/391940-ao3-estimated-reading-time
// Fixes initial WPM bug and removes vestigle code from their adaption of 
// Min's kudos/hits ratio script, https://greasyfork.org/scripts/3144-ao3-kudos-hits-ratio

// ~~ SETTINGS ~~ //

// how many words per minute do you want to say your reading speed is?
var wpm = 375;

// count readtime automatically: true/false
var always_count = true;

// colour background depending on readtime: true/false
var colourbg = true;

// lvl1 & lvl2 - time levels separating red, yellow and green background (in minutes)
var lvl1 = 60;  // fics that take more than this many minutes to read will be yellow or read
var lvl2 = 160; // fics that take more than this many minutes to read will be red

// highlight_red, highlight_yellow, highlight_green - background colours
var highlight_red = '#ffdede';
var highlight_yellow = '#fdf2a3';
var highlight_green = '#c4eac3';

// ~~ END OF SETTINGS ~~ //



// STUFF HAPPENS BELOW //

(function($) {

	// check user settings
	if (typeof(Storage) !== 'undefined') {

		var always_count_set = localStorage.getItem('alwayscountlocal');
		
		if (always_count_set == 'no') {
			always_count = false;
		}

	}

	// set defaults for countableness and sortableness
	var countable = false;
	var sortable = false;
	var stats_page = false;

	// check if it's a list of works or bookmarks, or header on work page, and attach the menu
	checkCountable();

	// if set to automatic
	if (always_count) {
		calculateReadtime();
	}




	// check if it's a list of works/bookmarks/statistics, or header on work page
	function checkCountable() {

		var found_stats = $('dl.stats');

		if (found_stats.length) {

			if (found_stats.closest('li').is('.work') || found_stats.closest('li').is('.bookmark')) {
				countable = true;
				sortable = true;

				addReadtimeMenu();
			}
			else if (found_stats.parents('.statistics').length) {
				countable = true;
				sortable = true;
				stats_page = true;

				addReadtimeMenu();
			}
			else if (found_stats.parents('dl.work').length) {
				countable = true;

				addReadtimeMenu();
			}
		}
	}


	function calculateReadtime() {

		if (countable) {

			$('dl.stats').each(function() {

                var words_value = $(this).find('dd.words'); // for some reason this can't read past the comma, and gets just the thousands

				// if hits and kudos were found
				if (words_value.length !== '0') {

					// get counts
                    var words_count = parseInt(words_value.text().replace(/,/g, ''));

          // count minutes
          var minutes = words_count/(wpm);

          var hrs = Math.floor(minutes/60);
          var mins = (minutes%60).toFixed(0);
          
					// get minutes with zero decimal points
          var minutes_print = hrs > 0 ? hrs + "h" + mins + "m" : mins + "m"

                    // add readtime stats
					var readtime_label = $('<dt class="kudoshits"></dt>').text('Readtime:');
					var readtime_value = $('<dd class="kudoshits"></dd>').text(minutes_print);
					words_value.after('\n', readtime_label, '\n', readtime_value);

					if (colourbg) {
						// colour background depending on percentage
						if (minutes <= lvl1) {
							readtime_value.css('background-color', highlight_green);
						}
						else if (minutes <= lvl2) {
							readtime_value.css('background-color', highlight_yellow);
						}
						else {
							readtime_value.css('background-color', highlight_red);
						}
					}

				}
			});
		}
	}


	// attach the menu
	function addReadtimeMenu() {

		// get the header menu
		var header_menu = $('ul.primary.navigation.actions');

		// create and insert menu button
		var readtime_menu = $('<li class="dropdown"></li>').html('<a>Readtime</a>');
		header_menu.find('li.search').before(readtime_menu);

		// create and append dropdown menu
		var drop_menu = $('<ul class="menu dropdown-menu"></li>');
		readtime_menu.append(drop_menu);

		// create button - count
		var button_count = $('<li></li>').html('<a>Calculate readtime now on this page</a>');
		button_count.click(function() {calculateReadtime();});

		// create button - always count
		var button_count_yes = $('<li class="count-yes"></li>').html('<a>Always calculate (click to change): YES</a>');
		drop_menu.on('click', 'li.count-yes', function() {
			localStorage.setItem('alwayscountlocal', 'no');
			button_count_yes.replaceWith(button_count_no);
		});

		// create button - not always count
		var button_count_no = $('<li class="count-no"></li>').html('<a>Always calculate (click to change): NO</a>');
		drop_menu.on('click', 'li.count-no', function() {
			localStorage.setItem('alwayscountlocal', 'yes');
			button_count_no.replaceWith(button_count_yes);
		});


		// append buttons to the dropdown menu
		drop_menu.append(button_count);

		if (typeof(Storage) !== 'undefined') {

			if (always_count) {
				drop_menu.append(button_count_yes);
			}
			else {
				drop_menu.append(button_count_no);
			}

		}
	}

})(jQuery);