forked from SpoTUI/SpoTUI
refactor(theme): remove legacy visualizer
This commit is contained in:
@@ -22,91 +22,6 @@ const style = `
|
|||||||
cursor: text;
|
cursor: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
#spotui-visualizer {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
display: none;
|
|
||||||
overflow: hidden;
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 2;
|
|
||||||
background:
|
|
||||||
radial-gradient(circle at 50% 65%, rgba(255, 140, 0, 0.12), rgba(0, 0, 0, 0) 42%),
|
|
||||||
linear-gradient(180deg, rgba(255, 69, 0, 0.08), rgba(0, 0, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#spotui-visualizer::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
background-image:
|
|
||||||
linear-gradient(rgba(255, 140, 0, 0.04) 1px, transparent 1px),
|
|
||||||
linear-gradient(90deg, rgba(255, 140, 0, 0.03) 1px, transparent 1px);
|
|
||||||
background-size: 100% 28px, 28px 100%;
|
|
||||||
opacity: 0.28;
|
|
||||||
}
|
|
||||||
|
|
||||||
#spotui-visualizer-fall {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0 0 90px 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 0;
|
|
||||||
color: #ff8c00;
|
|
||||||
white-space: pre;
|
|
||||||
text-align: center;
|
|
||||||
font-family: "JetBrains Mono", "Fira Code", monospace;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 1;
|
|
||||||
opacity: 0.92;
|
|
||||||
letter-spacing: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spotui-viz-line {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
will-change: transform, opacity, filter;
|
|
||||||
text-shadow: 0 0 12px rgba(255, 140, 0, 0.28);
|
|
||||||
}
|
|
||||||
|
|
||||||
.spotui-viz-char {
|
|
||||||
display: inline-block;
|
|
||||||
will-change: transform, opacity, filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
#spotui-visualizer-bars {
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
bottom: 114px;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: min(92vw, 1280px);
|
|
||||||
height: 34vh;
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 6px;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 220ms ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spotui-viz-bar {
|
|
||||||
flex: 1 1 0;
|
|
||||||
min-width: 4px;
|
|
||||||
max-width: 14px;
|
|
||||||
border-radius: 999px 999px 0 0;
|
|
||||||
background: linear-gradient(180deg, #ffa500 0%, #ff8c00 55%, #ff4500 100%);
|
|
||||||
box-shadow:
|
|
||||||
0 0 12px rgba(255, 140, 0, 0.36),
|
|
||||||
inset 0 0 0 1px rgba(255, 220, 160, 0.1);
|
|
||||||
transform-origin: bottom;
|
|
||||||
min-height: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#spotui-tui.spotui-has-visualizer #spotui-visualizer {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#spotui-logo {
|
#spotui-logo {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
@@ -210,32 +125,6 @@ body.spotui-tui-hidden #spotui-popup {
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.spotui-visualizer-active #spotui-output {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.spotui-visualizer-active #spotui-footer {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.spotui-visualizer-active #spotui-logo {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.spotui-visualizer-active #spotui-controls {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.spotui-visualizer-active #spotui-visualizer-bars {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.spotui-visualizer-active #spotui-input {
|
|
||||||
color: rgba(255, 140, 66, 0.58);
|
|
||||||
}
|
|
||||||
|
|
||||||
#spotui-popup {
|
#spotui-popup {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
@@ -303,26 +192,7 @@ const SPOTUI_ASCII_ART = [
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
let idleTimer = null;
|
|
||||||
let animeReady = null;
|
|
||||||
let visualizerRoot = null;
|
|
||||||
let visualizerFall = null;
|
|
||||||
let visualizerBars = null;
|
|
||||||
let visualizerBarEls = [];
|
|
||||||
let visualizerBarFrame = null;
|
|
||||||
let visualizerFallAnim = null;
|
|
||||||
let visualizerLineAnims = [];
|
|
||||||
let visualizerBarsTimer = null;
|
|
||||||
let visualizerActive = false;
|
|
||||||
let visualizerRequested = false;
|
|
||||||
let playbackWatcher = null;
|
|
||||||
let playbackIsPlaying = false;
|
|
||||||
let tuiMode = "command";
|
let tuiMode = "command";
|
||||||
let visualizerAudioContext = null;
|
|
||||||
let visualizerAudioSource = null;
|
|
||||||
let visualizerAnalyser = null;
|
|
||||||
let visualizerAudioData = null;
|
|
||||||
let visualizerAudioElement = null;
|
|
||||||
|
|
||||||
let results = [];
|
let results = [];
|
||||||
let selected = 0;
|
let selected = 0;
|
||||||
@@ -340,282 +210,6 @@ function setTuiMode(mode) {
|
|||||||
document.body.classList.toggle("spotui-command-mode", tuiMode !== "cli");
|
document.body.classList.toggle("spotui-command-mode", tuiMode !== "cli");
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadAnime() {
|
|
||||||
if (window.anime) return Promise.resolve(window.anime);
|
|
||||||
if (animeReady) return animeReady;
|
|
||||||
|
|
||||||
animeReady = new Promise((resolve, reject) => {
|
|
||||||
const existing = document.querySelector('script[data-spotui-anime="1"]');
|
|
||||||
if (existing) {
|
|
||||||
existing.addEventListener("load", () => resolve(window.anime), { once: true });
|
|
||||||
existing.addEventListener("error", () => reject(new Error("anime.js failed to load")), { once: true });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const script = document.createElement("script");
|
|
||||||
script.src = VISUALIZER_ANIME_SRC;
|
|
||||||
script.async = true;
|
|
||||||
script.dataset.spotuiAnime = "1";
|
|
||||||
script.onload = () => resolve(window.anime);
|
|
||||||
script.onerror = () => reject(new Error("anime.js failed to load"));
|
|
||||||
document.head.appendChild(script);
|
|
||||||
});
|
|
||||||
|
|
||||||
return animeReady;
|
|
||||||
}
|
|
||||||
|
|
||||||
function stopVisualizerAnimations() {
|
|
||||||
try {
|
|
||||||
visualizerFallAnim?.pause?.();
|
|
||||||
visualizerLineAnims.forEach((anim) => anim?.pause?.());
|
|
||||||
} catch {
|
|
||||||
}
|
|
||||||
|
|
||||||
visualizerFallAnim = null;
|
|
||||||
visualizerLineAnims = [];
|
|
||||||
if (visualizerBarsTimer) {
|
|
||||||
clearTimeout(visualizerBarsTimer);
|
|
||||||
visualizerBarsTimer = null;
|
|
||||||
}
|
|
||||||
if (visualizerBarFrame) {
|
|
||||||
cancelAnimationFrame(visualizerBarFrame);
|
|
||||||
visualizerBarFrame = null;
|
|
||||||
}
|
|
||||||
if (visualizerAudioContext?.state === "running") {
|
|
||||||
visualizerAudioContext.suspend().catch(() => {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureVisualizer() {
|
|
||||||
if (visualizerRoot) return;
|
|
||||||
|
|
||||||
visualizerRoot = document.createElement("div");
|
|
||||||
visualizerRoot.id = "spotui-visualizer";
|
|
||||||
|
|
||||||
visualizerFall = document.createElement("div");
|
|
||||||
visualizerFall.id = "spotui-visualizer-fall";
|
|
||||||
|
|
||||||
visualizerBars = document.createElement("div");
|
|
||||||
visualizerBars.id = "spotui-visualizer-bars";
|
|
||||||
|
|
||||||
visualizerBarEls = [];
|
|
||||||
for (let i = 0; i < VISUALIZER_BAR_COUNT; i += 1) {
|
|
||||||
const bar = document.createElement("div");
|
|
||||||
bar.className = "spotui-viz-bar";
|
|
||||||
bar.style.height = `${8 + (i % 6)}%`;
|
|
||||||
visualizerBars.appendChild(bar);
|
|
||||||
visualizerBarEls.push(bar);
|
|
||||||
}
|
|
||||||
|
|
||||||
visualizerRoot.appendChild(visualizerFall);
|
|
||||||
visualizerRoot.appendChild(visualizerBars);
|
|
||||||
document.body.appendChild(visualizerRoot);
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildVisualizerText() {
|
|
||||||
visualizerFall.innerHTML = "";
|
|
||||||
SPOTUI_ASCII_ART.forEach((line, index) => {
|
|
||||||
const el = document.createElement("div");
|
|
||||||
el.className = "spotui-viz-line";
|
|
||||||
for (const ch of line) {
|
|
||||||
const span = document.createElement("span");
|
|
||||||
span.className = "spotui-viz-char";
|
|
||||||
span.textContent = ch === " " ? "\u00A0" : ch;
|
|
||||||
span.dataset.char = ch;
|
|
||||||
el.appendChild(span);
|
|
||||||
}
|
|
||||||
el.dataset.index = String(index);
|
|
||||||
visualizerFall.appendChild(el);
|
|
||||||
});
|
|
||||||
return Array.from(visualizerFall.children);
|
|
||||||
}
|
|
||||||
|
|
||||||
function animateVisualizerBars() {
|
|
||||||
if (visualizerBarFrame) cancelAnimationFrame(visualizerBarFrame);
|
|
||||||
visualizerBars.style.opacity = "1";
|
|
||||||
|
|
||||||
const seeds = visualizerBarEls.map((_, index) => ({
|
|
||||||
phase: Math.random() * Math.PI * 2,
|
|
||||||
speed: 0.0012 + (index % 7) * 0.00012,
|
|
||||||
swing: 0.38 + (index % 5) * 0.08,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const tryAttachAudio = () => {
|
|
||||||
const AudioCtor = window.AudioContext || window.webkitAudioContext;
|
|
||||||
const audioEl = document.querySelector("audio");
|
|
||||||
if (!AudioCtor || !audioEl) return false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (visualizerAudioElement !== audioEl) {
|
|
||||||
if (visualizerAudioSource) {
|
|
||||||
try {
|
|
||||||
visualizerAudioSource.disconnect();
|
|
||||||
} catch {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
visualizerAudioContext ||= new AudioCtor();
|
|
||||||
visualizerAudioSource = visualizerAudioContext.createMediaElementSource(audioEl);
|
|
||||||
visualizerAnalyser = visualizerAudioContext.createAnalyser();
|
|
||||||
visualizerAnalyser.fftSize = 128;
|
|
||||||
visualizerAnalyser.smoothingTimeConstant = 0.78;
|
|
||||||
visualizerAudioData = new Uint8Array(visualizerAnalyser.frequencyBinCount);
|
|
||||||
visualizerAudioSource.connect(visualizerAnalyser);
|
|
||||||
visualizerAnalyser.connect(visualizerAudioContext.destination);
|
|
||||||
visualizerAudioElement = audioEl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (visualizerAudioContext.state === "suspended") {
|
|
||||||
visualizerAudioContext.resume().catch(() => {});
|
|
||||||
}
|
|
||||||
return Boolean(visualizerAnalyser);
|
|
||||||
} catch {
|
|
||||||
visualizerAnalyser = null;
|
|
||||||
visualizerAudioData = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const tick = () => {
|
|
||||||
if (!visualizerActive || !isPlaybackRunning()) {
|
|
||||||
visualizerBarFrame = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const now = performance.now();
|
|
||||||
const progress = Number(Spicetify?.Player?.getProgress?.() ?? 0);
|
|
||||||
const volume = Number(Spicetify?.Player?.getVolume?.() ?? 0.72);
|
|
||||||
const energyBase = 0.55 + Math.min(0.35, volume * 0.25);
|
|
||||||
const hasAudio = tryAttachAudio();
|
|
||||||
|
|
||||||
if (hasAudio && visualizerAnalyser && visualizerAudioData) {
|
|
||||||
visualizerAnalyser.getByteFrequencyData(visualizerAudioData);
|
|
||||||
const bucketSize = Math.max(1, Math.floor(visualizerAudioData.length / visualizerBarEls.length));
|
|
||||||
visualizerBarEls.forEach((bar, index) => {
|
|
||||||
let sum = 0;
|
|
||||||
let peak = 0;
|
|
||||||
const start = index * bucketSize;
|
|
||||||
const end = Math.min(visualizerAudioData.length, start + bucketSize);
|
|
||||||
for (let i = start; i < end; i += 1) {
|
|
||||||
const value = visualizerAudioData[i] || 0;
|
|
||||||
sum += value;
|
|
||||||
if (value > peak) peak = value;
|
|
||||||
}
|
|
||||||
const avg = sum / Math.max(1, end - start);
|
|
||||||
const height = 10 + (avg * 0.72 + peak * 0.28) * 0.32;
|
|
||||||
bar.style.height = `${Math.max(8, Math.min(100, height))}%`;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
visualizerBarEls.forEach((bar, index) => {
|
|
||||||
const seed = seeds[index];
|
|
||||||
const pulse = Math.sin(now * seed.speed + seed.phase) * 0.5 + 0.5;
|
|
||||||
const trackWave = Math.sin(progress / 140 + index * 0.42 + seed.phase * 0.7) * 0.5 + 0.5;
|
|
||||||
const jitter = (Math.sin(now * 0.0025 + index * 0.18) * 0.5 + 0.5) * 0.18;
|
|
||||||
const height = 10 + (pulse * 0.48 + trackWave * 0.34 + jitter) * (56 + (index % 8) * 2) * energyBase * seed.swing;
|
|
||||||
bar.style.height = `${Math.max(8, Math.min(100, height))}%`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
visualizerBarFrame = requestAnimationFrame(tick);
|
|
||||||
};
|
|
||||||
|
|
||||||
visualizerBarFrame = requestAnimationFrame(tick);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function enterVisualizerMode() {
|
|
||||||
if (visualizerActive || visualizerRequested || popup || document.body.classList.contains("spotui-search-mode") || !isPlaybackRunning()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
visualizerRequested = true;
|
|
||||||
ensureVisualizer();
|
|
||||||
visualizerActive = true;
|
|
||||||
document.body.classList.add("spotui-visualizer-active");
|
|
||||||
document.getElementById("spotui-tui")?.classList.add("spotui-has-visualizer");
|
|
||||||
visualizerBars.style.opacity = "0";
|
|
||||||
|
|
||||||
const lineEls = buildVisualizerText();
|
|
||||||
const charEls = lineEls.flatMap((line) => Array.from(line.children));
|
|
||||||
|
|
||||||
try {
|
|
||||||
const anime = await loadAnime();
|
|
||||||
if (!visualizerActive) {
|
|
||||||
visualizerRequested = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
stopVisualizerAnimations();
|
|
||||||
|
|
||||||
visualizerLineAnims = charEls.map((charEl, index) => {
|
|
||||||
const lineIndex = Number(charEl.parentElement?.dataset.index || 0);
|
|
||||||
const columnIndex = Array.from(charEl.parentElement?.children || []).indexOf(charEl);
|
|
||||||
const dropDistance = 240 + lineIndex * 22 + Math.random() * 160;
|
|
||||||
const spread = (columnIndex - 24) * 2.1 + (Math.random() - 0.5) * 34;
|
|
||||||
const drift = (Math.random() - 0.5) * 10;
|
|
||||||
return anime({
|
|
||||||
targets: charEl,
|
|
||||||
translateY: [0, dropDistance],
|
|
||||||
translateX: [0, spread + drift],
|
|
||||||
rotate: [0, (Math.random() - 0.5) * 58],
|
|
||||||
scale: [1, 0.9],
|
|
||||||
opacity: [0.92, 0],
|
|
||||||
duration: 1200 + lineIndex * 140 + (index % 6) * 45,
|
|
||||||
delay: lineIndex * 130 + columnIndex * 20,
|
|
||||||
easing: "easeInCubic",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
visualizerFallAnim = anime({
|
|
||||||
targets: visualizerFall,
|
|
||||||
opacity: [0, 1],
|
|
||||||
duration: 240,
|
|
||||||
easing: "linear",
|
|
||||||
});
|
|
||||||
|
|
||||||
visualizerBarsTimer = setTimeout(() => {
|
|
||||||
if (!visualizerActive || !isPlaybackRunning()) return;
|
|
||||||
visualizerBars.style.opacity = "1";
|
|
||||||
animateVisualizerBars();
|
|
||||||
}, 2100);
|
|
||||||
} catch {
|
|
||||||
visualizerBars.style.opacity = "1";
|
|
||||||
visualizerBarEls.forEach((bar, index) => {
|
|
||||||
bar.style.height = `${24 + (index % 7) * 8}%`;
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
visualizerRequested = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function exitVisualizerMode() {
|
|
||||||
if (!visualizerActive && !visualizerRequested) return;
|
|
||||||
visualizerActive = false;
|
|
||||||
visualizerRequested = false;
|
|
||||||
document.body.classList.remove("spotui-visualizer-active");
|
|
||||||
document.getElementById("spotui-tui")?.classList.remove("spotui-has-visualizer");
|
|
||||||
stopVisualizerAnimations();
|
|
||||||
if (visualizerBars) visualizerBars.style.opacity = "0";
|
|
||||||
if (visualizerRoot) visualizerRoot.replaceChildren(visualizerFall, visualizerBars);
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearIdleTimer() {
|
|
||||||
if (idleTimer) {
|
|
||||||
clearTimeout(idleTimer);
|
|
||||||
idleTimer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isPlaybackRunning() {
|
|
||||||
return Boolean(Spicetify?.Player?.isPlaying?.());
|
|
||||||
}
|
|
||||||
|
|
||||||
function scheduleIdleTimer() {
|
|
||||||
clearIdleTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
function noteActivity() {
|
|
||||||
clearIdleTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
function createCopyButton() {
|
function createCopyButton() {
|
||||||
const controls = document.createElement("div");
|
const controls = document.createElement("div");
|
||||||
controls.id = "spotui-controls";
|
controls.id = "spotui-controls";
|
||||||
@@ -661,7 +255,6 @@ function createCopyButton() {
|
|||||||
document.body.classList.remove("spotui-tui-hidden");
|
document.body.classList.remove("spotui-tui-hidden");
|
||||||
document.body.classList.remove("spotui-search-mode");
|
document.body.classList.remove("spotui-search-mode");
|
||||||
hideBtn.textContent = "Hide TUI";
|
hideBtn.textContent = "Hide TUI";
|
||||||
noteActivity();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -682,7 +275,6 @@ function createCopyButton() {
|
|||||||
spotifyBtn.textContent = "Enable Spotify";
|
spotifyBtn.textContent = "Enable Spotify";
|
||||||
hideBtn.textContent = "Hide TUI";
|
hideBtn.textContent = "Hide TUI";
|
||||||
syncLyricsState();
|
syncLyricsState();
|
||||||
noteActivity();
|
|
||||||
});
|
});
|
||||||
document.body.appendChild(backBtn);
|
document.body.appendChild(backBtn);
|
||||||
}
|
}
|
||||||
@@ -774,9 +366,7 @@ Type /help
|
|||||||
document.body.appendChild(box);
|
document.body.appendChild(box);
|
||||||
|
|
||||||
const input = document.getElementById("spotui-input");
|
const input = document.getElementById("spotui-input");
|
||||||
input.addEventListener("input", noteActivity);
|
|
||||||
input.addEventListener("keydown", async (e) => {
|
input.addEventListener("keydown", async (e) => {
|
||||||
noteActivity();
|
|
||||||
if (e.key === "Enter") {
|
if (e.key === "Enter") {
|
||||||
const cmd = input.value.trim();
|
const cmd = input.value.trim();
|
||||||
input.value = "";
|
input.value = "";
|
||||||
@@ -793,7 +383,6 @@ Type /help
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener("pointerdown", noteActivity, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function print(text) {
|
function print(text) {
|
||||||
@@ -834,7 +423,6 @@ async function execute(cmd) {
|
|||||||
}
|
}
|
||||||
if (command === "clear") {
|
if (command === "clear") {
|
||||||
document.getElementById("spotui-output").textContent = "";
|
document.getElementById("spotui-output").textContent = "";
|
||||||
noteActivity();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -894,7 +482,6 @@ async function execute(cmd) {
|
|||||||
document.body.classList.add("spotui-search-mode");
|
document.body.classList.add("spotui-search-mode");
|
||||||
document.body.classList.add("spotui-tui-hidden");
|
document.body.classList.add("spotui-tui-hidden");
|
||||||
syncLyricsState();
|
syncLyricsState();
|
||||||
clearIdleTimer();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1078,12 +665,10 @@ async function getPlaylists() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function openPlaylistPopup() {
|
async function openPlaylistPopup() {
|
||||||
clearIdleTimer();
|
|
||||||
try {
|
try {
|
||||||
playlists = await getPlaylists();
|
playlists = await getPlaylists();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
print("Playlist error: " + err.message);
|
print("Playlist error: " + err.message);
|
||||||
scheduleIdleTimer();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
popupSelected = 0;
|
popupSelected = 0;
|
||||||
@@ -1092,12 +677,10 @@ async function openPlaylistPopup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function openPlaylistTracksPopup() {
|
async function openPlaylistTracksPopup() {
|
||||||
clearIdleTimer();
|
|
||||||
try {
|
try {
|
||||||
const contextUri = getCurrentPlaylistContextUri();
|
const contextUri = getCurrentPlaylistContextUri();
|
||||||
if (!contextUri || !Spicetify.URI.isPlaylistV1OrV2(contextUri)) {
|
if (!contextUri || !Spicetify.URI.isPlaylistV1OrV2(contextUri)) {
|
||||||
print("List error: not currently playing a playlist.");
|
print("List error: not currently playing a playlist.");
|
||||||
scheduleIdleTimer();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const res = await Spicetify.Platform.PlaylistAPI.getContents(contextUri, {
|
const res = await Spicetify.Platform.PlaylistAPI.getContents(contextUri, {
|
||||||
@@ -1117,7 +700,6 @@ async function openPlaylistTracksPopup() {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
print("List error: " + err.message);
|
print("List error: " + err.message);
|
||||||
console.error("Playlist tracks popup error:", err);
|
console.error("Playlist tracks popup error:", err);
|
||||||
scheduleIdleTimer();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1150,7 +732,6 @@ function getQueueTracks() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function openQueuePopup() {
|
function openQueuePopup() {
|
||||||
clearIdleTimer();
|
|
||||||
const currentQueueTracks = getQueueTracks();
|
const currentQueueTracks = getQueueTracks();
|
||||||
if (!lastQueueSnapshot || lastQueueSnapshot.length === 0) {
|
if (!lastQueueSnapshot || lastQueueSnapshot.length === 0) {
|
||||||
lastQueueSnapshot = currentQueueTracks;
|
lastQueueSnapshot = currentQueueTracks;
|
||||||
@@ -1175,7 +756,6 @@ function closePopup() {
|
|||||||
popupTrackContext = null;
|
popupTrackContext = null;
|
||||||
const input = document.getElementById("spotui-input");
|
const input = document.getElementById("spotui-input");
|
||||||
if (input) input.focus();
|
if (input) input.focus();
|
||||||
scheduleIdleTimer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderPopup() {
|
function renderPopup() {
|
||||||
|
|||||||
Reference in New Issue
Block a user