From e525a74cc413846deca792d3e39249bdccaf9b6b Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 9 Aug 2023 17:50:17 +0300 Subject: [PATCH] allow upload img by pasting into public message field --- src/js/components/PublicMessageForm.tsx | 32 ++++++++++++++++++++++++- src/js/components/buttons/Upload.tsx | 27 ++++++++++----------- src/js/utils/uploadFile.ts | 21 ++++++++++++++++ 3 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 src/js/utils/uploadFile.ts diff --git a/src/js/components/PublicMessageForm.tsx b/src/js/components/PublicMessageForm.tsx index 980a902b..cb520f56 100644 --- a/src/js/components/PublicMessageForm.tsx +++ b/src/js/components/PublicMessageForm.tsx @@ -3,6 +3,8 @@ import $ from 'jquery'; import { Event } from 'nostr-tools'; import { createRef } from 'preact'; +import { uploadFile } from '@/utils/uploadFile'; + import Component from '../BaseComponent'; import Helpers from '../Helpers'; import Icons from '../Icons'; @@ -95,13 +97,40 @@ class PublicMessageForm extends Component { } onMsgTextPaste(event) { - const pasted = (event.clipboardData || window.clipboardData).getData('text'); + const clipboardData = event.clipboardData || window.clipboardData; + + // Handling magnet links + const pasted = clipboardData.getData('text'); const magnetRegex = /(magnet:\?xt=urn:btih:.*)/gi; const match = magnetRegex.exec(pasted); console.log('magnet match', match); if (match) { this.setState({ torrentId: match[0] }); } + + if (clipboardData.items) { + const items = clipboardData.items; + for (let i = 0; i < items.length; i++) { + if (items[i].type.startsWith('image/')) { + const blob = items[i].getAsFile(); + uploadFile( + blob, + (url) => { + const textEl = $(this.newMsgRef.current); + const currentVal = textEl.val(); + if (currentVal) { + textEl.val(currentVal + '\n\n' + url); + } else { + textEl.val(url); + } + }, + (errorMsg) => { + console.error(errorMsg); + }, + ); + } + } + } } onKeyUp(e) { @@ -142,6 +171,7 @@ class PublicMessageForm extends Component { } attachmentsChanged(event) { + // TODO use Upload btn const files = event.target.files || event.dataTransfer.files; if (files) { for (let i = 0; i < files.length; i++) { diff --git a/src/js/components/buttons/Upload.tsx b/src/js/components/buttons/Upload.tsx index fc81da06..ef3d511d 100644 --- a/src/js/components/buttons/Upload.tsx +++ b/src/js/components/buttons/Upload.tsx @@ -1,27 +1,24 @@ import { useState } from 'react'; +import { uploadFile } from '@/utils/uploadFile'; + const Upload = (props) => { const [error, setError] = useState(''); + const handleFileUpload = (event) => { const files = event.target.files || event.dataTransfer.files; if (files && files.length) { - const formData = new FormData(); - formData.append('fileToUpload', files[0]); - - fetch('https://nostr.build/api/upload/iris.php', { - method: 'POST', - body: formData, - }) - .then(async (response) => { - const url = await response.json(); - if (url && props.onUrl) { + uploadFile( + files[0], + (url) => { + if (props.onUrl) { props.onUrl(url); } - }) - .catch((error) => { - console.error('upload error', error); - setError('upload failed: ' + JSON.stringify(error)); - }); + }, + (errorMsg) => { + setError(errorMsg); + }, + ); } }; diff --git a/src/js/utils/uploadFile.ts b/src/js/utils/uploadFile.ts new file mode 100644 index 00000000..ce46d196 --- /dev/null +++ b/src/js/utils/uploadFile.ts @@ -0,0 +1,21 @@ +export const uploadFile = (file, onUrlCallback, onErrorCallback) => { + const formData = new FormData(); + formData.append('fileToUpload', file); + + fetch('https://nostr.build/api/upload/iris.php', { + method: 'POST', + body: formData, + }) + .then(async (response) => { + const url = await response.json(); + if (url && onUrlCallback) { + onUrlCallback(url); + } + }) + .catch((error) => { + console.error('upload error', error); + if (onErrorCallback) { + onErrorCallback('upload failed: ' + JSON.stringify(error)); + } + }); +};