// ==UserScript== // @name Custom Anime Scheduler // @namespace http://tampermonkey.net/ // @version 0.1 // @description Lets users track past seasons as they go by, with some QOL improvements for adding older anime. // @author You // @icon https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net // @grant GM_setValue // @grant GM_getValue // @match *.livechart.me/* // @require https://code.jquery.com/jquery-3.6.4.min.js // @run-at document-end // @license MIT // @downloadURL none // ==/UserScript== const $ = window.jQuery; //Converts a Date object to the format YYYY-MM-DD function convertToDateLinkText(date) { let realMonth = date.getMonth() + 1; // getMonth() returns months starting at 0 for January, so fixing it. let dateString = date.getDate(); if (dateString < 10) { //Adding a 0 so that it matches up with the url text for checking whether the week is the current one. dateString = '0' + dateString; } if (realMonth < 10) { realMonth = '0' + realMonth; } const dateLinkFormat_ = date.getFullYear() + '-' + realMonth + '-' + dateString; return dateLinkFormat_; } //Converts texts in format YYYY-MM-DD to a Date object function convertToDateObject(dateString) { const modifiedDateString = dateString + " 00:00:00"; //Without this, it will be set to the day before const dateObject = new Date(modifiedDateString); return dateObject; } //Returns the number of days since the last starting day, either Monday or Sunday function daysSinceStartingDay(date) { let daysSince; const startingDay_ = GM_getValue("starting_day"); if (startingDay_ == "monday") { //getDay() returns 0-6 depending days away from Sunday. daysSince = (date.getDay() + 6) % 7; } else { daysSince = date.getDay(); } return daysSince; } //Adjusts how much the schedule changed based on the time-flow options chosen. (potential update: adding the schedule's current date to make choices outside of 1 & 7 easier to track) function speedChange(diff) { const daysString = GM_getValue("days_speed"); const speed = Number(daysString); const newDiff = diff * Math.ceil(7 / speed); // speed=7 means that time passes normally, while speed=1 means that it passes 7 times faster return newDiff; } //Shifts the Date forward by the number of days specified in diff function shiftDate(date, diff) { const daysShifted = date.getDate() + diff; //Needs getDate() because it starting at the beginning of the month. date.setDate(daysShifted); } function getDayTextFromNum(num) { let weekDay; switch(num) { case 0: weekDay = "Sun"; break; case 1: weekDay = "Mon"; break; case 2: weekDay = "Tue"; break; case 3: weekDay = "Wed"; break; case 4: weekDay = "Thu"; break; case 5: weekDay = "Fri"; break; case 6: weekDay = "Sat"; break; } return weekDay; } //Returns the 3-letter text form of week days function getDayText(date) { let weekDay; const dayNum = date.getDay(); weekDay = getDayTextFromNum(dayNum); return weekDay; } //Converts a Date object to the text displayed by the last-week button function convertToDateButtonText(date) { let retString; let dateString = date.getDate(); const weekDay = getDayText(date); const realMonth = date.getMonth() + 1; if (dateString < 10) { //Adding a 0 so that it is two digits like in the original program. dateString = '0' + dateString; } retString = weekDay + ' ' + realMonth + '/' + dateString; return retString; } function GetURLParameter(sParam) { //From: https://stackoverflow.com/questions/12456639/how-to-get-data-from-url-with-jquery const sPageURL = window.location.search.substring(1); const sURLVariables = sPageURL.split('&'); for (let i = 0; i < sURLVariables.length; i++) { let sParameterName = sURLVariables[i].split('='); if (sParameterName[0] == sParam) { return decodeURIComponent(sParameterName[1]); } } } //The code is highlight which day is the currrent custom day, or to highlight future days black function highlightTTDay(dayText, dayStatus) { let timeTableBox = $('.timetable'); const tTDayQuery = 'h2:contains("' + dayText + '")'; let TTDayH2 = timeTableBox.find(tTDayQuery); let TTDay = TTDayH2.parent().parent(); TTDay.removeClass("past"); TTDay.addClass(dayStatus); } $(window).bind("load", function () { const $today = new Date(); const todayHoursToMidnight = convertToDateObject(convertToDateLinkText($today)); //Making sure there no weird behavior by setting the time to 00:00 or midnight like it is with the time of setting let scheduleDate = convertToDateObject(GM_getValue("start_date")); const settingDate = convertToDateObject(GM_getValue("setting_date")); const daysDiff = (todayHoursToMidnight - settingDate) / (1000 * 60 * 60 * 24); //Since the difference given is in ms, converting it to days const daysDiffWithSpeed = speedChange(daysDiff); shiftDate(scheduleDate, daysDiffWithSpeed); const currentCustomDateText = convertToDateLinkText(scheduleDate); //Setting the timetable to start on the chosen starting day const weekStartDiff = -daysSinceStartingDay(scheduleDate); shiftDate(scheduleDate, weekStartDiff); const dateLinkFormat = convertToDateLinkText(scheduleDate); const scheduleDateLink = 'https://www.livechart.me/timetable?date=' + dateLinkFormat; const SettingsTab = '
  • Settings
  • '; const CustomScheduleTab = '
  • Custom Schedule
  • '; $(SettingsTab).insertBefore('.site-header--navigation>.flex-spacer'); //Flex Spacer is the space between the top bar and the magnifying glass. let headlinesButton = $('a[href="/headlines"]').parent(); $(headlinesButton).attr('id', 'headlines-button'); $(CustomScheduleTab).insertBefore('.site-header--navigation>#headlines-button'); //Adding a "last week" button const urlDateText = GetURLParameter('date'); let urlDateObject = convertToDateObject(urlDateText); shiftDate(urlDateObject, -7); const urlDateLastWeekText = convertToDateLinkText(urlDateObject); const urlDateButtonText = convertToDateButtonText(urlDateObject); const lastWeekButton = '
    ' + urlDateButtonText + '
    '; let weekChangeRow = $('div.column.small-6.float-right.text-right').parent() if (weekChangeRow.find("a").length == 1) { //If is only the "next week" button. weekChangeRow.prepend(lastWeekButton); } //Highlighting the current day // Attribute data-timetable-day-start starts at -32400 on Jan 1, 1970, so dtds + 32400 = Jan 1 1970 date let currentCustomDate = convertToDateObject(currentCustomDateText); const scheduleDayText = getDayText(currentCustomDate); console.log("urlDateText is "+urlDateText+" and dateLinkFormat is "+dateLinkFormat); if (urlDateText == dateLinkFormat) { //If the url matches the current custom week highlightTTDay(scheduleDayText, "today"); const scheduleDayNum = currentCustomDate.getDay(); for (let i = scheduleDayNum; i < 7; i++) { let futureDayText = getDayTextFromNum(i); highlightTTDay(futureDayText, "future"); } const startingDay = GM_getValue("starting_day"); if (startingDay == "monday") { highlightTTDay("Sun", "future"); } } // Make it more readable, try making it list them vertically instead. 21 rows per column //Making it easier to search for years before 3 years ago let BrowseList = $('.small-up-4'); $('.small-up-4 > div:last-child').remove(); //Tried a number of other ways, but transposing matrices is the only thing that worked const rowsNum = 20; const colsNum = 4; let yearGrid = new Array (colsNum); for (let i = 0; i < colsNum; i++) { yearGrid[i] = new Array(rowsNum); } let i = 0; let k = 0; $('.small-up-4 div').each(function() { if (i < rowsNum) { yearGrid[k][i] = $(this); i++; } else { k++; if (k < colsNum) { i = 0; yearGrid[k][i] = $(this); } //Break wasn't working with .each() } }); const thisYear = $today.getFullYear(); //Using the i and k values from the previous loop for (let year = (thisYear - 3); year >= 1960; year--) { if (i < rowsNum) { yearGrid[k][i] = ('
    ' + year + '
    '); i++; } else { k++; if (k < colsNum) { i = 0; year++; } } } $(BrowseList).empty(); let r = 0; let c = 0; for (let r = 0; r < rowsNum; r++) { for (let c = 0; c < colsNum; c++) { $(BrowseList).append(yearGrid[c][r]); } } $(BrowseList).removeClass('grid-padding-x'); //Changing the name so users will know that it does something new (too slow)//const BrowseTab = 'label[for="browse_dropdown_trigger"]';//$(BrowseTab).text('Browse by Year ');//$(BrowseTab).append(''); //Adding the Customize Schedule settings bar let PreferencesList = '.large-push-2 > div[class="ul-tabs-overflow"] > ul[class="ul-tabs"]'; //note: selecting multiple classes doesn't work with > operator const ScheduleSettingsPrefTab = '
  • Edit Schedule
  • '; $(PreferencesList).append(ScheduleSettingsPrefTab); let prefBody = $('form[action*="/preferences/"]'); //Button Events $(".schedule-pref-tab").click(function() { const SchedulePrefFormStart = '
    '; const StartDate = ''; const StartingDay = ''; const DaysSpeed = ''; const SchedulePrefFormEnd = '
    '; //Setting the "Edit Schedule" button to the only active one. $('.ul-tabs li').each(function() { $(this).removeClass('active'); }); $(".schedule-pref-tab").addClass('active'); prefBody.empty(); prefBody.append(SchedulePrefFormStart + StartDate + StartingDay + StartingDayOptions + DaysSpeed + DaysSpeedOptions + SchedulePrefFormEnd); let startDateValue = $('label[for="starting_day"]').val(); //Setting the default to the last chosen values const prevStartingDayOption = 'option[value="' + GM_getValue("starting_day") + '"]'; $(prevStartingDayOption).attr("selected", "selected"); const prevSpeedOption = 'option[value="' + GM_getValue("days_speed") + '"]'; $(prevSpeedOption).attr("selected", "selected"); $('button[name="schedule-button"]').on('click', function(event) { event.preventDefault(); console.log("within $('input[name='schedule-button']').click(function() {"); let startDateValue = $('#start-date').val(); console.log("startDateValue is "+startDateValue); let startingDayValue = $('#starting-day').val(); let daysSpeedValue = $('#days-speed').val(); GM_setValue("start_date", startDateValue); GM_setValue("starting_day", startingDayValue); GM_setValue("days_speed", daysSpeedValue); let $thisDate = new Date(); let thisDateText = convertToDateLinkText($thisDate); GM_setValue("setting_date", thisDateText); location.reload(); //So that Custom Schedule updates right away so that clicking on it doesn't lead to the old settings }); }); });