Skip to content

Instantly share code, notes, and snippets.

@artzub
Last active February 21, 2021 05:56
Show Gist options
  • Save artzub/e29d8b748f7d556ff1971654bafefc82 to your computer and use it in GitHub Desktop.
Save artzub/e29d8b748f7d556ff1971654bafefc82 to your computer and use it in GitHub Desktop.
Add all subscription from the last watched to Watch Later Playlist
(function addAll() {
let neededVideoId = localStorage.getItem('_lastVideoId');
neededVideoId = neededVideoId || prompt('Enter id of the last video, or keep empty', '');
const delay = (ms = 100) => new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, ms)
});
const eventMouseEnter = new Event('mouseenter', {
view: window,
bubbles: false,
cancelable: false
});
const eventMouseClick = new MouseEvent('click', {
view: window,
bubbles: false,
cancelable: false,
detail: 1
});
let videos = [];
const checkWatched = async () => {
await delay(3e3);
videos = Array.from(document.querySelectorAll('#items > ytd-grid-video-renderer'));
const found = neededVideoId ? videos.find(item => item.data.videoId === neededVideoId) : videos.find(item => item.data.isWatched);
if (found) {
observer.disconnect();
stageSecond();
return;
}
if (videos.length > 0) {
videos[videos.length - 1].scrollIntoView();
}
};
let timer;
const runWaiter = () => {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(checkWatched, 2e3);
};
const processing = video => new Promise(resolve => {
console.log(video.data.videoId, 'processing');
const mouseenter = async (event) => {
await delay(1e3);
console.log(video.data.videoId, 'mouseenter');
video.removeEventListener('mouseenter', mouseenter, true);
setTimeout(async () => {
const button = video.querySelector('ytd-thumbnail-overlay-toggle-button-renderer:nth-child(1) #icon');
console.log(video.data.videoId, 'button', button);
if (button && button.parentNode && button.parentNode.data && !button.parentNode.data.isToggled) {
const buttonTap = async (event) => {
button.parentNode.removeEventListener('click', buttonTap, true);
console.log(video.data.videoId, 'click');
await delay(1e2);
resolve(true);
};
button.parentNode.addEventListener('click', buttonTap, true);
await delay(2e2);
const rect = video.getClientRects()[0];
const c = button.dispatchEvent(new MouseEvent('click', {
view: window,
bubbles: false,
cancelable: false,
detail: 1,
clientX: rect.x + rect.width - 20,
clientY: rect.y + 20
}));
await delay(1e2);
if (!c) {
resolve(false);
}
} else {
resolve(false);
}
}, 300);
}
video.addEventListener('mouseenter', mouseenter, true);
video.dispatchEvent(eventMouseEnter);
});
const stageSecond = async () => {
if (neededVideoId) {
const index = videos.findIndex(item => item.data.videoId === neededVideoId);
videos.splice(index, videos.length);
}
videos = videos.filter(item => !item.data.isWatched);
let l = videos.length;
let rect;
while(l--) {
if (window.breakNow) {
break;
}
window.scrollTo(0, videos[l].offsetTop - 200);
await delay(100);
console.log(l);
await processing(videos[l]);
videos[l].setAttribute('style', `border: 5px solid red;`);
}
};
const itemsContainer = document.querySelector('ytd-section-list-renderer');
const mutationListener = (mutationList, observer) => {
const list = mutationList.filter(item => item.target.id === 'items');
if (list.length > 0) {
runWaiter();
}
};
const observer = new MutationObserver(mutationListener);
observer.observe(itemsContainer, { childList: true, subtree: true });
checkWatched();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment