mirror of
https://github.com/radio95-rnt/RadioPlayer.git
synced 2026-07-29 07:09:15 +02:00
some ui changes
This commit is contained in:
+1
-1
@@ -71,7 +71,7 @@ async def ws_handler(websocket: ServerConnection, shared_data: dict, imc_q: mult
|
||||
await broadcast({"data": result, "event": "toplay"})
|
||||
elif action == "remove_toplay" or action == "toggle_official_toplay":
|
||||
idx = msg.get("indexes")
|
||||
if not isinstance(songs, list): await websocket.send(json.dumps({"error": "songs must be a list"}))
|
||||
if not isinstance(idx, list): await websocket.send(json.dumps({"error": "indexes must be a list"}))
|
||||
else:
|
||||
imc_q.put({"name": "activemod", "data": {"action": action, "indexes": idx}})
|
||||
result = await get_imc("activemod", {"action": "get_toplay"})
|
||||
|
||||
@@ -193,7 +193,6 @@
|
||||
<button id="skpn-inc" class="btn" style="padding:4px 10px;border:none">+</button>
|
||||
</div>
|
||||
<button id="jingle-btn" class="btn">🕭 Jingle</button>
|
||||
<button id="skipidx-btn" class="btn">⏭+ Skip in playlist</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -251,10 +250,6 @@
|
||||
<div class="collapsible-content listbox" id="subdir-box"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:8px; display: flex; gap: 8px;">
|
||||
<button id="add-to-queue-btn" class="btn primary" style="flex: 1;">Add to Bottom ▼</button>
|
||||
<button id="add-to-queue2-btn" class="btn primary" style="flex: 1;">Add to Top ▲</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
+19
-108
@@ -4,10 +4,8 @@ let playlist = [];
|
||||
let queue = [];
|
||||
let currentTrackPath = "";
|
||||
let currentTrackIndex = 0;
|
||||
let selectedPlaylistPath = null;
|
||||
let selectedPlaylistIndex = null;
|
||||
let selectedDir = null;
|
||||
let selectedSubFile = null;
|
||||
let basePath = "";
|
||||
let subBasePath = "";
|
||||
let skipCount = 0;
|
||||
@@ -231,7 +229,7 @@ function renderQueue() {
|
||||
queue.forEach(path => {
|
||||
const li = document.createElement("li");
|
||||
li.dataset.idx = i++;
|
||||
|
||||
|
||||
var c = path.replace(basePath, "");
|
||||
if(c.startsWith("!")) c = "(unofficial) " + c.slice(2)
|
||||
else c = "(official) " + c.slice(1)
|
||||
@@ -260,34 +258,26 @@ function updateDirs(payload) {
|
||||
box.innerHTML = "";
|
||||
basePath = payload.base || "";
|
||||
|
||||
const addItem = (name, onClick) => {
|
||||
const addItem = (name, onClick, onContext) => {
|
||||
const node = document.createElement("div");
|
||||
node.className = "item";
|
||||
node.textContent = name;
|
||||
node.addEventListener("click", () => onClick(node));
|
||||
node.addEventListener("click", (e) => onClick(node, e));
|
||||
if(onContext !== undefined) node.addEventListener("contextmenu", () => onContext(node, e));
|
||||
box.appendChild(node);
|
||||
};
|
||||
|
||||
(payload.dirs || []).sort().forEach(name => {
|
||||
if (!name.startsWith(".")) addItem(name, node => onDirClicked(name, node));
|
||||
if (!name.startsWith(".")) addItem(name, (node, e) => onDirClicked(name, node));
|
||||
});
|
||||
|
||||
(payload.files || []).sort().forEach(name => {
|
||||
if (!name.startsWith(".")) {
|
||||
addItem(name, node => {
|
||||
if (node.classList.contains("selected")) {
|
||||
node.classList.remove("selected");
|
||||
selectedDir = null;
|
||||
selectedSubFile = null;
|
||||
return;
|
||||
}
|
||||
clearListSelections("playlist-ul", "subdir-box");
|
||||
Array.from(box.children).forEach(c => c.classList.remove("selected"));
|
||||
node.classList.add("selected");
|
||||
node.dataset.type = "file";
|
||||
selectedDir = null;
|
||||
selectedSubFile = null;
|
||||
document.getElementById("subdir-box").innerHTML = "";
|
||||
addItem(name, () => {
|
||||
wsSend({ action: "add_to_toplay", songs: [basePath.replace(/\/$/, "") + "/" + name], top: false })
|
||||
}, (node, e) => {
|
||||
e.preventDefault()
|
||||
wsSend({ action: "add_to_toplay", songs: [basePath.replace(/\/$/, "") + "/" + name], top: true })
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -297,14 +287,12 @@ function onDirClicked(name, node) {
|
||||
if (node.classList.contains("selected")) {
|
||||
node.classList.remove("selected");
|
||||
selectedDir = null;
|
||||
selectedSubFile = null;
|
||||
document.getElementById("subdir-box").innerHTML = "";
|
||||
return;
|
||||
}
|
||||
clearListSelections("dirs-box", "playlist-ul");
|
||||
node.classList.add("selected");
|
||||
selectedDir = name;
|
||||
selectedSubFile = null;
|
||||
wsSend({ action: "request_dir", what: selectedDir });
|
||||
}
|
||||
|
||||
@@ -319,91 +307,26 @@ function applySubdir(payload) {
|
||||
node.className = "item";
|
||||
node.textContent = f;
|
||||
node.addEventListener("click", () => {
|
||||
if (node.classList.contains("selected")) {
|
||||
node.classList.remove("selected");
|
||||
selectedSubFile = null;
|
||||
return;
|
||||
}
|
||||
clearListSelections("subdir-box", "playlist-ul");
|
||||
Array.from(document.getElementById("dirs-box").children).forEach(c => c.classList.remove("selected"));
|
||||
|
||||
// Re-select the parent dir node
|
||||
Array.from(document.getElementById("dirs-box").children).forEach(c => {
|
||||
if (c.textContent === selectedDir) c.classList.add("selected");
|
||||
});
|
||||
|
||||
node.classList.add("selected");
|
||||
selectedSubFile = f;
|
||||
wsSend({ action: "add_to_toplay", songs: [subBasePath.replace(/\/$/, "") + "/" + f], top: false });
|
||||
});
|
||||
node.addEventListener("contextmenu", (e) => {
|
||||
e.preventDefault()
|
||||
wsSend({ action: "add_to_toplay", songs: [subBasePath.replace(/\/$/, "") + "/" + f], top: true });
|
||||
});
|
||||
box.appendChild(node);
|
||||
});
|
||||
}
|
||||
|
||||
function selectPlaylistItem(i, el) {
|
||||
const path = el.dataset.path;
|
||||
if (el.classList.contains("selected")) {
|
||||
el.classList.remove("selected");
|
||||
selectedPlaylistPath = null;
|
||||
updateControls();
|
||||
return;
|
||||
}
|
||||
clearListSelections("playlist-ul", "dirs-box", "subdir-box");
|
||||
el.classList.add("selected");
|
||||
selectedPlaylistPath = path;
|
||||
selectedPlaylistIndex = i;
|
||||
const action = skippedIndices.includes(i)
|
||||
? { action: "skipi", remove: i }
|
||||
: { action: "skipi", add: i };
|
||||
wsSend(action);
|
||||
updateControls();
|
||||
}
|
||||
|
||||
function addSelectedFileToQueue(top) {
|
||||
let fullPath = null;
|
||||
|
||||
if (selectedPlaylistPath != null) {
|
||||
const selected = playlist.find(t => t.path === selectedPlaylistPath);
|
||||
if (!selected) return false;
|
||||
const path = (selected.official ? "" : "!") + selected.path;
|
||||
wsSend({ action: "add_to_toplay", songs: [path], top });
|
||||
clearListSelections("playlist-ul");
|
||||
selectedPlaylistPath = null;
|
||||
selectedPlaylistIndex = null;
|
||||
updateControls();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (selectedSubFile && selectedDir) {
|
||||
fullPath = subBasePath.replace(/\/$/, "") + "/" + selectedSubFile;
|
||||
} else {
|
||||
const selectedFileEl = Array.from(document.getElementById("dirs-box").children).find(el => el.classList.contains("selected") && el.dataset.type === "file");
|
||||
if (selectedFileEl) {
|
||||
fullPath = basePath.replace(/\/$/, "") + "/" + selectedFileEl.textContent;
|
||||
}
|
||||
}
|
||||
|
||||
if (fullPath) {
|
||||
wsSend({ action: "add_to_toplay", songs: [fullPath], top });
|
||||
// Dir/subdir selections are intentionally preserved here
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function updateControls() {
|
||||
document.getElementById("clear-btn").disabled = queue.length === 0;
|
||||
|
||||
const btn = document.getElementById("skipidx-btn");
|
||||
if (selectedPlaylistIndex == null) {
|
||||
btn.textContent = "⏭+ Skip in playlist";
|
||||
btn.disabled = true;
|
||||
btn.classList.remove("activated");
|
||||
} else if (skippedIndices.includes(selectedPlaylistIndex)) {
|
||||
btn.textContent = "✓ Unskip in playlist";
|
||||
btn.disabled = false;
|
||||
btn.classList.add("activated");
|
||||
} else {
|
||||
btn.textContent = "⏭+ Skip in playlist";
|
||||
btn.disabled = false;
|
||||
btn.classList.remove("activated");
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("skip-btn").addEventListener("click", () => wsSend({ action: "skip" }));
|
||||
@@ -416,26 +339,14 @@ document.getElementById("jingle-btn").addEventListener("contextmenu", e => {
|
||||
wsSend({ action: "jingle", top: true });
|
||||
});
|
||||
|
||||
document.getElementById("skipidx-btn").addEventListener("click", () => {
|
||||
if (selectedPlaylistIndex == null) return;
|
||||
const action = skippedIndices.includes(selectedPlaylistIndex)
|
||||
? { action: "skipi", remove: selectedPlaylistIndex }
|
||||
: { action: "skipi", add: selectedPlaylistIndex };
|
||||
wsSend(action);
|
||||
});
|
||||
|
||||
document.getElementById("queue-title").addEventListener("click", () => toggleSection("section-queue"));
|
||||
document.getElementById("clear-btn").addEventListener("click", e => {
|
||||
e.stopPropagation();
|
||||
wsSend({ action: "clear_toplay" });
|
||||
});
|
||||
|
||||
document.getElementById("add-to-queue-btn").addEventListener("click", () => addSelectedFileToQueue(false));
|
||||
document.getElementById("add-to-queue2-btn").addEventListener("click", () => addSelectedFileToQueue(true));
|
||||
|
||||
document.addEventListener("keydown", e => {
|
||||
if (e.target.tagName === "INPUT") return;
|
||||
if (e.key === "Enter" && addSelectedFileToQueue(e.shiftKey)) e.preventDefault();
|
||||
else if (e.key === "s") wsSend({ action: "skip" });
|
||||
else if (e.key === "n") wsSend({ action: "skipc", add: 1 });
|
||||
else if (e.key === "m") wsSend({ action: "skipc", remove: -1 });
|
||||
|
||||
Reference in New Issue
Block a user