feat: add art selector

This commit is contained in:
bartosz-lipinski 2021-04-22 00:53:24 -05:00
parent a58a3baf39
commit 0fcbf48718
5 changed files with 106 additions and 30 deletions

View File

@ -416,11 +416,11 @@ export function AccountsProvider({ children = null as any }) {
if (!connection || !publicKey) {
setTokenAccounts([]);
} else {
// precacheUserTokenAccounts(connection, LEND_HOST_FEE_ADDRESS);
precacheUserTokenAccounts(connection, LEND_HOST_FEE_ADDRESS);
// precacheUserTokenAccounts(connection, publicKey).then(() => {
// setTokenAccounts(selectUserAccounts());
// });
precacheUserTokenAccounts(connection, publicKey).then(() => {
setTokenAccounts(selectUserAccounts());
});
// This can return different types of accounts: token-account, mint, multisig
// TODO: web3.js expose ability to filter.

View File

@ -53,6 +53,31 @@ code {
}
}
.ant-card-cover {
position: relative;
}
.card-close-button {
position: absolute;
top: 5px;
left: 5px;
z-index: 1;
width: 30px;
height: 30px;
border-radius: 30px;
background-color: #434343 !important;
:hover {
background-color: #434343;
}
}
.text-center {
align-self: center;
margin-left: auto;
margin-right: auto;
}
.ant-tabs-tab-active {
}

View File

@ -1,5 +1,5 @@
import React, { useLayoutEffect, useState } from 'react';
import { Card, Avatar, CardProps } from 'antd';
import { Card, Avatar, CardProps, Button } from 'antd';
import { MetadataCategory } from '@oyster/common';
import { ArtContent } from './../ArtContent';
import './index.less';
@ -15,15 +15,23 @@ export interface ArtCardProps extends CardProps {
artist?: string;
preview?: boolean;
small?: boolean;
close?: () => void;
}
export const ArtCard = (props: ArtCardProps) => {
const { className, small, category, image, name, preview, artist, ...rest } = props;
const { className, small, category, image, name, preview, artist, close, ...rest } = props;
return (
<Card
hoverable={true}
className={`art-card ${small ? 'small' : ''} ${className}`}
cover={<ArtContent category={category} content={image} preview={preview} />}
cover={<>
{close && <Button className="card-close-button" shape="circle" onClick={(e) => {
e.stopPropagation();
e.preventDefault();
close();
}} >X</Button>}
<ArtContent category={category} content={image} preview={preview} />
</>}
{...rest}
>
<Meta

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import {
Row,
Button,
@ -25,15 +25,32 @@ export const ArtSelector = (props: ArtSelectorProps) => {
const items = useUserArts();
const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set(props.selected.map(item => item.pubkey.toBase58())));
const map = useMemo(() => items.reduce((acc, item) => {
acc.set(item.pubkey.toBase58(), item.info);
return acc;
}, new Map<string, Metadata>()), [items]);
const [visible, setVisible] = useState(false);
const showModal = () => {
const open = () => {
clear();
setVisible(true);
};
useEffect(() => {
props.setSelected(items.filter(item => selectedItems.has(item.pubkey.toBase58())));
}, [selectedItems]);
const close = () => {
setVisible(false);
};
const clear = () => {
setSelectedItems(new Set());
};
const confirm = () => {
let list = items.filter(item => selectedItems.has(item.pubkey.toBase58()))
setSelected(list);
close();
}
const breakpointColumnsObj = {
default: 4,
@ -44,8 +61,37 @@ export const ArtSelector = (props: ArtSelectorProps) => {
return (
<>
<Button {...rest} onClick={() => showModal} />
<Modal visible={visible}>
<Masonry
breakpointCols={breakpointColumnsObj}
className="my-masonry-grid"
columnClassName="my-masonry-grid_column"
>
{[...selectedItems.keys()].map(m => {
const item = map.get(m);
if (!item) {
return;
}
return <ArtCard key={m}
image={item.extended?.image}
category={item.extended?.category}
name={item?.name}
symbol={item.symbol}
preview={false}
onClick={open}
close={() => {
setSelectedItems(new Set([...selectedItems.keys()].filter(_ => _ !== m)));
confirm();
}}
/>;
})}
{(allowMultiple || selectedItems.size === 0) && <div className="ant-card ant-card-bordered ant-card-hoverable art-card" style={{ width: 200, height: 300, display: 'flex' }} onClick={open} >
<span className="text-center">Add an NFT</span>
</div>}
</Masonry>
<Modal visible={visible} onCancel={close} onOk={confirm} width="100" footer={null}>
<Row className="call-to-action" style={{ marginBottom: 0 }}>
<h2>Select the NFT you want to sell</h2>
<p style={{ fontSize: '1.2rem' }}>
@ -64,13 +110,17 @@ export const ArtSelector = (props: ArtSelectorProps) => {
const onSelect = () => {
let list = [...selectedItems.keys()];
if (props.allowMultiple) {
if (allowMultiple) {
list = [];
}
isSelected ?
setSelectedItems(new Set(list.filter(item => item !== id))) :
setSelectedItems(new Set([...list, id]));
if(!allowMultiple) {
confirm();
}
};
return <ArtCard key={id}
@ -89,9 +139,7 @@ export const ArtSelector = (props: ArtSelectorProps) => {
<Button
type="primary"
size="large"
onClick={() => {
// TODO;
}}
onClick={confirm}
className="action-btn"
>
Confirm

View File

@ -242,9 +242,9 @@ export const AuctionCreateView = () => {
.map(step => <Step title={step[0]} />)}
</Steps>
</Col>}
<Col {...(saving ? { xl: 24 } : { xl: 16 })}>
<Col {...(saving ? { xl: 24 } : { xl: 16, md: 17 })}>
{stepsByCategory[attributes.category][step][1]}
{(0 < step && step < stepsByCategory[attributes.category].length) && <Button onClick={() => gotoNextStep(step - 1)}>Back</Button>}
{(0 < step && step < stepsByCategory[attributes.category].length) && <Button style={{ width: '100%' }} onClick={() => gotoNextStep(step - 1)}>Back</Button>}
</Col>
</Row>
</>
@ -327,18 +327,10 @@ const CopiesStep = (props: {
useEffect(() => {
props.setAttributes({
...props.attributes,
// TODO: add items
items: items.filter(item => selectedItems.has(item.pubkey.toBase58()))
})
}, [selectedItems]);
const breakpointColumnsObj = {
default: 4,
1100: 3,
700: 2,
500: 1
};
return (
<>
<Row className="call-to-action" style={{ marginBottom: 0 }}>
@ -348,8 +340,11 @@ const CopiesStep = (props: {
</p>
</Row>
<Row className="content-action">
<Col>
<ArtSelector selected={[]} setSelected={() => { }} allowMultiple={false}>Select NFT</ArtSelector>
<Col xl={24}>
<ArtSelector
selected={items.filter(item => selectedItems.has(item.pubkey.toBase58()))}
setSelected={(items) => setSelectedItems(new Set(items.map(item => item.pubkey.toBase58())))}
allowMultiple={false}>Select NFT</ArtSelector>
<label className="action-field">
<span className="field-title">How many copies do you want to create?</span>
<span className="field-info">Each copy will be given unique edition number e.g. 1 of 30</span>