nascent / Youtube like/dislike video and skip ad keyboard shortcuts

// ==UserScript==
// @name        Youtube like/dislike video and skip ad keyboard shortcuts
// @namespace   youtube
// @author      nascent
// @include     https://www.youtube.com/*
// @description Adds keyboard shortcuts [ and ] for liking and disliking videos, and s for skipping pre-video and banner ads. Option for browser notifications
// @version     1.8
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_registerMenuCommand
// @run-at      document-end
// @icon        https://www.google.com/s2/favicons?domain=youtube.com&sz=128
// @license     GPL-3.0-or-later
// ==/UserScript==

/* jshint esversion: 6 */

(function () {
  "use strict";

  // Retrieve the saved setting; if not set, default to true.
  let browserNotifications = GM_getValue("browserNotifications", true);
  const NOTIFICATION_DURATION_MILLIS = 3000; // duration for toast notification
  let lastToastElement = null;

  // Menu command for toggling browser notifications.
  function toggleBrowserNotifications() {
    browserNotifications = !browserNotifications;
    GM_setValue("browserNotifications", browserNotifications);
    alert(`Browser notifications are now ${browserNotifications ? "enabled" : "disabled"}.`);
  }
  GM_registerMenuCommand("Toggle Browser Notifications", toggleBrowserNotifications);

  // Function to show a toast notification.
  function showNotification(message) {
    if (!browserNotifications) {
      return;
    }
    // If a toast is already visible, remove it.
    if (lastToastElement !== null) {
      lastToastElement.remove();
      lastToastElement = null;
    }

    // Create a toast element (YouTube uses tp-yt-paper-toast for notifications).
    const toast = document.createElement('tp-yt-paper-toast');
    toast.innerText = message;
    toast.classList.add('toast-open');

    // Set up inline style properties for the toast.
    const styleProps = {
      outline: 'none',
      position: 'fixed',
      left: '24px',
      bottom: '24px',
      padding: '16px 24px',
      backgroundColor: '#323232',
      color: '#f1f1f1',
      fontSize: '14px',
      borderRadius: '4px',
      boxShadow: '0 2px 5px 0 rgba(0,0,0,0.26)',
      maxWidth: '297.547px',
      maxHeight: '48px',
      zIndex: '2202',
      opacity: '1',
      transition: 'transform 0.3s ease-in-out',
      transform: 'translateY(200%)'
    };

    for (const prop in styleProps) {
      toast.style[prop] = styleProps[prop];
    }

    document.body.appendChild(toast);
    lastToastElement = toast;

    // Show the toast notification.
    setTimeout(() => {
      toast.style.display = 'block';
    }, 0);

    // Ensure the toast animation occurs.
    setTimeout(() => {
      toast.style.transform = 'none';
    }, 10);

    // Hide and cleanly remove toast from the DOM after duration
    setTimeout(() => {
      if (toast) {
        toast.style.transform = 'translateY(200%)';
        setTimeout(() => {
          if (toast.parentNode) {
            toast.parentNode.removeChild(toast);
          }
          if (lastToastElement === toast) {
            lastToastElement = null;
          }
        }, 300); // Wait for CSS transition to finish
      }
    }, Math.max(0, NOTIFICATION_DURATION_MILLIS));
  }

  // Listen for keydown events.
  window.addEventListener("keydown", (e) => {
    // Only run on video watch pages.
    if (!/^\/watch/.test(location.pathname)) {
      return;
    }

    // Avoid interfering with input fields or editable content.
    const tag = e.target.tagName.toLowerCase();
    if (e.target.isContentEditable || tag === "input" || tag === "textarea") {
      return;
    }

    // Ignore when modifier keys are held.
    if (e.ctrlKey || e.altKey || e.metaKey || e.shiftKey) {
      return;
    }

    // "[" key to toggle like.
    if (e.code === "BracketLeft") {
      // Find the button dynamically at the exact moment of the keypress
      const likeBtn = document.querySelector("like-button-view-model button") || 
                      document.querySelector('button[aria-label*="like this video" i]');
      if (likeBtn) {
        likeBtn.click();
        if (browserNotifications) {
          setTimeout(() => {
            const action =
              likeBtn.getAttribute("aria-pressed") === "true"
                ? "Video Liked ❤️"
                : "Like Removed";
            showNotification(action);
          }, 100);
        }
      }
    }
    // "]" key to toggle dislike.
    else if (e.code === "BracketRight") {
      // Find the button dynamically at the exact moment of the keypress
      const dislikeBtn = document.querySelector("dislike-button-view-model button") || 
                         document.querySelector('button[aria-label*="dislike this video" i]');
      if (dislikeBtn) {
        dislikeBtn.click();
        if (browserNotifications) {
          setTimeout(() => {
            const action =
              dislikeBtn.getAttribute("aria-pressed") === "true"
                ? "Video Disliked 👎"
                : "Dislike Removed";
            showNotification(action);
          }, 100);
        }
      }
    }
    // "S" key to skip ads.
    else if (e.code === "KeyS") {
      const skipAdBtn = document.querySelector(".ytp-ad-skip-button, .ytp-ad-skip-button-modern, .ytp-skip-ad-button");
      const skipBannerAdBtn = document.querySelector(".ytp-ad-overlay-close-button");

      if (skipAdBtn) {
        skipAdBtn.click();
      } else if (skipBannerAdBtn) {
        skipBannerAdBtn.click();
      }
    }
  });
})();