Merge branch 'master' into three-v2

This commit is contained in:
Sean Yesmunt 2018-08-22 15:09:55 -04:00 committed by GitHub
commit fe616ad5ab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 66 additions and 52 deletions

View file

@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
* CSV and JSON viewer ([#1410](https://github.com/lbryio/lbry-desktop/pull/1410)) * 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)) * Recommended content on file viewer page ([#1845](https://github.com/lbryio/lbry-desktop/pull/1845))
* 3D File viewer improvements ([#1870](https://github.com/lbryio/lbry-desktop/pull/1870)) * 3D File viewer improvements ([#1870](https://github.com/lbryio/lbry-desktop/pull/1870))
* Desktop notification when publish is completed ([#1892](https://github.com/lbryio/lbry-desktop/pull/1892))
### Changed ### Changed
* Pass error message from spee.ch API during thumbnail upload ([#1840](https://github.com/lbryio/lbry-desktop/pull/1840)) * Pass error message from spee.ch API during thumbnail upload ([#1840](https://github.com/lbryio/lbry-desktop/pull/1840))

View file

@ -5,7 +5,7 @@
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/78b627d4f5524792adc48719835e1523)](https://www.codacy.com/app/LBRY/lbry-desktop?utm_source=github.com&utm_medium=referral&utm_content=lbryio/lbry-desktop&utm_campaign=Badge_Grade) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/78b627d4f5524792adc48719835e1523)](https://www.codacy.com/app/LBRY/lbry-desktop?utm_source=github.com&utm_medium=referral&utm_content=lbryio/lbry-desktop&utm_campaign=Badge_Grade)
[![chat on Discord](https://img.shields.io/discord/362322208485277697.svg?logo=discord)](https://chat.lbry.io) [![chat on Discord](https://img.shields.io/discord/362322208485277697.svg?logo=discord)](https://chat.lbry.io)
[![forthebadge](https://forthebadge.com/images/badges/certified-steve-bruhle.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/60-percent-of-the-time-works-every-time.svg)](https://forthebadge.com)
The LBRY app is a graphical browser for the decentralized content marketplace provided by the The LBRY app is a graphical browser for the decentralized content marketplace provided by the
[LBRY](https://lbry.io) protocol. It is essentially the [LBRY](https://lbry.io) protocol. It is essentially the
@ -32,10 +32,10 @@ To install from source or make changes to the application, continue to the next
**Community maintained** builds for Arch Linux and Flatpak are available, see below. These installs will need to be updated manually as the in-app update process only supports deb installs at this time. **Community maintained** builds for Arch Linux and Flatpak are available, see below. These installs will need to be updated manually as the in-app update process only supports deb installs at this time.
*Note: If coming from a deb install, the directory structure is different and you'll need to [migrate data](https://lbry.io/faq/backup-data).* *Note: If coming from a deb install, the directory structure is different and you'll need to [migrate data](https://lbry.io/faq/backup-data).*
| | Flatpak | Arch | | Flatpak | Arch | Raspberry Pi |
| --------------------- | ------------------------------------------| -------------------------------------------- | --------------------- | ------------------------------------------|------------------| --------------------------------------------
| Latest Release | [FlatHub Page](https://flathub.org/apps/details/io.lbry.lbry-app) | [AUR Package](https://aur.archlinux.org/packages/lbry-app-bin/) | Latest Release | [FlatHub Page](https://flathub.org/apps/details/io.lbry.lbry-app) | [AUR Package](https://aur.archlinux.org/packages/lbry-app-bin/) | [Pi Installer](https://lbrypi.com) |
| Maintainers | [@choofee](https://github.com/choffee)/[@iuyte](https://github.com/iuyte) | [@kcseb](https://github.com/kcseb)/[@TimurKiyivinski](https://github.com/TimurKiyivinski) | Maintainers | [@choofee](https://github.com/choffee)/[@iuyte](https://github.com/iuyte) | [@kcseb](https://github.com/kcseb)/[@TimurKiyivinski](https://github.com/TimurKiyivinski) |[@Madiator2011](https://github.com/kodxana)
## Usage ## Usage
Double click the installed application to browse with the LBRY network. Double click the installed application to browse with the LBRY network.

View file

@ -97,10 +97,13 @@ class FilePage extends React.Component<Props> {
checkSubscription = (props: Props) => { checkSubscription = (props: Props) => {
if (props.subscriptions.find(sub => sub.channelName === props.claim.channel_name)) { if (props.subscriptions.find(sub => sub.channelName === props.claim.channel_name)) {
props.checkSubscription( props.checkSubscription(
buildURI({ buildURI(
{
contentName: props.claim.channel_name, contentName: props.claim.channel_name,
claimId: props.claim.value.publisherSignature.certificateId, claimId: props.claim.value.publisherSignature.certificateId,
}, false) },
false
)
); );
} }
}; };
@ -157,6 +160,13 @@ 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">
@ -241,7 +251,7 @@ class FilePage extends React.Component<Props> {
</div> </div>
</div> </div>
</section> </section>
<RecommendedContent uri={uri} /> <RecommendedContent uri={recommendedUri} />
</Page> </Page>
); );
} }

View file

@ -1,4 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import * as settings from 'constants/settings';
import { import {
selectSubscriptionClaims, selectSubscriptionClaims,
selectSubscriptions, selectSubscriptions,
@ -6,25 +7,26 @@ import {
selectIsFetchingSubscriptions, selectIsFetchingSubscriptions,
selectNotifications, selectNotifications,
} from 'redux/selectors/subscriptions'; } from 'redux/selectors/subscriptions';
import { doFetchClaimsByChannel } from 'redux/actions/content';
import { setSubscriptionNotifications, doFetchMySubscriptions } from 'redux/actions/subscriptions'; import { setSubscriptionNotifications, doFetchMySubscriptions } from 'redux/actions/subscriptions';
import { doSetClientSetting } from 'redux/actions/settings';
import { makeSelectClientSetting } from 'redux/selectors/settings';
import SubscriptionsPage from './view'; import SubscriptionsPage from './view';
const select = state => ({ const select = state => ({
loading: loading:
selectIsFetchingSubscriptions(state) || selectIsFetchingSubscriptions(state) ||
Boolean(Object.keys(selectSubscriptionsBeingFetched(state)).length), Boolean(Object.keys(selectSubscriptionsBeingFetched(state)).length),
subscriptionsBeingFetched: selectSubscriptionsBeingFetched(state),
subscriptions: selectSubscriptions(state), subscriptions: selectSubscriptions(state),
subscriptionClaims: selectSubscriptionClaims(state), subscriptionClaims: selectSubscriptionClaims(state),
notifications: selectNotifications(state), notifications: selectNotifications(state),
autoDownload: makeSelectClientSetting(settings.AUTO_DOWNLOAD)(state),
}); });
export default connect( export default connect(
select, select,
{ {
doFetchClaimsByChannel,
setSubscriptionNotifications, setSubscriptionNotifications,
doFetchMySubscriptions, doFetchMySubscriptions,
doSetClientSetting,
} }
)(SubscriptionsPage); )(SubscriptionsPage);

View file

@ -1,26 +1,32 @@
// @flow // @flow
import React from 'react'; import React from 'react';
import Page from 'component/page'; import Page from 'component/page';
import * as settings from 'constants/settings';
import type { Subscription } from 'types/subscription'; import type { Subscription } from 'types/subscription';
import * as NOTIFICATION_TYPES from 'constants/notification_types'; import * as NOTIFICATION_TYPES from 'constants/notification_types';
import Button from 'component/button'; import Button from 'component/button';
import FileList from 'component/fileList'; import FileList from 'component/fileList';
import type { Claim } from 'types/claim'; import type { Claim } from 'types/claim';
import isDev from 'electron-is-dev';
import HiddenNsfwClaims from 'component/hiddenNsfwClaims'; import HiddenNsfwClaims from 'component/hiddenNsfwClaims';
import { FormField, FormRow } from 'component/common/form';
type Props = { type Props = {
doFetchClaimsByChannel: (string, number) => void,
doFetchMySubscriptions: () => void, doFetchMySubscriptions: () => void,
setSubscriptionNotifications: ({}) => void, setSubscriptionNotifications: ({}) => void,
subscriptions: Array<Subscription>, subscriptions: Array<Subscription>,
subscriptionClaims: Array<{ uri: string, claims: Array<Claim> }>, subscriptionClaims: Array<{ uri: string, claims: Array<Claim> }>,
subscriptionsBeingFetched: {},
notifications: {}, notifications: {},
loading: boolean, loading: boolean,
autoDownload: boolean,
doSetClientSetting: (string, boolean) => void,
}; };
export default class extends React.PureComponent<Props> { export default class extends React.PureComponent<Props> {
constructor() {
super();
(this: any).onAutoDownloadChange = this.onAutoDownloadChange.bind(this);
}
componentDidMount() { componentDidMount() {
const { notifications, setSubscriptionNotifications, doFetchMySubscriptions } = this.props; const { notifications, setSubscriptionNotifications, doFetchMySubscriptions } = this.props;
doFetchMySubscriptions(); doFetchMySubscriptions();
@ -37,43 +43,12 @@ export default class extends React.PureComponent<Props> {
setSubscriptionNotifications(newNotifications); setSubscriptionNotifications(newNotifications);
} }
componentDidUpdate() { onAutoDownloadChange(event: SyntheticInputEvent<*>) {
const { this.props.doSetClientSetting(settings.AUTO_DOWNLOAD, event.target.checked);
subscriptions,
subscriptionClaims,
doFetchClaimsByChannel,
subscriptionsBeingFetched,
} = this.props;
const subscriptionClaimMap = {};
subscriptionClaims.forEach(claim => {
/*
This check added 6/20/18 to fix function receiving empty claims unexpectedly.
The better fix is ensuring channels aren't added to byId if there are no associated claims
We are adding this now with the redesign release to ensure users see the correct subscriptions
*/
if (claim.claims.length) {
subscriptionClaimMap[claim.uri] = 1;
} else if (isDev) {
// eslint-disable no-console
console.error(
`Claim for ${
claim.uri
} was added to byId in redux but there are no loaded fetched claims. This shouldn't happen because a subscription should have claims attached to it.`
);
// eslint-enable no-console
}
});
subscriptions.forEach(sub => {
if (!subscriptionClaimMap[sub.uri] && !subscriptionsBeingFetched[sub.uri]) {
doFetchClaimsByChannel(sub.uri, 1);
}
});
} }
render() { render() {
const { subscriptions, subscriptionClaims, loading } = this.props; const { subscriptions, subscriptionClaims, loading, autoDownload } = this.props;
let claimList = []; let claimList = [];
subscriptionClaims.forEach(claimData => { subscriptionClaims.forEach(claimData => {
@ -85,6 +60,15 @@ export default class extends React.PureComponent<Props> {
return ( return (
<Page notContained loading={loading}> <Page notContained loading={loading}>
<HiddenNsfwClaims uris={subscriptionUris} /> <HiddenNsfwClaims uris={subscriptionUris} />
<FormRow alignRight>
<FormField
type="checkbox"
name="auto_download"
onChange={this.onAutoDownloadChange}
checked={autoDownload}
prefix={__('Automatically download new content from your subscriptions')}
/>
</FormRow>
{!subscriptions.length && ( {!subscriptions.length && (
<div className="page__empty"> <div className="page__empty">
{__("It looks like you aren't subscribed to any channels yet.")} {__("It looks like you aren't subscribed to any channels yet.")}

View file

@ -14,6 +14,8 @@ import type {
UpdatePublishFormAction, UpdatePublishFormAction,
PublishParams, PublishParams,
} from 'redux/reducers/publish'; } from 'redux/reducers/publish';
import { selectosNotificationsEnabled } from 'redux/selectors/settings';
import { doNavigate } from 'redux/actions/navigation';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
@ -274,6 +276,19 @@ export const doCheckPendingPublishes = () => (dispatch: Dispatch, getState: GetS
}); });
delete pendingPublishMap[claim.name]; delete pendingPublishMap[claim.name];
if (selectosNotificationsEnabled(getState())) {
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` ,
silent: false,
});
notif.onclick = () => {
dispatch(
doNavigate('/show', {
uri: claim.name,
})
);
};
}
} }
}); });

View file

@ -8,7 +8,7 @@ import type { Subscription } from 'types/subscription';
import { selectSubscriptions } from 'redux/selectors/subscriptions'; import { selectSubscriptions } from 'redux/selectors/subscriptions';
import { makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings';
import { Lbry, buildURI, parseURI } from 'lbry-redux'; import { Lbry, buildURI, parseURI } from 'lbry-redux';
import { doPurchaseUri } from 'redux/actions/content'; import { doPurchaseUri, doFetchClaimsByChannel } from 'redux/actions/content';
import { doClaimRewardType } from 'redux/actions/rewards'; import { doClaimRewardType } from 'redux/actions/rewards';
import Promise from 'bluebird'; import Promise from 'bluebird';
import Lbryio from 'lbryio'; import Lbryio from 'lbryio';
@ -91,6 +91,8 @@ export const doFetchMySubscriptions = () => (dispatch: Dispatch, getState: () =>
type: ACTIONS.FETCH_SUBSCRIPTIONS_SUCCESS, type: ACTIONS.FETCH_SUBSCRIPTIONS_SUCCESS,
data: subscriptions, data: subscriptions,
}); });
subscriptions.forEach(({ uri }) => dispatch(doFetchClaimsByChannel(uri)));
}) })
.catch(() => { .catch(() => {
dispatch({ dispatch({

View file

@ -40,7 +40,7 @@ export function doInstallNew() {
const payload = { app_version: pjson.version }; const payload = { app_version: pjson.version };
Lbry.status().then(status => { Lbry.status().then(status => {
payload.app_id = status.installation_id; payload.app_id = status.installation_id;
payload.node_id = status.lbry_id; if (status.dht) payload.node_id = status.dht.node_id;
Lbry.version().then(version => { Lbry.version().then(version => {
payload.daemon_version = version.lbrynet_version; payload.daemon_version = version.lbrynet_version;
payload.operating_system = version.os_system; payload.operating_system = version.os_system;