YouTube Quick Watch Later

Adds quick Watch Later button

// ==UserScript==
// @name         YouTube Quick Watch Later
// @namespace    http://tampermonkey.net/
// @version      2.4
// @description  Adds quick Watch Later button
// @author       kavinned
// @match        https://www.youtube.com/*
// @grant        GM_addStyle
// @icon         https://www.google.com/s2/favicons?sz=64&domain=YouTube.com
// @license      MIT
// ==/UserScript==

(function () {
    "use strict";

    // Configuration: Add "Save" translations here
    const SAVE_BUTTON_TEXTS = [
        "Save",      // English
        "儲存",      // Traditional Chinese
        "保存",      // Simplified Chinese
        "Guardar",   // Spanish
        "Sauvegarder", // French
        "Speichern", // German
        "Salvar",    // Portuguese
        "Сохранить", // Russian
        "保存",      // Japanese
        "저장",      // Korean
        "บันทึก",    // Thai
        "Simpan",    // Indonesian
        "Lưu"        // Vietnamese
    ];

    function addWatchLaterButton() {
        const targetDiv = document.querySelector(
            "#top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div"
        );
        if (!targetDiv || document.querySelector(".quick-watch-later")) return;

        const button = document.createElement("button");
        button.className = "quick-watch-later";
        button.textContent = "WL";

        button.addEventListener("click", function () {
            // Helper function to check if text contains any of the save button texts
            function containsSaveText(text) {
                return SAVE_BUTTON_TEXTS.some(saveText => text.includes(saveText));
            }

            // First check if Save button is directly visible
            const directSaveButton = document.querySelector(
                "ytd-menu-renderer yt-button-view-model .yt-spec-button-shape-next__button-text-content"
            );
            const directSaveButtonWithText = Array.from(
                document.querySelectorAll("ytd-menu-renderer yt-button-view-model .yt-spec-button-shape-next__button-text-content")
            ).find(element => containsSaveText(element.textContent));

            if (directSaveButtonWithText) {
                // Save button is directly visible, click it
                console.log("Direct save button found, clicking it");
                directSaveButtonWithText.click();
                
                // Then proceed to click the Watch Later button
                setTimeout(function () {
                    const watchLaterBox = document.querySelector(
                        "#playlists > ytd-playlist-add-to-option-renderer:first-child #checkbox"
                    );

                    if (
                        watchLaterBox &&
                        watchLaterBox.getAttribute("aria-checked") === "true"
                    ) {
                        const confirmRemove = window.confirm(
                            "This video is already in your Watch Later playlist. Do you want to remove it?"
                        );

                        if (confirmRemove) {
                            watchLaterBox.click();
                            const closeButton = document.querySelector(
                                "#button > yt-icon > span"
                            );
                            if (closeButton) {
                                closeButton.click();
                            }
                        } else {
                            const closeButton = document.querySelector(
                                "#button > yt-icon > span"
                            );
                            if (closeButton) {
                                closeButton.click();
                            }
                        }
                    } else {
                        // If the video isn't in Watch Later, proceed with adding it
                        watchLaterBox.click();
                        const closeButton = document.querySelector(
                            "#button > yt-icon > span"
                        );
                        if (closeButton) {
                            closeButton.click();
                        }
                    }
                }, 1000);
            } else {
                // Save button is in submenu, use original logic
                console.log("Save button not directly visible, opening menu");
                
                // First click menu button
                const menuButton = document.querySelector(
                    "#button-shape > button > yt-touch-feedback-shape > div"
                );
                menuButton.click();
                if (menuButton) {
                    console.log("menu clicked");
                }
                // Next click the Save button
                setTimeout(function () {
                    const saveButtons = document.querySelectorAll(
                        "#items > ytd-menu-service-item-renderer > tp-yt-paper-item > yt-formatted-string"
                    );
                    const saveButton = Array.from(saveButtons).find((button) =>
                        containsSaveText(button.textContent)
                    );
                    saveButton.click();
                    // Then click the Watch Later button
                    setTimeout(function () {
                        const watchLaterBox = document.querySelector(
                            "#playlists > ytd-playlist-add-to-option-renderer:first-child #checkbox"
                        );

                        if (
                            watchLaterBox &&
                            watchLaterBox.getAttribute("aria-checked") === "true"
                        ) {
                            const confirmRemove = window.confirm(
                                "This video is already in your Watch Later playlist. Do you want to remove it?"
                            );

                            if (confirmRemove) {
                                watchLaterBox.click();
                                const closeButton = document.querySelector(
                                    "#button > yt-icon > span"
                                );
                                if (closeButton) {
                                    closeButton.click();
                                }
                            } else {
                                const closeButton = document.querySelector(
                                    "#button > yt-icon > span"
                                );
                                if (closeButton) {
                                    closeButton.click();
                                }
                            }
                        } else {
                            // If the video isn't in Watch Later, proceed with adding it
                            watchLaterBox.click();
                            const closeButton = document.querySelector(
                                "#button > yt-icon > span"
                            );
                            if (closeButton) {
                                closeButton.click();
                            }
                        }
                    }, 1000);
                }, 100);
            }
        });

        targetDiv.appendChild(button);
    }

    setTimeout(addWatchLaterButton, 2000);

    const observer = new MutationObserver(() => {
        if (window.location.href.includes("/watch?")) {
            setTimeout(addWatchLaterButton, 1000);
        }
    });

    observer.observe(document.body, { childList: true, subtree: true });

    GM_addStyle(
        `#top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div {
            display: flex;
            flex-direction: row-reverse;
            gap: 5px;
        }
        #top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div > button {
            flex-direction: row;
            border-radius: 24px;
            border: none;
            padding-left: 20px;
            padding-right: 20px;
            color: white;
            font-weight: bold;
            background: #272727;
            cursor: pointer;

            &:hover {
                background: #414141;
            }
        }
        .ryd-tooltip.ryd-tooltip-new-design {
            height: 0px !important;
            width: 0px !important;
        }
        @media only screen and (max-width: 1200px) {
            #top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div {
                flex-direction: column;
            }
            #top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div > button {
                padding: 10.5px 0px;
            }

        }
    }`
    );
})();