toggle official and remove are index addressed

This commit is contained in:
2026-05-23 17:17:44 +02:00
parent 9044a31cc0
commit f205dd41f9
3 changed files with 34 additions and 9 deletions
+17 -4
View File
@@ -157,11 +157,24 @@ class Module(ActiveModifier):
with open(TOPLAY, "w") as f: f.write("") with open(TOPLAY, "w") as f: f.write("")
return {"status": "ok", "data": []} return {"status": "ok", "data": []}
elif data.get("action") == "remove_toplay": elif data.get("action") == "remove_toplay":
targets = data.get("songs", []) targets = data.get("indexes", [])
with self.file_lock: with self.file_lock:
with open(TOPLAY, "r") as f: with open(TOPLAY, "r") as f: lines = [l.strip() for l in f.readlines() if l.strip()]
lines = [l.strip() for l in f.readlines() if l.strip()] if isinstance(targets, list):
lines = [l for l in lines if l not in targets and l not in targets] target_set = set(targets)
lines = [l for i, l in enumerate(lines) if i not in target_set]
with open(TOPLAY, "w") as f: f.write('\n'.join(lines) + "\n")
return {"status": "ok", "data": lines}
elif data.get("action") == "toggle_official_toplay":
targets = data.get("indexes", [])
with self.file_lock:
with open(TOPLAY, "r") as f: lines = [l.strip() for l in f.readlines() if l.strip()]
if isinstance(targets, list):
target_set = set(targets)
for i in target_set:
if 0 <= i < len(lines):
if lines[i].startswith("!"): lines[i] = lines[i][1:]
else: lines[i] = "!" + lines[i]
with open(TOPLAY, "w") as f: f.write('\n'.join(lines) + "\n") with open(TOPLAY, "w") as f: f.write('\n'.join(lines) + "\n")
return {"status": "ok", "data": lines} return {"status": "ok", "data": lines}
elif data.get("action") == "skipc": elif data.get("action") == "skipc":
+9 -3
View File
@@ -60,7 +60,7 @@ async def ws_handler(websocket: ServerConnection, shared_data: dict, imc_q: mult
if action == "skip": if action == "skip":
imc_q.put({"name": "procman", "data": {"op": 2}}) imc_q.put({"name": "procman", "data": {"op": 2}})
await websocket.send(json.dumps({"event": "skip"})) await websocket.send(json.dumps({"event": "skip"}))
elif action == "add_to_toplay" or action == "remove_toplay": elif action == "add_to_toplay":
songs = msg.get("songs") songs = msg.get("songs")
at_top = msg.get("top", False) at_top = msg.get("top", False)
if not isinstance(songs, list): await websocket.send(json.dumps({"error": "songs must be a list"})) if not isinstance(songs, list): await websocket.send(json.dumps({"error": "songs must be a list"}))
@@ -69,6 +69,14 @@ async def ws_handler(websocket: ServerConnection, shared_data: dict, imc_q: mult
result = await get_imc("activemod", {"action": "get_toplay"}) result = await get_imc("activemod", {"action": "get_toplay"})
if result is not None: if result is not None:
await broadcast({"data": result, "event": "toplay"}) 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"}))
else:
imc_q.put({"name": "activemod", "data": {"action": action, "indexes": idx}})
result = await get_imc("activemod", {"action": "get_toplay"})
if result is not None:
await broadcast({"data": result, "event": "toplay"})
elif action == "get_toplay": elif action == "get_toplay":
result = await get_imc("activemod", {"action": "get_toplay"}) result = await get_imc("activemod", {"action": "get_toplay"})
if result is None: await websocket.send(json.dumps({"error": "timeout", "code": 504})) if result is None: await websocket.send(json.dumps({"error": "timeout", "code": 504}))
@@ -142,7 +150,6 @@ async def ws_handler(websocket: ServerConnection, shared_data: dict, imc_q: mult
else: else:
locks[lid] = websocket locks[lid] = websocket
await broadcast({"event": "lock", "id": lid, "data": True}) await broadcast({"event": "lock", "id": lid, "data": True})
elif action == "unlock": elif action == "unlock":
lid = msg.get("id") lid = msg.get("id")
if lid is None: if lid is None:
@@ -153,7 +160,6 @@ async def ws_handler(websocket: ServerConnection, shared_data: dict, imc_q: mult
else: else:
locks[lid] = None locks[lid] = None
await broadcast({"event": "lock", "id": lid, "data": False}) await broadcast({"event": "lock", "id": lid, "data": False})
else: await websocket.send(json.dumps({"event": "error", "error": "unknown action"})) else: await websocket.send(json.dumps({"event": "error", "error": "unknown action"}))
finally: finally:
# release every lock this client held on disconnect # release every lock this client held on disconnect
+8 -2
View File
@@ -227,9 +227,10 @@ function renderPlaylist() {
function renderQueue() { function renderQueue() {
const ul = document.getElementById("queue-ul"); const ul = document.getElementById("queue-ul");
ul.innerHTML = ""; ul.innerHTML = "";
var i = 0;
queue.forEach(path => { queue.forEach(path => {
const li = document.createElement("li"); const li = document.createElement("li");
li.dataset.line = path; li.dataset.idx = i++;
var c = path.replace(basePath, ""); var c = path.replace(basePath, "");
if(c.startsWith("!")) c = "(unofficial) " + c.slice(2) if(c.startsWith("!")) c = "(unofficial) " + c.slice(2)
@@ -241,9 +242,14 @@ function renderQueue() {
} }
li.addEventListener("click", () => { li.addEventListener("click", () => {
wsSend({ action: "remove_toplay", songs: [li.dataset.line] }); wsSend({ action: "remove_toplay", indexes: [li.dataset.idx] });
renderAll(); renderAll();
}); });
li.addEventListener("contextmenu", e => {
e.preventDefault();
wsSend({ action: "toggle_official_toplay", indexes: [li.dataset.idx] });
renderAll();
})
ul.appendChild(li); ul.appendChild(li);
}); });
updateControls(); updateControls();