Merge master into 'release'

This commit is contained in:
Sean Yesmunt 2018-08-27 19:04:07 -04:00
commit b7ead10b5b
15 changed files with 120 additions and 36 deletions

View file

@ -21,5 +21,6 @@ module.name_mapper='^rewards\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/rewards\1'
module.name_mapper='^modal\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/modal\1' module.name_mapper='^modal\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/modal\1'
module.name_mapper='^app\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/app\1' module.name_mapper='^app\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/app\1'
module.name_mapper='^native\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/native\1' module.name_mapper='^native\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/native\1'
module.name_mapper='^analytics\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/analytics\1'
[strict] [strict]

View file

@ -50,7 +50,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#31f7afa8a37f5741dac01fc1ecdf153f3bed95dc", "lbry-redux": "lbryio/lbry-redux#feffbe966fc568cef595ab66b314766261e855df",
"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

@ -2,16 +2,14 @@
import * as React from 'react'; import * as React from 'react';
import CardMedia from 'component/cardMedia'; import CardMedia from 'component/cardMedia';
import TruncatedText from 'component/common/truncated-text'; import TruncatedText from 'component/common/truncated-text';
import classnames from 'classnames';
/* import SubscribeButton from 'component/subscribeButton';
This component can probably be combined with FileTile
Currently the only difference is showing the number of files/empty channel
*/
type Props = { type Props = {
uri: string, uri: string,
isResolvingUri: boolean, isResolvingUri: boolean,
totalItems: number, totalItems: number,
size: string,
claim: ?{ claim: ?{
claim_id: string, claim_id: string,
name: string, name: string,
@ -21,6 +19,10 @@ type Props = {
}; };
class ChannelTile extends React.PureComponent<Props> { class ChannelTile extends React.PureComponent<Props> {
static defaultProps = {
size: 'regular',
};
componentDidMount() { componentDidMount() {
const { uri, resolveUri } = this.props; const { uri, resolveUri } = this.props;
@ -36,27 +38,54 @@ class ChannelTile extends React.PureComponent<Props> {
} }
render() { render() {
const { claim, navigate, isResolvingUri, totalItems, uri } = this.props; const { claim, navigate, isResolvingUri, totalItems, uri, size } = this.props;
let channelName, channelId;
let channelName;
let subscriptionUri;
if (claim) { if (claim) {
channelName = claim.name; channelName = claim.name;
channelId = claim.claim_id; subscriptionUri = claim.permanent_url;
} }
const onClick = () => navigate('/show', { uri }); const onClick = () => navigate('/show', { uri });
return ( return (
<section className="file-tile card--link" onClick={onClick} role="button"> <section
onClick={onClick}
role="button"
className={classnames('file-tile card--link', {
'file-tile--small': size === 'small',
'file-tile--large': size === 'large',
})}
>
<CardMedia title={channelName} thumbnail={null} /> <CardMedia title={channelName} thumbnail={null} />
<div className="file-tile__info"> <div className="file-tile__info">
{isResolvingUri && <div className="card__title--small">{__('Loading...')}</div>} {isResolvingUri && (
<div
className={classnames({
'card__title--small': size !== 'large',
'card__title--large': size === 'large',
})}
>
{__('Loading...')}
</div>
)}
{!isResolvingUri && ( {!isResolvingUri && (
<React.Fragment> <React.Fragment>
<div className="card__title--small card__title--file"> <div
className={classnames({
'card__title--file': size === 'regular',
'card__title--x-small': size === 'small',
'card__title--large': size === 'large',
})}
>
<TruncatedText lines={1}>{channelName || uri}</TruncatedText> <TruncatedText lines={1}>{channelName || uri}</TruncatedText>
</div> </div>
<div className="card__subtitle"> <div
className={classnames('card__subtitle', {
'card__subtitle--large': size === 'large',
})}
>
{totalItems > 0 && ( {totalItems > 0 && (
<span> <span>
{totalItems} {totalItems === 1 ? 'file' : 'files'} {totalItems} {totalItems === 1 ? 'file' : 'files'}
@ -66,6 +95,11 @@ class ChannelTile extends React.PureComponent<Props> {
</div> </div>
</React.Fragment> </React.Fragment>
)} )}
{subscriptionUri && (
<div className="card__actions">
<SubscribeButton uri={subscriptionUri} channelName={channelName} />
</div>
)}
</div> </div>
</section> </section>
); );

View file

@ -4,6 +4,7 @@ import {
makeSelectDownloadingForUri, makeSelectDownloadingForUri,
makeSelectLoadingForUri, makeSelectLoadingForUri,
makeSelectCostInfoForUri, makeSelectCostInfoForUri,
makeSelectClaimForUri,
} from 'lbry-redux'; } from 'lbry-redux';
import { doOpenFileInShell } from 'redux/actions/file'; import { doOpenFileInShell } from 'redux/actions/file';
import { doPurchaseUri, doStartDownload } from 'redux/actions/content'; import { doPurchaseUri, doStartDownload } from 'redux/actions/content';
@ -16,6 +17,7 @@ const select = (state, props) => ({
downloading: makeSelectDownloadingForUri(props.uri)(state), downloading: makeSelectDownloadingForUri(props.uri)(state),
costInfo: makeSelectCostInfoForUri(props.uri)(state), costInfo: makeSelectCostInfoForUri(props.uri)(state),
loading: makeSelectLoadingForUri(props.uri)(state), loading: makeSelectLoadingForUri(props.uri)(state),
claim: makeSelectClaimForUri(props.uri)(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({
@ -25,4 +27,7 @@ const perform = dispatch => ({
doPause: () => dispatch(doPause()), doPause: () => dispatch(doPause()),
}); });
export default connect(select, perform)(FileDownloadLink); export default connect(
select,
perform
)(FileDownloadLink);

View file

@ -3,8 +3,11 @@ import React from 'react';
import Button from 'component/button'; import Button from 'component/button';
import * as icons from 'constants/icons'; import * as icons from 'constants/icons';
import ToolTip from 'component/common/tooltip'; import ToolTip from 'component/common/tooltip';
import analytics from 'analytics';
import type { Claim } from 'types/claim';
type Props = { type Props = {
claim: Claim,
uri: string, uri: string,
downloading: boolean, downloading: boolean,
fileInfo: ?{ fileInfo: ?{
@ -48,6 +51,7 @@ class FileDownloadLink extends React.PureComponent<Props> {
costInfo, costInfo,
loading, loading,
doPause, doPause,
claim,
} = this.props; } = this.props;
const openFile = () => { const openFile = () => {
@ -80,6 +84,12 @@ class FileDownloadLink extends React.PureComponent<Props> {
iconColor="green" iconColor="green"
onClick={() => { onClick={() => {
purchaseUri(uri); purchaseUri(uri);
const { name, claim_id: claimId, nout, txid } = claim;
// // ideally outpoint would exist inside of claim information
// // we can use it after https://github.com/lbryio/lbry/issues/1306 is addressed
const outpoint = `${txid}:${nout}`;
analytics.apiLogView(`${name}#${claimId}`, outpoint, claimId);
}} }}
/> />
</ToolTip> </ToolTip>

View file

@ -1,10 +1,16 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectClaimForUri, doSearch, makeSelectRecommendedContentForUri } from 'lbry-redux'; import {
makeSelectClaimForUri,
doSearch,
makeSelectRecommendedContentForUri,
selectIsSearching,
} from 'lbry-redux';
import RecommendedVideos from './view'; import RecommendedVideos from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
recommendedContent: makeSelectRecommendedContentForUri(props.uri)(state), recommendedContent: makeSelectRecommendedContentForUri(props.uri)(state),
isSearching: selectIsSearching(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({

View file

@ -7,6 +7,7 @@ type Props = {
uri: string, uri: string,
claim: ?Claim, claim: ?Claim,
recommendedContent: Array<string>, recommendedContent: Array<string>,
isSearching: boolean,
search: string => void, search: string => void,
}; };
@ -46,13 +47,12 @@ export default class RecommendedContent extends React.PureComponent<Props> {
didSearch: ?boolean; didSearch: ?boolean;
render() { render() {
const { recommendedContent } = this.props; const { recommendedContent, isSearching } = this.props;
return ( return (
<section className="card__list--recommended"> <section className="card__list--recommended">
<span>Related</span> <span>Related</span>
{recommendedContent && {recommendedContent &&
recommendedContent.length &&
recommendedContent.map(recommendedUri => ( recommendedContent.map(recommendedUri => (
<FileTile <FileTile
size="small" size="small"
@ -62,6 +62,9 @@ export default class RecommendedContent extends React.PureComponent<Props> {
uri={recommendedUri} uri={recommendedUri}
/> />
))} ))}
{recommendedContent &&
!recommendedContent.length &&
!isSearching && <div className="card__subtitle">No related content found</div>}
</section> </section>
); );
} }

View file

@ -41,7 +41,9 @@ export default (props: Props) => {
icon={isSubscribed ? undefined : icons.HEART} icon={isSubscribed ? undefined : icons.HEART}
button="alt" button="alt"
label={subscriptionLabel} label={subscriptionLabel}
onClick={() => { onClick={e => {
e.stopPropagation();
if (!subscriptions.length) { if (!subscriptions.length) {
doNotify({ id: MODALS.FIRST_SUBSCRIPTION }); doNotify({ id: MODALS.FIRST_SUBSCRIPTION });
} }

View file

@ -160,13 +160,6 @@ class FilePage extends React.Component<Props> {
editUri = buildURI(uriObject); editUri = buildURI(uriObject);
} }
let recommendedUri = uri;
if (!recommendedUri.includes('#')) {
// at a vanity url
// append the claim ID so we can properly strip it out of reccomended videos
recommendedUri = `${recommendedUri}#${claim.claim_id}`;
}
return ( return (
<Page forContent> <Page forContent>
<section className="content__wrapper"> <section className="content__wrapper">
@ -251,7 +244,7 @@ class FilePage extends React.Component<Props> {
</div> </div>
</div> </div>
</section> </section>
<RecommendedContent uri={recommendedUri} /> <RecommendedContent uri={uri} />
</Page> </Page>
); );
} }

View file

@ -1,11 +1,15 @@
// @flow // @flow
import * as React from 'react'; import * as React from 'react';
import * as settings from 'constants/settings'; import * as settings from 'constants/settings';
import { isURIValid, normalizeURI } from 'lbry-redux'; import { isURIValid, normalizeURI, parseURI } from 'lbry-redux';
import { FormField, FormRow } from 'component/common/form'; import { FormField, FormRow } from 'component/common/form';
import FileTile from 'component/fileTile'; import FileTile from 'component/fileTile';
import ChannelTile from 'component/channelTile';
import FileListSearch from 'component/fileListSearch'; import FileListSearch from 'component/fileListSearch';
import Page from 'component/page'; import Page from 'component/page';
import ToolTip from 'component/common/tooltip';
import Icon from 'component/common/icon';
import * as icons from 'constants/icons';
type Props = { type Props = {
query: ?string, query: ?string,
@ -32,13 +36,35 @@ class SearchPage extends React.PureComponent<Props> {
render() { render() {
const { query, resultCount } = this.props; const { query, resultCount } = this.props;
const isValid = isURIValid(query);
let uri;
let isChannel;
if (isValid) {
uri = normalizeURI(query);
({ isChannel } = parseURI(uri));
}
return ( return (
<Page noPadding> <Page noPadding>
{query && {query &&
isURIValid(query) && ( isValid && (
<div className="search__top"> <div className="search__top">
<div className="file-list__header">{`lbry://${query}`}</div> <div className="file-list__header">
<FileTile size="large" displayHiddenMessage uri={normalizeURI(query)} /> {`lbry://${query}`}
<ToolTip
icon
body={__('This is the resolution of a LBRY URL and not controlled by LBRY Inc.')}
>
<Icon icon={icons.HELP} />
</ToolTip>
</div>
{isChannel ? (
<ChannelTile size="large" uri={uri} />
) : (
<FileTile size="large" displayHiddenMessage uri={uri} />
)}
</div> </div>
)} )}
<div className="search__content"> <div className="search__content">

View file

@ -278,13 +278,15 @@ export const doCheckPendingPublishes = () => (dispatch: Dispatch, getState: GetS
delete pendingPublishMap[claim.name]; delete pendingPublishMap[claim.name];
if (selectosNotificationsEnabled(getState())) { if (selectosNotificationsEnabled(getState())) {
const notif = new window.Notification('LBRY Publish Complete', { const notif = new window.Notification('LBRY Publish Complete', {
body: `${claim.value.stream.metadata.title} has been published to lbry://${claim.name}. Click here to view it` , body: `${claim.value.stream.metadata.title} has been published to lbry://${
silent: false, claim.name
}. Click here to view it`,
silent: false,
}); });
notif.onclick = () => { notif.onclick = () => {
dispatch( dispatch(
doNavigate('/show', { doNavigate('/show', {
uri: claim.name, uri: claim.permanent_url,
}) })
); );
}; };

View file

@ -137,6 +137,7 @@ $large-breakpoint: 1921px;
--search-item-border-color: transparent; --search-item-border-color: transparent;
--search-item-active-color: var(--color-black); --search-item-active-color: var(--color-black);
--search-modal-input-height: 70px; --search-modal-input-height: 70px;
--search-exact-result: #eaeaea;
/* Nav */ /* Nav */
--nav-color: var(--color-grey-dark); --nav-color: var(--color-grey-dark);

View file

@ -87,7 +87,7 @@
.search__top { .search__top {
padding: 0 $spacing-width $spacing-width; padding: 0 $spacing-width $spacing-width;
background-color: var(--card-bg); background-color: var(--search-exact-result);
} }
.search__content { .search__content {

View file

@ -62,6 +62,7 @@
--search-active-bg-color: #13233C; --search-active-bg-color: #13233C;
--search-active-shadow: 0 6px 9px -2px var(--color-grey--dark); --search-active-shadow: 0 6px 9px -2px var(--color-grey--dark);
--search-modal-input-height: 70px; --search-modal-input-height: 70px;
--search-exact-result: #4C5D77;
/* Nav */ /* Nav */
--nav-color: #44548F; --nav-color: #44548F;

View file

@ -5655,9 +5655,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#31f7afa8a37f5741dac01fc1ecdf153f3bed95dc: lbry-redux@lbryio/lbry-redux#ccda4117ee503e30abae355c77d3783a141e9492:
version "0.0.1" version "0.0.1"
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/31f7afa8a37f5741dac01fc1ecdf153f3bed95dc" resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/ccda4117ee503e30abae355c77d3783a141e9492"
dependencies: dependencies:
proxy-polyfill "0.1.6" proxy-polyfill "0.1.6"
reselect "^3.0.0" reselect "^3.0.0"