From d035247b78d47baba92e50f1ea2f10425c2adc50 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 19 Jun 2019 22:56:17 -0400 Subject: [PATCH 01/10] point change email button to faq arcticle until we add that functionality --- src/ui/component/userEmail/view.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui/component/userEmail/view.jsx b/src/ui/component/userEmail/view.jsx index eaa413476..81f9a55f6 100644 --- a/src/ui/component/userEmail/view.jsx +++ b/src/ui/component/userEmail/view.jsx @@ -43,7 +43,9 @@ function UserEmail(props: Props) { readOnly label={__('Your Email')} value={email} - inputButton={ + ); } -} + + // Handle lbry:// uris passed in, or already formatted web urls + let path = navigate; + if (path) { + if (path.startsWith('lbry://')) { + path = formatLbryUriForWeb(path); + } else if (!path.startsWith('/')) { + // Force a leading slash so new paths aren't appended on to the current path + path = `/${path}`; + } + } + + return path ? ( + { + e.stopPropagation(); + if (onClick) { + onClick(); + } + }} + className={combinedClassName} + activeClassName={activeClass} + > + {content} + + ) : ( + + ); +}); export default Button; diff --git a/src/ui/component/common/icon-custom.jsx b/src/ui/component/common/icon-custom.jsx index e4ddd82fd..36b725ff7 100644 --- a/src/ui/component/common/icon-custom.jsx +++ b/src/ui/component/common/icon-custom.jsx @@ -1,6 +1,7 @@ // @flow +// A housing for all of our icons. Mostly taken fromhttps://github.com/feathericons/react-feather import * as ICONS from 'constants/icons'; -import React from 'react'; +import React, { forwardRef } from 'react'; type IconProps = { size: number, @@ -8,28 +9,37 @@ type IconProps = { }; // Returns a react component -const buildIcon = (iconStrokes: React$Node, options?: {} = {}) => (props: IconProps) => { - const { size = 24, color = 'currentColor', ...otherProps } = props; - return ( - - {iconStrokes} - - ); -}; +const buildIcon = (iconStrokes: React$Node, options?: {} = {}) => + forwardRef((props: IconProps, ref) => { + const { size = 24, color = 'currentColor', ...otherProps } = props; + return ( + + {iconStrokes} + + ); + }); -export const customIcons = { +export const icons = { + // The LBRY icon is different from the base icon set so don't use buildIcon() + [ICONS.LBRY]: ( + + + + + ), [ICONS.ARROW_LEFT]: buildIcon( @@ -46,48 +56,12 @@ export const customIcons = { ), - [ICONS.VIEW]: buildIcon( - - - - - - - - - - ), - [ICONS.HOME]: buildIcon( ), - [ICONS.MENU]: buildIcon( - - ), - [ICONS.PLAY]: buildIcon( - - - - ), [ICONS.UPLOAD]: buildIcon( ), - // Extended from the feather-icons Heart - [ICONS.UNSUBSCRIBE]: buildIcon( - + [ICONS.SUBSCRIPTION]: buildIcon( + ), - // The LBRY icon is different from the base icon set so don't use buildIcon() - [ICONS.LBRY]: props => ( - - - - + [ICONS.SETTINGS]: buildIcon( + + + + + ), + [ICONS.ACCOUNT]: buildIcon( + + + + + ), + [ICONS.OVERVIEW]: buildIcon(), + [ICONS.WALLET]: buildIcon( + + + + + + + + + ), + [ICONS.LIBRARY]: buildIcon(), + [ICONS.EDIT]: buildIcon( + + + + + ), + [ICONS.DOWNLOAD]: buildIcon( + + + + + + ), + [ICONS.HELP]: buildIcon( + + + + + + ), + [ICONS.LIGHT]: buildIcon( + + + + + + + + + + + + ), + [ICONS.DARK]: buildIcon(), + [ICONS.SEARCH]: buildIcon( + + + + + ), + [ICONS.TIP]: buildIcon( + + + + + + + + ), + [ICONS.SHARE]: buildIcon( + + + + + + + + ), + [ICONS.REPORT]: buildIcon( + + + + + ), + [ICONS.EXTERNAL]: buildIcon( + + + + + + ), + [ICONS.DELETE]: buildIcon( + + + + + ), + [ICONS.COPY]: buildIcon( + + + + + ), + [ICONS.REMOVE]: buildIcon( + + + + + ), + [ICONS.ADD]: buildIcon( + + + + + ), + [ICONS.CHAT]: buildIcon( + ), }; diff --git a/src/ui/component/common/icon.jsx b/src/ui/component/common/icon.jsx index fc13a5851..e07fa0da2 100644 --- a/src/ui/component/common/icon.jsx +++ b/src/ui/component/common/icon.jsx @@ -1,10 +1,9 @@ // @flow import * as ICONS from 'constants/icons'; -import * as FEATHER_ICONS from 'react-feather'; import React from 'react'; import Tooltip from 'component/common/tooltip'; import classnames from 'classnames'; -import { customIcons } from './icon-custom'; +import { icons } from './icon-custom'; // It would be nice to standardize this somehow // These are copied from `scss/vars`, can they both come from the same source? @@ -27,6 +26,10 @@ class IconComponent extends React.PureComponent { return __('Featured content. Earn rewards for watching.'); case ICONS.DOWNLOAD: return __('This file is downloaded.'); + case ICONS.SUBSCRIPTION: + return __('You are subscribed to this channel.'); + case ICONS.SETTINGS: + return __('Your settings.'); default: return null; } @@ -47,9 +50,10 @@ class IconComponent extends React.PureComponent { render() { const { icon, tooltip, iconColor, size, className } = this.props; - const Icon = customIcons[this.props.icon] || FEATHER_ICONS[this.props.icon]; + const Icon = icons[this.props.icon]; if (!Icon) { + console.error('no icon found for ', icon); return null; } @@ -67,13 +71,7 @@ class IconComponent extends React.PureComponent { const inner = ; - return tooltipText ? ( - - {inner} - - ) : ( - inner - ); + return tooltipText ? {inner} : inner; } } diff --git a/src/ui/component/common/tooltip.jsx b/src/ui/component/common/tooltip.jsx index c26ad47cb..241c7299e 100644 --- a/src/ui/component/common/tooltip.jsx +++ b/src/ui/component/common/tooltip.jsx @@ -1,71 +1,17 @@ // @flow import * as React from 'react'; -import classnames from 'classnames'; +import ReachTooltip from '@reach/tooltip'; +import '@reach/tooltip/styles.css'; type Props = { - body: string, - label?: string, + label: string, children?: React.Node, - icon?: boolean, - direction: string, - onComponent?: boolean, // extra padding to account for button/form field size - alwaysVisible?: boolean, // should tooltip stay open, guide callbacks will close it manually }; -type State = { - direction: string, -}; +function Tooltip(props: Props) { + const { children, label } = props; -class ToolTip extends React.PureComponent { - static defaultProps = { - direction: 'bottom', - alwaysVisible: false, - }; - - constructor(props: Props) { - super(props); - this.state = { - direction: this.props.direction, - }; - } - - tooltip: ?HTMLSpanElement; - - render() { - const { direction } = this.state; - const { children, label, body, icon, onComponent, alwaysVisible } = this.props; - - const tooltipContent = children || label; - const bodyLength = body.length; - const isShortDescription = bodyLength < 30; - - return ( - - {tooltipContent} - { - this.tooltip = ref; - }} - className={classnames('tooltip__body', { - 'tooltip__body--short': isShortDescription, - })} - > - {body} - - - ); - } + return {children}; } -export default ToolTip; +export default Tooltip; diff --git a/src/ui/component/copyableText/view.jsx b/src/ui/component/copyableText/view.jsx index 5a292719c..756af2fbd 100644 --- a/src/ui/component/copyableText/view.jsx +++ b/src/ui/component/copyableText/view.jsx @@ -45,7 +45,7 @@ export default class CopyableText extends React.PureComponent { inputButton={ ); } else { diff --git a/src/ui/constants/pages.js b/src/ui/constants/pages.js index 0354ad17d..537b62f82 100644 --- a/src/ui/constants/pages.js +++ b/src/ui/constants/pages.js @@ -20,3 +20,4 @@ export const SEARCH = 'search'; export const TRANSACTIONS = 'transactions'; export const TAGS = 'tags'; export const WALLET = 'wallet'; +export const FOLLOWING = 'following'; diff --git a/src/ui/page/file/view.jsx b/src/ui/page/file/view.jsx index a57e43271..0514b8a7d 100644 --- a/src/ui/page/file/view.jsx +++ b/src/ui/page/file/view.jsx @@ -232,9 +232,9 @@ class FilePage extends React.Component { {claimIsMine && ( -
+

