// ==UserScript== // @name Netflix Mark Watched // @author SirGrypin // @version 1.6 // @namespace watched_netflix // @description Mark Netflix shows as watched. // @include https://www.netflix.com/* // @require https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js // @grant GM_registerMenuCommand // @license MIT // @downloadURL none // ==/UserScript== function addWatchedButton(element) { var id = JSON.parse(decodeURI(element.data('ui-tracking-context'))).video_id; var watched = localStorage.getItem("watched_" + id); if (watched === 'true') { element.closest('.title-card-container').addClass('g_watched'); } var watchedEye = $('
👁
'); watchedEye.click(function () { var cardContainer = $(this).closest('.title-card-container'); var isWatched = cardContainer.hasClass('g_watched'); if (isWatched) { cardContainer.removeClass('g_watched'); markAsUnwatched(id); } else { cardContainer.addClass('g_watched'); markAsWatched(id); } }); element.closest('.title-card-container').append(watchedEye); } // Function to mark a show as watched function markAsWatched(videoId) { // Prefix the key with "watched_" localStorage.setItem("watched_" + videoId, "true"); } // Function to mark a show as unwatched function markAsUnwatched(videoId) { // Prefix the key with "watched_" localStorage.setItem("watched_" + videoId, "false"); } // Backup data related to watched shows to a JSON file function backupWatchedShows() { var watchedData = {}; for (var key in localStorage) { if (key.startsWith("watched_")) { watchedData[key] = localStorage[key]; } } var data = JSON.stringify(watchedData); var blob = new Blob([data], { type: "application/json" }); var url = URL.createObjectURL(blob); var a = document.createElement("a"); a.href = url; a.download = "watchedShowsBackup.json"; a.style.display = "none"; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } // Restore data related to watched shows from a JSON file function restoreWatchedShows() { var input = document.createElement("input"); input.type = "file"; input.accept = ".json"; input.click(); input.addEventListener("change", function () { var file = input.files[0]; var reader = new FileReader(); reader.onload = function () { try { var data = JSON.parse(reader.result); for (var key in data) { localStorage.setItem(key, data[key]); } alert("Watched shows data restored successfully."); } catch (e) { alert("Error restoring data: " + e); } }; if (file) { reader.readAsText(file); } }); } $(document).ready(function () { // Initial execution for the elements present on the page load $('[data-ui-tracking-context]').each(function () { addWatchedButton($(this)); }); // Add a MutationObserver to detect when new elements are added var observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.addedNodes) { $(mutation.addedNodes).find('[data-ui-tracking-context]').each(function () { addWatchedButton($(this)); }); } }); }); // Observe changes in the DOM, including dynamically loaded content observer.observe(document.body, { childList: true, subtree: true }); GM_registerMenuCommand("Backup Watched Shows", backupWatchedShows); GM_registerMenuCommand("Restore Watched Shows", restoreWatchedShows); $('head').append(` `); });