Merge master into release #1920
16 changed files with 74 additions and 22 deletions
|
@ -17,7 +17,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
||||||
* 3D File viewer features and performance/memory usage improvements ([#1870](https://github.com/lbryio/lbry-desktop/pull/1870))
|
* 3D File viewer features and performance/memory usage 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))
|
* Desktop notification when publish is completed ([#1892](https://github.com/lbryio/lbry-desktop/pull/1892))
|
||||||
* FAQ to Publishing Area ([#1833](https://github.com/lbryio/lbry-desktop/pull/1833))
|
* FAQ to Publishing Area ([#1833](https://github.com/lbryio/lbry-desktop/pull/1833))
|
||||||
|
* FAQ to wallet security area ([#1917](https://github.com/lbryio/lbry-desktop/pull/1917))
|
||||||
### Changed
|
### Changed
|
||||||
* Upgraded LBRY Protocol to [version 0.21.2](https://github.com/lbryio/lbry/releases/tag/v0.21.2) fixing a download bug.
|
* Upgraded LBRY Protocol to [version 0.21.2](https://github.com/lbryio/lbry/releases/tag/v0.21.2) fixing a download bug.
|
||||||
* Searching now shows results by default, including direct lbry:// URL tile
|
* Searching now shows results by default, including direct lbry:// URL tile
|
||||||
|
|
|
@ -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#eae0d134d92d83f733b85a8ecebf529a6e9799cf",
|
"lbry-redux": "lbryio/lbry-redux#421321a78397251589e5a890f4caa95e79975e2b",
|
||||||
"localforage": "^1.7.1",
|
"localforage": "^1.7.1",
|
||||||
"mammoth": "^1.4.6",
|
"mammoth": "^1.4.6",
|
||||||
"mime": "^2.3.1",
|
"mime": "^2.3.1",
|
||||||
|
|
|
@ -44,7 +44,13 @@ const analytics: Analytics = {
|
||||||
}
|
}
|
||||||
analyticsEnabled = enabled;
|
analyticsEnabled = enabled;
|
||||||
},
|
},
|
||||||
apiLogView: (uri: string, outpoint: string, claimId: string, timeToStart?: number): void => {
|
apiLogView: (
|
||||||
|
uri: string,
|
||||||
|
outpoint: string,
|
||||||
|
claimId: string,
|
||||||
|
timeToStart?: number,
|
||||||
|
onSuccessCb: ?() => void
|
||||||
|
): void => {
|
||||||
if (analyticsEnabled) {
|
if (analyticsEnabled) {
|
||||||
const params = {
|
const params = {
|
||||||
uri,
|
uri,
|
||||||
|
@ -56,7 +62,13 @@ const analytics: Analytics = {
|
||||||
params.time_to_start = timeToStart;
|
params.time_to_start = timeToStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lbryio.call('file', 'view', params).catch(() => {});
|
Lbryio.call('file', 'view', params)
|
||||||
|
.then(() => {
|
||||||
|
if (onSuccessCb) {
|
||||||
|
onSuccessCb();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { doChangeVolume } from 'redux/actions/app';
|
||||||
import { selectVolume } from 'redux/selectors/app';
|
import { selectVolume } from 'redux/selectors/app';
|
||||||
import { doPlayUri, doSetPlayingUri } from 'redux/actions/content';
|
import { doPlayUri, doSetPlayingUri } from 'redux/actions/content';
|
||||||
import { doPlay, doPause, savePosition } from 'redux/actions/media';
|
import { doPlay, doPause, savePosition } from 'redux/actions/media';
|
||||||
|
import { doClaimEligiblePurchaseRewards } from 'redux/actions/rewards';
|
||||||
import {
|
import {
|
||||||
makeSelectMetadataForUri,
|
makeSelectMetadataForUri,
|
||||||
makeSelectContentTypeForUri,
|
makeSelectContentTypeForUri,
|
||||||
|
@ -35,7 +36,7 @@ const select = (state, props) => ({
|
||||||
mediaPosition: makeSelectMediaPositionForUri(props.uri)(state),
|
mediaPosition: makeSelectMediaPositionForUri(props.uri)(state),
|
||||||
autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state),
|
autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state),
|
||||||
searchBarFocused: selectSearchBarFocused(state),
|
searchBarFocused: selectSearchBarFocused(state),
|
||||||
fileInfoErrors: selectFileInfoErrors(state)
|
fileInfoErrors: selectFileInfoErrors(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
|
@ -45,6 +46,7 @@ const perform = dispatch => ({
|
||||||
doPlay: () => dispatch(doPlay()),
|
doPlay: () => dispatch(doPlay()),
|
||||||
doPause: () => dispatch(doPause()),
|
doPause: () => dispatch(doPause()),
|
||||||
savePosition: (claimId, position) => dispatch(savePosition(claimId, position)),
|
savePosition: (claimId, position) => dispatch(savePosition(claimId, position)),
|
||||||
|
claimRewards: () => dispatch(doClaimEligiblePurchaseRewards()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
|
|
@ -44,6 +44,7 @@ type Props = {
|
||||||
play: string => void,
|
play: string => void,
|
||||||
searchBarFocused: boolean,
|
searchBarFocused: boolean,
|
||||||
mediaType: string,
|
mediaType: string,
|
||||||
|
claimRewards: () => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileViewer extends React.PureComponent<Props> {
|
class FileViewer extends React.PureComponent<Props> {
|
||||||
|
@ -169,7 +170,8 @@ class FileViewer extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fireAnalyticsEvent = (claim, startTime, playTime) => {
|
fireAnalyticsEvent(claim, startTime, playTime) {
|
||||||
|
const { claimRewards } = this.props;
|
||||||
const { name, claim_id: claimId, txid, nout } = claim;
|
const { name, claim_id: claimId, txid, nout } = claim;
|
||||||
|
|
||||||
// ideally outpoint would exist inside of claim information
|
// ideally outpoint would exist inside of claim information
|
||||||
|
@ -181,8 +183,8 @@ class FileViewer extends React.PureComponent<Props> {
|
||||||
timeToStart = playTime - startTime;
|
timeToStart = playTime - startTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
analytics.apiLogView(`${name}#${claimId}`, outpoint, claimId, timeToStart);
|
analytics.apiLogView(`${name}#${claimId}`, outpoint, claimId, timeToStart, claimRewards);
|
||||||
};
|
}
|
||||||
|
|
||||||
startedPlayingCb: ?() => void;
|
startedPlayingCb: ?() => void;
|
||||||
startTime: ?number;
|
startTime: ?number;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import FileTile from 'component/fileTile';
|
import FileTile from 'component/fileTile';
|
||||||
import type { Claim } from 'types/claim';
|
import type { Claim } from 'types/claim';
|
||||||
|
import Spinner from 'component/spinner';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
|
@ -65,6 +66,7 @@ export default class RecommendedContent extends React.PureComponent<Props> {
|
||||||
{recommendedContent &&
|
{recommendedContent &&
|
||||||
!recommendedContent.length &&
|
!recommendedContent.length &&
|
||||||
!isSearching && <div className="card__subtitle">No related content found</div>}
|
!isSearching && <div className="card__subtitle">No related content found</div>}
|
||||||
|
{isSearching && <Spinner type="small" />}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectUnclaimedRewardValue, selectFetchingRewards } from 'redux/selectors/rewards';
|
import { selectUnclaimedRewardValue, selectFetchingRewards } from 'redux/selectors/rewards';
|
||||||
import { doRewardList } from 'redux/actions/rewards';
|
import { doRewardList } from 'redux/actions/rewards';
|
||||||
|
import { doFetchRewardedContent } from 'redux/actions/content';
|
||||||
import RewardSummary from './view';
|
import RewardSummary from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
@ -10,6 +11,7 @@ const select = state => ({
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
fetchRewards: () => dispatch(doRewardList()),
|
fetchRewards: () => dispatch(doRewardList()),
|
||||||
|
fetchRewardedContent: () => dispatch(doFetchRewardedContent()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
|
|
@ -8,11 +8,13 @@ type Props = {
|
||||||
unclaimedRewardAmount: number,
|
unclaimedRewardAmount: number,
|
||||||
fetching: boolean,
|
fetching: boolean,
|
||||||
fetchRewards: () => void,
|
fetchRewards: () => void,
|
||||||
|
fetchRewardedContent: () => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
class RewardSummary extends React.Component<Props> {
|
class RewardSummary extends React.Component<Props> {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.fetchRewards();
|
this.props.fetchRewards();
|
||||||
|
this.props.fetchRewardedContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -19,6 +19,7 @@ const Spinner = (props: Props) => {
|
||||||
'spinner--dark': !light && (dark || theme === LIGHT_THEME),
|
'spinner--dark': !light && (dark || theme === LIGHT_THEME),
|
||||||
'spinner--light': !dark && (light || theme === DARK_THEME),
|
'spinner--light': !dark && (light || theme === DARK_THEME),
|
||||||
'spinner--splash': type === 'splash',
|
'spinner--splash': type === 'splash',
|
||||||
|
'spinner--small': type === 'small',
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div className="rect rect1" />
|
<div className="rect rect1" />
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doFetchFeaturedUris } from 'redux/actions/content';
|
import { doFetchFeaturedUris, doFetchRewardedContent } from 'redux/actions/content';
|
||||||
import { selectFeaturedUris, selectFetchingFeaturedUris } from 'redux/selectors/content';
|
import { selectFeaturedUris, selectFetchingFeaturedUris } from 'redux/selectors/content';
|
||||||
import DiscoverPage from './view';
|
import DiscoverPage from './view';
|
||||||
|
|
||||||
|
@ -11,6 +10,10 @@ const select = state => ({
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
fetchFeaturedUris: () => dispatch(doFetchFeaturedUris()),
|
fetchFeaturedUris: () => dispatch(doFetchFeaturedUris()),
|
||||||
|
fetchRewardedContent: () => dispatch(doFetchRewardedContent()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(DiscoverPage);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(DiscoverPage);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import CategoryList from 'component/categoryList';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
fetchFeaturedUris: () => void,
|
fetchFeaturedUris: () => void,
|
||||||
|
fetchRewardedContent: () => void,
|
||||||
fetchingFeaturedUris: boolean,
|
fetchingFeaturedUris: boolean,
|
||||||
featuredUris: {},
|
featuredUris: {},
|
||||||
};
|
};
|
||||||
|
@ -16,9 +17,14 @@ class DiscoverPage extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
const { fetchFeaturedUris } = this.props;
|
const { fetchFeaturedUris, fetchRewardedContent } = this.props;
|
||||||
fetchFeaturedUris();
|
fetchFeaturedUris();
|
||||||
this.continousFetch = setInterval(fetchFeaturedUris, 1000 * 60 * 60);
|
fetchRewardedContent();
|
||||||
|
|
||||||
|
this.continousFetch = setInterval(() => {
|
||||||
|
fetchFeaturedUris();
|
||||||
|
fetchRewardedContent();
|
||||||
|
}, 1000 * 60 * 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
|
|
@ -349,9 +349,18 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||||
onChange={e => this.onChangeEncryptWallet(e)}
|
onChange={e => this.onChangeEncryptWallet(e)}
|
||||||
checked={walletEncrypted}
|
checked={walletEncrypted}
|
||||||
postfix={__('Encrypt my wallet with a custom password.')}
|
postfix={__('Encrypt my wallet with a custom password.')}
|
||||||
helper={__(
|
helper={
|
||||||
|
<React.Fragment>
|
||||||
|
{__(
|
||||||
'Secure your local wallet data with a custom password. Lost passwords cannot be recovered.'
|
'Secure your local wallet data with a custom password. Lost passwords cannot be recovered.'
|
||||||
)}
|
)}{' '}
|
||||||
|
<Button
|
||||||
|
button="link"
|
||||||
|
label={__('Learn more')}
|
||||||
|
href="https://lbry.io/faq/wallet-encryption"
|
||||||
|
/>.
|
||||||
|
</React.Fragment>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
<section className="card card--section">
|
<section className="card card--section">
|
||||||
|
|
|
@ -2,7 +2,6 @@ import * as NOTIFICATION_TYPES from 'constants/notification_types';
|
||||||
import { ipcRenderer } from 'electron';
|
import { ipcRenderer } from 'electron';
|
||||||
import Lbryio from 'lbryio';
|
import Lbryio from 'lbryio';
|
||||||
import { doAlertError } from 'redux/actions/app';
|
import { doAlertError } from 'redux/actions/app';
|
||||||
import { doClaimEligiblePurchaseRewards } from 'redux/actions/rewards';
|
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import {
|
import {
|
||||||
setSubscriptionLatest,
|
setSubscriptionLatest,
|
||||||
|
@ -230,7 +229,6 @@ export function doStartDownload(uri, outpoint) {
|
||||||
export function doDownloadFile(uri, streamInfo) {
|
export function doDownloadFile(uri, streamInfo) {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
dispatch(doStartDownload(uri, streamInfo.outpoint));
|
dispatch(doStartDownload(uri, streamInfo.outpoint));
|
||||||
dispatch(doClaimEligiblePurchaseRewards());
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,8 +249,7 @@ export const doChannelSubscribe = (subscription: Subscription) => (
|
||||||
dispatch(doClaimRewardType(rewards.SUBSCRIPTION, { failSilently: true }));
|
dispatch(doClaimRewardType(rewards.SUBSCRIPTION, { failSilently: true }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// should be subUri
|
dispatch(doCheckSubscription(subscription.uri, true));
|
||||||
dispatch(doCheckSubscription(subscription, true));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doChannelUnsubscribe = (subscription: Subscription) => (
|
export const doChannelUnsubscribe = (subscription: Subscription) => (
|
||||||
|
|
|
@ -50,6 +50,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.spinner--small {
|
||||||
|
margin: $spacing-vertical * 1/3 0;
|
||||||
|
width: 40px;
|
||||||
|
height: 32px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 10px;
|
||||||
|
|
||||||
|
.rect {
|
||||||
|
height: 100%;
|
||||||
|
width: 3px;
|
||||||
|
margin: 0 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes sk-stretchdelay {
|
@keyframes sk-stretchdelay {
|
||||||
0%,
|
0%,
|
||||||
40%,
|
40%,
|
||||||
|
|
|
@ -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#ccda4117ee503e30abae355c77d3783a141e9492:
|
lbry-redux@lbryio/lbry-redux#eae0d134d92d83f733b85a8ecebf529a6e9799cf:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/ccda4117ee503e30abae355c77d3783a141e9492"
|
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/eae0d134d92d83f733b85a8ecebf529a6e9799cf"
|
||||||
dependencies:
|
dependencies:
|
||||||
proxy-polyfill "0.1.6"
|
proxy-polyfill "0.1.6"
|
||||||
reselect "^3.0.0"
|
reselect "^3.0.0"
|
||||||
|
|
Loading…
Reference in a new issue