From 1c3d5cd85163fc062ff29246f673820afc34f7b8 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Mon, 14 Nov 2022 01:23:04 +0100 Subject: [PATCH 1/2] Add paste button next to copy button --- ui/media/js/dnd.js | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/ui/media/js/dnd.js b/ui/media/js/dnd.js index ab1b97cc..ca6ec2f4 100644 --- a/ui/media/js/dnd.js +++ b/ui/media/js/dnd.js @@ -396,12 +396,36 @@ const TASK_REQ_NO_EXPORT = [ "save_to_disk_path" ] -// Adds a copy icon if the browser grants permission to write to clipboard. +// Retrieve clipboard content and try to parse it +async function pasteFromClipboard() { + //const text = await navigator.clipboard.readText() + let text = await navigator.clipboard.readText(); + text=text.trim(); + if (text.startsWith('{') && text.endsWith('}')) { + try { + const task = JSON.parse(text) + restoreTaskToUI(task) + } catch (e) { + console.warn(`Clipboard JSON couldn't be parsed.`, e) + } + return + } + // Normal txt file. + const task = parseTaskFromText(text) + if (task) { + restoreTaskToUI(task) + } else { + console.warn(`Clipboard content - File couldn't be parsed.`) + } +} + +// Adds a copy and a paste icon if the browser grants permission to write to clipboard. function checkWriteToClipboardPermission (result) { if (result.state == "granted" || result.state == "prompt") { const resetSettings = document.getElementById('reset-image-settings') + + // COPY ICON const copyIcon = document.createElement('i') - // copyIcon.id = 'copy-image-settings' copyIcon.className = 'fa-solid fa-clipboard section-button' copyIcon.innerHTML = `Copy Image Settings` copyIcon.addEventListener('click', (event) => { @@ -415,8 +439,20 @@ function checkWriteToClipboardPermission (result) { navigator.clipboard.writeText(JSON.stringify(uiState, undefined, 4)) }) resetSettings.parentNode.insertBefore(copyIcon, resetSettings) + + // PASTE ICON + const pasteIcon = document.createElement('i') + pasteIcon.className = 'fa-solid fa-paste section-button' + pasteIcon.innerHTML = `Paste Image Settings` + pasteIcon.addEventListener('click', (event) => { + event.stopPropagation() + pasteFromClipboard() + }) + resetSettings.parentNode.insertBefore(pasteIcon, resetSettings) } } + +// Determine which access we have to the clipboard. Clipboard access is only available on localhost or via TLS. navigator.permissions.query({ name: "clipboard-write" }).then(checkWriteToClipboardPermission, (e) => { if (e instanceof TypeError && typeof navigator?.clipboard?.writeText === 'function') { // Fix for firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1560373 From e561e4de0b11ba75518b0d521647c6dfbc3e49dc Mon Sep 17 00:00:00 2001 From: JeLuF Date: Mon, 14 Nov 2022 01:58:24 +0100 Subject: [PATCH 2/2] Visual feedback for the copy and paste icons --- ui/media/css/main.css | 4 ++++ ui/media/js/dnd.js | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/ui/media/css/main.css b/ui/media/css/main.css index 2c1b1473..1e726709 100644 --- a/ui/media/css/main.css +++ b/ui/media/css/main.css @@ -887,3 +887,7 @@ input::file-selector-button { margin-bottom: 15px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.15), 0 6px 20px 0 rgba(0, 0, 0, 0.15); } + +i.active { + background: var(--accent-color); +} diff --git a/ui/media/js/dnd.js b/ui/media/js/dnd.js index ca6ec2f4..1a1c115d 100644 --- a/ui/media/js/dnd.js +++ b/ui/media/js/dnd.js @@ -430,6 +430,10 @@ function checkWriteToClipboardPermission (result) { copyIcon.innerHTML = `Copy Image Settings` copyIcon.addEventListener('click', (event) => { event.stopPropagation() + // Add css class 'active' + copyIcon.classList.add('active') + // In 1000 ms remove the 'active' class + asyncDelay(1000).then(() => copyIcon.classList.remove('active')) const uiState = readUI() TASK_REQ_NO_EXPORT.forEach((key) => delete uiState.reqBody[key]) if (uiState.reqBody.init_image && !IMAGE_REGEX.test(uiState.reqBody.init_image)) { @@ -446,6 +450,10 @@ function checkWriteToClipboardPermission (result) { pasteIcon.innerHTML = `Paste Image Settings` pasteIcon.addEventListener('click', (event) => { event.stopPropagation() + // Add css class 'active' + pasteIcon.classList.add('active') + // In 1000 ms remove the 'active' class + asyncDelay(1000).then(() => pasteIcon.classList.remove('active')) pasteFromClipboard() }) resetSettings.parentNode.insertBefore(pasteIcon, resetSettings)