From b4518ab4e8c8e5f26badbeb38a18d2355dd31849 Mon Sep 17 00:00:00 2001 From: schlagmichdoch Date: Fri, 19 Aug 2022 17:04:34 +0200 Subject: [PATCH 01/16] add text support to send clipboard data _onPaste() functionality --- client/scripts/ui.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/scripts/ui.js b/client/scripts/ui.js index 0c159841..68596bb7 100644 --- a/client/scripts/ui.js +++ b/client/scripts/ui.js @@ -56,8 +56,9 @@ class PeersUI { const files = e.clipboardData.files || e.clipboardData.items .filter(i => i.type.indexOf('image') > -1) .map(i => i.getAsFile()); + const text = e.clipboardData.getData("Text"); const peers = document.querySelectorAll('x-peer'); - // send the pasted image content to the only peer if there is one + // send the pasted image/text content to the only peer if there is one // otherwise, select the peer somehow by notifying the client that // "image data has been pasted, click the client to which to send it" // not implemented @@ -66,6 +67,11 @@ class PeersUI { files: files, to: $$('x-peer').id }); + } else if (text.length > 0 && peers.length === 1) { + Events.fire('send-text', { + text: text, + to: $$('x-peer').id + }); } } } From 67d0321d9829e55de760d4b4ba8a516edcd8ebab Mon Sep 17 00:00:00 2001 From: schlagmichdoch Date: Tue, 23 Aug 2022 04:16:21 +0200 Subject: [PATCH 02/16] add pasteMode in PeersUI and change PeerUI behaviour accordingly --- client/scripts/network.js | 4 + client/scripts/ui.js | 173 +++++++++++++++++++++++++++++++------- 2 files changed, 147 insertions(+), 30 deletions(-) diff --git a/client/scripts/network.js b/client/scripts/network.js index eb599014..98752be5 100644 --- a/client/scripts/network.js +++ b/client/scripts/network.js @@ -512,6 +512,10 @@ class Events { static on(type, callback) { return window.addEventListener(type, callback, false); } + + static off(type, callback) { + window.removeEventListener(type, callback, false); + } } diff --git a/client/scripts/ui.js b/client/scripts/ui.js index 68596bb7..78c45651 100644 --- a/client/scripts/ui.js +++ b/client/scripts/ui.js @@ -14,6 +14,7 @@ Events.on('display-name', e => { }); class PeersUI { + pasteMode = false; constructor() { Events.on('peer-joined', e => this._onPeerJoined(e.detail)); @@ -21,11 +22,12 @@ class PeersUI { Events.on('peers', e => this._onPeers(e.detail)); Events.on('file-progress', e => this._onFileProgress(e.detail)); Events.on('paste', e => this._onPaste(e)); + Events.on('load', e => this._onLoadCheckPaste()); } _onPeerJoined(peer) { if ($(peer.id)) return; // peer already exists - const peerUI = new PeerUI(peer); + const peerUI = new PeerUI(peer, this.pasteMode); $$('x-peers').appendChild(peerUI.$el); setTimeout(e => window.animateBackground(false), 1750); // Stop animation } @@ -52,36 +54,133 @@ class PeersUI { const $peers = $$('x-peers').innerHTML = ''; } - _onPaste(e) { - const files = e.clipboardData.files || e.clipboardData.items - .filter(i => i.type.indexOf('image') > -1) - .map(i => i.getAsFile()); - const text = e.clipboardData.getData("Text"); - const peers = document.querySelectorAll('x-peer'); - // send the pasted image/text content to the only peer if there is one + _getPeers() { + let peers = [] + const peersNodes = document.querySelectorAll('x-peer'); + peersNodes.forEach(function(peersNode) { + peers.push({ + id: peersNode.id, + name: peersNode.name, + rtcSupported: peersNode.rtcSupported + }) + }); + return peers; + } + + _onLoadCheckPaste() { + const urlParams = new URLSearchParams(window.location.search); + if(urlParams.has('paste')) { + this._activatePasteMode(() => this._getClipboardData()) + //replace url in history to prevent unwanted pasting on reload or back/forward + window.history.replaceState({}, "title**", '/'); + } + } + + async _onPaste(e) { + //only paste, when no dialog is open + const dialogNodes = document.querySelectorAll('x-dialog'); + let dialogIsOpen = false + dialogNodes.forEach(function (dialogNode) { + for(let i=0; i i.indexOf('text') === -1); + if (typesFiles.length > 0) { + // everything except text + const blob = await clipboardItems[0].getType(typesFiles[0]) + files.push(new File([blob], 'file', {type: typesFiles[0]})); + } + + let text = ''; + const typesText = clipboardItems[0].types.filter(i => i.indexOf('text') > -1); + if (typesText.length > 0) { + // text only + const blob = await clipboardItems[0].getType(typesText[0]) + text = await blob.text(); + } + return [files, text]; + } catch (err) { + console.error('Failed to read clipboard contents: ', err); + } + } + + async getClipboardDataCallback(e, _callback) { + const [files, text] = await _callback(); + const peerId = e.detail.peerId; + this._sendClipboardData(files, text, peerId); + } + + _activatePasteMode(_callback) { + Events.on('paste-touchend-click', e => this.getClipboardDataCallback(e, _callback)); + this.pasteMode = true; + this._onPeers(this._getPeers()); + const xInstructions = document.querySelectorAll('x-instructions')[0]; + xInstructions.setAttribute('desktop', 'Click to send clipboard content') + xInstructions.setAttribute('mobile', 'Tap to send clipboard content') + } + + _deactivatePasteMode(_callback) { + Events.off('paste-touchend-click', e => this._sendClipboardData(_callback, e.detail.peerId)); + this.pasteMode = false; + this._onPeers(this._getPeers()); + const xInstructions = document.querySelectorAll('x-instructions')[0]; + xInstructions.setAttribute('desktop', 'Click to send files or right click to send a message') + xInstructions.setAttribute('mobile', 'Tap to send files or long tap to send a message') } + + _sendClipboardData(files, text, peerId) { + console.debug(files) + console.debug(text) + console.debug(peerId) + // send the pasted file/text content to the only peer if there is one // otherwise, select the peer somehow by notifying the client that // "image data has been pasted, click the client to which to send it" - // not implemented - if (files.length > 0 && peers.length === 1) { + if (files.length > 0) { Events.fire('files-selected', { files: files, - to: $$('x-peer').id + to: peerId }); - } else if (text.length > 0 && peers.length === 1) { + } else if (text.length > 0) { Events.fire('send-text', { text: text, - to: $$('x-peer').id + to: peerId }); } + this._deactivatePasteMode(); } } class PeerUI { html() { + let title = !this._pasteMode + ? 'Click to send files or right click to send a message' + : 'Click to send clipboard content' + return ` -