Skip to content

Commit

Permalink
NFT - upload, proxying
Browse files Browse the repository at this point in the history
  • Loading branch information
1aerostorm committed Nov 22, 2023
1 parent d9a0c33 commit 529c0e1
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 9 deletions.
6 changes: 5 additions & 1 deletion app/components/elements/nft/NFTSmallIcon.jsx
Original file line number Diff line number Diff line change
@@ -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 <a className='NFTSmallIcon'
style={{ backgroundImage: `url(${image})` }} href={image} target='_blank' rel='nofollow noreferrer' {...rest}></a>
style={{ backgroundImage: `url(${url})` }} href={url} target='_blank' rel='nofollow noreferrer' {...rest}></a>
}
}

Expand Down
5 changes: 4 additions & 1 deletion app/components/elements/nft/NFTTokenItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}
Expand Down Expand Up @@ -154,10 +155,12 @@ class NFTTokenItem extends Component {
</div>
}

let tokenImage = image.startsWith('http') ? proxifyNFTImage(image) : image

return <a href={link} target='_blank' rel='noopener noreferrer'>
<div className={'NFTTokenItem ' + (isCollection && isMy ? ' collection' : '')}
title={(isCollection && isMy) ? tt('nft_tokens_jsx.your_token') : ''}>
<img className='token-image' src={image} alt='' title={data.title}/>
<img className='token-image' src={tokenImage} alt='' title={data.title}/>
{!isMy && <Link to={'/@' + token.owner} className='token-owner' title={tt('nft_tokens_jsx.owner')}>
{'@' + token.owner}
</Link>}
Expand Down
84 changes: 81 additions & 3 deletions app/components/modules/nft/CreateNFTCollection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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 (<div className='CreateNFTCollection'>
<CloseButton onClick={onClose} />
Expand Down Expand Up @@ -287,8 +342,18 @@ class CreateNFTCollection extends Component {
<div className='row'>
<div className='column small-12'>
<div className='input-group' style={{marginBottom: 5}}>
<Field name='image' type='text' onBlur={this.onImageBlur}
onChange={(e) => this.onImageChange(e, values, setFieldValue)} />
<a onMouseDown={this.onUploadImageClick}
style={selectorStyleCover}>
{imageUploading ? `${tt(`user_saga_js.image_upload.uploading`)} ...` : tt(`g.upload`)}
</a>
<Dropzone style={{width: `100%`}}
onDrop={(af, rf) => this.onDropImage(af, rf, values, setFieldValue)}
className={'none'}
disableClick multiple={false} accept="image/*"
ref={(node) => { this.dropzone = node; }}>
<Field name='image' type='text' onBlur={this.onImageBlur}
onChange={(e) => this.onImageChange(e, values, setFieldValue)} />
</Dropzone>
<img src={values.image || 'empty'} className='image-preview' style={{ visibility: (showImage && values.image) ? 'visible' : 'hidden' }} />
</div>
<ErrorMessage name='image' component='div' className='error' />
Expand Down Expand Up @@ -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
) => {
Expand Down
84 changes: 81 additions & 3 deletions app/components/modules/nft/IssueNFTToken.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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 (<div className='IssueNFTToken'>
<CloseButton onClick={onClose} />
Expand Down Expand Up @@ -271,8 +326,18 @@ class IssueNFTToken extends Component {
<div className='row'>
<div className='column small-12'>
<div className='input-group' style={{marginBottom: 5}}>
<Field name='image' type='text' onBlur={this.onImageBlur}
onChange={(e) => this.onImageChange(e, values, setFieldValue)} />
<a onMouseDown={this.onUploadImageClick}
style={selectorStyleCover}>
{imageUploading ? `${tt(`user_saga_js.image_upload.uploading`)} ...` : tt(`g.upload`)}
</a>
<Dropzone style={{width: `100%`}}
onDrop={(af, rf) => this.onDropImage(af, rf, values, setFieldValue)}
className={'none'}
disableClick multiple={false} accept="image/*"
ref={(node) => { this.dropzone = node; }}>
<Field name='image' disabled={imageUploading} type='text' onBlur={this.onImageBlur}
onChange={(e) => this.onImageChange(e, values, setFieldValue)} />
</Dropzone>
<img src={values.image || 'empty'} className='image-preview' style={{ visibility: (showImage && values.image) ? 'visible' : 'hidden' }} />
</div>
<ErrorMessage name='image' component='div' className='error' />
Expand Down Expand Up @@ -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
) => {
Expand Down
5 changes: 4 additions & 1 deletion app/redux/UserSaga_UploadImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -198,4 +198,7 @@ function* uploadImage(action) {
};

xhr.send(formData);
} catch (err) {
console.error(err)
}
}
8 changes: 8 additions & 0 deletions app/utils/ProxifyUrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 529c0e1

Please sign in to comment.