improve channel edit styling
This commit is contained in:
parent
16bcaf7ceb
commit
0c28dee85e
9 changed files with 265 additions and 245 deletions
|
@ -124,7 +124,7 @@
|
|||
"jsmediatags": "^3.8.1",
|
||||
"json-loader": "^0.5.4",
|
||||
"lbry-format": "https://github.com/lbryio/lbry-format.git",
|
||||
"lbry-redux": "lbryio/lbry-redux#9a676ee311d573b84d11f402d918aeee77be76e1",
|
||||
"lbry-redux": "lbryio/lbry-redux#efccab44cb025a14fd81ec05ffca0314710c8529",
|
||||
"lbryinc": "lbryio/lbryinc#43d382d9b74d396a581a74d87e4c53105e04f845",
|
||||
"lint-staged": "^7.0.2",
|
||||
"localforage": "^1.7.1",
|
||||
|
|
204
src/ui/component/channelEdit/view.jsx
Normal file
204
src/ui/component/channelEdit/view.jsx
Normal file
|
@ -0,0 +1,204 @@
|
|||
// @flow
|
||||
import React, { useState } from 'react';
|
||||
import { parseURI } from 'lbry-redux';
|
||||
import { Form, FormField } from 'component/common/form';
|
||||
import Button from 'component/button';
|
||||
|
||||
import SelectAsset from '../selectAsset/view';
|
||||
|
||||
type Props = {
|
||||
uri: string,
|
||||
|
||||
title: ?string,
|
||||
amount: string,
|
||||
cover: ?string,
|
||||
thumbnail: ?string,
|
||||
location: { search: string },
|
||||
description: string,
|
||||
website: string,
|
||||
email: string,
|
||||
balance: number,
|
||||
tags: Array<string>,
|
||||
locations: Array<string>,
|
||||
languages: Array<string>,
|
||||
|
||||
updateChannel: any => void,
|
||||
|
||||
updateThumb: string => void,
|
||||
updateCover: string => void,
|
||||
setEditing: boolean => void,
|
||||
};
|
||||
|
||||
function ChannelForm(props: Props) {
|
||||
const {
|
||||
uri,
|
||||
title,
|
||||
cover,
|
||||
description,
|
||||
website,
|
||||
email,
|
||||
thumbnail,
|
||||
tags,
|
||||
locations,
|
||||
languages,
|
||||
amount,
|
||||
updateChannel,
|
||||
setEditing,
|
||||
updateThumb,
|
||||
updateCover,
|
||||
} = props;
|
||||
const { claimId } = parseURI(uri);
|
||||
|
||||
// fill this in with sdk data
|
||||
const channelParams = {
|
||||
website: website,
|
||||
email: email,
|
||||
languages: languages || [],
|
||||
cover: cover,
|
||||
description: description,
|
||||
locations: locations || [],
|
||||
title: title,
|
||||
thumbnail: thumbnail,
|
||||
tags: tags || [],
|
||||
claim_id: claimId,
|
||||
amount: amount,
|
||||
};
|
||||
|
||||
const [params, setParams] = useState(channelParams);
|
||||
const [bidError, setBidError] = useState('');
|
||||
|
||||
const MINIMUM_PUBLISH_BID = 0.00000001;
|
||||
// If a user changes tabs, update the url so it stays on the same page if they refresh.
|
||||
// We don't want to use links here because we can't animate the tab change and using links
|
||||
// would alter the Tab label's role attribute, which should stay role="tab" to work with keyboards/screen readers.
|
||||
|
||||
const handleBidChange = (bid: number) => {
|
||||
const { balance, amount } = props;
|
||||
const totalAvailableBidAmount = parseFloat(amount) + parseFloat(balance);
|
||||
setParams({ ...params, amount: bid });
|
||||
setBidError('');
|
||||
if (bid <= 0.0 || isNaN(bid)) {
|
||||
setBidError(__('Deposit cannot be 0'));
|
||||
} else if (totalAvailableBidAmount === bid) {
|
||||
setBidError(__('Please decrease your deposit to account for transaction fees'));
|
||||
} else if (totalAvailableBidAmount < bid) {
|
||||
setBidError(__('Deposit cannot be higher than your balance'));
|
||||
} else if (bid <= MINIMUM_PUBLISH_BID) {
|
||||
setBidError(__('Your deposit must be higher'));
|
||||
}
|
||||
};
|
||||
|
||||
const handleThumbnailChange = (url: string) => {
|
||||
setParams({ ...params, thumbnail: url });
|
||||
updateThumb(url);
|
||||
};
|
||||
|
||||
const handleCoverChange = (url: string) => {
|
||||
setParams({ ...params, cover: url });
|
||||
updateCover(url);
|
||||
};
|
||||
// TODO clear and bail after submit
|
||||
return (
|
||||
<section className={'card--section'}>
|
||||
<div className="help">
|
||||
<p>{__('We can explain...')}</p>
|
||||
<p>
|
||||
{__(
|
||||
"We know this page won't win any design awards, we just wanted to release a very very very basic version that just barely kinda works so people can use it right now. There is a much nicer version being worked on."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<Form onSubmit={channelParams => updateChannel(channelParams)}>
|
||||
<div className="card__content">
|
||||
<SelectAsset
|
||||
onUpdate={v => handleThumbnailChange(v)}
|
||||
currentValue={params.thumbnail}
|
||||
assetName={'Thumbnail'}
|
||||
recommended={'(400x400)'}
|
||||
/>
|
||||
|
||||
<SelectAsset
|
||||
onUpdate={v => handleCoverChange(v)}
|
||||
currentValue={params.cover}
|
||||
assetName={'Cover'}
|
||||
recommended={'(1000x300)'}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="text"
|
||||
name="channel_title2"
|
||||
label={__('Title')}
|
||||
placeholder={__('Titular Title')}
|
||||
disabled={false}
|
||||
value={params.title}
|
||||
onChange={e => setParams({ ...params, title: e.target.value })}
|
||||
/>
|
||||
<FormField
|
||||
className="form-field--price-amount"
|
||||
type="number"
|
||||
name="content_bid2"
|
||||
step="any"
|
||||
label={__('Deposit (LBC)')}
|
||||
postfix="LBC"
|
||||
value={params.amount}
|
||||
error={bidError}
|
||||
min="0.0"
|
||||
disabled={false}
|
||||
onChange={event => handleBidChange(parseFloat(event.target.value))}
|
||||
placeholder={0.1}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="text"
|
||||
name="channel_website2"
|
||||
label={__('Website')}
|
||||
placeholder={__('aprettygoodsite.com')}
|
||||
disabled={false}
|
||||
value={params.website}
|
||||
onChange={e => setParams({ ...params, website: e.target.value })}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="text"
|
||||
name="content_email2"
|
||||
label={__('Email')}
|
||||
placeholder={__('yourstruly@example.com')}
|
||||
disabled={false}
|
||||
value={params.email}
|
||||
onChange={e => setParams({ ...params, email: e.target.value })}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="markdown"
|
||||
name="content_description2"
|
||||
label={__('Description')}
|
||||
placeholder={__('Description of your content')}
|
||||
value={params.description}
|
||||
disabled={false}
|
||||
onChange={text => setParams({ ...params, description: text })}
|
||||
/>
|
||||
<div className={'card__actions'}>
|
||||
<Button
|
||||
button="primary"
|
||||
label={__('Submit')}
|
||||
onClick={() => {
|
||||
updateChannel(params);
|
||||
setEditing(false);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
button="link"
|
||||
label={__('Cancel')}
|
||||
onClick={() => {
|
||||
setParams({ ...channelParams });
|
||||
setEditing(false);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default ChannelForm;
|
|
@ -1,208 +0,0 @@
|
|||
// @flow
|
||||
import React, { useState } from 'react';
|
||||
import { parseURI } from 'lbry-redux';
|
||||
import { Form, FormField } from 'component/common/form';
|
||||
import Button from 'component/button';
|
||||
|
||||
import SelectAsset from '../../component/selectAsset/view';
|
||||
|
||||
type Props = {
|
||||
uri: string,
|
||||
|
||||
title: ?string,
|
||||
amount: string,
|
||||
cover: ?string,
|
||||
thumbnail: ?string,
|
||||
location: { search: string },
|
||||
description: string,
|
||||
website: string,
|
||||
email: string,
|
||||
balance: number,
|
||||
tags: Array<string>,
|
||||
locations: Array<string>,
|
||||
languages: Array<string>,
|
||||
|
||||
updateChannel: any => void,
|
||||
|
||||
updateThumb: string => void,
|
||||
updateCover: string => void,
|
||||
setEditing: boolean => void,
|
||||
};
|
||||
|
||||
function ChannelForm(props: Props) {
|
||||
const {
|
||||
uri,
|
||||
title,
|
||||
cover,
|
||||
description,
|
||||
website,
|
||||
email,
|
||||
thumbnail,
|
||||
tags,
|
||||
locations,
|
||||
languages,
|
||||
amount,
|
||||
updateChannel,
|
||||
setEditing,
|
||||
updateThumb,
|
||||
updateCover,
|
||||
} = props;
|
||||
const { claimId } = parseURI(uri);
|
||||
|
||||
// fill this in with sdk data
|
||||
const channelParams = {
|
||||
website: website,
|
||||
email: email,
|
||||
languages: languages || [],
|
||||
cover: cover,
|
||||
description: description,
|
||||
locations: locations || [],
|
||||
title: title,
|
||||
thumbnail: thumbnail,
|
||||
tags: tags || [],
|
||||
claim_id: claimId,
|
||||
amount: amount,
|
||||
};
|
||||
|
||||
const [params, setParams] = useState(channelParams);
|
||||
const [bidError, setBidError] = useState('');
|
||||
|
||||
const MINIMUM_PUBLISH_BID = 0.00000001;
|
||||
// If a user changes tabs, update the url so it stays on the same page if they refresh.
|
||||
// We don't want to use links here because we can't animate the tab change and using links
|
||||
// would alter the Tab label's role attribute, which should stay role="tab" to work with keyboards/screen readers.
|
||||
|
||||
const handleBidChange = (bid: number) => {
|
||||
const { balance, amount } = props;
|
||||
const totalAvailableBidAmount = parseFloat(amount) + parseFloat(balance);
|
||||
setParams({ ...params, amount: bid });
|
||||
setBidError('');
|
||||
if (bid <= 0.0 || isNaN(bid)) {
|
||||
setBidError(__('Deposit cannot be 0'));
|
||||
} else if (totalAvailableBidAmount === bid) {
|
||||
setBidError(__('Please decrease your deposit to account for transaction fees'));
|
||||
} else if (totalAvailableBidAmount < bid) {
|
||||
setBidError(__('Deposit cannot be higher than your balance'));
|
||||
} else if (bid <= MINIMUM_PUBLISH_BID) {
|
||||
setBidError(__('Your deposit must be higher'));
|
||||
}
|
||||
};
|
||||
|
||||
const handleThumbnailChange = (url: string) => {
|
||||
setParams({ ...params, thumbnail: url });
|
||||
updateThumb(url);
|
||||
};
|
||||
|
||||
const handleCoverChange = (url: string) => {
|
||||
setParams({ ...params, cover: url });
|
||||
updateCover(url);
|
||||
};
|
||||
// TODO clear and bail after submit
|
||||
return (
|
||||
<div className={'card--section'}>
|
||||
<section>
|
||||
<div className={'card__title--flex-between'}>
|
||||
<header className="card__header">
|
||||
<h2 className="card__title">{__('Edit')}</h2>
|
||||
</header>
|
||||
<div className={'card__actions'}>
|
||||
<Button button="primary" label={__('Submit')} onClick={() => updateChannel(params)} />
|
||||
|
||||
<Button
|
||||
button="link"
|
||||
label={__('Cancel')}
|
||||
onClick={() => {
|
||||
setParams({ ...channelParams });
|
||||
setEditing(false);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Form onSubmit={channelParams => updateChannel(channelParams)}>
|
||||
<div className="card__content">
|
||||
<SelectAsset
|
||||
onUpdate={v => handleThumbnailChange(v)}
|
||||
currentValue={params.thumbnail}
|
||||
assetName={'Thumbnail'}
|
||||
recommended={'(400x400)'}
|
||||
/>
|
||||
|
||||
<SelectAsset
|
||||
onUpdate={v => handleCoverChange(v)}
|
||||
currentValue={params.cover}
|
||||
assetName={'Cover'}
|
||||
recommended={'(1000x300)'}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="text"
|
||||
name="channel_title2"
|
||||
label={__('Title')}
|
||||
placeholder={__('Titular Title')}
|
||||
disabled={false}
|
||||
value={params.title}
|
||||
onChange={e => setParams({ ...params, title: e.target.value })}
|
||||
/>
|
||||
<FormField
|
||||
className="form-field--price-amount"
|
||||
type="number"
|
||||
name="content_bid2"
|
||||
step="any"
|
||||
label={__('Deposit (LBC)')}
|
||||
postfix="LBC"
|
||||
value={params.amount}
|
||||
error={bidError}
|
||||
min="0.0"
|
||||
disabled={false}
|
||||
onChange={event => handleBidChange(parseFloat(event.target.value))}
|
||||
placeholder={0.1}
|
||||
// helper={
|
||||
// <BidHelpText
|
||||
// uri={shortUri}
|
||||
// isResolvingUri={isResolvingUri}
|
||||
// amountNeededForTakeover={amountNeededForTakeover}
|
||||
// />
|
||||
// }
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="text"
|
||||
name="channel_website2"
|
||||
label={__('Website')}
|
||||
placeholder={__('aprettygoodsite.com')}
|
||||
disabled={false}
|
||||
value={params.website}
|
||||
onChange={e => setParams({ ...params, website: e.target.value })}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="text"
|
||||
name="content_email2"
|
||||
label={__('Email')}
|
||||
placeholder={__('yourstruly@example.com')}
|
||||
disabled={false}
|
||||
value={params.email}
|
||||
onChange={e => setParams({ ...params, email: e.target.value })}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="markdown"
|
||||
name="content_description2"
|
||||
label={__('Description')}
|
||||
placeholder={__('Description of your content')}
|
||||
value={params.description}
|
||||
disabled={false}
|
||||
onChange={text => setParams({ ...params, description: text })}
|
||||
/>
|
||||
<div className={'card__actions'}>
|
||||
<Button button="primary" label={__('Submit')} onClick={() => updateChannel(params)} />
|
||||
<Button button="link" label={__('Cancel')} onClick={() => setParams({ ...channelParams })} />
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ChannelForm;
|
|
@ -6,7 +6,7 @@ import FileSelector from 'component/common/file-selector';
|
|||
import Button from 'component/button';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import uuid from 'uuid/v4';
|
||||
|
||||
const filters = [
|
||||
{
|
||||
|
@ -61,7 +61,7 @@ function SelectAsset(props: Props) {
|
|||
setUploadStatus(SPEECH_UPLOADING);
|
||||
|
||||
const data = new FormData();
|
||||
const name = uuidv4();
|
||||
const name = uuid();
|
||||
const file = new File([thumbnail], fileName, { type: fileType });
|
||||
data.append('name', name);
|
||||
data.append('file', file);
|
||||
|
|
|
@ -11,7 +11,7 @@ import { formatLbryUriForWeb } from 'util/uri';
|
|||
import ChannelContent from 'component/channelContent';
|
||||
import ChannelAbout from 'component/channelAbout';
|
||||
import ChannelThumbnail from 'component/channelThumbnail';
|
||||
import ChannelForm from 'component/channelForm';
|
||||
import ChannelEdit from 'component/channelEdit';
|
||||
import * as ICONS from 'constants/icons';
|
||||
|
||||
const PAGE_VIEW_QUERY = `view`;
|
||||
|
@ -43,7 +43,7 @@ function ChannelPage(props: Props) {
|
|||
// If a user changes tabs, update the url so it stays on the same page if they refresh.
|
||||
// We don't want to use links here because we can't animate the tab change and using links
|
||||
// would alter the Tab label's role attribute, which should stay role="tab" to work with keyboards/screen readers.
|
||||
const tabIndex = currentView === ABOUT_PAGE ? 1 : 0;
|
||||
const tabIndex = currentView === ABOUT_PAGE || editing ? 1 : 0;
|
||||
const onTabChange = newTabIndex => {
|
||||
let url = formatLbryUriForWeb(uri);
|
||||
let search = '?';
|
||||
|
@ -75,7 +75,7 @@ function ChannelPage(props: Props) {
|
|||
<h1 className="channel__title">
|
||||
{title || channelName}
|
||||
{channelIsMine && !editing && (
|
||||
<Button onClick={() => setEditing(!editing)} icon={ICONS.EDIT} iconSize={49} />
|
||||
<Button title={__('Edit')} onClick={() => setEditing(!editing)} icon={ICONS.EDIT} iconSize={49} />
|
||||
)}
|
||||
</h1>
|
||||
<h2 className="channel__url">
|
||||
|
@ -84,35 +84,34 @@ function ChannelPage(props: Props) {
|
|||
</h2>
|
||||
</div>
|
||||
</header>
|
||||
{!editing && (
|
||||
<Tabs onChange={onTabChange} index={tabIndex}>
|
||||
<TabList className="tabs__list--channel-page">
|
||||
<Tab>{__('Content')}</Tab>
|
||||
<Tab>{__('About')}</Tab>
|
||||
<div className="card__actions">
|
||||
<ShareButton uri={uri} />
|
||||
<SubscribeButton uri={uri} />
|
||||
</div>
|
||||
</TabList>
|
||||
<Tabs onChange={onTabChange} index={tabIndex}>
|
||||
<TabList className="tabs__list--channel-page">
|
||||
<Tab disabled={editing}>{__('Content')}</Tab>
|
||||
<Tab>{editing ? __('Editing Your Channel') : __('About')}</Tab>
|
||||
<div className="card__actions">
|
||||
<ShareButton uri={uri} />
|
||||
<SubscribeButton uri={uri} />
|
||||
</div>
|
||||
</TabList>
|
||||
|
||||
<TabPanels>
|
||||
<TabPanel>
|
||||
<ChannelContent uri={uri} />
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<TabPanels>
|
||||
<TabPanel>
|
||||
<ChannelContent uri={uri} />
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
{editing ? (
|
||||
<ChannelEdit
|
||||
uri={uri}
|
||||
setEditing={setEditing}
|
||||
updateThumb={v => setThumbPreview(v)}
|
||||
updateCover={v => setCoverPreview(v)}
|
||||
/>
|
||||
) : (
|
||||
<ChannelAbout uri={uri} />
|
||||
</TabPanel>
|
||||
</TabPanels>
|
||||
</Tabs>
|
||||
)}
|
||||
{editing && (
|
||||
<ChannelForm
|
||||
uri={uri}
|
||||
setEditing={setEditing}
|
||||
updateThumb={v => setThumbPreview(v)}
|
||||
updateCover={v => setCoverPreview(v)}
|
||||
/>
|
||||
)}
|
||||
)}
|
||||
</TabPanel>
|
||||
</TabPanels>
|
||||
</Tabs>
|
||||
</div>
|
||||
</Page>
|
||||
);
|
||||
|
|
|
@ -86,6 +86,12 @@ $metadata-z-index: 1;
|
|||
font-size: 3rem;
|
||||
font-weight: 800;
|
||||
margin-right: var(--spacing-large);
|
||||
|
||||
// Quick hack to get this to work
|
||||
// We should have a generic style for "header with button next to it"
|
||||
.button {
|
||||
margin-left: var(--spacing-medium);
|
||||
}
|
||||
}
|
||||
|
||||
.channel__url {
|
||||
|
|
|
@ -460,5 +460,24 @@
|
|||
"LBRY names cannot contain that symbol ($, #, @)": "LBRY names cannot contain that symbol ($, #, @)",
|
||||
"Path copied.": "Path copied.",
|
||||
"Open Folder": "Open Folder",
|
||||
"Create Backup": "Create Backup"
|
||||
}
|
||||
"Create Backup": "Create Backup",
|
||||
"Submit": "Submit",
|
||||
"Website": "Website",
|
||||
"aprettygoodsite.com": "aprettygoodsite.com",
|
||||
"yourstruly@example.com": "yourstruly@example.com",
|
||||
"Thumbnail source": "Thumbnail source",
|
||||
"Thumbnail (400x400)": "Thumbnail (400x400)",
|
||||
"https://example.com/image.png": "https://example.com/image.png",
|
||||
"Cover source": "Cover source",
|
||||
"Cover (1000x300)": "Cover (1000x300)",
|
||||
"Editing": "Editing",
|
||||
"Edit Your Channel": "Edit Your Channel",
|
||||
"Editing Your Channel": "Editing Your Channel",
|
||||
"We can explain... We know this page won't win any design awards, we have a cool idea for channel edits in the future. We just wanted to release a very very very basic version that just barely kinda works so people can use it.": "We can explain... We know this page won't win any design awards, we have a cool idea for channel edits in the future. We just wanted to release a very very very basic version that just barely kinda works so people can use it.",
|
||||
"We can explain... \n\n We know this page won't win any design awards, we have a cool idea for channel edits in the future. We just wanted to release a very very very basic version that just barely kinda works so people can use it.": "We can explain... \n\n We know this page won't win any design awards, we have a cool idea for channel edits in the future. We just wanted to release a very very very basic version that just barely kinda works so people can use it.",
|
||||
"We can explain...": "We can explain...",
|
||||
"We know this page won't win any design awards, we have a cool idea for channel edits in the future. We just wanted to release a very very very basic version that just barely kinda works so people can use": "We know this page won't win any design awards, we have a cool idea for channel edits in the future. We just wanted to release a very very very basic version that just barely kinda works so people can use",
|
||||
"We know this page won't win any design awards, we just wanted to release a very very very basic version that just barely kinda works so people can use": "We know this page won't win any design awards, we just wanted to release a very very very basic version that just barely kinda works so people can use",
|
||||
"We know this page won't win any design awards, we just wanted to release a very very very basic version that just barely kinda works so people can use it right now. There is a much nicer version in the works.": "We know this page won't win any design awards, we just wanted to release a very very very basic version that just barely kinda works so people can use it right now. There is a much nicer version in the works.",
|
||||
"We know this page won't win any design awards, we just wanted to release a very very very basic version that just barely kinda works so people can use it right now. There is a much nicer version being worked on.": "We know this page won't win any design awards, we just wanted to release a very very very basic version that just barely kinda works so people can use it right now. There is a much nicer version being worked on."
|
||||
}
|
|
@ -6646,9 +6646,9 @@ lazy-val@^1.0.3, lazy-val@^1.0.4:
|
|||
yargs "^13.2.2"
|
||||
zstd-codec "^0.1.1"
|
||||
|
||||
lbry-redux@lbryio/lbry-redux#9a676ee311d573b84d11f402d918aeee77be76e1:
|
||||
lbry-redux@lbryio/lbry-redux#efccab44cb025a14fd81ec05ffca0314710c8529:
|
||||
version "0.0.1"
|
||||
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/9a676ee311d573b84d11f402d918aeee77be76e1"
|
||||
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/efccab44cb025a14fd81ec05ffca0314710c8529"
|
||||
dependencies:
|
||||
proxy-polyfill "0.1.6"
|
||||
reselect "^3.0.0"
|
||||
|
|
Loading…
Add table
Reference in a new issue