add recommended content

This commit is contained in:
Sean Yesmunt 2018-08-03 14:28:11 -04:00
parent 58a3740986
commit 8b90a8421c
12 changed files with 86 additions and 64 deletions

View file

@ -51,7 +51,7 @@
"formik": "^0.10.4", "formik": "^0.10.4",
"hast-util-sanitize": "^1.1.2", "hast-util-sanitize": "^1.1.2",
"keytar": "^4.2.1", "keytar": "^4.2.1",
"lbry-redux": "lbryio/lbry-redux#83fec2a8419cbf0f1fafdc98a50dab3051191ef5", "lbry-redux": "lbryio/lbry-redux#8794a775bf71e7b8b7d1ac44392196bb58a0042a",
"localforage": "^1.7.1", "localforage": "^1.7.1",
"mammoth": "^1.4.6", "mammoth": "^1.4.6",
"mime": "^2.3.1", "mime": "^2.3.1",

View file

@ -97,17 +97,13 @@ class FileCard extends React.PureComponent<Props> {
<TruncatedText lines={3}>{title}</TruncatedText> <TruncatedText lines={3}>{title}</TruncatedText>
</div> </div>
<div className="card__subtitle"> <div className="card__subtitle">
{pending ? ( {pending ? <div>Pending...</div> : <UriIndicator uri={uri} link />}
<div>Pending...</div> </div>
) : ( <div className="card__file-properties">
<React.Fragment> {showPrice && <FilePrice uri={uri} />}
<UriIndicator uri={uri} link /> {isRewardContent && <Icon iconColor="red" icon={icons.FEATURED} />}
{isRewardContent && <Icon iconColor="red" icon={icons.FEATURED} />} {fileInfo && <Icon icon={icons.LOCAL} />}
{fileInfo && <Icon icon={icons.LOCAL} />}
</React.Fragment>
)}
</div> </div>
{showPrice && <FilePrice uri={uri} />}
</div> </div>
</section> </section>
); );

View file

