您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A script to slightly enhance everynoise's user experience
当前为
// ==UserScript== // @name Everynoise Enhancement Script // @namespace http://tampermonkey.net/ // @version 0.4.3 // @description A script to slightly enhance everynoise's user experience // @author NeroYuki // @match https://everynoise.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=https://everynoise.com/ // @license MIT // ==/UserScript== /** function highlight(which) { if (gdivs.length == 0) { gdivs = document.getElementsByClassName('genre'); } for (i=0; i<gdivs.length; i++) { thisdiv = gdivs[i]; thistext = thisdiv.firstChild.textContent; if (thisdiv.className.indexOf('scanme') > -1) { basename = 'genre scanme'; } else { basename = 'genre'; } if (which.length > 0 && which.trim() == thistext.trim().replace('"', '')) { thisdiv.className = basename + ' current'; if(typeof thisdiv.scrollIntoViewIfNeeded == 'function') { thisdiv.scrollIntoViewIfNeeded(); } else { thisdiv.scrollIntoView({behavior: "smooth", block: "center", inline: "center"}); } } else { thisdiv.className = basename; } } } **/ (function() { 'use strict'; // Your code here... var head = document.getElementsByTagName('head')[0]; var thisScript = document.scripts[0] var cloneScript= document.createElement('script'); if (thisScript) { cloneScript.textContent = thisScript.textContent.replace(/scandur \= 6000/g, 'scandur = 29000'); cloneScript.textContent = cloneScript.textContent.replace('function playx(key, genre, me) {', 'async function playx(key, genre, me) {'); cloneScript.textContent = cloneScript.textContent.replace('highlight(genre);', 'highlight(genre, sample_title);'); cloneScript.textContent = cloneScript.textContent.replace('function highlight(which)', 'function highlight(which, sample_title = "")'); cloneScript.textContent = cloneScript.textContent.replace('me.setAttribute(\'played\', clicknumber++);', ''); cloneScript.textContent = cloneScript.textContent.replace('async function playx(key, genre, me) {', 'async function playx(key, genre, me, loop = false) {'); cloneScript.textContent = cloneScript.textContent.replace('if (nowplaying == genre) {', 'if (nowplaying == genre && !loop) {'); cloneScript.textContent = cloneScript.textContent.replace('window.clearTimeout(nowpending);', 'if (!loop) { window.clearTimeout(nowpending); }'); cloneScript.textContent = cloneScript.textContent.replace('picked.onclick();', 'if (!isLooping) { window.clearTimeout(nowpending); picked.onclick(); } else { window.clearTimeout(nowpending); }'); cloneScript.textContent = cloneScript.textContent.replace('thisdiv.scrollIntoViewIfNeeded(false);', 'thisdiv.scrollIntoViewIfNeeded(true);'); var cloneScriptLines = cloneScript.textContent.split('\n'); var dataInsertLine = 0 cloneScriptLines.splice(dataInsertLine, 0, ` var genreData = []; fetch('https://raw.githubusercontent.com/NeroYuki/AnotherElaina/master/resources/spotify_genres.json') .then(async (response) => { genreData = await response.json(); }); var isLooping = false; const dbName = "everynoise_ext"; let db = null; const request = indexedDB.open(dbName, 2); request.onerror = (event) => { alert('error, please disable the userscript'); }; request.onsuccess = (event) => { db = event.target.result; db.transaction("genres") .objectStore("genres").get("pop").onsuccess = (event) => { const res = event.target.result if (!res) { console.log('adding data'); fetch('https://raw.githubusercontent.com/NeroYuki/AnotherElaina/master/resources/spotify_genres_artists_top50.json') .then(async (response) => { console.log('fetched artists genre mapping'); genreArtist = await response.json(); for (const genre of genreArtist) { db .transaction("genres", "readwrite") .objectStore("genres") .add(genre); } }); } } }; request.onupgradeneeded = (event) => { db = event.target.result; const objectStore = db.createObjectStore("genres", { keyPath: "genre" }); // Use transaction oncomplete to make sure the objectStore creation is // finished before adding data into it. objectStore.transaction.oncomplete = (event) => { console.log('creation done') }; }; function getData(dataStore, key) { return new Promise((resolve, reject) => { const dataFetch = db.transaction(dataStore) .objectStore(dataStore).get(key); dataFetch.onsuccess = (event) => { const res = event.target.result resolve(res); } dataFetch.onerror = (event) => { reject(event); } }) } `); var insertLoopLine = cloneScriptLines.findIndex(val => val.includes('var spotifyplayer = document.getElementById(\'spotifyplayer\');')) + 1; cloneScriptLines.splice(insertLoopLine, 0, ` console.log(genre, key); spotifyplayer.onended = () => { console.log('ended') playx(key, genre, me, true); }; `); var insertSelectionLine = cloneScriptLines.findIndex(val => val.includes('previewurl = me.getAttribute(\'preview_url\')')) + 1; cloneScriptLines.splice(insertSelectionLine, 0, ` let sample_title = me.getAttribute('title').replace('e.g. ', ''); const res = await getData('genres', genre) var selectionIndex = res?.artists ? Math.floor(Math.random() * res.artists.length + 1) : 0; if (selectionIndex > 1) { previewurl = res.artists[selectionIndex - 1].preview_url; sample_title = res.artists[selectionIndex - 1].sample_song; } `); var insertStartResetStateLine = cloneScriptLines.findIndex(val => val.includes('if (state == \'stop\') {')) - 1; cloneScriptLines.splice(insertStartResetStateLine, 0, ` if (state == 'start') { isLooping = false; } `); var insertLine = cloneScriptLines.findIndex(val => val.includes('thisdiv.scrollIntoView({behavior: "smooth", block: "center", inline: "center"});')) + 2; cloneScriptLines.splice(insertLine, 0, ` var label = document.getElementById('genre_label'); if (!label) { label = document.createElement('div'); document.body.appendChild(label); } var title_label = document.getElementById('title_label'); if (!title_label) { title_label = document.createElement('div'); document.body.appendChild(title_label); } var loop_label = document.getElementById('loop_label'); if (!loop_label) { loop_label = document.createElement('div'); document.body.appendChild(loop_label); } let genreInfo = genreData.find(val => val.genre === which.trim()) label.id = 'genre_label'; title_label.id = 'title_label'; loop_label.id = 'loop_label'; label.style.position = title_label.style.position = loop_label.style.position = 'absolute'; label.style.color = title_label.style.color = loop_label.style.color = 'black'; label.style.backgroundColor = title_label.style.backgroundColor = 'white'; loop_label.style.backgroundColor = isLooping ? 'green' : 'white'; label.style.padding = title_label.style.padding = loop_label.style.padding = '5px'; label.style.display = title_label.style.display = loop_label.style.display = 'none'; label.textContent = genreInfo ? genreInfo.desc : "No description"; title_label.textContent = '▶ ' + (sample_title ? sample_title : "Unknown title"); loop_label.textContent = '↻' // set the label position to be above the highlighted div var rect = thisdiv.getBoundingClientRect(); label.style.left = Math.max(10, (parseInt(thisdiv.style.left) - 100)) + 'px'; label.style.width = '300px' label.style.top = (parseInt(thisdiv.style.top) + 96) + 'px'; label.style.border = 'solid 1px black'; // show the label label.style.display = 'block'; title_label.style.left = Math.max(10, (parseInt(thisdiv.style.left) - 100)) + 'px'; title_label.style.top = (parseInt(thisdiv.style.top) + 36) + 'px'; title_label.style.border = 'solid 1px black'; // show the label title_label.style.display = sample_title ? 'block' : 'none'; loop_label.style.left = Math.max(10, (parseInt(thisdiv.style.left) - 124)) + 'px'; loop_label.style.top = (parseInt(thisdiv.style.top) + 36) + 'px'; loop_label.style.border = 'solid 1px black'; // show the label loop_label.style.display = 'block'; loop_label.onclick = () => { isLooping = !isLooping; loop_label.style.backgroundColor = isLooping ? 'green' : 'white'; } if(typeof label.scrollIntoViewIfNeeded == 'function') { label.scrollIntoViewIfNeeded(); } `); cloneScript.textContent = cloneScriptLines.join('\n'); head.appendChild(cloneScript); thisScript.remove(); } })();