// ==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(`
`);
});