New Features
* Implements Terminal
This commit is contained in:
217
player.js
217
player.js
@@ -9,6 +9,11 @@
|
||||
let refreshBtn = document.querySelector(".refresh");
|
||||
let ovr = document.querySelector(".OVR");
|
||||
let fullScreenBtn = document.querySelector(".fullscreen");
|
||||
let terminalBtn = document.querySelector(".terminal-btn");
|
||||
let terminalOverlay = document.getElementById("terminal-overlay");
|
||||
let terminalInput = document.getElementById("terminal-input");
|
||||
let terminalOutput = document.getElementById("terminal-output");
|
||||
let terminalClose = document.querySelector(".terminal-close");
|
||||
let errorEl = document.querySelector(".ERRORS");
|
||||
let currentEffectIndex = 0;
|
||||
const modalEl = document.getElementById("intro-modal");
|
||||
@@ -113,15 +118,15 @@
|
||||
});
|
||||
|
||||
document.addEventListener("keyup", (event) => {
|
||||
if (!terminalOverlay.classList.contains("hidden")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { key } = event;
|
||||
switch (key) {
|
||||
case " ":
|
||||
togglePlay();
|
||||
break;
|
||||
case "a":
|
||||
break;
|
||||
case "d":
|
||||
break;
|
||||
case "w":
|
||||
volumeUp();
|
||||
break;
|
||||
@@ -143,6 +148,9 @@
|
||||
case "e":
|
||||
rotateHydraEffect();
|
||||
break;
|
||||
case "t":
|
||||
toggleTerminal();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -255,10 +263,11 @@
|
||||
}
|
||||
|
||||
function updateInfo(trackDetails) {
|
||||
titleEl.innerText = trackDetails.title;
|
||||
document.title = `Now Playing... ${trackDetails.title}`;
|
||||
const trackTitle = trackDetails.title.toString().toUpperCase() || "Unknown Track";
|
||||
titleEl.innerText = trackTitle;
|
||||
document.title = `Now Playing... ${trackTitle}`;
|
||||
coverArtEl.style.backgroundImage = `url("${retroWaveRu}${trackDetails.artworkUrl}")`;
|
||||
ovr.innerHTML = `${trackDetails.title}`;
|
||||
ovr.innerHTML = `> ${trackTitle}`;
|
||||
}
|
||||
|
||||
function getHistory() {
|
||||
@@ -324,6 +333,27 @@ https://retrowave.ru/${musicData.streamUrl}
|
||||
fullScreenBtn.addEventListener("click", () => {
|
||||
toggleFullScreen();
|
||||
});
|
||||
|
||||
terminalBtn.addEventListener("click", () => {
|
||||
toggleTerminal();
|
||||
});
|
||||
|
||||
terminalClose.addEventListener("click", () => {
|
||||
closeTerminal();
|
||||
});
|
||||
|
||||
terminalInput.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Enter") {
|
||||
executeCommand(terminalInput.value.trim());
|
||||
terminalInput.value = "";
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Escape" && !terminalOverlay.classList.contains("hidden")) {
|
||||
closeTerminal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function toggleFullScreen() {
|
||||
@@ -469,4 +499,177 @@ https://retrowave.ru/${musicData.streamUrl}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleTerminal() {
|
||||
terminalOverlay.classList.toggle("hidden");
|
||||
if (!terminalOverlay.classList.contains("hidden")) {
|
||||
terminalInput.focus();
|
||||
}
|
||||
}
|
||||
|
||||
function closeTerminal() {
|
||||
terminalOverlay.classList.add("hidden");
|
||||
}
|
||||
|
||||
function addTerminalLine(text, isCommand = false) {
|
||||
const line = document.createElement("div");
|
||||
line.className = "terminal-line";
|
||||
if (isCommand) {
|
||||
line.innerHTML = `<span style="color: #000000; font-weight: normal;">indrajith@retrowave:$ ${text}</span>`;
|
||||
} else {
|
||||
line.textContent = text;
|
||||
}
|
||||
terminalOutput.appendChild(line);
|
||||
terminalOutput.scrollTop = terminalOutput.scrollHeight;
|
||||
}
|
||||
|
||||
function executeCommand(command) {
|
||||
if (!command) return;
|
||||
|
||||
addTerminalLine(command, true);
|
||||
|
||||
const args = command.toLowerCase().split(' ');
|
||||
const cmd = args[0];
|
||||
|
||||
switch (cmd) {
|
||||
case 'help':
|
||||
addTerminalLine('Available commands:');
|
||||
addTerminalLine(' help - Show this help message');
|
||||
addTerminalLine(' play - Start/resume playback');
|
||||
addTerminalLine(' pause - Pause playback');
|
||||
addTerminalLine(' next - Skip to next track');
|
||||
addTerminalLine(' volume [0-10] - Set volume (0-10)');
|
||||
addTerminalLine(' status - Show current track info');
|
||||
addTerminalLine(' history - Download playlist history');
|
||||
addTerminalLine(' effect [list|name] - Change/list visual effects');
|
||||
addTerminalLine(' fullscreen - Toggle fullscreen mode');
|
||||
addTerminalLine(' clear - Clear terminal');
|
||||
addTerminalLine(' exit - Close terminal');
|
||||
break;
|
||||
|
||||
case 'play':
|
||||
if (howlerInstance && !isPlaying) {
|
||||
togglePlay();
|
||||
addTerminalLine('Playback resumed.');
|
||||
} else if (isPlaying) {
|
||||
addTerminalLine('Already playing.');
|
||||
} else {
|
||||
addTerminalLine('No track loaded.');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'pause':
|
||||
if (howlerInstance && isPlaying) {
|
||||
togglePlay();
|
||||
addTerminalLine('Playback paused.');
|
||||
} else {
|
||||
addTerminalLine('Not currently playing.');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'next':
|
||||
if (howlerInstance) {
|
||||
playNextTrack();
|
||||
addTerminalLine('Skipped to next track.');
|
||||
} else {
|
||||
addTerminalLine('No track loaded.');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'volume':
|
||||
if (args[1]) {
|
||||
const vol = parseInt(args[1]);
|
||||
if (vol >= 0 && vol <= 10) {
|
||||
volume = vol / 10;
|
||||
if (howlerInstance) setVolume();
|
||||
addTerminalLine(`Volume set to ${vol}/10`);
|
||||
} else {
|
||||
addTerminalLine('Volume must be between 0 and 10.');
|
||||
}
|
||||
} else {
|
||||
addTerminalLine(`Current volume: ${Math.round(volume * 10)}/10`);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'status':
|
||||
if (currentTracks.length > 0) {
|
||||
const track = currentTracks[0];
|
||||
addTerminalLine(`Now playing: ${track.title}`);
|
||||
addTerminalLine(`Status: ${isPlaying ? 'Playing' : 'Paused'}`);
|
||||
addTerminalLine(`Volume: ${Math.round(volume * 10)}/10`);
|
||||
} else {
|
||||
addTerminalLine('No track loaded.');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'history':
|
||||
downloadHistory();
|
||||
addTerminalLine('Playlist history downloaded.');
|
||||
break;
|
||||
|
||||
case 'effect':
|
||||
if (args[1]) {
|
||||
if (args[1] === 'list') {
|
||||
addTerminalLine('Available effects:');
|
||||
addTerminalLine(' vernoi - Voronoi pattern effect');
|
||||
addTerminalLine(' waveyzz - Wave synthesis effect');
|
||||
addTerminalLine(' oscrotate - Oscillating rotation effect');
|
||||
addTerminalLine('Usage: effect <effect_name> or effect list');
|
||||
} else {
|
||||
const effectName = args[1].toLowerCase();
|
||||
let effectIndex = -1;
|
||||
|
||||
switch (effectName) {
|
||||
case 'vernoi':
|
||||
effectIndex = 0;
|
||||
break;
|
||||
case 'waveyzz':
|
||||
effectIndex = 1;
|
||||
break;
|
||||
case 'oscrotate':
|
||||
effectIndex = 2;
|
||||
break;
|
||||
default:
|
||||
addTerminalLine(`Unknown effect: ${effectName}`);
|
||||
addTerminalLine('Type "effect list" to see available effects.');
|
||||
break;
|
||||
}
|
||||
|
||||
if (effectIndex !== -1) {
|
||||
try {
|
||||
hydraEffects[effectIndex]();
|
||||
currentEffectIndex = effectIndex;
|
||||
addTerminalLine(`Effect changed to: ${effectName}`);
|
||||
} catch (error) {
|
||||
addTerminalLine('Failed to apply effect.');
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rotateHydraEffect();
|
||||
addTerminalLine('Visualization changed to next effect.');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'fullscreen':
|
||||
toggleFullScreen();
|
||||
addTerminalLine('Toggled fullscreen mode.');
|
||||
break;
|
||||
|
||||
case 'clear':
|
||||
terminalOutput.innerHTML = '';
|
||||
break;
|
||||
|
||||
case 'exit':
|
||||
closeTerminal();
|
||||
break;
|
||||
|
||||
default:
|
||||
addTerminalLine(`Command not found: ${cmd}`);
|
||||
addTerminalLine('Type "help" for available commands.');
|
||||
break;
|
||||
}
|
||||
|
||||
addTerminalLine('');
|
||||
}
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user