import * as React from 'react'
import { storiesOf } from '@storybook/react'
import {
IPreviewController,
PreviewCamera,
PreviewEmote,
PreviewProjection,
WearableWithBlobs
} from '@dcl/schemas/dist/dapps/preview'
import { BodyShape, Metrics } from '@dcl/schemas/dist/platform/item'
import { WearableCategory } from '@dcl/schemas'
import { Button } from '../Button/Button'
import { Navbar } from '../Navbar/Navbar'
import { Tabs } from '../Tabs/Tabs'
import { Page } from '../Page/Page'
import { Hero } from '../Hero/Hero'
import { Container } from '../Container/Container'
import { Header } from '../Header/Header'
import { Footer } from '../Footer/Footer'
import { Row } from '../Row/Row'
import { Center } from '../Center/Center'
import { SliderField } from '../SliderField/SliderField'
import { WearablePreview } from './WearablePreview'
import { EmoteControls } from './EmoteControls'
import './WearablePreview.stories.css'
const getRandomHex = () => {
return '#' + Math.random().toString(16).slice(2, 8)
}
const getRandomProfile = () => {
return 'default' + ((Math.random() * 50) | 0)
}
const RandomConfigProvider = (props: {
children: (hair: string, skin: string, profile: string) => React.ReactElement
}) => {
const [hair, setHair] = React.useState(getRandomHex())
const [skin, setSkin] = React.useState(getRandomHex())
const [profile, setProfile] = React.useState(getRandomProfile())
React.useEffect(() => {
setInterval(() => {
setHair(getRandomHex())
setSkin(getRandomHex())
setProfile(getRandomProfile())
}, 5000)
}, [])
return props.children(hair, skin, profile)
}
function toWearableWithBlobs(file: File, isEmote = false): WearableWithBlobs {
return {
id: 'some-id',
name: '',
description: '',
image: '',
thumbnail: '',
i18n: [],
data: {
category: WearableCategory.HAT,
hides: [],
replaces: [],
tags: [],
representations: [
{
bodyShapes: [BodyShape.MALE, BodyShape.FEMALE],
mainFile: 'model.glb',
contents: [
{
key: 'model.glb',
blob: file
}
],
overrideHides: [],
overrideReplaces: []
}
]
},
emoteDataV0: isEmote ? { loop: false } : undefined
}
}
storiesOf('WearablePreview', module)
.add('Preview an item', () => (
))
.add('Preview a token', () => (
))
.add('Preview a token from mumbai', () => (
))
.add('Preview a texture wearable', () => (
))
.add('Using custom skin', () => (
))
.add('Using custom hair', () => (
))
.add('Using custom shape', () => (
))
.add('Using a profile', () => (
))
.add('Using a profile + emote', () => (
))
.add('Using a wearable preview + profile + emote', () => (
))
.add('Using static camera', () => (
))
.add('Using onLoad callback', () => (
console.log('loaded!')}
/>
))
.add('Using onError callback', () => (
console.error(error.message)}
/>
))
.add('Use as Hero', () => (
Atlas
Market
My Assets
This page has a hero
))
.add('With hot reload', () => (
{(hair, skin, profile) => (
console.log('loaded!')}
/>
)}
))
.add('From URL', () => (
))
.add('From base64', () => (
))
.add('Without auto rotation', () => (
))
.add('Without background (or transparent background)', () => (
))
.add('With custom background color', () => (
))
.add('Take screenshot and metrics', () => {
const [screenshot, setScreenshot] = React.useState('')
const [metrics, setMetrics] = React.useState(null)
const ref = React.useRef(null)
const onLoad = React.useCallback(() => {
ref.current = ref.current ?? WearablePreview.createController('some-id')
}, [])
return (
{screenshot &&
}
{metrics && {JSON.stringify(metrics)}
}
)
})
.add('With EmoteControls', () => {
return (
)
})
.add('Emote Events', () => {
const [goTo, setGoTo] = React.useState('0')
const [screenshot, setScreenshot] = React.useState('')
const [length, setLength] = React.useState('')
const ref = React.useRef(null)
const onLoad = React.useCallback(() => {
ref.current = ref.current ?? WearablePreview.createController('some-id')
}, [])
return (
)
})
.add('Preview from a file', () => {
const inputRef = React.useRef()
const [file, setFile] = React.useState(null)
return (
{file ? (
) : (
setFile(inputRef.current.files[0])}
/>
)}
)
})
.add('Emote thumbnail picker', () => {
const inputRef = React.useRef()
const [file, setFile] = React.useState(null)
const [screenshot, setScreenshot] = React.useState('')
const [length, setLength] = React.useState(0)
const ref = React.useRef(null)
const onLoad = React.useCallback(async () => {
ref.current =
ref.current ?? WearablePreview.createController('thumbnail-picker')
setLength(await ref.current.emote.getLength())
}, [])
return (
{file ? (
<>
{screenshot &&
}
{length > 0 && (
{
await ref.current.emote.pause()
await ref.current.emote.goTo(value / 100)
}}
/>
)}
>
) : (
setFile(inputRef.current.files[0])}
/>
)}
)
})
.add('With offset', () => (
))
.add('Camera from the front', () => (
))
.add('Camera from the top', () => (
))
.add('Different projections', () => (
))
.add('Custom peerUrl', () => (
))
.add('Without fade effect', () => (
{(_hair, _skin, profile) => (
)}
))