@ -116,7 +116,7 @@ class FileTile extends React.PureComponent<Props> {
'card__title--x-small': small, 'card__title--x-small': small,
})} })}
> >
<TruncatedText lines={3}>{title || name}</TruncatedText> <TruncatedText lines={small ? 2 : 3}>{title || name}</TruncatedText>
</div> </div>
<div <div
className={classnames('card__subtitle', { className={classnames('card__subtitle', {

View file

@ -1,19 +1,19 @@
import * as settings from 'constants/settings'; import * as settings from 'constants/settings';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doFetchClaimsByChannel } from 'redux/actions/content'; import { makeSelectClaimForUri, doSearch, makeSelectRecommendedContentForUri } from 'lbry-redux';
import { makeSelectClaimsInChannelForCurrentPage } from 'lbry-redux';
import { doSetClientSetting } from 'redux/actions/settings'; import { doSetClientSetting } from 'redux/actions/settings';
import { makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings';
import RecommendedVideos from './view'; import RecommendedVideos from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claimsInChannel: makeSelectClaimsInChannelForCurrentPage(props.channelUri)(state), claim: makeSelectClaimForUri(props.uri)(state),
recommendedContent: makeSelectRecommendedContentForUri(props.uri)(state),
autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state), autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({
fetchClaims: (uri, page) => dispatch(doFetchClaimsByChannel(uri, page)),
setAutoplay: value => dispatch(doSetClientSetting(settings.AUTOPLAY, value)), setAutoplay: value => dispatch(doSetClientSetting(settings.AUTOPLAY, value)),
search: query => dispatch(doSearch(query, 20)),
}); });
export default connect( export default connect(

View file

@ -4,47 +4,65 @@ import FileTile from 'component/fileTile';
import { FormRow, FormField } from 'component/common/form'; import { FormRow, FormField } from 'component/common/form';
import ToolTip from 'component/common/tooltip'; import ToolTip from 'component/common/tooltip';
import type { Claim } from 'types/claim'; import type { Claim } from 'types/claim';
import { buildURI, parseURI } from 'lbry-redux';
type Props = { type Props = {
uri: string, uri: string,
channelUri: ?string, claim: ?Claim,
claimsInChannel: ?Array<Claim>,
autoplay: boolean, autoplay: boolean,
recommendedContent: Array<string>,
search: string => void,
setAutoplay: boolean => void, setAutoplay: boolean => void,
fetchClaims: (string, number) => void,
}; };
export default class RecommendedContent extends React.PureComponent<Props> { type State = {
didSearch: boolean,
};
export default class RecommendedContent extends React.PureComponent<Props, State> {
constructor() {
super();
this.state = {
didSearch: false,
};
}
componentDidMount() { componentDidMount() {
const { channelUri, fetchClaims, claimsInChannel } = this.props; this.getRecommendedContent();
if (channelUri && !claimsInChannel) { }
fetchClaims(channelUri, 1);
componentDidUpdate(prevProps: Props) {
const { claim, uri } = this.props;
const { didSearch } = this.state;
if (uri !== prevProps.uri) {
this.setState({ didSearch: false });
}
if (claim && !didSearch) {
this.getRecommendedContent();
}
}
getRecommendedContent() {
const { claim, search } = this.props;
if (claim && claim.value && claim.value.stream && claim.value.stream.metadata) {
const {
value: {
stream: {
metadata: { title },
},
},
} = claim;
// console.log("search", title)
search(title);
this.setState({ didSearch: true });
} }
} }
render() { render() {
const { claimsInChannel, autoplay, uri, setAutoplay } = this.props; const { autoplay, setAutoplay, recommendedContent } = this.props;
let recommendedContent;
if (claimsInChannel) {
recommendedContent = claimsInChannel.filter(claim => {
const { name, claim_id: claimId, channel_name: channelName, value } = claim;
const { isChannel } = parseURI(uri);
// 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;
});
}
return ( return (
<section className="card__list--recommended"> <section className="card__list--recommended">
@ -62,12 +80,14 @@ export default class RecommendedContent extends React.PureComponent<Props> {
</ToolTip> </ToolTip>
</FormRow> </FormRow>
{recommendedContent && {recommendedContent &&
recommendedContent.map(({ permanent_url: permanentUrl }) => ( recommendedContent.length &&
recommendedContent.map(recommendedUri => (
<FileTile <FileTile
small small
hideNoResult
displayDescription={false} displayDescription={false}
key={permanentUrl} key={recommendedUri}
uri={`lbry://${permanentUrl}`} uri={recommendedUri}
/> />
))} ))}
</section> </section>

View file

@ -218,7 +218,7 @@ class FilePage extends React.Component<Props> {
</div> </div>
</div> </div>
</section> </section>
<RecommendedContent uri={uri} channelUri={`lbry://${subscriptionUri}`} /> <RecommendedContent uri={uri} />
</Page> </Page>
); );
} }

View file

@ -274,7 +274,7 @@ p {
} }
.credit-amount--free { .credit-amount--free {
color: var(--color-secondary); color: var(--color-credit-free);
&.credit-amount--file-page { &.credit-amount--file-page {
color: var(--color-dark-blue); color: var(--color-dark-blue);
@ -283,7 +283,7 @@ p {
} }
.credit-amount--cost { .credit-amount--cost {
color: var(--color-yellow); color: var(--color-credit-price);
&.credit-amount--file-page { &.credit-amount--file-page {
color: var(--color-black); color: var(--color-black);

View file

@ -9,7 +9,7 @@ $large-breakpoint: 1921px;
:root { :root {
/* Widths & spacings */ /* Widths & spacings */
--side-nav-width: 190px; --side-nav-width: 160px;
--side-nav-width-m: 240px; --side-nav-width-m: 240px;
--side-nav-width-l: 320px; --side-nav-width-l: 320px;
--font-size-subtext-multiple: 0.92; --font-size-subtext-multiple: 0.92;
@ -31,7 +31,7 @@ $large-breakpoint: 1921px;
--color-dark-blue: #2f6f61; --color-dark-blue: #2f6f61;
--color-light-blue: #49b2e2; --color-light-blue: #49b2e2;
--color-red: #e2495e; --color-red: #e2495e;
--color-yellow: #fbd55e; --color-yellow: #e8b414;
--color-green: #399483; --color-green: #399483;
--color-green-light: #effbe4; --color-green-light: #effbe4;
--color-green-blue: #2ec1a8; --color-green-blue: #2ec1a8;
@ -49,6 +49,8 @@ $large-breakpoint: 1921px;
--color-bg-alt: var(--color-grey-light); --color-bg-alt: var(--color-grey-light);
--color-placeholder: var(--color-grey); --color-placeholder: var(--color-grey);
--color-search-placeholder: var(--color-placeholder); --color-search-placeholder: var(--color-placeholder);
--color-credit-free: var(--color-dark-blue);
--color-credit-price: var(--color-yellow);
/* Shadows */ /* Shadows */
--box-shadow-layer: transparent; // 0 2px 4px rgba(0,0,0,0.25); --box-shadow-layer: transparent; // 0 2px 4px rgba(0,0,0,0.25);

View file

@ -142,12 +142,6 @@
font-size: 14px; font-size: 14px;
font-family: 'metropolis-medium'; font-family: 'metropolis-medium';
color: var(--card-text-color); color: var(--card-text-color);
display: flex;
align-items: center;
.icon {
margin: 0 0 0 $spacing-vertical * 1/3;
}
} }
.card__subtitle--x-small { .card__subtitle--x-small {
@ -170,6 +164,15 @@
padding-top: $spacing-vertical * 2/3; padding-top: $spacing-vertical * 2/3;
} }
.card__file-properties {
display: flex;
align-items: center;
.icon {
margin: 0 0 0 $spacing-vertical * 1/3;
}
}
// .card-media__internal__links should always be inside a card // .card-media__internal__links should always be inside a card
.card { .card {
.card-media__internal-links { .card-media__internal-links {

View file

@ -1,5 +1,5 @@
.nav { .nav {
width: var(--side-nav-width); min-width: var(--side-nav-width);
background-color: var(--nav-bg-color); background-color: var(--nav-bg-color);
padding: $spacing-width * 1/3; padding: $spacing-width * 1/3;
color: var(--nav-color); color: var(--nav-color);
@ -13,11 +13,11 @@
@media (min-width: $medium-breakpoint) { @media (min-width: $medium-breakpoint) {
padding-left: $spacing-width; 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) { @media (min-width: $large-breakpoint) {
width: calc(var(--side-nav-width) * 1.4); width: calc(var(--side-nav-width) * 1.6);
} }
} }

View file

@ -9,6 +9,7 @@
--color-bg: var(--color-blue-grey); --color-bg: var(--color-blue-grey);
--color-bg-alt: #2D3D56; --color-bg-alt: #2D3D56;
--color-placeholder: var(--color-bg-alt); --color-placeholder: var(--color-bg-alt);
--color-credit-free: var(--color-secondary);
/* Text */ /* Text */
--text-color: var(--color-white); --text-color: var(--color-white);

View file

@ -5651,9 +5651,9 @@ lazy-val@^1.0.3:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.3.tgz#bb97b200ef00801d94c317e29dc6ed39e31c5edc" 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" 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: dependencies:
proxy-polyfill "0.1.6" proxy-polyfill "0.1.6"
reselect "^3.0.0" reselect "^3.0.0"