This commit is contained in:
Sean Yesmunt 2019-12-06 14:42:44 -05:00
parent 5515c94ce0
commit e00f89b890
21 changed files with 64 additions and 179 deletions

View file

@ -4,11 +4,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [0.39.0] - [2019-3-19]
## [0.38.0] - [Unreleased]
### Fixed
### Added
- Allows channel thumbnails to be clickable on file pages ([#3304](https://github.com/lbryio/lbry-desktop/pull/3304))
- Dedicated Channel Creation page ([#3305](https://github.com/lbryio/lbry-desktop/pull/3305))
### Changed
## [0.37.2] - [2019-11-21]
@ -20,8 +24,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added
- 'New Channel' button in channels page ([#3305](https://github.com/lbryio/lbry-desktop/pull/3305))
- Dedicated Channel Creation page ([#3305](https://github.com/lbryio/lbry-desktop/pull/3305))
- Setting to start the app minimized when you login (Linux/Windows only) ([#3236](https://github.com/lbryio/lbry-desktop/pull/3236))
- Search on downloads page ([#2969](https://github.com/lbryio/lbry-desktop/pull/2969))
- Clear support state when clearing cache in settings([#3149](https://github.com/lbryio/lbry-desktop/pull/3149))

View file

@ -159,7 +159,7 @@
"react-paginate": "^5.2.1",
"react-redux": "^6.0.1",
"react-router": "^5.0.0",
"react-router-dom": "^5.1.0",
"react-router-dom": "^5.0.0",
"react-simplemde-editor": "^4.0.0",
"react-spring": "^8.0.20",
"react-sticky-box": "^0.8.0",

View file

@ -1,8 +1,7 @@
// @flow
import React, { Fragment } from 'react';
import React from 'react';
import { isNameValid } from 'lbry-redux';
import { FormField } from 'component/common/form';
import BusyIndicator from 'component/common/busy-indicator';
import { Form, FormField } from 'component/common/form';
import Button from 'component/button';
import analytics from 'analytics';
@ -38,7 +37,7 @@ class ChannelCreate extends React.PureComponent<Props, State> {
(this: any).handleNewChannelNameChange = this.handleNewChannelNameChange.bind(this);
(this: any).handleNewChannelBidChange = this.handleNewChannelBidChange.bind(this);
(this: any).handleCreateChannelClick = this.handleCreateChannelClick.bind(this);
(this: any).handleCreateChannel = this.handleCreateChannel.bind(this);
}
handleNewChannelNameChange(event: SyntheticInputEvent<*>) {
@ -78,7 +77,7 @@ class ChannelCreate extends React.PureComponent<Props, State> {
});
}
handleCreateChannelClick() {
handleCreateChannel() {
const { balance, createChannel, onSuccess } = this.props;
const { newChannelBid, newChannelName } = this.state;
@ -125,7 +124,7 @@ class ChannelCreate extends React.PureComponent<Props, State> {
} = this.state;
return (
<Fragment>
<Form onSubmit={this.handleCreateChannel}>
{createChannelError && <div className="error-text">{createChannelError}</div>}
<div>
<FormField
@ -151,17 +150,16 @@ class ChannelCreate extends React.PureComponent<Props, State> {
/>
<div className="card__actions">
<Button
type="submit"
button="primary"
label={!creatingChannel ? __('Create channel') : __('Creating channel...')}
onClick={this.handleCreateChannelClick}
disabled={
!newChannelName || !newChannelBid || creatingChannel || newChannelNameError || newChannelBidError
}
/>
</div>
</div>
{creatingChannel && <BusyIndicator message={`Creating Channel ${newChannelName}...`} />}
</Fragment>
</Form>
);
}
}

View file

@ -1,12 +1,5 @@
// @flow
/*
On submit, this component calls publish, which dispatches doPublishDesktop.
doPublishDesktop calls lbry-redux Lbry publish method using lbry-redux publish state as params.
Publish simply instructs the SDK to find the file path on disk and publish it with the provided metadata.
On web, the Lbry publish method call is overridden in platform/web/api-setup, using a function in platform/web/publish.
File upload is carried out in the background by that function.
*/
import React, { useEffect, Fragment } from 'react';
import { CHANNEL_NEW, CHANNEL_ANONYMOUS } from 'constants/claim';
import { buildURI, isURIValid } from 'lbry-redux';
@ -18,7 +11,6 @@ type Props = {
name: ?string,
channel: string,
resolveUri: string => void,
// Add back type
updatePublishForm: any => void,
onSuccess: () => void,
};

View file

@ -322,20 +322,4 @@ export const icons = {
<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z" />
</g>
),
[ICONS.NEW_CHANNEL]: buildIcon(
<g>
<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
<circle cx="8.5" cy="7" r="4" />
<line x1="20" y1="8" x2="20" y2="14" />
<line x1="23" y1="11" x2="17" y2="11" />
</g>
),
[ICONS.NEW_PUBLISH]: buildIcon(
<g>
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
<polyline points="14 2 14 8 20 8" />
<line x1="12" y1="18" x2="12" y2="12" />
<line x1="9" y1="15" x2="15" y2="15" />
</g>
),
};

View file

@ -11,12 +11,13 @@ import React, { useEffect, Fragment } from 'react';
import { CHANNEL_NEW, CHANNEL_ANONYMOUS } from 'constants/claim';
import { buildURI, isURIValid, isNameValid, THUMBNAIL_STATUSES } from 'lbry-redux';
import Button from 'component/button';
import ChannelSection from 'component/selectChannel';
import SelectChannel from 'component/selectChannel';
import classnames from 'classnames';
import TagsSelect from 'component/tagsSelect';
import PublishText from 'component/publishText';
import PublishPrice from 'component/publishPrice';
import PublishFile from 'component/publishFile';
import PublishName from 'component/publishName';
import PublishAdditionalOptions from 'component/publishAdditionalOptions';
import PublishFormErrors from 'component/publishFormErrors';
import SelectThumbnail from 'component/selectThumbnail';
@ -162,7 +163,7 @@ function PublishForm(props: Props) {
<Card
actions={
<React.Fragment>
<ChannelSection channel={channel} onChannelChange={channel => updatePublishForm({ channel })} />
<SelectChannel channel={channel} onChannelChange={channel => updatePublishForm({ channel })} />
<p className="help">
{__('This is a username or handle that your content can be found under.')}{' '}
{__('Ex. @Marvel, @TheBeatles, @BooksByJoe')}
@ -171,6 +172,7 @@ function PublishForm(props: Props) {
}
/>
<PublishName disabled={formDisabled} />
<PublishPrice disabled={formDisabled} />
<PublishAdditionalOptions disabled={formDisabled} />

View file

@ -24,7 +24,6 @@ import FourOhFourPage from 'page/fourOhFour';
import SignInPage from 'page/signIn';
import SignInVerifyPage from 'page/signInVerify';
import ChannelsPage from 'page/channels';
import ChannelCreatePage from 'page/channelCreate';
// Tell the browser we are handling scroll restoration
if ('scrollRestoration' in history) {
@ -93,7 +92,6 @@ function AppRouter(props: Props) {
<PrivateRoute {...props} path={`/$/${PAGES.BLOCKED}`} component={ListBlockedPage} />
<PrivateRoute {...props} path={`/$/${PAGES.WALLET}`} exact component={WalletPage} />
<PrivateRoute {...props} path={`/$/${PAGES.CHANNELS}`} component={ChannelsPage} />
<PrivateRoute {...props} path={`/$/${PAGES.CHANNEL_CREATE}`} component={ChannelCreatePage} />
{/* Below need to go at the end to make sure we don't match any of our pages first */}
<Route path="/:claimName" exact component={ShowPage} />

View file

@ -77,25 +77,31 @@ class ChannelSection extends React.PureComponent<Props, State> {
{fetchingChannels ? (
<BusyIndicator message="Updating channels" />
) : (
<fieldset-section>
<FormField
name="channel"
label={__('Channel')}
type="select"
onChange={this.handleChannelChange}
value={channel}
>
<option value={CHANNEL_ANONYMOUS}>{__('Anonymous')}</option>
{channels &&
channels.map(({ name, claim_id: claimId }) => (
<option key={claimId} value={name}>
{name}
</option>
))}
<option value={CHANNEL_NEW}>{__('New channel...')}</option>
</FormField>
{addingChannel && <ChannelCreate onSuccess={this.handleChangeToNewChannel} />}
</fieldset-section>
<Fragment>
<div className="section">
<FormField
name="channel"
label={__('Channel')}
type="select"
onChange={this.handleChannelChange}
value={channel}
>
<option value={CHANNEL_ANONYMOUS}>{__('Anonymous')}</option>
{channels &&
channels.map(({ name, claim_id: claimId }) => (
<option key={claimId} value={name}>
{name}
</option>
))}
<option value={CHANNEL_NEW}>{__('New channel...')}</option>
</FormField>
</div>
{addingChannel && (
<div className="section">
<ChannelCreate onSuccess={this.handleChangeToNewChannel} />
</div>
)}
</Fragment>
)}
</Fragment>
);

View file

@ -75,7 +75,7 @@ function SideBar(props: Props) {
<Button
navigate={`/$/${PAGES.FOLLOWING}`}
label={__('Customize')}
icon={ICONS.CUSTOMIZE}
icon={ICONS.EDIT}
className="navigation-link"
activeClass="navigation-link--active"
/>

View file

@ -14,7 +14,6 @@ export const PUBLISH = 'UploadCloud';
export const REMOVE = 'X';
export const ADD = 'Plus';
export const EDIT = 'Edit';
export const CUSTOMIZE = 'Edit'; // Used as icon for 'Customize'
export const DELETE = 'Trash';
export const REPORT = 'Flag';
export const HELP = 'HelpCircle';
@ -79,5 +78,3 @@ export const EYE = 'Eye';
export const EYE_OFF = 'EyeOff';
export const SIGN_OUT = 'SignOut';
export const SIGN_IN = 'SignIn';
export const NEW_CHANNEL = 'UserPlus';
export const NEW_PUBLISH = 'FilePlus';

View file

@ -8,4 +8,7 @@ const perform = {
doHideModal,
};
export default connect(select, perform)(ChannelCreate);
export default connect(
select,
perform
)(ChannelCreate);

View file

@ -1,17 +1,18 @@
// @flow
import React from 'react';
import ChannelCreate from 'component/channelCreate';
import ChannelForm from 'component/channelForm';
import { Modal } from 'modal/modal';
type Props = { doHideModal: () => void };
const ChannelCreateModal = (props: Props) => {
const ModalChannelCreate = (props: Props) => {
const { doHideModal } = props;
return (
<Modal isOpen type="card" onAborted={doHideModal}>
<ChannelCreate />
<ChannelForm onSuccess={doHideModal} />
</Modal>
);
};
export default ChannelCreateModal;
export default ModalChannelCreate;

View file

@ -30,6 +30,7 @@ import ModalCommentAcknowledgement from 'modal/modalCommentAcknowledgement';
import ModalWalletSend from 'modal/modalWalletSend';
import ModalWalletReceive from 'modal/modalWalletReceive';
import ModalYoutubeWelcome from 'modal/modalYoutubeWelcome';
import ModalCreateChannel from 'modal/modalChannelCreate';
type Props = {
modal: { id: string, modalProps: {} },
@ -108,6 +109,8 @@ function ModalRouter(props: Props) {
return <ModalWalletReceive {...modalProps} />;
case MODALS.YOUTUBE_WELCOME:
return <ModalYoutubeWelcome />;
case MODALS.CREATE_CHANNEL:
return <ModalCreateChannel {...modalProps} />;
default:
return null;
}

View file

@ -1,10 +0,0 @@
import { connect } from 'react-redux';
import { selectBalance } from 'lbry-redux';
import ChannelCreatePage from './view';
import { withRouter } from 'react-router';
const select = state => ({
balance: selectBalance(state),
});
export default withRouter(connect(select, null)(ChannelCreatePage));

View file

@ -1,59 +0,0 @@
// @flow
import React, { Fragment } from 'react';
import ChannelForm from 'component/channelForm';
import * as PAGES from 'constants/pages';
import Page from 'component/page';
import Yrbl from 'component/yrbl';
import LbcSymbol from 'component/common/lbc-symbol';
import { useHistory } from 'react-router-dom';
type Props = {
balance: number,
};
function ChannelCreatePage(props: Props) {
const { balance } = props;
function scrollToTop() {
const mainContent = document.querySelector('main');
if (mainContent) {
mainContent.scrollTop = 0; // It would be nice to animate this
}
}
let history = useHistory();
const returnToChannelList = () => history.push(`/$/${PAGES.CHANNELS}`);
return (
<Page>
{balance === 0 && (
<Fragment>
<Yrbl
title={__("You can't publish things quite yet")}
subtitle={
<Fragment>
<p>
{__(
'LBRY uses a blockchain, which is a fancy way of saying that users (you) are in control of your data.'
)}
</p>
<p>
{__('Because of the blockchain, some actions require LBRY credits')} (
<LbcSymbol />
).
</p>
<p>
<LbcSymbol />{' '}
{__(
'allows you to do some neat things, like paying your favorite creators for their content. And no company can stop you.'
)}
</p>
</Fragment>
}
/>
</Fragment>
)}
<ChannelForm scrollToTop={scrollToTop} disabled={balance === 0} onSuccess={returnToChannelList} />
</Page>
);
}
export default ChannelCreatePage;

View file

@ -1,6 +1,7 @@
import { connect } from 'react-redux';
import { selectMyChannelClaims, doFetchChannelListMine, selectFetchingMyChannels } from 'lbry-redux';
import { selectYoutubeChannels } from 'lbryinc';
import { doOpenModal } from 'redux/actions/app';
import ChannelsPage from './view';
const select = state => ({
@ -10,6 +11,7 @@ const select = state => ({
});
const perform = dispatch => ({
openModal: id => dispatch(doOpenModal(id)),
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
});

View file

@ -5,20 +5,18 @@ import Page from 'component/page';
import Button from 'component/button';
import YoutubeTransferStatus from 'component/youtubeTransferStatus';
import Spinner from 'component/spinner';
import * as PAGES from 'constants/pages';
import * as ICONS from 'constants/icons';
import * as MODALS from 'constants/modal_types';
import { doOpenModal } from '../../redux/actions/app';
type Props = {
channels: Array<ChannelClaim>,
fetchChannelListMine: () => void,
fetchingChannels: boolean,
youtubeChannels: ?Array<any>,
openModal: string => void,
};
export default function ChannelsPage(props: Props) {
const { channels, fetchChannelListMine, fetchingChannels, youtubeChannels } = props;
const { channels, fetchChannelListMine, fetchingChannels, youtubeChannels, openModal } = props;
const hasYoutubeChannels = youtubeChannels && Boolean(youtubeChannels.length);
const hasPendingChannels = channels && channels.some(channel => channel.confirmations === -1);
@ -48,12 +46,7 @@ export default function ChannelsPage(props: Props) {
loading={fetchingChannels}
uris={channels.map(channel => channel.permanent_url)}
headerAltControls={
<Button
iconSize={20}
label={__('New Channel')}
icon={ICONS.NEW_CHANNEL}
onClick={() => doOpenModal(MODALS.CREATE_CHANNEL)}
/>
<Button button="link" label={__('New Channel')} onClick={() => openModal(MODALS.CREATE_CHANNEL)} />
}
/>
</div>
@ -66,13 +59,7 @@ export default function ChannelsPage(props: Props) {
<h2 className="section__title--large">{__('No Channels Created Yet')}</h2>
<div className="section__actions">
<Button
iconSize={20}
label={__('New Channel')}
button="link"
icon={ICONS.NEW_CHANNEL}
navigate={`/$/${PAGES.CHANNEL_CREATE}`}
/>
<Button button="primary" label={__('New Channel')} onClick={() => openModal(MODALS.CREATE_CHANNEL)} />
</div>
</div>
</section>

View file

@ -5,7 +5,6 @@ import ClaimListDiscover from 'component/claimListDiscover';
import TagsSelect from 'component/tagsSelect';
import Page from 'component/page';
import Button from 'component/button';
import * as ICONS from 'constants/icons';
type Props = {
followedTags: Array<Tag>,
@ -22,15 +21,7 @@ function DiscoverPage(props: Props) {
hideCustomization={IS_WEB && !email}
personalView
tags={followedTags.map(tag => tag.name)}
meta={
<Button
button="link"
label={__('Customize')}
requiresAuth={IS_WEB}
navigate={`/$/${PAGES.FOLLOWING}`}
icon={ICONS.EDIT}
/>
}
meta={<Button button="link" label={__('Customize')} requiresAuth={IS_WEB} navigate={`/$/${PAGES.FOLLOWING}`} />}
/>
</Page>
);

View file

@ -7,7 +7,6 @@ import Paginate from 'component/common/paginate';
import { PAGE_SIZE } from 'constants/claim';
import WebUploadList from 'component/webUploadList';
import Spinner from 'component/spinner';
import * as ICONS from 'constants/icons';
type Props = {
checkPendingPublishes: () => void,
@ -36,9 +35,7 @@ function FileListPublished(props: Props) {
loading={fetching}
persistedStorageKey="claim-list-published"
uris={urls}
headerAltControls={
<Button button="link" label={__('New Publish')} navigate="/$/publish" icon={ICONS.NEW_PUBLISH} />
}
headerAltControls={<Button button="link" label={__('New Publish')} navigate="/$/publish" />}
/>
<Paginate totalPages={Math.ceil(Number(urlTotal) / Number(PAGE_SIZE))} loading={fetching} />
</div>

View file

@ -49,11 +49,6 @@
& > * {
margin-left: var(--spacing-small);
}
.button__content svg {
width: var(--claim-list-alt-control-icon-width);
height: var(--claim-list-alt-control-icon-height);
}
}
.claim-preview {

View file

@ -61,8 +61,4 @@ $large-breakpoint: 1921px;
--file-list-thumbnail-width: 10rem;
--tag-height: 1.5rem;
// SVG Icons
--claim-list-alt-control-icon-width: 20px;
--claim-list-alt-control-icon-height: 20px;
}