diff --git a/modules/active_modifier.py b/modules/active_modifier.py index baf4d0a..84a99ec 100644 --- a/modules/active_modifier.py +++ b/modules/active_modifier.py @@ -131,7 +131,7 @@ class Module(ActiveModifier): def imc(self, imc: InterModuleCommunication) -> None: super().imc(imc) - self._imc.register(self, "activemod") + imc.register(self, "activemod") def imc_data(self, source: BaseIMCModule, source_name: str | None, data: object, broadcast: bool) -> object: if not isinstance(data, dict) or broadcast: return @@ -154,14 +154,16 @@ class Module(ActiveModifier): with open(TOPLAY, "r") as f: return {"status": "ok", "data": [i.strip() for i in f.readlines() if i.strip()]} elif data.get("action") == "clear_toplay": with self.file_lock: - # Due to policy, i will not recommend to strip the next song but only the songs after. + with open(TOPLAY, "w") as f: f.write("") + return {"status": "ok", "data": []} + elif data.get("action") == "remove_toplay": + targets = data.get("songs", []) + with self.file_lock: with open(TOPLAY, "r") as f: - first_line, i = "", 0 - while not first_line.strip() and i < 3: - first_line = f.readline() - i += 1 - with open(TOPLAY, "w") as f: f.write(first_line.strip() + "\n") - return {"status": "ok", "data": [first_line.strip()]} + lines = [l.strip() for l in f.readlines() if l.strip()] + lines = [l for l in lines if l not in targets and l not in targets] + with open(TOPLAY, "w") as f: f.write('\n'.join(lines) + "\n") + return {"status": "ok", "data": lines} elif data.get("action") == "skipc": if (count := data.get("set", -1)) > -1: self.skip_next = count if (count2 := data.get("add", None)): self.skip_next += count2 diff --git a/modules/web.py b/modules/web.py index fcfed4c..f3f005a 100644 --- a/modules/web.py +++ b/modules/web.py @@ -60,12 +60,12 @@ async def ws_handler(websocket: ServerConnection, shared_data: dict, imc_q: mult if action == "skip": imc_q.put({"name": "procman", "data": {"op": 2}}) await websocket.send(json.dumps({"event": "skip"})) - elif action == "add_to_toplay": + elif action == "add_to_toplay" or action == "remove_toplay": songs = msg.get("songs") at_top = msg.get("top", False) if not isinstance(songs, list): await websocket.send(json.dumps({"error": "songs must be a list"})) else: - imc_q.put({"name": "activemod", "data": {"action": "add_to_toplay", "songs": songs, "top": at_top}}) + imc_q.put({"name": "activemod", "data": {"action": action, "songs": songs, "top": at_top}}) result = await get_imc("activemod", {"action": "get_toplay"}) if result is not None: await broadcast({"data": result, "event": "toplay"}) diff --git a/modules/web/index.html b/modules/web/index.html index 53ddd82..7325017 100644 --- a/modules/web/index.html +++ b/modules/web/index.html @@ -51,6 +51,8 @@ ul.playlist li.selected{background:rgba(62, 165, 255, 0.305)} ul.playlist li.pointer{background:rgba(255,255,255,0.04)} + #queue-ul li:hover {text-decoration: line-through;} + .controls{display:flex; gap:4px; margin-top:4px} .listbox{ diff --git a/modules/web/web.js b/modules/web/web.js index c741f36..d149b59 100644 --- a/modules/web/web.js +++ b/modules/web/web.js @@ -214,17 +214,13 @@ function renderPlaylist() { li.style.textDecoration = "line-through"; skipCountToRender--; } - if (skippedIndices.includes(i)) { - li.style.textDecoration = "line-through"; - } + if (skippedIndices.includes(i)) li.style.textDecoration = "line-through"; li.textContent = `${i === currentTrackIndex ? "▶ " : " "}${String(i).padStart(indexDigits, "0")}: ${displayPath}`; ul.appendChild(li); }); - if (currentIndex !== null) { - ul.children[currentIndex]?.scrollIntoView({ block: "center", behavior: "smooth" }); - } + if (currentIndex !== null) ul.children[currentIndex]?.scrollIntoView({ block: "center", behavior: "smooth" }); updateControls(); } @@ -234,6 +230,8 @@ function renderQueue() { queue.forEach(path => { const li = document.createElement("li"); var c = path.replace(basePath, ""); + li.dataset.line = c; + if(c.startsWith("!")) c = "(unofficial) " + c.slice(2) else c = "(official) " + c.slice(1) li.textContent = c; @@ -241,6 +239,11 @@ function renderQueue() { li.style.textDecoration = "line-through"; skipCountToRender--; } + + li.addEventListener("click", () => { + wsSend({ action: "remove_toplay", songs: [li.dataset.line] }); + renderAll(); + }); ul.appendChild(li); }); updateControls();