import React, { useEffect, useState } from 'react' import Form from '../../molecules/Form/index' import { PublishFormSchema, PublishFormUiSchema, publishFormData, PublishFormDataInterface } from '../../../models/PublishForm' import useStoredValue from '../../../hooks/useStoredValue' import { MetaDataMarket } from '../../../@types/MetaData' import { File, MetaData } from '@oceanprotocol/squid' import { isBrowser, toStringNoMS } from '../../../utils' import { toast } from 'react-toastify' import { useRouter } from 'next/router' import styles from './PublishForm.module.css' import utils from 'web3-utils' import AssetModel from '../../../models/Asset' import { useWeb3, useOcean } from '@oceanprotocol/react' import { Service, ServiceCompute } from '@oceanprotocol/squid/dist/node/ddo/Service' declare type PublishFormProps = {} const FILES_DATA_LOCAL_STORAGE_KEY = 'filesData' const PUBLISH_FORM_LOCAL_STORAGE_KEY = 'publishForm' export function getFilesData() { let localFileData: File[] = [] if (isBrowser) { const storedData = localStorage.getItem(FILES_DATA_LOCAL_STORAGE_KEY) if (storedData) { localFileData = localFileData.concat(JSON.parse(storedData) as File[]) } } return localFileData } export function clearFilesData() { if (isBrowser) localStorage.setItem(FILES_DATA_LOCAL_STORAGE_KEY, JSON.stringify([])) } export function transformPublishFormToMetadata( data: PublishFormDataInterface ): MetaDataMarket { const currentTime = toStringNoMS(new Date()) const { title, price, author, license, summary, holder, keywords, termsAndConditions, supportName, supportEmail, dateRange, access } = data const metadata: MetaDataMarket = { main: { ...AssetModel.main, name: title, price: utils.toWei(price.toString()), author, dateCreated: currentTime, datePublished: currentTime, files: getFilesData(), license }, // ------- additional information ------- additionalInformation: { ...AssetModel.additionalInformation, description: summary, copyrightHolder: holder, tags: keywords?.split(','), termsAndConditions, supportName, supportEmail, access: access || 'Download' }, // ------- curation ------- curation: AssetModel.curation } if (dateRange) { const newDateRange = JSON.parse(dateRange) if (newDateRange.length > 1) { metadata.additionalInformation.dateRange = JSON.parse(dateRange) } else if (newDateRange.length === 1) { // eslint-disable-next-line prefer-destructuring metadata.main.dateCreated = newDateRange[0] } } return metadata } const PublishForm: React.FC = () => { const [buttonDisabled, setButtonDisabled] = useState(false) const { web3Connect } = useWeb3() const { ocean, account } = useOcean() const router = useRouter() const [data, updateData] = useStoredValue( PUBLISH_FORM_LOCAL_STORAGE_KEY, publishFormData ) useEffect(() => { setButtonDisabled(!ocean) }, [ocean]) const handleChange = ({ formData }: { formData: PublishFormDataInterface }) => { updateData(formData) } const handleSubmit = async ({ formData }: { formData: PublishFormDataInterface }) => { setButtonDisabled(true) const submittingToast = toast.info('submitting asset', { className: styles.info }) if (ocean == null) { await web3Connect.connect() } if (ocean) { const metadata = transformPublishFormToMetadata(formData) // if services array stays empty, the default access service // will be created by squid-js let services: Service[] = [] if (metadata.additionalInformation.access === 'Compute') { const computeService: ServiceCompute = await ocean.compute.createComputeServiceAttributes( account, metadata.main.price, // Note: a hack without consequences. // Will make metadata.main.datePublished (automatically created by Aquarius) // go out of sync with this service.main.datePublished. toStringNoMS(new Date(Date.now())) ) services = [computeService] } console.log(metadata as MetaData) try { const asset = await ocean.assets.create( metadata as MetaData, account, services ) // Reset the form to initial values updateData(publishFormData) clearFilesData() // User feedback and redirect toast.success('asset created successfully', { className: styles.success }) toast.dismiss(submittingToast) router.push(`/asset/${asset.id}`) } catch (e) { console.log(e) } finally { setButtonDisabled(false) } // Reset the form to initial values // User feedback and redirect } } const handleError = () => toast.error('Please check form. There are some errors', { className: styles.error }) return (
) } export default PublishForm