// ==UserScript== // @name AniWave QoL // @namespace http://tampermonkey.net/ // @version 1.0 // @description Moves episode list under player, auto expands player, auto 1080p, removes some unnecessary stuff, other UI changes. // @author grinnch // @license MIT // @match https://aniwave.to/* // @icon https://cdn2.steamgriddb.com/icon_thumb/21b203a02c91d5272135dbbebe6afc00.png // @grant none // @downloadURL none // ==/UserScript== (async () => { 'use strict'; function waitForElement(selector, baseElement = document.body) { return new Promise(resolve => { if (baseElement.querySelector(selector)) { return resolve(baseElement.querySelector(selector)); } const observer = new MutationObserver(mutations => { if (baseElement.querySelector(selector)) { resolve(baseElement.querySelector(selector)); observer.disconnect(); } }); observer.observe(baseElement, { childList: true, subtree: true }); }); } function modifyStyle() { // Places episode-panel underneath player let element = document.querySelector('#w-media'); if (element) { element.style.flexDirection = 'column'; } let episodesElement = document.querySelector('#w-media #w-episodes'); if (episodesElement) { episodesElement.style.order = '3'; episodesElement.style.maxWidth = 'unset'; episodesElement.style.marginTop = '10px'; episodesElement.style.marginLeft = '85px'; episodesElement.style.marginRight = '85px'; } let episodesBodyElement = document.querySelector('#w-media #w-episodes .body .episodes'); if (episodesBodyElement) { episodesBodyElement.style.position = 'static'; episodesBodyElement.style.maxHeight = '300px'; episodesBodyElement.style.overflowY = 'auto'; } // Adds padding to player to fit on-screen let playerElement = document.querySelector('#w-media #w-player'); if (playerElement) { playerElement.style.marginLeft = '85px'; playerElement.style.marginRight = '85px'; } // Adds left-padding to related panel let sidebarElement = document.querySelector('#watch-main aside.sidebar'); if (sidebarElement) { sidebarElement.style.marginLeft = '10px'; sidebarElement.style.marginRight = '10px'; } // Adds left-padding to info let descriptionElement = document.querySelector('#w-info'); if (descriptionElement) { descriptionElement.style.marginLeft = '10px'; descriptionElement.style.marginRight = '10px'; } } // Call the function to modify the style initially modifyStyle(); // Create a MutationObserver instance to watch for changes in the element let observer = new MutationObserver(modifyStyle); // Start observing the target element let target = document.querySelector('#w-media'); if (target) { observer.observe(target, { attributes: true, childList: true, subtree: true }); } window.onload = function() { // Remove built-in ad var elements = document.getElementsByClassName('mb-4 text-center'); while(elements.length > 0){ while(elements[0].firstChild) { elements[0].removeChild(elements[0].firstChild); } elements[0].classList.remove('mb-4', 'text-center'); } // Remove sharing var bsharingElements = document.getElementsByClassName('bsharing mb-4'); while(bsharingElements.length > 0){ while(bsharingElements[0].firstChild) { bsharingElements[0].removeChild(bsharingElements[0].firstChild); } bsharingElements[0].classList.remove('bsharing', 'mb-4'); } // Auto expand var expandElement = document.querySelector('.ctrl.expand'); if (expandElement) { expandElement.click(); } }; // Waits for settings button to load const settingsButtonSelector = 'div.jw-icon.jw-icon-inline.jw-button-color.jw-reset.jw-icon-settings.jw-settings-submenu-button'; await waitForElement(settingsButtonSelector); // Set the quality to the highest const player = jwplayer(); // 0 = auto, 1 = highest player.on('firstFrame', () => player.setCurrentQuality(1)); })();