From 5fd9c5965457992b0a1112842a77830e499bfaf7 Mon Sep 17 00:00:00 2001 From: Barry Gitarts Date: Mon, 13 May 2019 08:56:50 -0400 Subject: [PATCH] add create delegate --- src/components/MainCointainer.jsx | 2 + src/components/projects/CreateDelegate.jsx | 405 +++++++++++++++++++++ 2 files changed, 407 insertions(+) create mode 100644 src/components/projects/CreateDelegate.jsx diff --git a/src/components/MainCointainer.jsx b/src/components/MainCointainer.jsx index 061c541..33fd552 100644 --- a/src/components/MainCointainer.jsx +++ b/src/components/MainCointainer.jsx @@ -28,6 +28,7 @@ import Projects from './projects/Projects' import Project from './projects/Project' import BackProject from './projects/BackProject' import CreateProject from './projects/CreateProject' +import CreateDelegate from './projects/CreateDelegate' const drawerWidth = 240 @@ -189,6 +190,7 @@ class PersistentDrawerLeft extends React.Component { } /> + } /> {this.props.children} diff --git a/src/components/projects/CreateDelegate.jsx b/src/components/projects/CreateDelegate.jsx new file mode 100644 index 0000000..b6bef05 --- /dev/null +++ b/src/components/projects/CreateDelegate.jsx @@ -0,0 +1,405 @@ +/*global Buffer*/ +import React, { createRef, useState, useContext } from 'react' +import { Formik } from 'formik' +import LiquidPledging from '../../embarkArtifacts/contracts/LiquidPledging' +import TextField from '@material-ui/core/TextField' +import Divider from '@material-ui/core/Divider' +import FormControlLabel from '@material-ui/core/FormControlLabel' +import Switch from '@material-ui/core/Switch' +import Button from '@material-ui/core/Button' +import InputAdornment from '@material-ui/core/InputAdornment' +import CloudUpload from '@material-ui/icons/CloudUpload' +import { withStyles } from '@material-ui/core/styles' +import { formatForIpfs, uploadToIpfs, formatMedia, isWeb } from '../../utils/ipfs' +import { FundingContext } from '../../context' +import {ZERO_ADDRESS} from '../../utils/address' +import CurrencySelect from '../base/CurrencySelect' + +const { addDelegate } = LiquidPledging.methods + + +const hoursToSeconds = hours => hours * 60 * 60 +const helperText = 'The length of time in hours the Delegate can be vetoed. Whenever this delegate is in a delegate chain the time allowed to veto any event must be greater than or equal to this time' + +const styles = theme => ({ + root: { + display: 'grid', + gridTemplateColumns: 'repeat(12, [col] 1fr)', + gridTemplateRows: 'repeat(5, [row] auto)', + gridColumnGap: '1em', + gridRowGap: '3ch', + fontFamily: theme.typography.fontFamily, + [theme.breakpoints.up('sm')]: { + margin: '1.75rem 4.5rem' + } + }, + title: { + display: 'grid', + fontSize: '2.5rem', + gridColumnStart: '1', + gridColumnEnd: '13', + gridRowStart: '1', + gridRowEnd: '6', + textAlign: 'center' + }, + submissionRoot: { + display: 'grid', + gridTemplateColumns: 'repeat(12, [col] 1fr)', + gridTemplateRows: 'repeat(5, [row] auto)', + gridColumnGap: '1em', + gridColumnStart: '1', + gridColumnEnd: '13', + gridRowGap: '2ch', + }, + formControl: { + gridColumnStart: '6' + }, + formButton: { + gridColumnStart: '1', + gridColumnEnd: '13', + height: '50px' + }, + textField: { + gridColumnStart: '1', + gridColumnEnd: '13' + }, + textInput: { + fontSize: '2rem' + } +}) + + +const createJSON = values => { + const { + title, + subtitle, + creator, + avatar, + goal, + goalToken, + video, + isPlaying, + description + } = values + + const manifest = { + title, + subtitle, + creator, + avatar: formatMedia(avatar), + goal, + goalToken, + description, + media: { + isPlaying, + type: 'video' + } + } + + if (isWeb(video)) Object.assign(manifest.media, { url: formatMedia(video) }) + else Object.assign(manifest.media, { file: formatMedia(video) }) + return JSON.stringify(manifest, null, 2) +} + +const Title = ({ className }) => ( +
+
Create Delegate
+ +
+) + +let uploadInput = createRef() +const getDelegateId = response => { + const { events: { DelegateAdded: { returnValues: { idDelegate } } } } = response + return idDelegate +} +const addDelegateSucessMsg = response => { + const { events: { DelegateAdded: { returnValues: { idDelegate } } } } = response + return `Delegate created with ID of ${idDelegate}, will redirect to your new delegate page in a few seconds` +} +const SubmissionSection = ({ classes, history }) => { + const [uploads, setUploads] = useState({}) + const { account, openSnackBar } = useContext(FundingContext) + return ( + { + const { title, commitTime } = values + const manifest = createJSON(values) + let fileLists = [] + Object.keys(uploads).forEach(k => { + fileLists = [...fileLists, formatForIpfs(uploads[k][0])] + }) + fileLists.push({ + path: '/root/manifest.json', content: Buffer.from(manifest) + }) + const contentHash = await uploadToIpfs(fileLists) + const args = [title, contentHash, hoursToSeconds(commitTime), ZERO_ADDRESS] + addDelegate(...args) + .estimateGas({ from: account }) + .then(async gas => { + addDelegate(...args) + .send({ from: account, gas: gas + 100 }) + .then(res => { + console.log({res}) + openSnackBar('success', addDelegateSucessMsg(res)) + setTimeout(() => { + history.push(`/delegate/${getDelegateId(res)}`) + resetForm() + }, 5000) + }) + .catch(e => openSnackBar('error', e)) + }) + console.log({manifest, values, uploads, fileLists, contentHash}) + + }} + > + {({ + values, + errors: _errors, + touched: _touched, + handleChange, + handleBlur, + handleSubmit, + setFieldValue, + setStatus, + status, + isSubmitting + }) => { + return ( +
+ { + uploadInput = input + }} + type="file" + multiple + onChange={ + (e) => { + const file = e.target.files + const {activeField} = status + setFieldValue(activeField, file[0]['name']) + setUploads({...uploads, [activeField]: file}) + setStatus({ + ...status, + activeField: null + }) + } + } + style={{display: 'none'}} + /> + + + + + + { + const activeField = 'avatar' + setStatus({ ...status, activeField }) + uploadInput.click() + } + } + /> + + ), + classes: { + input: classes.textInput + } + }} + id="avatar" + name="avatar" + label="Upload or enter link to delegate avatar" + placeholder="upload or enter link to delegate avatar" + margin="normal" + variant="outlined" + onChange={handleChange} + onBlur={handleBlur} + value={values.avatar || ''} + /> + + + + { + const activeField = 'video' + setStatus({ ...status, activeField }) + uploadInput.click() + } + } + /> + + ), + classes: { + input: classes.textInput + } + }} + id="video" + name="video" + label="Upload video or enter url" + placeholder="Upload video or enter url" + margin="normal" + variant="outlined" + onChange={handleChange} + onBlur={handleBlur} + value={values.video || ''} + /> + + } + label="Autoplay video?" + /> + + + + ) + } + } +
+ ) +} + +function CreateDelegate({ classes, history }) { + return ( +
+ + <SubmissionSection classes={classes} history={history} /> + </div> + ) +} + +const StyledDelegate = withStyles(styles)(CreateDelegate) +export default StyledDelegate