diff --git a/CHANGELOG.md b/CHANGELOG.md index 3678db79c..bba8fdee5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). * Wallet Encryption/Decryption user flows ([#1785](https://github.com/lbryio/lbry-desktop/pull/1785)) * Add FAQ to Publishing Area ([#1833](https://github.com/lbryio/lbry-desktop/pull/1833)) * Better preview for content ([#620](https://github.com/lbryio/lbry-desktop/pull/620)) - * Add new markdown and docx viewer ([#1826](https://github.com/lbryio/lbry-desktop/pull/1826)) - * Add new viewer for human-readable text files ([#1826](https://github.com/lbryio/lbry-desktop/pull/1826)) - * Add csv and json viewer ([#1410](https://github.com/lbryio/lbry-desktop/pull/1410)) + * New markdown and docx viewer ([#1826](https://github.com/lbryio/lbry-desktop/pull/1826)) + * New viewer for human-readable text files ([#1826](https://github.com/lbryio/lbry-desktop/pull/1826)) + * CSV and JSON viewer ([#1410](https://github.com/lbryio/lbry-desktop/pull/1410)) + * Recommended content on file viewer page ([#1845](https://github.com/lbryio/lbry-desktop/pull/1845)) ### Changed * Pass error message from spee.ch API during thumbnail upload ([#1840](https://github.com/lbryio/lbry-desktop/pull/1840)) diff --git a/package.json b/package.json index 5a6e0741a..dfae48926 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "formik": "^0.10.4", "hast-util-sanitize": "^1.1.2", "keytar": "^4.2.1", - "lbry-redux": "lbryio/lbry-redux#83fec2a8419cbf0f1fafdc98a50dab3051191ef5", + "lbry-redux": "lbryio/lbry-redux#8794a775bf71e7b8b7d1ac44392196bb58a0042a", "localforage": "^1.7.1", "mammoth": "^1.4.6", "mime": "^2.3.1", diff --git a/src/renderer/component/common/form-components/form-field.jsx b/src/renderer/component/common/form-components/form-field.jsx index 140c7d6af..a38722d94 100644 --- a/src/renderer/component/common/form-components/form-field.jsx +++ b/src/renderer/component/common/form-components/form-field.jsx @@ -40,7 +40,6 @@ export class FormField extends React.PureComponent { children, stretch, affixClass, - firstInList, ...inputProps } = this.props; @@ -103,7 +102,6 @@ export class FormField extends React.PureComponent {
{prefix && ( diff --git a/src/renderer/component/common/form-components/form-row.jsx b/src/renderer/component/common/form-components/form-row.jsx index f694c305e..79f1b5cd0 100644 --- a/src/renderer/component/common/form-components/form-row.jsx +++ b/src/renderer/component/common/form-components/form-row.jsx @@ -17,7 +17,7 @@ export class FormRow extends React.PureComponent { }; render() { - const { centered, children, padded, verticallyCentered, stretch, alignRight } = this.props; + const { children, padded, verticallyCentered, stretch, alignRight } = this.props; return (
{
- {title} + {title}
- {pending ? ( -
Pending...
- ) : ( - - - {isRewardContent && } - {fileInfo && } - - )} + {pending ?
Pending...
: } +
+
+ {showPrice && } + {isRewardContent && } + {fileInfo && }
- {showPrice && }
); diff --git a/src/renderer/component/filePrice/view.jsx b/src/renderer/component/filePrice/view.jsx index ebb0318f1..0dd645a2f 100644 --- a/src/renderer/component/filePrice/view.jsx +++ b/src/renderer/component/filePrice/view.jsx @@ -13,6 +13,7 @@ type Props = { filePage?: boolean, inheritStyle?: boolean, showLBC?: boolean, + hideFree?: boolean, // hide the file price if it's free }; class FilePrice extends React.PureComponent { @@ -37,7 +38,11 @@ class FilePrice extends React.PureComponent { }; render() { - const { costInfo, showFullPrice, filePage, inheritStyle, showLBC } = this.props; + const { costInfo, showFullPrice, filePage, inheritStyle, showLBC, hideFree } = this.props; + + if (costInfo && !costInfo.cost && hideFree) { + return null; + } return costInfo ? ( { 'card__title--x-small': small, })} > - {title || name} + {title || name}
- {showUri ? uri : channel || __('Anonymous')} - {isRewardContent && } + + {showUri ? uri : channel || __('Anonymous')} + +
+
+ + {isRewardContent && } {showLocal && isDownloaded && }
- {displayDescription && (
{description} diff --git a/src/renderer/component/recommendedContent/index.js b/src/renderer/component/recommendedContent/index.js index 2588d29c9..166498b6d 100644 --- a/src/renderer/component/recommendedContent/index.js +++ b/src/renderer/component/recommendedContent/index.js @@ -1,19 +1,14 @@ -import * as settings from 'constants/settings'; import { connect } from 'react-redux'; -import { doFetchClaimsByChannel } from 'redux/actions/content'; -import { makeSelectClaimsInChannelForCurrentPage } from 'lbry-redux'; -import { doSetClientSetting } from 'redux/actions/settings'; -import { makeSelectClientSetting } from 'redux/selectors/settings'; +import { makeSelectClaimForUri, doSearch, makeSelectRecommendedContentForUri } from 'lbry-redux'; import RecommendedVideos from './view'; const select = (state, props) => ({ - claimsInChannel: makeSelectClaimsInChannelForCurrentPage(props.channelUri)(state), - autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state), + claim: makeSelectClaimForUri(props.uri)(state), + recommendedContent: makeSelectRecommendedContentForUri(props.uri)(state), }); const perform = dispatch => ({ - fetchClaims: (uri, page) => dispatch(doFetchClaimsByChannel(uri, page)), - setAutoplay: value => dispatch(doSetClientSetting(settings.AUTOPLAY, value)), + search: query => dispatch(doSearch(query, 20, undefined, true)), }); export default connect( diff --git a/src/renderer/component/recommendedContent/view.jsx b/src/renderer/component/recommendedContent/view.jsx index df2ac55e6..a713eaa26 100644 --- a/src/renderer/component/recommendedContent/view.jsx +++ b/src/renderer/component/recommendedContent/view.jsx @@ -1,73 +1,72 @@ // @flow import React from 'react'; import FileTile from 'component/fileTile'; -import { FormRow, FormField } from 'component/common/form'; -import ToolTip from 'component/common/tooltip'; import type { Claim } from 'types/claim'; -import { buildURI, parseURI } from 'lbry-redux'; type Props = { uri: string, - channelUri: ?string, - claimsInChannel: ?Array, - autoplay: boolean, - setAutoplay: boolean => void, - fetchClaims: (string, number) => void, + claim: ?Claim, + recommendedContent: Array, + search: string => void, }; -export default class RecommendedContent extends React.PureComponent { +export default class RecommendedContent extends React.PureComponent { + constructor() { + super(); + + this.didSearch = undefined; + } + componentDidMount() { - const { channelUri, fetchClaims, claimsInChannel } = this.props; - if (channelUri && !claimsInChannel) { - fetchClaims(channelUri, 1); + this.getRecommendedContent(); + } + + componentDidUpdate(prevProps: Props) { + const { claim, uri } = this.props; + + if (uri !== prevProps.uri) { + this.didSearch = false; + } + + if (claim && !this.didSearch) { + this.getRecommendedContent(); } } - render() { - const { claimsInChannel, autoplay, uri, setAutoplay } = this.props; + getRecommendedContent() { + const { claim, search } = this.props; - let recommendedContent; - if (claimsInChannel) { - recommendedContent = claimsInChannel.filter(claim => { - const { name, claim_id: claimId, channel_name: channelName, value } = claim; - const { isChannel } = parseURI(uri); + if (claim && claim.value && claim.value.stream && claim.value.stream.metadata) { + const { + value: { + stream: { + metadata: { title }, + }, + }, + } = claim; - // The uri may include the channel name - const recommendedUri = - isChannel && value && value.publisherSignature - ? buildURI({ - contentName: name, - claimName: channelName, - claimId: value.publisherSignature.certificateId, - }) - : buildURI({ claimName: name, claimId }); - - return recommendedUri !== uri; - }); + search(title); + this.didSearch = true; } + } + + didSearch: ?boolean; + + render() { + const { recommendedContent } = this.props; return (
- - - setAutoplay(e.target.checked)} - /> - - + Related {recommendedContent && - recommendedContent.map(({ permanent_url: permanentUrl }) => ( + recommendedContent.length && + recommendedContent.map(recommendedUri => ( ))}
diff --git a/src/renderer/modal/modalCreditIntro/view.jsx b/src/renderer/modal/modalCreditIntro/view.jsx index f16f1bc9c..559cb1e39 100644 --- a/src/renderer/modal/modalCreditIntro/view.jsx +++ b/src/renderer/modal/modalCreditIntro/view.jsx @@ -27,14 +27,14 @@ const ModalCreditIntro = (props: Props) => {

{currentBalance <= 0 && (

- You currently have , so the actions you - can take are limited. + You currently have , so the actions + you can take are limited.

)} {Boolean(totalRewardValue) && (

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

)} diff --git a/src/renderer/page/file/view.jsx b/src/renderer/page/file/view.jsx index b70e69461..8eba0ed2d 100644 --- a/src/renderer/page/file/view.jsx +++ b/src/renderer/page/file/view.jsx @@ -1,5 +1,6 @@ // @flow import * as React from 'react'; +import * as settings from 'constants/settings'; import { buildURI, normalizeURI, MODALS } from 'lbry-redux'; import FileViewer from 'component/fileViewer'; import Thumbnail from 'component/common/thumbnail'; @@ -20,6 +21,8 @@ import FileDownloadLink from 'component/fileDownloadLink'; import classnames from 'classnames'; import getMediaType from 'util/getMediaType'; import RecommendedContent from 'component/recommendedContent'; +import { FormField, FormRow } from 'component/common/form'; +import ToolTip from 'component/common/tooltip'; type Props = { claim: Claim, @@ -43,6 +46,8 @@ type Props = { prepareEdit: ({}, string) => void, checkSubscription: ({ channelName: string, uri: string }) => void, subscriptions: Array, + setClientSetting: (string, boolean | string) => void, + autoplay: boolean, }; class FilePage extends React.Component { @@ -59,6 +64,12 @@ class FilePage extends React.Component { 'application', ]; + constructor(props: Props) { + super(props); + + (this: any).onAutoplayChange = this.onAutoplayChange.bind(this); + } + componentDidMount() { const { uri, fileInfo, fetchFileInfo, fetchCostInfo } = this.props; @@ -79,6 +90,10 @@ class FilePage extends React.Component { } } + onAutoplayChange(event: SyntheticInputEvent<*>) { + this.props.setClientSetting(settings.AUTOPLAY, event.target.checked); + } + checkSubscription = (props: Props) => { if (props.subscriptions.find(sub => sub.channelName === props.claim.channel_name)) { props.checkSubscription({ @@ -108,6 +123,7 @@ class FilePage extends React.Component { navigate, costInfo, fileInfo, + autoplay, } = this.props; // File info @@ -213,12 +229,23 @@ class FilePage extends React.Component {
+ + + + +
- + ); } diff --git a/src/renderer/scss/_gui.scss b/src/renderer/scss/_gui.scss index cae904513..33899285f 100644 --- a/src/renderer/scss/_gui.scss +++ b/src/renderer/scss/_gui.scss @@ -257,10 +257,8 @@ p { } .credit-amount { - font-family: 'metropolis-bold'; font-size: 10px; white-space: nowrap; - padding: $spacing-vertical * 1/6 0; } .credit-amount--large { @@ -269,12 +267,13 @@ p { } .credit-amount--file-page { + font-family: 'metropolis-bold'; border-radius: 5px; padding: 5px; } .credit-amount--free { - color: var(--color-secondary); + color: var(--color-credit-free); &.credit-amount--file-page { color: var(--color-dark-blue); @@ -283,7 +282,7 @@ p { } .credit-amount--cost { - color: var(--color-yellow); + color: var(--color-credit-price); &.credit-amount--file-page { color: var(--color-black); diff --git a/src/renderer/scss/_vars.scss b/src/renderer/scss/_vars.scss index ac80156c0..64fa23cfe 100644 --- a/src/renderer/scss/_vars.scss +++ b/src/renderer/scss/_vars.scss @@ -9,7 +9,7 @@ $large-breakpoint: 1921px; :root { /* Widths & spacings */ - --side-nav-width: 190px; + --side-nav-width: 160px; --side-nav-width-m: 240px; --side-nav-width-l: 320px; --font-size-subtext-multiple: 0.92; @@ -49,6 +49,8 @@ $large-breakpoint: 1921px; --color-bg-alt: var(--color-grey-light); --color-placeholder: var(--color-grey); --color-search-placeholder: var(--color-placeholder); + --color-credit-free: var(--color-dark-blue); + --color-credit-price: var(--card-text-color); /* Shadows */ --box-shadow-layer: transparent; // 0 2px 4px rgba(0,0,0,0.25); diff --git a/src/renderer/scss/component/_card.scss b/src/renderer/scss/component/_card.scss index 40ba15923..57f107813 100644 --- a/src/renderer/scss/component/_card.scss +++ b/src/renderer/scss/component/_card.scss @@ -111,11 +111,12 @@ } .card__title--small { - font-size: 14px; - line-height: 18px; + font-size: 12px; + line-height: 12px; - @media only screen and (min-width: $large-breakpoint) { - font-size: 16px; + @media only screen and (min-width: $medium-breakpoint) { + font-size: 14px; + line-height: 14px; } } @@ -135,6 +136,13 @@ .card__title--file-card { padding-top: $spacing-vertical * 1/3; + // height is the same height that two lines of title fill + // doing this so content below the title is inline accross the row + height: 30px; + + @media only screen and (min-width: $medium-breakpoint) { + height: 36px; + } } .card__subtitle { @@ -142,12 +150,6 @@ font-size: 14px; font-family: 'metropolis-medium'; color: var(--card-text-color); - display: flex; - align-items: center; - - .icon { - margin: 0 0 0 $spacing-vertical * 1/3; - } } .card__subtitle--x-small { @@ -170,6 +172,18 @@ padding-top: $spacing-vertical * 2/3; } +.card__file-properties { + display: flex; + align-items: center; + padding-top: $spacing-vertical * 1/3; + color: var(--card-text-color); + + .icon + .icon, + .credit-amount + .icon { + margin-left: $spacing-vertical * 1/3; + } +} + // .card-media__internal__links should always be inside a card .card { .card-media__internal-links { diff --git a/src/renderer/scss/component/_file-list.scss b/src/renderer/scss/component/_file-list.scss index b4ed9e7ac..ee2583015 100644 --- a/src/renderer/scss/component/_file-list.scss +++ b/src/renderer/scss/component/_file-list.scss @@ -31,9 +31,15 @@ .card__subtitle { line-height: 1; + display: flex; + align-items: center; } } +.file-tile__channel { + padding-right: $spacing-width * 1/4; +} + .file-tile.file-tile--small { padding-top: $spacing-vertical * 2/3; diff --git a/src/renderer/scss/component/_form-field.scss b/src/renderer/scss/component/_form-field.scss index f27667ec2..15fbe14e5 100644 --- a/src/renderer/scss/component/_form-field.scss +++ b/src/renderer/scss/component/_form-field.scss @@ -12,7 +12,7 @@ } &.form-row--padded { - padding-top: $spacing-vertical * 2/3; + padding-top: $spacing-vertical * 1/3; } &.form-row--vertically-centered { diff --git a/src/renderer/scss/component/_nav.scss b/src/renderer/scss/component/_nav.scss index fb1162c9a..ff282eea1 100644 --- a/src/renderer/scss/component/_nav.scss +++ b/src/renderer/scss/component/_nav.scss @@ -1,5 +1,5 @@ .nav { - width: var(--side-nav-width); + min-width: var(--side-nav-width); background-color: var(--nav-bg-color); padding: $spacing-width * 1/3; color: var(--nav-color); @@ -13,11 +13,11 @@ @media (min-width: $medium-breakpoint) { padding-left: $spacing-width; - width: calc(var(--side-nav-width) * 1.2); + width: calc(var(--side-nav-width) * 1.4); } @media (min-width: $large-breakpoint) { - width: calc(var(--side-nav-width) * 1.4); + width: calc(var(--side-nav-width) * 1.6); } } diff --git a/src/renderer/scss/component/_toggle.scss b/src/renderer/scss/component/_toggle.scss index 446361fd8..bb13b7696 100644 --- a/src/renderer/scss/component/_toggle.scss +++ b/src/renderer/scss/component/_toggle.scss @@ -9,6 +9,7 @@ padding: 0; user-select: none; margin-bottom: auto; + margin-top: 2px; } .react-toggle-screenreader-only { @@ -30,8 +31,8 @@ } .react-toggle-track { - width: 50px; - height: 24px; + width: 40px; + height: 19px; padding: 0; border-radius: 30px; background-color: #4d4d4d; @@ -61,7 +62,7 @@ margin-top: auto; margin-bottom: auto; line-height: 0; - left: 8px; + left: 6px; opacity: 0; -webkit-transition: opacity 0.25s ease; -moz-transition: opacity 0.25s ease; @@ -98,8 +99,8 @@ position: absolute; top: 1px; left: 1px; - width: 22px; - height: 22px; + width: 17px; + height: 17px; border: 1px solid #4d4d4d; border-radius: 50%; background-color: #fafafa; @@ -108,6 +109,6 @@ } .react-toggle--checked .react-toggle-thumb { - left: 27px; + left: 22px; border-color: var(--input-switch-color); } diff --git a/src/renderer/scss/component/_tooltip.scss b/src/renderer/scss/component/_tooltip.scss index ff58835f6..9acd75954 100644 --- a/src/renderer/scss/component/_tooltip.scss +++ b/src/renderer/scss/component/_tooltip.scss @@ -75,8 +75,8 @@ .tooltip--right { .tooltip__body { - margin-top: -5px; - margin-left: 10px; + margin-top: -30px; + margin-left: 110%; &::after { top: 17px; diff --git a/src/renderer/types/claim.js b/src/renderer/types/claim.js index 3878294d9..ec060f2e6 100644 --- a/src/renderer/types/claim.js +++ b/src/renderer/types/claim.js @@ -34,6 +34,8 @@ export type Claim = { publisherSignature: ?{ certificateId: ?string, }, - stream: ?Metadata, + stream: { + metadata: ?Metadata, + }, }, }; diff --git a/static/themes/dark.css b/static/themes/dark.css index 7343530d5..d3ca442c5 100644 --- a/static/themes/dark.css +++ b/static/themes/dark.css @@ -9,6 +9,7 @@ --color-bg: var(--color-blue-grey); --color-bg-alt: #2D3D56; --color-placeholder: var(--color-bg-alt); + --color-credit-free: var(--color-secondary); /* Text */ --text-color: var(--color-white); diff --git a/yarn.lock b/yarn.lock index 4e3f7c24d..13d1c7185 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5651,9 +5651,9 @@ lazy-val@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.3.tgz#bb97b200ef00801d94c317e29dc6ed39e31c5edc" -lbry-redux@lbryio/lbry-redux#b4fffe863df316bc73183567ab978221ee623b8c: +lbry-redux@lbryio/lbry-redux#03c3354c12f7834e6ed63705ff19487669be32b9: version "0.0.1" - resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/b4fffe863df316bc73183567ab978221ee623b8c" + resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/03c3354c12f7834e6ed63705ff19487669be32b9" dependencies: proxy-polyfill "0.1.6" reselect "^3.0.0"