From c53221ba01701d3427739dce6c9ae536ef5bf764 Mon Sep 17 00:00:00 2001 From: schlagmichdoch Date: Thu, 19 Jan 2023 04:40:28 +0100 Subject: [PATCH] Add Base64ZipDialog to PairDrop via share-menu on iOS --- public/index.html | 12 +++++++++++- public/scripts/ui.js | 43 +++++++++++++++++++++++++++++++++++++++++-- public/styles.css | 20 +++++++++++++++++++- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/public/index.html b/public/index.html index 1e3d15c..0d1c106 100644 --- a/public/index.html +++ b/public/index.html @@ -88,7 +88,7 @@
You can be discovered by everyone on this network
- +
@@ -116,6 +116,7 @@
+
@@ -192,6 +193,15 @@ + + + + + + + + +
File Transfer Completed diff --git a/public/scripts/ui.js b/public/scripts/ui.js index 112c79f..83f5d39 100644 --- a/public/scripts/ui.js +++ b/public/scripts/ui.js @@ -990,6 +990,45 @@ class ReceiveTextDialog extends Dialog { } } +class Base64ZipDialog extends Dialog { + + constructor() { + super('base64ZipDialog'); + const urlParams = new URL(window.location).searchParams; + const base64zip = urlParams.get('base64zip'); + this.$pasteBtn = this.$el.querySelector('#base64ZipPasteBtn') + this.$pasteBtn.addEventListener('click', _ => this.processClipboard()) + if (base64zip) this.show(); + } + + async processClipboard() { + this.$pasteBtn.pointerEvents = "none"; + this.$pasteBtn.innerText = "Processing..."; + try { + const base64zip = await navigator.clipboard.readText(); + let bstr = atob(base64zip), n = bstr.length, u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + + const zipBlob = new File([u8arr], 'archive.zip'); + + let files = []; + const zipEntries = await zipper.getEntries(zipBlob); + for (let i = 0; i < zipEntries.length; i++) { + let fileBlob = await zipper.getData(zipEntries[i]); + files.push(new File([fileBlob], zipEntries[i].filename)); + } + Events.fire('activate-paste-mode', {files: files, text: ""}) + } catch (e) { + Events.fire('notify-user', 'Clipboard content is malformed.') + } finally { + window.history.replaceState({}, "Rewrite URL", '/'); + this.hide(); + } + } +} + class Toast extends Dialog { constructor() { super('toast'); @@ -1155,9 +1194,8 @@ class WebShareTargetUI { }) caches.delete("share_target_files").then( _ => console.log("shared files deleted from cache")); } - window.history.replaceState({}, "Rewrite URL", '/'); //remove room_key from url + window.history.replaceState({}, "Rewrite URL", '/'); } - } } @@ -1391,6 +1429,7 @@ class PairDrop { const receiveTextDialog = new ReceiveTextDialog(); const pairDeviceDialog = new PairDeviceDialog(); const clearDevicesDialog = new ClearDevicesDialog(); + const base64ZipDialog = new Base64ZipDialog(); const toast = new Toast(); const notifications = new Notifications(); const networkStatusUI = new NetworkStatusUI(); diff --git a/public/styles.css b/public/styles.css index 6a7d28b..270563d 100644 --- a/public/styles.css +++ b/public/styles.css @@ -532,10 +532,28 @@ x-dialog .row-reverse { pointer-events: none; } +#base64ZipPasteBtn { + width: 100%; + height: 40vh; + border: solid 12px #438cff; +} + +#base64ZipDialog button { + margin: auto; + border-radius: 8px; +} + +#base64ZipDialog button[close] { + margin-top: 20px; +} +#base64ZipDialog button[close]:before { + border-radius: 8px; +} + /* Button */ .button { - padding: 0 16px; + padding: 2px 16px 0; box-sizing: border-box; min-height: 36px; min-width: 100px;