updates in component state
updates work asset upload works channelForm component
This commit is contained in:
parent
c86b376279
commit
16bcaf7ceb
11 changed files with 467 additions and 40 deletions
34
src/ui/component/channelForm/index.js
Normal file
34
src/ui/component/channelForm/index.js
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import {
|
||||||
|
makeSelectTitleForUri,
|
||||||
|
makeSelectThumbnailForUri,
|
||||||
|
makeSelectCoverForUri,
|
||||||
|
selectCurrentChannelPage,
|
||||||
|
makeSelectMetadataItemForUri,
|
||||||
|
doUpdateChannel,
|
||||||
|
makeSelectAmountForUri,
|
||||||
|
} from 'lbry-redux';
|
||||||
|
import ChannelPage from './view';
|
||||||
|
|
||||||
|
const select = (state, props) => ({
|
||||||
|
title: makeSelectTitleForUri(props.uri)(state),
|
||||||
|
thumbnail: makeSelectThumbnailForUri(props.uri)(state),
|
||||||
|
cover: makeSelectCoverForUri(props.uri)(state),
|
||||||
|
page: selectCurrentChannelPage(state),
|
||||||
|
description: makeSelectMetadataItemForUri(props.uri, 'description')(state),
|
||||||
|
website: makeSelectMetadataItemForUri(props.uri, 'website_url')(state),
|
||||||
|
email: makeSelectMetadataItemForUri(props.uri, 'email')(state),
|
||||||
|
tags: makeSelectMetadataItemForUri(props.uri, 'tags')(state),
|
||||||
|
locations: makeSelectMetadataItemForUri(props.uri, 'locations')(state),
|
||||||
|
languages: makeSelectMetadataItemForUri(props.uri, 'languages')(state),
|
||||||
|
amount: makeSelectAmountForUri(props.uri)(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
const perform = dispatch => ({
|
||||||
|
updateChannel: params => dispatch(doUpdateChannel(params)),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(ChannelPage);
|
208
src/ui/component/channelForm/view.jsx
Normal file
208
src/ui/component/channelForm/view.jsx
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
// @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;
|
|
@ -8,10 +8,11 @@ type Props = {
|
||||||
thumbnail: ?string,
|
thumbnail: ?string,
|
||||||
uri: string,
|
uri: string,
|
||||||
className?: string,
|
className?: string,
|
||||||
|
thumbnailPreview: ?string,
|
||||||
};
|
};
|
||||||
|
|
||||||
function ChannelThumbnail(props: Props) {
|
function ChannelThumbnail(props: Props) {
|
||||||
const { thumbnail, uri, className } = props;
|
const { thumbnail, uri, className, thumbnailPreview } = props;
|
||||||
|
|
||||||
// Generate a random color class based on the first letter of the channel name
|
// Generate a random color class based on the first letter of the channel name
|
||||||
const { channelName } = parseURI(uri);
|
const { channelName } = parseURI(uri);
|
||||||
|
@ -24,8 +25,8 @@ function ChannelThumbnail(props: Props) {
|
||||||
[colorClassName]: !thumbnail,
|
[colorClassName]: !thumbnail,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{!thumbnail && <img className="channel-thumbnail__default" src={Gerbil} />}
|
{!thumbnail && <img className="channel-thumbnail__default" src={thumbnailPreview || Gerbil} />}
|
||||||
{thumbnail && <img className="channel-thumbnail__custom" src={thumbnail} />}
|
{thumbnail && <img className="channel-thumbnail__custom" src={thumbnailPreview || thumbnail} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ type FileFilters = {
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
type: string,
|
type: string,
|
||||||
currentPath: ?string,
|
currentPath?: ?string,
|
||||||
onFileChosen: (string, string) => void,
|
onFileChosen: (string, string) => void,
|
||||||
label?: string,
|
label?: string,
|
||||||
placeholder?: string,
|
placeholder?: string,
|
||||||
|
|
12
src/ui/component/selectAsset/index.js
Normal file
12
src/ui/component/selectAsset/index.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doOpenModal } from 'redux/actions/app';
|
||||||
|
import SelectThumbnail from './view';
|
||||||
|
|
||||||
|
const perform = dispatch => ({
|
||||||
|
openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
null,
|
||||||
|
perform
|
||||||
|
)(SelectThumbnail);
|
BIN
src/ui/component/selectAsset/thumbnail-broken.png
Normal file
BIN
src/ui/component/selectAsset/thumbnail-broken.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
BIN
src/ui/component/selectAsset/thumbnail-missing.png
Normal file
BIN
src/ui/component/selectAsset/thumbnail-missing.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
142
src/ui/component/selectAsset/view.jsx
Normal file
142
src/ui/component/selectAsset/view.jsx
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { FormField } from 'component/common/form';
|
||||||
|
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';
|
||||||
|
|
||||||
|
const filters = [
|
||||||
|
{
|
||||||
|
name: __('Thumbnail Image'),
|
||||||
|
extensions: ['png', 'jpg', 'jpeg', 'gif'],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const SOURCE_URL = 'url';
|
||||||
|
const SOURCE_UPLOAD = 'upload';
|
||||||
|
const SPEECH_READY = 'READY';
|
||||||
|
const SPEECH_UPLOADING = 'UPLOADING';
|
||||||
|
type Props = {
|
||||||
|
assetName: string,
|
||||||
|
currentValue: ?string,
|
||||||
|
onUpdate: string => void,
|
||||||
|
recommended: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
function SelectAsset(props: Props) {
|
||||||
|
const { onUpdate, assetName, currentValue, recommended } = props;
|
||||||
|
const [assetSource, setAssetSource] = useState(SOURCE_URL);
|
||||||
|
const [pathSelected, setPathSelected] = useState('');
|
||||||
|
const [uploadStatus, setUploadStatus] = useState(SPEECH_READY);
|
||||||
|
|
||||||
|
function doUploadAsset(filePath, thumbnailBuffer) {
|
||||||
|
let thumbnail, fileExt, fileName, fileType;
|
||||||
|
if (filePath) {
|
||||||
|
thumbnail = fs.readFileSync(filePath);
|
||||||
|
fileExt = path.extname(filePath);
|
||||||
|
fileName = path.basename(filePath);
|
||||||
|
fileType = `image/${fileExt.slice(1)}`;
|
||||||
|
} else if (thumbnailBuffer) {
|
||||||
|
thumbnail = thumbnailBuffer;
|
||||||
|
fileExt = '.png';
|
||||||
|
fileName = 'thumbnail.png';
|
||||||
|
fileType = 'image/png';
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploadError = (error = '') => {
|
||||||
|
console.log('error', error);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setUrl = path => {
|
||||||
|
setUploadStatus(SPEECH_READY);
|
||||||
|
onUpdate(path);
|
||||||
|
setAssetSource(SOURCE_URL);
|
||||||
|
};
|
||||||
|
|
||||||
|
setUploadStatus(SPEECH_UPLOADING);
|
||||||
|
|
||||||
|
const data = new FormData();
|
||||||
|
const name = uuidv4();
|
||||||
|
const file = new File([thumbnail], fileName, { type: fileType });
|
||||||
|
data.append('name', name);
|
||||||
|
data.append('file', file);
|
||||||
|
|
||||||
|
return fetch('https://spee.ch/api/claim/publish', {
|
||||||
|
method: 'POST',
|
||||||
|
body: data,
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(json => (json.success ? setUrl(`${json.data.serveUrl}`) : uploadError(json.message)))
|
||||||
|
.catch(err => uploadError(err.message));
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<fieldset-section>
|
||||||
|
<fieldset-group className="fieldset-group--smushed">
|
||||||
|
<FormField
|
||||||
|
type="select"
|
||||||
|
name={assetName}
|
||||||
|
value={assetSource}
|
||||||
|
onChange={e => setAssetSource(e.target.value)}
|
||||||
|
label={__(assetName + ' source')}
|
||||||
|
>
|
||||||
|
<option key={'lmmnop'} value={'url'}>
|
||||||
|
URL
|
||||||
|
</option>
|
||||||
|
<option key={'lmmnopq'} value={'upload'}>
|
||||||
|
UPLOAD
|
||||||
|
</option>
|
||||||
|
</FormField>
|
||||||
|
{assetSource === SOURCE_UPLOAD && (
|
||||||
|
<>
|
||||||
|
{!pathSelected && (
|
||||||
|
<FileSelector
|
||||||
|
label={'File to upload'}
|
||||||
|
name={'assetSelector'}
|
||||||
|
onFileChosen={path => {
|
||||||
|
setPathSelected(path);
|
||||||
|
}}
|
||||||
|
filters={filters}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{pathSelected && (
|
||||||
|
<div>
|
||||||
|
{`...${pathSelected.slice(-18)}`} {uploadStatus}{' '}
|
||||||
|
<Button button={'primary'} onClick={() => doUploadAsset(pathSelected)}>
|
||||||
|
Upload
|
||||||
|
</Button>{' '}
|
||||||
|
<Button
|
||||||
|
button={'secondary'}
|
||||||
|
onClick={() => {
|
||||||
|
setPathSelected('');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Clear
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{assetSource === SOURCE_URL && (
|
||||||
|
<FormField
|
||||||
|
type={'text'}
|
||||||
|
name={'thumbnail'}
|
||||||
|
label={__(assetName + ' ' + recommended)}
|
||||||
|
placeholder={__('https://example.com/image.png')}
|
||||||
|
disabled={false}
|
||||||
|
value={currentValue}
|
||||||
|
onChange={e => {
|
||||||
|
onUpdate(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</fieldset-group>
|
||||||
|
</fieldset-section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SelectAsset;
|
|
@ -1,15 +1,18 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { parseURI } from 'lbry-redux';
|
import { parseURI } from 'lbry-redux';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import SubscribeButton from 'component/subscribeButton';
|
import SubscribeButton from 'component/subscribeButton';
|
||||||
import ShareButton from 'component/shareButton';
|
import ShareButton from 'component/shareButton';
|
||||||
import { Tabs, TabList, Tab, TabPanels, TabPanel } from 'component/common/tabs';
|
import { Tabs, TabList, Tab, TabPanels, TabPanel } from 'component/common/tabs';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
|
import Button from 'component/button';
|
||||||
import { formatLbryUriForWeb } from 'util/uri';
|
import { formatLbryUriForWeb } from 'util/uri';
|
||||||
import ChannelContent from 'component/channelContent';
|
import ChannelContent from 'component/channelContent';
|
||||||
import ChannelAbout from 'component/channelAbout';
|
import ChannelAbout from 'component/channelAbout';
|
||||||
import ChannelThumbnail from 'component/channelThumbnail';
|
import ChannelThumbnail from 'component/channelThumbnail';
|
||||||
|
import ChannelForm from 'component/channelForm';
|
||||||
|
import * as ICONS from 'constants/icons';
|
||||||
|
|
||||||
const PAGE_VIEW_QUERY = `view`;
|
const PAGE_VIEW_QUERY = `view`;
|
||||||
const ABOUT_PAGE = `about`;
|
const ABOUT_PAGE = `about`;
|
||||||
|
@ -23,15 +26,20 @@ type Props = {
|
||||||
location: { search: string },
|
location: { search: string },
|
||||||
history: { push: string => void },
|
history: { push: string => void },
|
||||||
match: { params: { attribute: ?string } },
|
match: { params: { attribute: ?string } },
|
||||||
|
channelIsMine: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
function ChannelPage(props: Props) {
|
function ChannelPage(props: Props) {
|
||||||
const { uri, title, cover, history, location, page } = props;
|
const { uri, title, cover, history, location, page, channelIsMine, thumbnail } = props;
|
||||||
const { channelName, claimName, claimId } = parseURI(uri);
|
const { channelName, claimName, claimId } = parseURI(uri);
|
||||||
const { search } = location;
|
const { search } = location;
|
||||||
const urlParams = new URLSearchParams(search);
|
const urlParams = new URLSearchParams(search);
|
||||||
const currentView = urlParams.get(PAGE_VIEW_QUERY) || undefined;
|
const currentView = urlParams.get(PAGE_VIEW_QUERY) || undefined;
|
||||||
|
|
||||||
|
const [editing, setEditing] = useState(false);
|
||||||
|
const [thumbPreview, setThumbPreview] = useState(thumbnail);
|
||||||
|
const [coverPreview, setCoverPreview] = useState(cover);
|
||||||
|
|
||||||
// If a user changes tabs, update the url so it stays on the same page if they refresh.
|
// 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
|
// 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.
|
// would alter the Tab label's role attribute, which should stay role="tab" to work with keyboards/screen readers.
|
||||||
|
@ -52,40 +60,59 @@ function ChannelPage(props: Props) {
|
||||||
<Page>
|
<Page>
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<header className="channel-cover">
|
<header className="channel-cover">
|
||||||
{cover && <img className="channel-cover__custom" src={cover} />}
|
{!editing && cover && <img className="channel-cover__custom" src={cover} />}
|
||||||
|
{editing && <img className="channel-cover__custom" src={coverPreview} />}
|
||||||
<div className="channel__primary-info">
|
{/* component that offers select/upload */}
|
||||||
<ChannelThumbnail className="channel__thumbnail--channel-page" uri={uri} />
|
<div className="channel__primary-info ">
|
||||||
|
{!editing && <ChannelThumbnail className="channel__thumbnail--channel-page" uri={uri} />}
|
||||||
<div>
|
{editing && (
|
||||||
<h1 className="channel__title">{title || channelName}</h1>
|
<ChannelThumbnail
|
||||||
<h2 className="channel__url">
|
className="channel__thumbnail--channel-page"
|
||||||
{claimName}
|
uri={uri}
|
||||||
{claimId && `#${claimId}`}
|
thumbnailPreview={thumbPreview}
|
||||||
</h2>
|
/>
|
||||||
</div>
|
)}
|
||||||
|
<h1 className="channel__title">
|
||||||
|
{title || channelName}
|
||||||
|
{channelIsMine && !editing && (
|
||||||
|
<Button onClick={() => setEditing(!editing)} icon={ICONS.EDIT} iconSize={49} />
|
||||||
|
)}
|
||||||
|
</h1>
|
||||||
|
<h2 className="channel__url">
|
||||||
|
{claimName}
|
||||||
|
{claimId && `#${claimId}`}
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</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}>
|
<TabPanels>
|
||||||
<TabList className="tabs__list--channel-page">
|
<TabPanel>
|
||||||
<Tab>{__('Content')}</Tab>
|
<ChannelContent uri={uri} />
|
||||||
<Tab>{__('About')}</Tab>
|
</TabPanel>
|
||||||
<div className="card__actions">
|
<TabPanel>
|
||||||
<ShareButton uri={uri} />
|
<ChannelAbout uri={uri} />
|
||||||
<SubscribeButton uri={uri} />
|
</TabPanel>
|
||||||
</div>
|
</TabPanels>
|
||||||
</TabList>
|
</Tabs>
|
||||||
|
)}
|
||||||
<TabPanels>
|
{editing && (
|
||||||
<TabPanel>
|
<ChannelForm
|
||||||
<ChannelContent uri={uri} />
|
uri={uri}
|
||||||
</TabPanel>
|
setEditing={setEditing}
|
||||||
<TabPanel>
|
updateThumb={v => setThumbPreview(v)}
|
||||||
<ChannelAbout uri={uri} />
|
updateCover={v => setCoverPreview(v)}
|
||||||
</TabPanel>
|
/>
|
||||||
</TabPanels>
|
)}
|
||||||
</Tabs>
|
|
||||||
</div>
|
</div>
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
|
|
|
@ -345,7 +345,7 @@ export const doPublish = () => (dispatch: Dispatch, getState: () => {}) => {
|
||||||
dispatch({ type: ACTIONS.PUBLISH_FAIL });
|
dispatch({ type: ACTIONS.PUBLISH_FAIL });
|
||||||
dispatch(doError(error.message));
|
dispatch(doError(error.message));
|
||||||
};
|
};
|
||||||
|
console.log('PP', publishPayload);
|
||||||
return Lbry.publish(publishPayload).then(success, failure);
|
return Lbry.publish(publishPayload).then(success, failure);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -286,5 +286,8 @@
|
||||||
"Multi-language support is brand new and incomplete. Switching your language may have unintended consequences.": "Multi-language support is brand new and incomplete. Switching your language may have unintended consequences.",
|
"Multi-language support is brand new and incomplete. Switching your language may have unintended consequences.": "Multi-language support is brand new and incomplete. Switching your language may have unintended consequences.",
|
||||||
"Wallet": "Wallet",
|
"Wallet": "Wallet",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Following": "Following"
|
"Following": "Following",
|
||||||
}
|
"Update ready to install": "Update ready to install",
|
||||||
|
"Install now": "Install now",
|
||||||
|
"Edit": "Edit"
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue