// ==UserScript==
// @name Pinterest Slideshow (dvirzxc's fork)
// @namespace https://greasyfork.org/users/1257389
// @version 1.0.05
// @description Fork from French Bond's Pinterest Slideshow script (ver. 1.5.1) with a bunch of my amateur copilot assisted code. - Start a slideshow on any Pinterest page where there's pins.
// @author dvirzxc
// @match https://*.pinterest.com/*
// @match https://*.pinterest.at/*
// @match https://*.pinterest.ca/*
// @match https://*.pinterest.ch/*
// @match https://*.pinterest.cl/*
// @match https://*.pinterest.co.kr/*
// @match https://*.pinterest.co.uk/*
// @match https://*.pinterest.com.au/*
// @match https://*.pinterest.com.mx/*
// @match https://*.pinterest.de/*
// @match https://*.pinterest.dk/*
// @match https://*.pinterest.es/*
// @match https://*.pinterest.fr/*
// @match https://*.pinterest.ie/*
// @match https://*.pinterest.info/*
// @match https://*.pinterest.it/*
// @match https://*.pinterest.jp/*
// @match https://*.pinterest.nz/*
// @match https://*.pinterest.ph/*
// @match https://*.pinterest.pt/*
// @match https://*.pinterest.se/*
// @license MIT
// @grant GM_registerMenuCommand
// @require http://code.jquery.com/jquery-latest.js
// @downloadURL https://update.greasyfork.icu/scripts/486595/Pinterest%20Slideshow%20%28dvirzxc%27s%20fork%29.user.js
// @updateURL https://update.greasyfork.icu/scripts/486595/Pinterest%20Slideshow%20%28dvirzxc%27s%20fork%29.meta.js
// ==/UserScript==
/* globals jQuery, $ */
$(function () {
'use strict';
let customSlideInterval = 1000; // Default slide interval in milliseconds
let pins = [];
let c = 0; // Current slide number
let interval;
let running = 0;
let observer;
function init() {
addSlideShowButton();
addSlideShowImageAndControls();
collectPinsInfo();
observeDynamicChanges();
addKeyboardShortcuts();
addContextMenuOptions();
}
function addSlideShowButton() {
$('body').append(
'
' +
'
' +
'Slideshow' +
'
' +
'
'
);
$('.slideshow-button').click(startSlideshow);
}
function addSlideShowImageAndControls() {
// Add slideshow div
$('body').append(
'' +
'
![]()
' +
'
'
);
// Add the slideshow menu
$('.slideshow').append(
''
);
$('.menu-slideshow')
.append(
'Stop
'
)
.append('/
');
// Handle Stop Button
$('.stop-slideshow').click(stopSlideshow);
}
function collectPinsInfo() {
const newPins = getPinsInfo();
newPins.forEach(newPin => {
if (!pins.some(pin => pin.href === newPin.href)) {
pins.push(newPin);
}
});
console.log(pins);
}
function observeDynamicChanges() {
observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.addedNodes.length) {
collectPinsInfo();
}
});
});
var config = {
childList: true,
subtree: true
};
observer.observe(document.body, config);
}
function getPinsInfo() {
return Array.from(document.querySelectorAll('[data-test-id="pinWrapper"]')).map(function (pinWrapper) {
const a = pinWrapper.querySelector('a');
const imageContainerLink = a.getAttribute('href');
const img = a.querySelector('img');
return {
href: a.getAttribute('href'),
src: findBestQualityImage(a),
imageContainerLink: imageContainerLink
};
});
}
function findBestQualityImage(a) {
const img = a.querySelector('img');
if (img) {
const imgSrcSet = img.getAttribute('srcset');
if (imgSrcSet) {
const srcSetArray = imgSrcSet.split(',').map(function (s) {
return s.trim().split(' ');
});
srcSetArray.sort(function (a, b) {
return parseInt(b[1]) - parseInt(a[1]);
});
return srcSetArray[0][0];
} else {
return img.getAttribute('src');
}
}
return null;
}
function startSlideshow() {
$('.slideshow').show();
console.log('Starting slideshow');
console.log('Number of slides: ' + pins.length);
console.log('Slide interval: ' + customSlideInterval / 1000 + 's');
c = 0;
running = 1;
clearInterval(interval);
interval = setInterval(nextSlide, customSlideInterval);
showSlide();
}
function showSlide() {
console.log('Current slide: ' + (c + 1));
const pin = pins[c];
$('#slideshow-img').attr('src', pin.src);
$('#slideshow-link').attr('href', pin.imageContainerLink);
$('.info-slideshow').html(c + 1 + '/' + pins.length);
preloadNextSlide();
}
async function preloadNextSlide() {
const nextSlide = c + 1;
if (nextSlide > pins.length - 1) return;
const pin = pins[nextSlide];
console.log('Preloading next slide: ' + pin.src);
preloadPictures([pin.src]);
}
function preloadPictures(pictureUrls) {
let loaded = 0;
pictureUrls.forEach(function (url) {
const img = new Image();
img.onload = function () {
loaded++;
if (loaded === pictureUrls.length) {
console.log('All images preloaded');
}
};
img.onerror = function () {
loaded++;
console.error('Failed to load image:', url);
};
img.src = url;
});
}
function stopSlideshow() {
clearInterval(interval);
running = 0;
$('.slideshow').hide();
console.log('Slideshow stopped');
}
function pauseSlideshow() {
clearInterval(interval);
running = 0;
console.log('Slideshow paused');
}
function resumeSlideshow() {
if (!running) {
clearInterval(interval);
interval = setInterval(nextSlide, customSlideInterval);
running = 1;
console.log('Slideshow resumed');
}
}
function previousSlide() {
c--;
if (c < 0) c = pins.length - 1;
showSlide();
}
function nextSlide() {
c++;
if (c > pins.length - 1) c = 0;
showSlide();
}
function addKeyboardShortcuts() {
$(document).on('keydown', function (e) {
if (e.key === 'p') {
pauseSlideshow();
} else if (e.key === 'l') {
resumeSlideshow();
} else if (e.key === 'ArrowLeft') {
previousSlide();
} else if (e.key === 'ArrowRight') {
nextSlide();
}
});
}
function addContextMenuOptions() {
GM_registerMenuCommand("Set slide interval to 0.5s", function() {
customSlideInterval = 500;
console.log("Slide interval set to 0.5s");
});
GM_registerMenuCommand("Set slide interval to 1s", function() {
customSlideInterval = 1000;
console.log("Slide interval set to 1s");
});
GM_registerMenuCommand("Set slide interval to 3s", function() {
customSlideInterval = 3000;
console.log("Slide interval set to 3s");
});
GM_registerMenuCommand("Set slide interval to 5s", function() {
customSlideInterval = 5000;
console.log("Slide interval set to 5s");
});
GM_registerMenuCommand("Set slide interval to 10s", function() {
customSlideInterval = 10000;
console.log("Slide interval set to 10s");
});
}
init();
});