{viewCount} {viewCount !== 1 ? __('Views') : __('View')} -

+

)} diff --git a/src/ui/page/tagsEdit/index.js b/src/ui/page/following/index.js similarity index 69% rename from src/ui/page/tagsEdit/index.js rename to src/ui/page/following/index.js index 7e9153c8e..97edfb98c 100644 --- a/src/ui/page/tagsEdit/index.js +++ b/src/ui/page/following/index.js @@ -1,9 +1,11 @@ import { connect } from 'react-redux'; import { selectFollowedTags } from 'lbry-redux'; +import { selectSubscriptions } from 'redux/selectors/subscriptions'; import TagsEdit from './view'; const select = state => ({ followedTags: selectFollowedTags(state), + subscribedChannels: selectSubscriptions(state), }); const perform = {}; diff --git a/src/ui/page/following/view.jsx b/src/ui/page/following/view.jsx new file mode 100644 index 000000000..9edcff43f --- /dev/null +++ b/src/ui/page/following/view.jsx @@ -0,0 +1,30 @@ +// @flow +import React from 'react'; +import Page from 'component/page'; +import TagsSelect from 'component/tagsSelect'; +import ClaimList from 'component/claimList'; + +type Props = { + subscribedChannels: Array<{ uri: string }>, +}; + +function DiscoverPage(props: Props) { + const { subscribedChannels } = props; + + return ( + +
+ +
+
+ {__('Channels You Are Following')}} + empty={__("You aren't following any channels.")} + uris={subscribedChannels.map(({ uri }) => uri)} + /> +
+
+ ); +} + +export default DiscoverPage; diff --git a/src/ui/page/publish/index.js b/src/ui/page/publish/index.js index 8389f1622..6ca157047 100644 --- a/src/ui/page/publish/index.js +++ b/src/ui/page/publish/index.js @@ -1,46 +1,14 @@ import { connect } from 'react-redux'; -import { doResolveUri, selectBalance } from 'lbry-redux'; -import { - selectPublishFormValues, - selectIsStillEditing, - selectMyClaimForUri, - selectIsResolvingPublishUris, - selectTakeOverAmount, -} from 'redux/selectors/publish'; -import { - doResetThumbnailStatus, - doClearPublish, - doUpdatePublishForm, - doPublish, - doPrepareEdit, -} from 'redux/actions/publish'; +import { selectBalance } from 'lbry-redux'; import { selectUnclaimedRewardValue } from 'lbryinc'; import PublishPage from './view'; const select = state => ({ - ...selectPublishFormValues(state), - // The winning claim for a short lbry uri - amountNeededForTakeover: selectTakeOverAmount(state), - // My previously published claims under this short lbry uri - myClaimForUri: selectMyClaimForUri(state), - // If I clicked the "edit" button, have I changed the uri? - // Need this to make it easier to find the source on previously published content - isStillEditing: selectIsStillEditing(state), balance: selectBalance(state), - isResolvingUri: selectIsResolvingPublishUris(state), totalRewardValue: selectUnclaimedRewardValue(state), }); -const perform = dispatch => ({ - updatePublishForm: value => dispatch(doUpdatePublishForm(value)), - clearPublish: () => dispatch(doClearPublish()), - resolveUri: uri => dispatch(doResolveUri(uri)), - publish: params => dispatch(doPublish(params)), - prepareEdit: (claim, uri) => dispatch(doPrepareEdit(claim, uri)), - resetThumbnailStatus: () => dispatch(doResetThumbnailStatus()), -}); - export default connect( select, - perform + null )(PublishPage); diff --git a/src/ui/page/publish/view.jsx b/src/ui/page/publish/view.jsx index 6903a79b4..91da03dc0 100644 --- a/src/ui/page/publish/view.jsx +++ b/src/ui/page/publish/view.jsx @@ -1,3 +1,4 @@ +// @flow import React, { Fragment } from 'react'; import PublishForm from 'component/publishForm'; import Page from 'component/page'; @@ -6,64 +7,67 @@ import LbcSymbol from 'component/common/lbc-symbol'; import CreditAmount from 'component/common/credit-amount'; import Button from 'component/button'; -class PublishPage extends React.PureComponent { - scrollToTop = () => { +type Props = { + balance: number, + totalRewardValue: number, +}; + +function PublishPage(props: Props) { + const { balance, totalRewardValue } = props; + const totalRewardRounded = Math.floor(totalRewardValue / 10) * 10; + + function scrollToTop() { const mainContent = document.querySelector('main'); if (mainContent) { mainContent.scrollTop = 0; // It would be nice to animate this } - }; - - render() { - const { balance, totalRewardValue } = this.props; - const totalRewardRounded = Math.floor(totalRewardValue / 10) * 10; - - return ( - - {balance === 0 && ( - - -

- {__( - 'LBRY uses a blockchain, which is a fancy way of saying that users (you) are in control of your data.' - )} -

-

- {__('Because of the blockchain, some actions require LBRY credits')} ( - - ). -

-

- {' '} - {__( - 'allows you to do some neat things, like paying your favorite creators for their content. And no company can stop you.' - )} -

-
- } - /> -
-
-

{__('LBRY Credits Required')}

-
-

- {__(' There are a variety of ways to get credits, including more than')}{' '} - {' '} - {__('in free rewards for participating in the LBRY beta.')} -

-
-
-
- - )} - -
- ); } + + return ( + + {balance === 0 && ( + + +

+ {__( + 'LBRY uses a blockchain, which is a fancy way of saying that users (you) are in control of your data.' + )} +

+

+ {__('Because of the blockchain, some actions require LBRY credits')} ( + + ). +

+

+ {' '} + {__( + 'allows you to do some neat things, like paying your favorite creators for their content. And no company can stop you.' + )} +

+
+ } + /> +
+
+

{__('LBRY Credits Required')}

+
+

+ {__(' There are a variety of ways to get credits, including more than')}{' '} + {' '} + {__('in free rewards for participating in the LBRY beta.')} +

+
+
+
+ + )} + +
+ ); } export default PublishPage; diff --git a/src/ui/page/search/view.jsx b/src/ui/page/search/view.jsx index 0bc39f4d2..faeec7bd4 100644 --- a/src/ui/page/search/view.jsx +++ b/src/ui/page/search/view.jsx @@ -2,7 +2,7 @@ import * as ICONS from 'constants/icons'; import React, { useEffect, Fragment } from 'react'; import { isURIValid, normalizeURI } from 'lbry-redux'; -import ClaimListItem from 'component/claimListItem'; +import ClaimPreview from 'component/claimPreview'; import ClaimList from 'component/claimList'; import Page from 'component/page'; import SearchOptions from 'component/searchOptions'; @@ -29,7 +29,6 @@ export default function SearchPage(props: Props) { useEffect(() => { if (urlQuery) { - console.log('search', urlQuery); search(urlQuery); } }, [search, urlQuery]); @@ -44,7 +43,7 @@ export default function SearchPage(props: Props) { - + )} diff --git a/src/ui/page/subscriptions/view.jsx b/src/ui/page/subscriptions/view.jsx index 28774a65d..3b1dccf75 100644 --- a/src/ui/page/subscriptions/view.jsx +++ b/src/ui/page/subscriptions/view.jsx @@ -36,7 +36,7 @@ export default function SubscriptionsPage(props: Props) { const viewingSuggestedSubs = urlParams.get('view'); function onClick() { - let url = `/$/${PAGES.SUBSCRIPTIONS}`; + let url = `/$/${PAGES.FOLLOWING}`; if (!viewingSuggestedSubs) { url += '?view=discover'; } @@ -54,6 +54,7 @@ export default function SubscriptionsPage(props: Props) { const ids = idString.split(','); const options = { channel_ids: ids, + order_by: ['release_time'], }; doClaimSearch(20, options); @@ -72,7 +73,8 @@ export default function SubscriptionsPage(props: Props) { onClick={() => onClick()} /> } - uris={viewingSuggestedSubs ? suggestedSubscriptions.map(sub => sub.uri) : uris} + // Fix the need to reverse this + uris={viewingSuggestedSubs ? suggestedSubscriptions.map(sub => sub.uri) : uris.reverse()} /> diff --git a/src/ui/page/tagsEdit/view.jsx b/src/ui/page/tagsEdit/view.jsx deleted file mode 100644 index 99bd051de..000000000 --- a/src/ui/page/tagsEdit/view.jsx +++ /dev/null @@ -1,18 +0,0 @@ -// @flow -import React from 'react'; -import Page from 'component/page'; -import TagsSelect from 'component/tagsSelect'; - -type Props = {}; - -function DiscoverPage(props: Props) { - return ( - -
- -
-
- ); -} - -export default DiscoverPage; diff --git a/src/ui/redux/actions/publish.js b/src/ui/redux/actions/publish.js index 5f9f8c132..57b43d010 100644 --- a/src/ui/redux/actions/publish.js +++ b/src/ui/redux/actions/publish.js @@ -15,6 +15,7 @@ import { } from 'lbry-redux'; import { doOpenModal } from 'redux/actions/app'; import { selectosNotificationsEnabled } from 'redux/selectors/settings'; +import { selectMyClaimForUri, selectPublishFormValues } from 'redux/selectors/publish'; import { push } from 'connected-react-router'; import analytics from 'analytics'; import { formatLbryUriForWeb } from 'util/uri'; @@ -146,7 +147,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis // use same values as default state // fee will be undefined for free content fee = { - amount: 0, + amount: '0', currency: 'LBC', }, languages, @@ -159,11 +160,11 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis const publishData: UpdatePublishFormData = { name, channel: channelName, - bid: amount, + bid: Number(amount), contentIsFree: !fee.amount, author, description, - fee: { amount: fee.amount, currency: fee.currency }, + fee, languages, thumbnail: thumbnail ? thumbnail.url : null, title, @@ -201,10 +202,13 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData }); }; -export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getState: () => {}) => { +export const doPublish = () => (dispatch: Dispatch, getState: () => {}) => { dispatch({ type: ACTIONS.PUBLISH_START }); const state = getState(); + const publishData = selectPublishFormValues(state); + const myClaimForUri = selectMyClaimForUri(state); + const myChannels = selectMyChannelClaims(state); const myClaims = selectMyClaimsWithoutChannels(state); @@ -214,8 +218,9 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat filePath, description, language, - license, licenseUrl, + licenseType, + otherLicenseDescription, thumbnail, channel, title, @@ -223,8 +228,19 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat fee, uri, nsfw, - claim, - } = params; + tags, + locations, + } = publishData; + + let publishingLicense; + switch (licenseType) { + case COPYRIGHT: + case OTHER: + publishingLicense = otherLicenseDescription; + break; + default: + publishingLicense = licenseType; + } // get the claim id from the channel name, we will use that instead const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel); @@ -244,29 +260,19 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat fee_amount?: string, } = { name, - bid: creditsToString(bid), title, - license, - languages: [language], description, - tags: (claim && claim.value.tags) || [], - locations: claim && claim.value.locations, + locations, + bid: creditsToString(bid), + license: publishingLicense, + languages: [language], + tags: tags && tags.map(tag => tag.name), + license_url: licenseType === COPYRIGHT ? '' : licenseUrl, + thumbnail_url: thumbnail, }; - // Temporary solution to keep the same publish flow with the new tags api - // Eventually we will allow users to enter their own tags on publish - // `nsfw` will probably be removed - - if (licenseUrl) { - publishPayload.license_url = licenseUrl; - } - - if (thumbnail) { - publishPayload.thumbnail_url = thumbnail; - } - - if (claim && claim.value.release_time) { - publishPayload.release_time = Number(claim.value.release_time); + if (myClaimForUri && myClaimForUri.value.release_time) { + publishPayload.release_time = Number(myClaimForUri.value.release_time); } if (nsfw) { @@ -346,23 +352,25 @@ export const doCheckPendingPublishes = () => (dispatch: Dispatch, getState: GetS const checkFileList = () => { Lbry.claim_list().then(claims => { - claims.forEach(claim => { - // If it's confirmed, check if it was pending previously - if (claim.confirmations > 0 && pendingById[claim.claim_id]) { - delete pendingById[claim.claim_id]; + if (claims) { + claims.forEach(claim => { + // If it's confirmed, check if it was pending previously + if (claim.confirmations > 0 && pendingById[claim.claim_id]) { + delete pendingById[claim.claim_id]; - // If it's confirmed, check if we should notify the user - if (selectosNotificationsEnabled(getState())) { - const notif = new window.Notification('LBRY Publish Complete', { - body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`, - silent: false, - }); - notif.onclick = () => { - dispatch(push(formatLbryUriForWeb(claim.permanent_url))); - }; + // If it's confirmed, check if we should notify the user + if (selectosNotificationsEnabled(getState())) { + const notif = new window.Notification('LBRY Publish Complete', { + body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`, + silent: false, + }); + notif.onclick = () => { + dispatch(push(formatLbryUriForWeb(claim.permanent_url))); + }; + } } - } - }); + }); + } dispatch({ type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, diff --git a/src/ui/redux/reducers/publish.js b/src/ui/redux/reducers/publish.js index b49049361..2749e666b 100644 --- a/src/ui/redux/reducers/publish.js +++ b/src/ui/redux/reducers/publish.js @@ -27,6 +27,7 @@ type PublishState = { bidError: ?string, otherLicenseDescription: string, licenseUrl: string, + tags: Array, }; const defaultState: PublishState = { @@ -53,6 +54,7 @@ const defaultState: PublishState = { licenseType: 'None', otherLicenseDescription: 'All rights reserved', licenseUrl: '', + tags: [], publishing: false, publishSuccess: false, publishError: undefined, diff --git a/src/ui/redux/selectors/publish.js b/src/ui/redux/selectors/publish.js index 05e88e4ed..6127c33fe 100644 --- a/src/ui/redux/selectors/publish.js +++ b/src/ui/redux/selectors/publish.js @@ -18,6 +18,12 @@ export const selectPublishFormValues = createSelector( } ); +export const makeSelectPublishFormValue = item => + createSelector( + selectState, + state => state[item] + ); + // Is the current uri the same as the uri they clicked "edit" on export const selectIsStillEditing = createSelector( selectPublishFormValues, diff --git a/src/ui/scss/component/_file-list.scss b/src/ui/scss/component/_file-list.scss index cc08e1b85..0620bbc2f 100644 --- a/src/ui/scss/component/_file-list.scss +++ b/src/ui/scss/component/_file-list.scss @@ -1,4 +1,4 @@ -.file-list__header { +.claim-list__header { display: flex; align-items: center; min-height: 4.5rem; @@ -31,12 +31,13 @@ } } -.file-list__header--small { +.claim-list__header--small { height: 3rem; + min-height: 3rem; font-size: 1em; } -.file-list__dropdown { +.claim-list__dropdown { background-position: 95% center; background-repeat: no-repeat; background-size: 1.2rem; @@ -50,8 +51,8 @@ background-color: lighten($lbry-black, 10%); } -.file-list__header, -.file-list__dropdown { +.claim-list__header, +.claim-list__dropdown { background-color: lighten($lbry-black, 10%); [data-mode='dark'] & { @@ -59,17 +60,17 @@ } } -.file-list__header-text { +.claim-list__header-text { display: flex; align-items: center; } -.file-list__header-text, -.file-list__dropdown { +.claim-list__header-text, +.claim-list__dropdown { font-size: 1.3rem; } -.file-list__alt-controls { +.claim-list__alt-controls { display: flex; align-items: center; margin-left: auto; @@ -80,7 +81,7 @@ } } -.file-list__item { +.claim-list__item { display: flex; position: relative; font-size: 1.3rem; @@ -103,12 +104,12 @@ } } -.file-list__item--injected, -.file-list__item { - border-bottom: 1px solid rgba($lbry-teal-5, 0.1); +.claim-list__item--injected, +.claim-list__item + .claim-list__item { + border-top: 1px solid rgba($lbry-teal-5, 0.1); } -.file-list__item--large { +.claim-list__item--large { @include mediaThumbHoverZoom; font-size: 1.6rem; border-bottom: 0; @@ -124,36 +125,49 @@ } } -.file-list__item-metadata { +.claim-list__pending { + cursor: pointer; + opacity: 0.6; + + &:hover { + background-color: $lbry-white; + + [data-mode='dark'] & { + background-color: lighten($lbry-black, 5%); + } + } +} + +.claim-list__item-metadata { display: flex; flex-direction: column; width: 100%; } -.file-list__item-info { +.claim-list__item-info { align-items: flex-start; } -.file-list__item-info, -.file-list__item-properties { +.claim-list__item-info, +.claim-list__item-properties { display: flex; justify-content: space-between; } -.file-list__item-properties { +.claim-list__item-properties { align-items: flex-end; } -.file-list__item-title { +.claim-list__item-title { font-weight: 600; margin-right: auto; } -.file-list__item-tags { +.claim-list__item-tags { margin-left: 0; } -.file-list__meta { +.claim-list__meta { padding: var(--spacing-medium); background-color: lighten($lbry-teal-5, 55%); } diff --git a/src/ui/scss/component/_form-field.scss b/src/ui/scss/component/_form-field.scss index 9d4c38db5..c454d45a3 100644 --- a/src/ui/scss/component/_form-field.scss +++ b/src/ui/scss/component/_form-field.scss @@ -1,16 +1,36 @@ @import '~@lbry/components/sass/form/_index.scss'; +// replace this +form { + // setting the font size here sizes everything within + &:not(:last-child) { + margin-bottom: var(--spacing-s); + } +} + +input, +select { + height: var(--spacing-l); + border: 1px solid; +} + +checkbox-element, +radio-element, +select { + cursor: pointer; +} + +textarea { + &::placeholder { + opacity: 0.4; + } +} + // lbry/components overrides and minor styles // Some items have very specific styling // This is because many styles inside `lbry/components/sass/form/` are very specific // As styles become hardened here, they _should_ slowly move over to that repo -input, -textarea, -select { - border-radius: var(--input-border-radius); -} - input-submit { align-items: center; } @@ -21,7 +41,8 @@ input[type='number'] { input[type='text'], input[type='number'], -select { +select, +textarea { padding-bottom: 0.1em; [data-mode='dark'] & { @@ -31,6 +52,14 @@ select { } } +input, +select, +textarea { + border-color: lighten($lbry-black, 20%); + border-radius: var(--input-border-radius); + border-width: 1px; +} + fieldset-section { label { width: auto; diff --git a/src/ui/scss/component/_main.scss b/src/ui/scss/component/_main.scss index 89d5c205d..3f535d262 100644 --- a/src/ui/scss/component/_main.scss +++ b/src/ui/scss/component/_main.scss @@ -5,6 +5,7 @@ padding-top: var(--header-height); padding-left: var(--spacing-large); padding-right: var(--spacing-large); + padding-bottom: var(--spacing-large); background-color: mix($lbry-white, $lbry-gray-1, 70%); display: flex; diff --git a/src/ui/scss/component/_placeholder.scss b/src/ui/scss/component/_placeholder.scss index 02d6cca55..3933c5a12 100644 --- a/src/ui/scss/component/_placeholder.scss +++ b/src/ui/scss/component/_placeholder.scss @@ -9,7 +9,7 @@ .placeholder { display: flex; - &.file-list__item-title { + &.claim-list__item-title { width: 100%; height: 3rem; } -- 2.45.2 From b60ed92c0d408c5e9eb8a5d8a3cf81d5037faa42 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 26 Jun 2019 16:17:39 -0400 Subject: [PATCH 06/10] fix: button color --- src/ui/component/button/view.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ui/component/button/view.jsx b/src/ui/component/button/view.jsx index effdef03b..f34e0cf7e 100644 --- a/src/ui/component/button/view.jsx +++ b/src/ui/component/button/view.jsx @@ -22,6 +22,7 @@ type Props = { type: string, button: ?string, // primary, secondary, alt, link iconSize?: number, + iconColor?: string, constrict: ?boolean, // to shorten the button and ellipsis, only use for links activeClass?: string, innerRef: ?any, @@ -51,6 +52,7 @@ const Button = forwardRef((props: Props, ref: any) => { description, button, iconSize, + iconColor, constrict, activeClass, ...otherProps @@ -75,10 +77,10 @@ const Button = forwardRef((props: Props, ref: any) => { const content = ( - {icon && } + {icon && } {label && {label}} {children && children} - {iconRight && } + {iconRight && } ); -- 2.45.2 From a7a67f6561c7970261e614d44876454a76cb02d1 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 26 Jun 2019 16:36:17 -0400 Subject: [PATCH 07/10] fix: PublishPrice props --- src/ui/component/publishPrice/index.js | 41 +++----------------------- 1 file changed, 4 insertions(+), 37 deletions(-) diff --git a/src/ui/component/publishPrice/index.js b/src/ui/component/publishPrice/index.js index 8389f1622..ffaa82b58 100644 --- a/src/ui/component/publishPrice/index.js +++ b/src/ui/component/publishPrice/index.js @@ -1,46 +1,13 @@ import { connect } from 'react-redux'; -import { doResolveUri, selectBalance } from 'lbry-redux'; -import { - selectPublishFormValues, - selectIsStillEditing, - selectMyClaimForUri, - selectIsResolvingPublishUris, - selectTakeOverAmount, -} from 'redux/selectors/publish'; -import { - doResetThumbnailStatus, - doClearPublish, - doUpdatePublishForm, - doPublish, - doPrepareEdit, -} from 'redux/actions/publish'; -import { selectUnclaimedRewardValue } from 'lbryinc'; +import { makeSelectPublishFormValue } from 'redux/selectors/publish'; import PublishPage from './view'; const select = state => ({ - ...selectPublishFormValues(state), - // The winning claim for a short lbry uri - amountNeededForTakeover: selectTakeOverAmount(state), - // My previously published claims under this short lbry uri - myClaimForUri: selectMyClaimForUri(state), - // If I clicked the "edit" button, have I changed the uri? - // Need this to make it easier to find the source on previously published content - isStillEditing: selectIsStillEditing(state), - balance: selectBalance(state), - isResolvingUri: selectIsResolvingPublishUris(state), - totalRewardValue: selectUnclaimedRewardValue(state), -}); - -const perform = dispatch => ({ - updatePublishForm: value => dispatch(doUpdatePublishForm(value)), - clearPublish: () => dispatch(doClearPublish()), - resolveUri: uri => dispatch(doResolveUri(uri)), - publish: params => dispatch(doPublish(params)), - prepareEdit: (claim, uri) => dispatch(doPrepareEdit(claim, uri)), - resetThumbnailStatus: () => dispatch(doResetThumbnailStatus()), + contentIsFree: makeSelectPublishFormValue('contentIsFree')(state), + fee: makeSelectPublishFormValue('fee')(state), }); export default connect( select, - perform + null )(PublishPage); -- 2.45.2 From 7f5aff8cd0f5baf8a299d6df3206eda17da934c9 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 26 Jun 2019 18:07:07 -0400 Subject: [PATCH 08/10] fix: claim list sorting --- src/ui/component/claimList/view.jsx | 2 +- src/ui/component/subscribeButton/view.jsx | 4 ++-- src/ui/page/subscriptions/view.jsx | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/ui/component/claimList/view.jsx b/src/ui/component/claimList/view.jsx index 8458175ca..c8f742e4f 100644 --- a/src/ui/component/claimList/view.jsx +++ b/src/ui/component/claimList/view.jsx @@ -26,8 +26,8 @@ type Props = { export default function ClaimList(props: Props) { const { uris, headerAltControls, injectedItem, loading, persistedStorageKey, empty, meta, type, header } = props; const [currentSort, setCurrentSort] = usePersistedState(persistedStorageKey, SORT_NEW); - const sortedUris = uris && currentSort === SORT_NEW ? uris.slice().reverse() : uris; const hasUris = uris && !!uris.length; + const sortedUris = (hasUris && (currentSort === SORT_NEW ? uris : uris.slice().reverse())) || []; function handleSortChange() { setCurrentSort(currentSort === SORT_NEW ? SORT_OLD : SORT_NEW); diff --git a/src/ui/component/subscribeButton/view.jsx b/src/ui/component/subscribeButton/view.jsx index 034845107..776b1de7b 100644 --- a/src/ui/component/subscribeButton/view.jsx +++ b/src/ui/component/subscribeButton/view.jsx @@ -34,7 +34,7 @@ export default function SubscribeButton(props: Props) { } = props; const subscriptionHandler = isSubscribed ? doChannelUnsubscribe : doChannelSubscribe; - const subscriptionLabel = isSubscribed ? __('Subscribed') : __('Subscribe'); + const subscriptionLabel = isSubscribed ? __('Following') : __('Follow'); const { claimName } = parseURI(uri); @@ -57,7 +57,7 @@ export default function SubscribeButton(props: Props) { }); if (showSnackBarOnSubscribe) { - doToast({ message: `${__('Successfully subscribed to')} ${claimName}!` }); + doToast({ message: `${__('Now following ')} ${claimName}!` }); } }} /> diff --git a/src/ui/page/subscriptions/view.jsx b/src/ui/page/subscriptions/view.jsx index 3b1dccf75..193098d70 100644 --- a/src/ui/page/subscriptions/view.jsx +++ b/src/ui/page/subscriptions/view.jsx @@ -69,12 +69,11 @@ export default function SubscriptionsPage(props: Props) { headerAltControls={