From 4c7875f32515a4e612c03c0d2623604f3311834c Mon Sep 17 00:00:00 2001 From: ErikrafT <139592038+erikraft@users.noreply.github.com> Date: Sat, 10 May 2025 13:15:02 -0300 Subject: [PATCH] Update ui.js --- public/scripts/ui.js | 474 ++++++++++++++++--------------------------- 1 file changed, 172 insertions(+), 302 deletions(-) diff --git a/public/scripts/ui.js b/public/scripts/ui.js index d8fd81c..f03e3f5 100644 --- a/public/scripts/ui.js +++ b/public/scripts/ui.js @@ -183,42 +183,37 @@ class PeersUI { if (this.shareMode.active || Dialog.anyDialogShown()) return; e.preventDefault(); + e.stopPropagation(); this._onDragEnd(); - // Verifica se há peers conectados if (!$$('x-peer')) { - window.pairdrop.toast.show('Nenhum dispositivo conectado para compartilhar'); + Events.fire('notify-user', Localization.getTranslation("notifications.no-peers-connected")); return; } - if ($$('x-peer') && $$('x-peer').contains(e.target)) return; // dropped on peer + if ($$('x-peer') && $$('x-peer').contains(e.target)) return; - let files = e.dataTransfer.files; - let text = e.dataTransfer.getData("text"); - - // convert FileList to Array - files = [...files]; + const files = [...e.dataTransfer.files]; + const text = e.dataTransfer.getData("text/plain"); if (files.length > 0) { try { - // Verifica cada arquivo antes de ativar o modo de compartilhamento for (const file of files) { - await window.pairdrop.contentModeration.processFile(file); + if (file.size > 1024 * 1024 * 1024) { // 1GB + throw new Error(Localization.getTranslation("notifications.file-too-large")); + } } - - Events.fire('activate-share-mode', { - files: files - }); + Events.fire('activate-share-mode', { files }); } catch (error) { - window.pairdrop.toast.show(error.message); + Events.fire('notify-user', error.message); + } + } else if (text && text.trim()) { + if (ShareTextDialog.isApproveShareTextSet()) { + Events.fire('share-text-dialog', text.trim()); + } else { + Events.fire('activate-share-mode', { text: text.trim() }); } - } - else if (text) { - // Remove verificação de spam para texto - Events.fire('activate-share-mode', { - text: text - }); } } @@ -239,31 +234,27 @@ class PeersUI { async _onPaste(e) { if (this.shareMode.active || Dialog.anyDialogShown()) return; - let files = e.clipboardData.files; - let text = e.clipboardData.getData("text"); - - // convert FileList to Array - files = [...files]; + e.preventDefault(); + const files = [...e.clipboardData.files]; + const text = e.clipboardData.getData("text/plain"); if (files.length > 0) { try { - // Verifica cada arquivo antes de ativar o modo de compartilhamento for (const file of files) { - await window.pairdrop.contentModeration.processFile(file); + if (file.size > 1024 * 1024 * 1024) { // 1GB + throw new Error(Localization.getTranslation("notifications.file-too-large")); + } } - - Events.fire('activate-share-mode', { - files: files - }); + Events.fire('activate-share-mode', { files }); } catch (error) { - window.pairdrop.toast.show(error.message); + Events.fire('notify-user', error.message); + } + } else if (text && text.trim()) { + if (ShareTextDialog.isApproveShareTextSet()) { + Events.fire('share-text-dialog', text.trim()); + } else { + Events.fire('activate-share-mode', { text: text.trim() }); } - } - else if (text) { - // Remove verificação de spam para texto - Events.fire('activate-share-mode', { - text: text - }); } } @@ -278,50 +269,35 @@ class PeersUI { Events.on('share-mode-pointerdown', this._activateCallback); - const sharedText = Localization.getTranslation("instructions.activate-share-mode-shared-text"); - const andOtherFilesPlural = Localization.getTranslation("instructions.activate-share-mode-and-other-files-plural", null, {count: files.length-1}); - const andOtherFiles = Localization.getTranslation("instructions.activate-share-mode-and-other-file"); - let descriptorComplete, descriptorItem, descriptorOther, descriptorInstructions; - if (files.length > 2) { - // files shared - descriptorItem = files[0].name; - descriptorOther = andOtherFilesPlural; - descriptorComplete = `${descriptorItem} ${descriptorOther}`; - } - else if (files.length === 2) { - descriptorItem = files[0].name; - descriptorOther = andOtherFiles; - descriptorComplete = `${descriptorItem} ${descriptorOther}`; - } else if (files.length === 1) { - descriptorItem = files[0].name; - descriptorComplete = descriptorItem; - } - else { - // text shared - descriptorItem = text.replace(/\s/g," "); - descriptorComplete = sharedText; - } - if (files.length > 0) { + if (files.length > 2) { + descriptorItem = files[0].name; + descriptorOther = Localization.getTranslation("instructions.activate-share-mode-and-other-files-plural", null, {count: files.length-1}); + descriptorComplete = `${descriptorItem} ${descriptorOther}`; + } else if (files.length === 2) { + descriptorItem = files[0].name; + descriptorOther = Localization.getTranslation("instructions.activate-share-mode-and-other-file"); + descriptorComplete = `${descriptorItem} ${descriptorOther}`; + } else { + descriptorItem = files[0].name; + descriptorComplete = descriptorItem; + } + if (descriptorOther) { this.$shareModeDescriptorOther.innerText = descriptorOther; this.$shareModeDescriptorOther.removeAttribute('hidden'); } - if (files.length > 1) { - descriptorInstructions = Localization.getTranslation("instructions.activate-share-mode-shared-files-plural", null, {count: files.length}); - } - else { - descriptorInstructions = Localization.getTranslation("instructions.activate-share-mode-shared-file"); - } + + descriptorInstructions = files.length > 1 + ? Localization.getTranslation("instructions.activate-share-mode-shared-files-plural", null, {count: files.length}) + : Localization.getTranslation("instructions.activate-share-mode-shared-file"); if (files[0].type.split('/')[0] === 'image') { try { - let imageUrl = await getThumbnailAsDataUrl(files[0], 80, null, 0.9); - + const imageUrl = await getThumbnailAsDataUrl(files[0], 80, null, 0.9); this.$shareModeImageThumb.style.backgroundImage = `url(${imageUrl})`; - this.$shareModeImageThumb.removeAttribute('hidden'); } catch (e) { console.error(e); @@ -330,13 +306,12 @@ class PeersUI { } else { this.$shareModeFileThumb.removeAttribute('hidden'); } - } - else { + } else { this.$shareModeTextThumb.removeAttribute('hidden'); - this.$shareModeEditBtn.addEventListener('click', this._editShareTextCallback); this.$shareModeEditBtn.removeAttribute('hidden'); - + descriptorItem = text.replace(/\s/g," "); + descriptorComplete = Localization.getTranslation("instructions.activate-share-mode-shared-text"); descriptorInstructions = Localization.getTranslation("instructions.activate-share-mode-shared-text"); } @@ -347,7 +322,6 @@ class PeersUI { this.$xInstructions.setAttribute('mobile', mobile); this.$sharePanel.removeAttribute('hidden'); - this.$shareModeDescriptor.removeAttribute('hidden'); this.$shareModeDescriptorItem.innerText = descriptorItem; @@ -384,47 +358,61 @@ class PeersUI { this.shareMode.text = ""; Events.off('share-mode-pointerdown', this._activateCallback); + if (this._editShareTextCallback) { + this.$shareModeEditBtn.removeEventListener('click', this._editShareTextCallback); + this._editShareTextCallback = null; + } - const desktop = Localization.getTranslation("instructions.x-instructions_desktop"); - const mobile = Localization.getTranslation("instructions.x-instructions_mobile"); + this.$sharePanel.setAttribute('hidden', ''); + this.$shareModeDescriptor.setAttribute('hidden', ''); + this.$shareModeDescriptorItem.innerText = ""; + this.$shareModeDescriptorOther.setAttribute('hidden', ''); + this.$shareModeImageThumb.setAttribute('hidden', ''); + this.$shareModeFileThumb.setAttribute('hidden', ''); + this.$shareModeTextThumb.setAttribute('hidden', ''); + this.$shareModeEditBtn.setAttribute('hidden', ''); - this.$xInstructions.setAttribute('desktop', desktop); - this.$xInstructions.setAttribute('mobile', mobile); - - this.$sharePanel.setAttribute('hidden', true); - - this.$shareModeImageThumb.setAttribute('hidden', true); - this.$shareModeFileThumb.setAttribute('hidden', true); - this.$shareModeTextThumb.setAttribute('hidden', true); - - this.$shareModeDescriptorItem.innerHTML = ""; - this.$shareModeDescriptorItem.classList.remove('cursive'); - this.$shareModeDescriptorOther.innerHTML = ""; - this.$shareModeDescriptorOther.setAttribute('hidden', true); - this.$shareModeEditBtn.removeEventListener('click', this._editShareTextCallback); - this.$shareModeEditBtn.setAttribute('hidden', true); - - console.log('Share mode deactivated.') Events.fire('share-mode-changed', { active: false }); } _sendShareData(e) { - // send the shared file/text content const peerId = e.detail.peerId; - const files = this.shareMode.files; - const text = this.shareMode.text; + const peer = this.peers[peerId]; - if (files.length > 0) { - Events.fire('files-selected', { - files: files, - to: peerId - }); + if (!peer) return; + + try { + if (this.shareMode.files.length > 0) { + Events.fire('files-selected', { + files: this.shareMode.files, + to: peerId + }); + } else if (this.shareMode.text) { + const text = this.shareMode.text.trim(); + if (text) { + Events.fire('send-text', { + text: text, + to: peerId + }); + } + } + } catch (error) { + console.error('Erro ao enviar dados:', error); + Events.fire('notify-user', Localization.getTranslation("notifications.send-error")); + } finally { + this._deactivateShareMode(); } - else if (text.length > 0) { - Events.fire('send-text', { - text: text, - to: peerId - }); + } + + _onShareModeChanged(active = false, descriptor = "") { + if (active) { + this.$sharePanel.removeAttribute('hidden'); + this.$shareModeDescriptor.removeAttribute('hidden'); + this.$shareModeDescriptor.textContent = descriptor; + } else { + this.$sharePanel.setAttribute('hidden', ''); + this.$shareModeDescriptor.setAttribute('hidden', ''); + this.$shareModeDescriptor.textContent = ""; } } } @@ -1975,23 +1963,30 @@ class SendTextDialog extends Dialog { } async _onPaste(e) { - e.preventDefault() + if (this.shareMode.active || Dialog.anyDialogShown()) return; - const text = (e.clipboardData || window.clipboardData).getData('text'); - const selection = window.getSelection(); + e.preventDefault(); + const files = [...e.clipboardData.files]; + const text = e.clipboardData.getData("text/plain"); - if (selection.rangeCount) { - selection.deleteFromDocument(); - const textNode = document.createTextNode(text); - const range = document.createRange(); - range.setStart(textNode, textNode.length); - range.collapse(true); - selection.getRangeAt(0).insertNode(textNode); - selection.removeAllRanges(); - selection.addRange(range); + if (files.length > 0) { + try { + for (const file of files) { + if (file.size > 1024 * 1024 * 1024) { // 1GB + throw new Error(Localization.getTranslation("notifications.file-too-large")); + } + } + Events.fire('activate-share-mode', { files }); + } catch (error) { + Events.fire('notify-user', error.message); + } + } else if (text && text.trim()) { + if (ShareTextDialog.isApproveShareTextSet()) { + Events.fire('share-text-dialog', text.trim()); + } else { + Events.fire('activate-share-mode', { text: text.trim() }); + } } - - this._onInput(); } _textEmpty() { @@ -2044,204 +2039,79 @@ class SendTextDialog extends Dialog { class ReceiveTextDialog extends Dialog { constructor() { super('receive-text-dialog'); - this.textQueue = []; + this.$text = $('receive-text-dialog-text'); + this.$copyBtn = $('receive-text-dialog-copy'); + this.$downloadBtn = $('receive-text-dialog-download'); + + this._onCopy = this._onCopy.bind(this); + this._onDownload = this._onDownload.bind(this); + + this.$copyBtn.addEventListener('click', this._onCopy); + this.$downloadBtn.addEventListener('click', this._onDownload); Events.on('text', e => this._onText(e.detail.text, e.detail.peerId)); } async _onText(text, peerId) { + if (!text) return; + try { - // Remove verificação de spam para texto recebido - this.textQueue.push({ - text: text, - peerId: peerId - }); - - if (!this.isShown()) { - await this._dequeueRequests(); + // Limpa o texto de caracteres inválidos + text = text.replace(/[\x00-\x1F\x7F-\x9F]/g, ''); + + // Verifica se o texto está vazio após a limpeza + if (!text.trim()) { + window.pairdrop.toast.show('Texto recebido está vazio ou contém apenas caracteres inválidos'); + return; } + + // Verifica se o texto foi bloqueado pela moderação + await window.pairdrop.contentModeration.processText(text); + + // Mostra o diálogo com o texto + this._showReceiveTextDialog(text, peerId); + + // Notifica o usuário + window.pairdrop.toast.show('Texto recebido com sucesso'); } catch (error) { - window.pairdrop.toast.show(error.message); + window.pairdrop.toast.show('Erro ao processar texto: ' + error.message); } } - async showBlockedMessageDialog(text, contentType) { - return new Promise((resolve) => { - const dialog = document.createElement('div'); - dialog.className = 'dialog blocked-message-dialog'; - - const title = this.getBlockedMessageReason(contentType); - const icon = this.getWarningIcon(contentType); - - dialog.innerHTML = ` -