From 529c0e161f4435078ffe3f595c3f34db3803a4db Mon Sep 17 00:00:00 2001 From: 1aerostorm Date: Wed, 22 Nov 2023 21:02:13 +0000 Subject: [PATCH] NFT - upload, proxying --- app/components/elements/nft/NFTSmallIcon.jsx | 6 +- app/components/elements/nft/NFTTokenItem.jsx | 5 +- .../modules/nft/CreateNFTCollection.jsx | 84 ++++++++++++++++++- app/components/modules/nft/IssueNFTToken.jsx | 84 ++++++++++++++++++- app/redux/UserSaga_UploadImage.js | 5 +- app/utils/ProxifyUrl.js | 8 ++ 6 files changed, 183 insertions(+), 9 deletions(-) diff --git a/app/components/elements/nft/NFTSmallIcon.jsx b/app/components/elements/nft/NFTSmallIcon.jsx index c3dba89..0b2f3a6 100644 --- a/app/components/elements/nft/NFTSmallIcon.jsx +++ b/app/components/elements/nft/NFTSmallIcon.jsx @@ -1,11 +1,15 @@ import React, { Component, } from 'react' +import { proxifyNFTImage } from 'app/utils/ProxifyUrl' + class NFTSmallIcon extends Component { render() { const { image, ...rest } = this.props + const url = image.startsWith('http') ? proxifyNFTImage(image) : image + return + style={{ backgroundImage: `url(${url})` }} href={url} target='_blank' rel='nofollow noreferrer' {...rest}> } } diff --git a/app/components/elements/nft/NFTTokenItem.jsx b/app/components/elements/nft/NFTTokenItem.jsx index d3c1782..d546e8f 100644 --- a/app/components/elements/nft/NFTTokenItem.jsx +++ b/app/components/elements/nft/NFTTokenItem.jsx @@ -11,6 +11,7 @@ import g from 'app/redux/GlobalReducer' import user from 'app/redux/User' import transaction from 'app/redux/Transaction' import { getAssetMeta } from 'app/utils/market/utils' +import { proxifyNFTImage } from 'app/utils/ProxifyUrl' class NFTTokenItem extends Component { state = {} @@ -154,10 +155,12 @@ class NFTTokenItem extends Component { } + let tokenImage = image.startsWith('http') ? proxifyNFTImage(image) : image + return
- + {!isMy && {'@' + token.owner} } diff --git a/app/components/modules/nft/CreateNFTCollection.jsx b/app/components/modules/nft/CreateNFTCollection.jsx index d953d1d..b03745b 100644 --- a/app/components/modules/nft/CreateNFTCollection.jsx +++ b/app/components/modules/nft/CreateNFTCollection.jsx @@ -3,6 +3,7 @@ import tt from 'counterpart' import { connect, } from 'react-redux' import CloseButton from 'react-foundation-components/lib/global/close-button' import { Formik, Form, Field, ErrorMessage, } from 'formik' +import Dropzone from 'react-dropzone' import Expandable from 'app/components/elements/Expandable' import LoadingIndicator from 'app/components/elements/LoadingIndicator' @@ -226,9 +227,63 @@ class CreateNFTCollection extends Component { } } + uploadImage = (file, name = '', values, setFieldValue) => { + const {notify} = this.props + const {uploadImage} = this.props + this.setState({imageUploading: true}) + uploadImage(file, progress => { + if (progress.url) { + setFieldValue('image', progress.url) + this.setState({ + showImage: true + }) + this.updateJSONMetadata(values, setFieldValue, { image: progress.url }) + } + if (progress.error) { + const { error } = progress; + notify(error, 10000) + } + this.setState({ imageUploading: false }) + }) + } + + onDropImage = (acceptedFiles, rejectedFiles, values, setFieldValue) => { + if (!acceptedFiles.length) { + if (rejectedFiles.length) { + alert(tt('reply_editor.please_insert_only_image_files')) + console.log('onDrop Rejected files: ', rejectedFiles) + } + return + } + const file = acceptedFiles[0] + this.uploadImage(file, file.name, values, setFieldValue) + } + + onUploadImageClick = () => { + this.dropzone.open(); + } + render() { const { onClose, } = this.props; - const { submitting, showImage, errorMessage, hideErrors } = this.state + const { submitting, showImage, errorMessage, hideErrors, imageUploading } = this.state + + const selectorStyleCover = imageUploading ? + { + whiteSpace: `nowrap`, + display: `flex`, + alignItems: `center`, + paddingLeft: '0px', + paddingRight: '12px', + pointerEvents: `none`, + cursor: `default`, + opacity: `0.6` + } : + { + display: `flex`, + alignItems: `center`, + paddingLeft: '0px', + paddingRight: '12px', + } return (
@@ -287,8 +342,18 @@ class CreateNFTCollection extends Component {
- this.onImageChange(e, values, setFieldValue)} /> + + {imageUploading ? `${tt(`user_saga_js.image_upload.uploading`)} ...` : tt(`g.upload`)} + + this.onDropImage(af, rf, values, setFieldValue)} + className={'none'} + disableClick multiple={false} accept="image/*" + ref={(node) => { this.dropzone = node; }}> + this.onImageChange(e, values, setFieldValue)} /> +
@@ -373,6 +438,19 @@ export default connect( }, dispatch => ({ + uploadImage: (file, progress) => { + dispatch({ + type: 'user/UPLOAD_IMAGE', + payload: {file, progress}, + }) + }, + notify: (message, dismiss = 3000) => { + dispatch({type: 'ADD_NOTIFICATION', payload: { + key: "settings_" + Date.now(), + message, + dismissAfter: dismiss} + }) + }, createCollection: ( name, json_metadata, max_token_count, currentUser, successCallback, errorCallback ) => { diff --git a/app/components/modules/nft/IssueNFTToken.jsx b/app/components/modules/nft/IssueNFTToken.jsx index df971b6..1b07785 100644 --- a/app/components/modules/nft/IssueNFTToken.jsx +++ b/app/components/modules/nft/IssueNFTToken.jsx @@ -4,6 +4,7 @@ import { connect, } from 'react-redux' import CloseButton from 'react-foundation-components/lib/global/close-button' import { Formik, Form, Field, ErrorMessage, } from 'formik' import { Asset, validateAccountName } from 'golos-lib-js/lib/utils' +import Dropzone from 'react-dropzone' import Expandable from 'app/components/elements/Expandable' import LoadingIndicator from 'app/components/elements/LoadingIndicator' @@ -195,9 +196,63 @@ class IssueNFTToken extends Component { } } + uploadImage = (file, name = '', values, setFieldValue) => { + const {notify} = this.props + const {uploadImage} = this.props + this.setState({imageUploading: true}) + uploadImage(file, progress => { + if (progress.url) { + setFieldValue('image', progress.url) + this.setState({ + showImage: true + }) + this.updateJSONMetadata(values, setFieldValue, { image: progress.url }) + } + if (progress.error) { + const { error } = progress; + notify(error, 10000) + } + this.setState({ imageUploading: false }) + }) + } + + onDropImage = (acceptedFiles, rejectedFiles, values, setFieldValue) => { + if (!acceptedFiles.length) { + if (rejectedFiles.length) { + alert(tt('reply_editor.please_insert_only_image_files')) + console.log('onDrop Rejected files: ', rejectedFiles) + } + return + } + const file = acceptedFiles[0] + this.uploadImage(file, file.name, values, setFieldValue) + } + + onUploadImageClick = () => { + this.dropzone.open(); + } + render() { const { issueName, issueNum, cprops, onClose, } = this.props; - const { submitting, showImage, errorMessage } = this.state + const { submitting, showImage, errorMessage, imageUploading } = this.state + + const selectorStyleCover = imageUploading ? + { + whiteSpace: `nowrap`, + display: `flex`, + alignItems: `center`, + paddingLeft: '0px', + paddingRight: '12px', + pointerEvents: `none`, + cursor: `default`, + opacity: `0.6` + } : + { + display: `flex`, + alignItems: `center`, + paddingLeft: '0px', + paddingRight: '12px', + } return (
@@ -271,8 +326,18 @@ class IssueNFTToken extends Component {
- this.onImageChange(e, values, setFieldValue)} /> + + {imageUploading ? `${tt(`user_saga_js.image_upload.uploading`)} ...` : tt(`g.upload`)} + + this.onDropImage(af, rf, values, setFieldValue)} + className={'none'} + disableClick multiple={false} accept="image/*" + ref={(node) => { this.dropzone = node; }}> + this.onImageChange(e, values, setFieldValue)} /> +
@@ -336,6 +401,19 @@ export default connect( }, dispatch => ({ + uploadImage: (file, progress) => { + dispatch({ + type: 'user/UPLOAD_IMAGE', + payload: {file, progress}, + }) + }, + notify: (message, dismiss = 3000) => { + dispatch({type: 'ADD_NOTIFICATION', payload: { + key: "settings_" + Date.now(), + message, + dismissAfter: dismiss} + }) + }, issueToken: ( name, to, json_metadata, currentUser, successCallback, errorCallback ) => { diff --git a/app/redux/UserSaga_UploadImage.js b/app/redux/UserSaga_UploadImage.js index b0f73c7..5f5f856 100644 --- a/app/redux/UserSaga_UploadImage.js +++ b/app/redux/UserSaga_UploadImage.js @@ -30,7 +30,7 @@ const ERRORS_MATCH = [ ], ]; -function* uploadImage(action) { +function* uploadImage(action) {try{ const { file, dataUrl, filename = 'image.txt', progress, useGolosImages = false } = action.payload; function onError(txt) { @@ -198,4 +198,7 @@ function* uploadImage(action) { }; xhr.send(formData); +} catch (err) { + console.error(err) +} } diff --git a/app/utils/ProxifyUrl.js b/app/utils/ProxifyUrl.js index d964bf3..ce7386d 100644 --- a/app/utils/ProxifyUrl.js +++ b/app/utils/ProxifyUrl.js @@ -30,6 +30,14 @@ export const proxifyImageUrl = (url, dimensions = '0x0') => { return prefix + url; }; +export const proxifyNFTImage = (url) => { + if (!$STM_Config) + return url + let prefix = '' + if ($STM_Config.images.img_proxy_prefix && $STM_Config.images.use_img_proxy !== false) prefix += fixHost($STM_Config.images.img_proxy_prefix) + '/orig/png/' + return prefix + url +}; + /** * Strips all proxy domains from the beginning of the url. Adds the global proxy if dimension is specified * @param {string} url