mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
first go at randomly-generated ocean waves
This commit is contained in:
parent
08c42e8fa6
commit
d3810168aa
1236
package-lock.json
generated
1236
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -32,6 +32,7 @@
|
|||||||
"axios": "^0.24.0",
|
"axios": "^0.24.0",
|
||||||
"chart.js": "^2.9.4",
|
"chart.js": "^2.9.4",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
|
"d3": "^7.1.1",
|
||||||
"date-fns": "^2.25.0",
|
"date-fns": "^2.25.0",
|
||||||
"decimal.js": "^10.3.1",
|
"decimal.js": "^10.3.1",
|
||||||
"dom-confetti": "^0.2.2",
|
"dom-confetti": "^0.2.2",
|
||||||
@ -80,6 +81,7 @@
|
|||||||
"@graphql-codegen/typescript-react-apollo": "^3.1.6",
|
"@graphql-codegen/typescript-react-apollo": "^3.1.6",
|
||||||
"@svgr/webpack": "^5.5.0",
|
"@svgr/webpack": "^5.5.0",
|
||||||
"@types/chart.js": "^2.9.32",
|
"@types/chart.js": "^2.9.32",
|
||||||
|
"@types/d3": "^7.1.0",
|
||||||
"@types/js-cookie": "^3.0.0",
|
"@types/js-cookie": "^3.0.0",
|
||||||
"@types/loadable__component": "^5.13.1",
|
"@types/loadable__component": "^5.13.1",
|
||||||
"@types/lodash.debounce": "^4.0.3",
|
"@types/lodash.debounce": "^4.0.3",
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { renderStaticWaves } from './oceanWaves'
|
||||||
|
|
||||||
export interface NftOptions {
|
export interface NftOptions {
|
||||||
name: string
|
name: string
|
||||||
symbol: string
|
symbol: string
|
||||||
@ -24,9 +26,10 @@ function encodeSvg(svgString: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function generateNftOptions(): NftOptions {
|
export function generateNftOptions(): NftOptions {
|
||||||
// TODO: generate new SVG image here
|
|
||||||
// @images/arrow.svg test
|
// @images/arrow.svg test
|
||||||
const image = `<svg><path d="M0 10.4304L16.3396 10.4304L8.88727 17.6833L10.2401 19L20 9.5L10.2401 0L8.88727 1.31491L16.3396 8.56959L0 8.56959V10.4304Z" /></svg>`
|
const image = renderStaticWaves()
|
||||||
|
// const image = new XMLSerializer().serializeToString(waves)
|
||||||
|
// const image = `<svg><path d="M0 10.4304L16.3396 10.4304L8.88727 17.6833L10.2401 19L20 9.5L10.2401 0L8.88727 1.31491L16.3396 8.56959L0 8.56959V10.4304Z" /></svg>`
|
||||||
|
|
||||||
const newNft: NftOptions = {
|
const newNft: NftOptions = {
|
||||||
name: 'Ocean Asset v4 NFT',
|
name: 'Ocean Asset v4 NFT',
|
||||||
|
50
src/@utils/oceanWaves.ts
Normal file
50
src/@utils/oceanWaves.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import * as d3 from 'd3'
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ocean Protocol D3 waves
|
||||||
|
* https://oceanprotocol.com/art
|
||||||
|
* Based off of Bostock's Circle Wave
|
||||||
|
* https://bl.ocks.org/mbostock/2d466ec3417722e3568cd83fc35338e3
|
||||||
|
*/
|
||||||
|
export function renderStaticWaves(): string {
|
||||||
|
const svg = d3.create('svg')
|
||||||
|
const width = 1000
|
||||||
|
const height = 250
|
||||||
|
console.log(height)
|
||||||
|
const x = d3.scaleLinear().range([0, width])
|
||||||
|
const angles = d3.range(Math.random(), 4 * Math.PI, Math.PI / 20)
|
||||||
|
|
||||||
|
const path = svg
|
||||||
|
// .append('rect')
|
||||||
|
// .attr('fill', '#fff')
|
||||||
|
// .attr('width', '100%')
|
||||||
|
// .attr('height', '100%')
|
||||||
|
.append('g')
|
||||||
|
.attr('transform', `translate(${width / -4}, ${height / 2})`)
|
||||||
|
.attr('fill', 'none')
|
||||||
|
.attr('stroke-width', 2)
|
||||||
|
.selectAll('path')
|
||||||
|
.data(['#FF4092', '#E000CF', '#8B98A9', '#E2E2E2'])
|
||||||
|
.enter()
|
||||||
|
.append('path')
|
||||||
|
.attr('stroke', (d) => d)
|
||||||
|
.style('mix-blend-mode', 'darken')
|
||||||
|
.datum((d, i) => {
|
||||||
|
return d3
|
||||||
|
.line()
|
||||||
|
.curve(d3.curveBasisOpen)
|
||||||
|
.x((angles: any) => x(angles / 4))
|
||||||
|
.y((angles: any) => {
|
||||||
|
const t = d3.now() / 3000
|
||||||
|
return (
|
||||||
|
Math.cos(angles * 8 - (i * 2 * Math.PI) / 10 + t) *
|
||||||
|
Math.pow((2 + Math.cos(angles - t)) / 2, 4) *
|
||||||
|
15
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
path.attr('d', (d) => d(angles as any))
|
||||||
|
|
||||||
|
return `<svg>${svg.node().innerHTML}</svg>`
|
||||||
|
}
|
@ -6,9 +6,31 @@ export interface FileMetadata {
|
|||||||
contentLength: string
|
contentLength: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getEncryptedFileUrls(
|
||||||
|
files: string[],
|
||||||
|
providerUrl: string,
|
||||||
|
did: string,
|
||||||
|
accountId: string
|
||||||
|
): Promise<string> {
|
||||||
|
try {
|
||||||
|
// https://github.com/oceanprotocol/provider/blob/v4main/API.md#encrypt-endpoint
|
||||||
|
const url = `${providerUrl}/api/v1/services/encrypt`
|
||||||
|
const response: AxiosResponse<{ encryptedDocument: string }> =
|
||||||
|
await axios.post(url, {
|
||||||
|
documentId: did,
|
||||||
|
signature: '', // TODO: add signature
|
||||||
|
publisherAddress: accountId,
|
||||||
|
document: files
|
||||||
|
})
|
||||||
|
return response?.data?.encryptedDocument
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error parsing json: ' + error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function getFileInfo(
|
export async function getFileInfo(
|
||||||
url: string | DID,
|
url: string | DID,
|
||||||
providerUri: string,
|
providerUrl: string,
|
||||||
cancelToken: CancelToken
|
cancelToken: CancelToken
|
||||||
): Promise<FileMetadata[]> {
|
): Promise<FileMetadata[]> {
|
||||||
let postBody
|
let postBody
|
||||||
@ -22,7 +44,7 @@ export async function getFileInfo(
|
|||||||
url
|
url
|
||||||
}
|
}
|
||||||
const response: AxiosResponse<FileMetadata[]> = await axios.post(
|
const response: AxiosResponse<FileMetadata[]> = await axios.post(
|
||||||
`${providerUri}/api/v1/services/fileinfo`,
|
`${providerUrl}/api/v1/services/fileinfo`,
|
||||||
postBody,
|
postBody,
|
||||||
{
|
{
|
||||||
cancelToken
|
cancelToken
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
.advancedBtn {
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
import React, { ReactElement, useState, FormEvent, ChangeEvent } from 'react'
|
|
||||||
import Input from '@shared/FormInput'
|
|
||||||
import Button from '@shared/atoms/Button'
|
|
||||||
import { Field } from 'formik'
|
|
||||||
import styles from './AdvancedSettings.module.css'
|
|
||||||
|
|
||||||
export default function AdvancedSettings(prop: {
|
|
||||||
content: FormStepContent
|
|
||||||
handleFieldChange: (
|
|
||||||
e: ChangeEvent<HTMLInputElement>,
|
|
||||||
field: FormFieldContent
|
|
||||||
) => void
|
|
||||||
}): ReactElement {
|
|
||||||
const [showAdvancedSettings, setShowAdvancedSettings] =
|
|
||||||
useState<boolean>(false)
|
|
||||||
|
|
||||||
function toggleAdvancedSettings(e: FormEvent<Element>) {
|
|
||||||
e.preventDefault()
|
|
||||||
setShowAdvancedSettings(!!showAdvancedSettings)
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Button
|
|
||||||
className={styles.advancedBtn}
|
|
||||||
style="text"
|
|
||||||
size="small"
|
|
||||||
onClick={toggleAdvancedSettings}
|
|
||||||
>
|
|
||||||
Advanced Settings
|
|
||||||
</Button>
|
|
||||||
{showAdvancedSettings &&
|
|
||||||
prop.content.fields.map(
|
|
||||||
(field: FormFieldContent) =>
|
|
||||||
field.advanced === true && (
|
|
||||||
<Field
|
|
||||||
key={field.name}
|
|
||||||
{...field}
|
|
||||||
options={field.options}
|
|
||||||
component={Input}
|
|
||||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
|
||||||
prop.handleFieldChange(e, field)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
@ -18,4 +18,17 @@
|
|||||||
height: 128px;
|
height: 128px;
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh {
|
||||||
|
position: absolute;
|
||||||
|
right: calc(var(--spacer) / 4);
|
||||||
|
bottom: calc(var(--spacer) / 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh svg {
|
||||||
|
fill: var(--brand-pink);
|
||||||
|
width: var(--font-size-mini);
|
||||||
|
height: var(--font-size-mini);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
import Button from '@shared/atoms/Button'
|
||||||
import { InputProps } from '@shared/FormInput'
|
import { InputProps } from '@shared/FormInput'
|
||||||
import { generateNftOptions } from '@utils/nft'
|
import { generateNftOptions } from '@utils/nft'
|
||||||
import { useField } from 'formik'
|
import { useField } from 'formik'
|
||||||
import React, { ReactElement, useEffect } from 'react'
|
import React, { ReactElement, useEffect } from 'react'
|
||||||
|
import Refresh from '@images/refresh.svg'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
|
|
||||||
export default function Nft(props: InputProps): ReactElement {
|
export default function Nft(props: InputProps): ReactElement {
|
||||||
@ -19,6 +21,19 @@ export default function Nft(props: InputProps): ReactElement {
|
|||||||
<div className={styles.nft}>
|
<div className={styles.nft}>
|
||||||
<figure className={styles.image}>
|
<figure className={styles.image}>
|
||||||
<img src={field?.value?.image} width="128" height="128" />
|
<img src={field?.value?.image} width="128" height="128" />
|
||||||
|
<Button
|
||||||
|
style="text"
|
||||||
|
size="small"
|
||||||
|
className={styles.refresh}
|
||||||
|
title="Generate new image"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
const nftOptions = generateNftOptions()
|
||||||
|
helpers.setValue({ ...nftOptions })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Refresh />
|
||||||
|
</Button>
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
<div className={styles.token}>
|
<div className={styles.token}>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import axios, { AxiosResponse } from 'axios'
|
import { getEncryptedFileUrls } from '@utils/provider'
|
||||||
import { sha256 } from 'js-sha256'
|
import { sha256 } from 'js-sha256'
|
||||||
import slugify from 'slugify'
|
import slugify from 'slugify'
|
||||||
import { FormPublishData } from './_types'
|
import { FormPublishData } from './_types'
|
||||||
@ -10,28 +10,6 @@ export function getFieldContent(
|
|||||||
return fields.filter((field: FormFieldContent) => field.name === fieldName)[0]
|
return fields.filter((field: FormFieldContent) => field.name === fieldName)[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getEncryptedFileUrls(
|
|
||||||
files: string[],
|
|
||||||
providerUrl: string,
|
|
||||||
did: string,
|
|
||||||
accountId: string
|
|
||||||
): Promise<string> {
|
|
||||||
try {
|
|
||||||
// https://github.com/oceanprotocol/provider/blob/v4main/API.md#encrypt-endpoint
|
|
||||||
const url = `${providerUrl}/api/v1/services/encrypt`
|
|
||||||
const response: AxiosResponse<{ encryptedDocument: string }> =
|
|
||||||
await axios.post(url, {
|
|
||||||
documentId: did,
|
|
||||||
signature: '', // TODO: add signature
|
|
||||||
publisherAddress: accountId,
|
|
||||||
document: files
|
|
||||||
})
|
|
||||||
return response?.data?.encryptedDocument
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error parsing json: ' + error.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getUrlFileExtension(fileUrl: string): string {
|
function getUrlFileExtension(fileUrl: string): string {
|
||||||
const splittedFileUrl = fileUrl.split('.')
|
const splittedFileUrl = fileUrl.split('.')
|
||||||
return splittedFileUrl[splittedFileUrl.length - 1]
|
return splittedFileUrl[splittedFileUrl.length - 1]
|
||||||
|
Loading…
Reference in New Issue
Block a user