diff --git a/flipstreamviewer.py b/flipstreamviewer.py index ded6090..e31e8ae 100644 --- a/flipstreamviewer.py +++ b/flipstreamviewer.py @@ -170,8 +170,20 @@ div#presetXorkeyInputDiv { display: none; } -.FlipStreamPreviewBox { +.FlipStreamPasteBox { + border: 1px dimgray; max-width: 100%; + min-height: 2em; + max-height: 8em; + object-fit: scale-down; +} + +.FlipStreamPreviewBox { + border: 1px dimgray; + max-width: 100%; + min-height: 2em; + max-height: 8em; + object-fit: scale-down; } .FlipStreamPreviewRoi { @@ -785,6 +797,23 @@ function detailsState() { } detailsState(); +function onPasteBox() { + document.querySelectorAll('.FlipStreamPasteBox').forEach(i => { + i.tabIndex = 0; + i.onclick = () => i.focus(); + i.onpaste = e => { + const f = e.clipboardData.files[0]; + if (f?.type[0] == 'i') fetch(`/flipstreamviewer/paste_upload?label=${i.name}`, {method:'POST', body:f}); + }; + i.onkeydown = e => { + if (e.key === 'Delete' || e.key === 'Backspace') { + fetch(`/flipstreamviewer/paste_remove?label=${i.name}`, {method:'POST'}); + } + }; + }); +} +onPasteBox(); + function toggleView() { const leftPanel = document.getElementById("leftPanel"); const rightPanel = document.getElementById("rightPanel"); @@ -819,6 +848,7 @@ function hideView() { messageBox.style.visibility = "hidden"; document.getElementById("loraPreview").src = ""; document.querySelectorAll('.FlipStreamPreviewBox').forEach(x => x.src = ""); + document.querySelectorAll('.FlipStreamPasteBox').forEach(x => x.src = ""); leftPanel.style.visibility = "hidden"; centerPanel.style.visibility = "hidden"; rightPanel.style.visibility = "hidden"; @@ -876,6 +906,11 @@ async function refreshView() { x.src = `/flipstreamviewer/preview?label=${x.name}&mtime=${data.preview_mtime[x.id] || 0}`; } }); + document.querySelectorAll('.FlipStreamPasteBox').forEach(async x => { + if (x.src != "") { + x.src = `/flipstreamviewer/paste?label=${x.name}&mtime=${data.paste_mtime[x.id] || 0}`; + } + }); const response = await fetch('/flipstreamviewer/stream/info'); streamInfo = await response.json(); @@ -1044,7 +1079,7 @@ async def preview(request): if request.remote not in allowed_ips: raise HTTPForbidden() - label = request.rel_url.query.get('label', '') + label = request.query.get('label', '') key = label + "PreviewBox" if key in state: data = state[key][1] @@ -1061,6 +1096,38 @@ async def preview_setroi(request): return web.Response() +@server.PromptServer.instance.routes.get("/flipstreamviewer/paste") +async def paste(request): + if request.remote not in allowed_ips: + raise HTTPForbidden() + + label = request.query.get('label', '') + key = label + "PasteBox" + if key in state: + data = state[key][1] + else: + data = b"" + return web.Response(body=data, headers={"Content-Type": "image/png"}) + + +@server.PromptServer.instance.routes.post("/flipstreamviewer/paste_upload") +async def paste_upload(request): + if request.remote not in allowed_ips: raise HTTPForbidden() + label = request.query.get('label', '') + state[label + "PasteBox"] = (time.time(), await request.read()) + return web.Response() + + +@server.PromptServer.instance.routes.post("/flipstreamviewer/paste_remove") +async def paste_upload(request): + if request.remote not in allowed_ips: raise HTTPForbidden() + label = request.query.get('label', '') + key = label + "PasteBox" + if key in state: + del state[key] + return web.Response() + + @server.PromptServer.instance.routes.get("/flipstreamviewer") async def viewer(request): if request.remote not in allowed_ips: @@ -1078,12 +1145,12 @@ async def viewer(request): def add_button(title, capture, update, hook): block[f"{title}"] = f"""