mirror of
https://github.com/LBRYFoundation/lbry-desktop.git
synced 2025-08-31 09:21:27 +00:00
commit
aee048e726
50 changed files with 319 additions and 347 deletions
36
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
36
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
## PR Checklist
|
||||||
|
Please check all that apply to this PR using "x":
|
||||||
|
|
||||||
|
- [ ] I have checked that this PR is not a duplicate of an existing PR (open, closed or merged)
|
||||||
|
- [ ] I have checked that this PR does not introduce a breaking change
|
||||||
|
- [ ] This PR introduces breaking changes and I have provided a detailed explanation below
|
||||||
|
|
||||||
|
|
||||||
|
## PR Type
|
||||||
|
What kind of change does this PR introduce?
|
||||||
|
|
||||||
|
<!-- Please check all that apply to this PR using "x". -->
|
||||||
|
|
||||||
|
- [ ] Bugfix
|
||||||
|
- [ ] Feature
|
||||||
|
- [ ] Breaking changes (bugfix or feature that introduces breaking changes)
|
||||||
|
- [ ] Code style update (formatting)
|
||||||
|
- [ ] Refactoring (no functional changes)
|
||||||
|
- [ ] Documentation changes
|
||||||
|
- [ ] Other - Please describe:
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
Issue Number: N/A
|
||||||
|
|
||||||
|
|
||||||
|
## What is the current behavior?
|
||||||
|
|
||||||
|
|
||||||
|
## What is the new behavior?
|
||||||
|
|
||||||
|
|
||||||
|
## Other information
|
||||||
|
|
||||||
|
|
||||||
|
<!-- If this PR contains a breaking change, please describe the impact and solution strategy for existing applications below. -->
|
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
* Adds Persistence to File List Filter Selections ([#2050](https://github.com/lbryio/lbry-desktop/pull/2050))
|
* Adds Persistence to File List Filter Selections ([#2050](https://github.com/lbryio/lbry-desktop/pull/2050))
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
* Upgraded to lbrynet v0.30.0 ([#1998](https://github.com/lbryio/lbry-desktop/pull/1998))
|
||||||
* Make tooltip smarter ([#1979](https://github.com/lbryio/lbry-desktop/pull/1979))
|
* Make tooltip smarter ([#1979](https://github.com/lbryio/lbry-desktop/pull/1979))
|
||||||
* Change channel pages to have 48 items instead of 10 ([#2002](https://github.com/lbryio/lbry-desktop/pull/2002))
|
* Change channel pages to have 48 items instead of 10 ([#2002](https://github.com/lbryio/lbry-desktop/pull/2002))
|
||||||
* Update to https ([#2016](https://github.com/lbryio/lbry-desktop/pull/2016))
|
* Update to https ([#2016](https://github.com/lbryio/lbry-desktop/pull/2016))
|
||||||
|
@ -96,6 +97,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
* Fix middle click link error ([#1843](https://github.com/lbryio/lbry-desktop/issues/1843)}
|
* Fix middle click link error ([#1843](https://github.com/lbryio/lbry-desktop/issues/1843)}
|
||||||
* Problem with search auto-complete menu when scrolling over file viewer ([#1847](https://github.com/lbryio/lbry-desktop/issues/1847))
|
* Problem with search auto-complete menu when scrolling over file viewer ([#1847](https://github.com/lbryio/lbry-desktop/issues/1847))
|
||||||
* Show label when publish button is disabled while uploading thumbnail to spee.ch ([#1867](https://github.com/lbryio/lbry-desktop/pull/1867))
|
* Show label when publish button is disabled while uploading thumbnail to spee.ch ([#1867](https://github.com/lbryio/lbry-desktop/pull/1867))
|
||||||
|
* Edit option missing from certain published claims ([#1756](https://github.com/lbryio/lbry-desktop/issues/1756))
|
||||||
|
* Navigation issue with channels that have more than one page ([#1797](https://github.com/lbryio/lbry-desktop/pull/1797))
|
||||||
|
* Navigation issue with channels that have more than one page ([#1797](https://github.com/lbryio/lbry-desktop/pull/1797))
|
||||||
|
* Upgrade modals would stack on-top of each other if the app was kept open for a long time ([#1857](https://github.com/lbryio/lbry-desktop/pull/1857))
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
* 3D file viewer for OBJ & STL file types ([#1558](https://github.com/lbryio/lbry-desktop/pull/1558))
|
* 3D file viewer for OBJ & STL file types ([#1558](https://github.com/lbryio/lbry-desktop/pull/1558))
|
||||||
|
@ -114,14 +119,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
* More descriptive error message when Shapeshift is unavailable ([#1771](https://github.com/lbryio/lbry-desktop/pull/1771))
|
* More descriptive error message when Shapeshift is unavailable ([#1771](https://github.com/lbryio/lbry-desktop/pull/1771))
|
||||||
* Rename the Github repo to lbry-desktop ([#1765](https://github.com/lbryio/lbry-desktop/pull/1765))
|
* Rename the Github repo to lbry-desktop ([#1765](https://github.com/lbryio/lbry-desktop/pull/1765))
|
||||||
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Edit option missing from certain published claims ([#1756](https://github.com/lbryio/lbry-desktop/issues/1756))
|
|
||||||
* Navigation issue with channels that have more than one page ([#1797](https://github.com/lbryio/lbry-desktop/pull/1797))
|
|
||||||
* Navigation issue with channels that have more than one page ([#1797](https://github.com/lbryio/lbry-desktop/pull/1797))
|
|
||||||
* Upgrade modals would stack on-top of each other if the app was kept open for a long time ([#1857](https://github.com/lbryio/lbry-desktop/pull/1857))
|
|
||||||
|
|
||||||
|
|
||||||
## [0.22.2] - 2018-07-09
|
## [0.22.2] - 2018-07-09
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# LBRY App
|
# LBRY App
|
||||||
|
|
||||||
|
[](https://github.com/lbryio/lbry-desktop/blob/master/LICENSE)
|
||||||
[](https://travis-ci.org/lbryio/lbry-desktop)
|
[](https://travis-ci.org/lbryio/lbry-desktop)
|
||||||
[](https://david-dm.org/lbryio/lbry-desktop)
|
[](https://david-dm.org/lbryio/lbry-desktop)
|
||||||
[](https://www.codacy.com/app/LBRY/lbry-desktop?utm_source=github.com&utm_medium=referral&utm_content=lbryio/lbry-desktop&utm_campaign=Badge_Grade)
|
[](https://www.codacy.com/app/LBRY/lbry-desktop?utm_source=github.com&utm_medium=referral&utm_content=lbryio/lbry-desktop&utm_campaign=Badge_Grade)
|
||||||
|
|
|
@ -17,7 +17,7 @@ const downloadDaemon = targetPlatform =>
|
||||||
let currentPlatform = os.platform();
|
let currentPlatform = os.platform();
|
||||||
|
|
||||||
var daemonPlatform = process.env.TARGET || targetPlatform || currentPlatform;
|
var daemonPlatform = process.env.TARGET || targetPlatform || currentPlatform;
|
||||||
if (daemonPlatform === 'mac' || daemonPlatform === 'darwin') daemonPlatform = 'macos';
|
if (daemonPlatform === 'mac' || daemonPlatform === 'darwin') daemonPlatform = 'mac';
|
||||||
if (daemonPlatform === 'win32' || daemonPlatform === 'windows') {
|
if (daemonPlatform === 'win32' || daemonPlatform === 'windows') {
|
||||||
daemonPlatform = 'windows';
|
daemonPlatform = 'windows';
|
||||||
daemonFileName = daemonFileName + '.exe';
|
daemonFileName = daemonFileName + '.exe';
|
||||||
|
|
10
package.json
10
package.json
|
@ -49,8 +49,8 @@
|
||||||
"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#03aea43da5f12bc01546a92bdf460ebd08681013",
|
"lbry-redux": "lbryio/lbry-redux#f193d38c61ea061679ebc7b4ca139a0e9c95ef8a",
|
||||||
"lbryinc": "lbryio/lbryinc#3f34af546ee73ff2ee7d8ad05e540b3b0aa658fb",
|
"lbryinc": "lbryio/lbryinc#7a458ea13ceceffa0191e73139f94e5c953f22b1",
|
||||||
"localforage": "^1.7.1",
|
"localforage": "^1.7.1",
|
||||||
"mammoth": "^1.4.6",
|
"mammoth": "^1.4.6",
|
||||||
"mime": "^2.3.1",
|
"mime": "^2.3.1",
|
||||||
|
@ -134,9 +134,9 @@
|
||||||
"yarn": "^1.3"
|
"yarn": "^1.3"
|
||||||
},
|
},
|
||||||
"lbrySettings": {
|
"lbrySettings": {
|
||||||
"lbrynetDaemonVersion": "0.21.2",
|
"lbrynetDaemonVersion": "0.30.0",
|
||||||
"lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-daemon-vDAEMONVER-OSNAME.zip",
|
"lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-OSNAME.zip",
|
||||||
"lbrynetDaemonDir": "static/daemon",
|
"lbrynetDaemonDir": "static/daemon",
|
||||||
"lbrynetDaemonFileName": "lbrynet-daemon"
|
"lbrynetDaemonFileName": "lbrynet"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import path from 'path';
|
||||||
import { spawn, execSync } from 'child_process';
|
import { spawn, execSync } from 'child_process';
|
||||||
|
|
||||||
export default class Daemon {
|
export default class Daemon {
|
||||||
static path = process.env.LBRY_DAEMON || path.join(__static, 'daemon/lbrynet-daemon');
|
static path = process.env.LBRY_DAEMON || path.join(__static, 'daemon/lbrynet');
|
||||||
subprocess;
|
subprocess;
|
||||||
handlers;
|
handlers;
|
||||||
|
|
||||||
|
@ -12,13 +12,12 @@ export default class Daemon {
|
||||||
}
|
}
|
||||||
|
|
||||||
launch() {
|
launch() {
|
||||||
console.log('Launching daemon:', Daemon.path);
|
this.subprocess = spawn(Daemon.path, ['start']);
|
||||||
this.subprocess = spawn(Daemon.path);
|
|
||||||
|
|
||||||
this.subprocess.stdout.on('data', data => console.log(`Daemon: ${data}`));
|
this.subprocess.stdout.on('data', data => console.log(`Daemon: ${data}`));
|
||||||
this.subprocess.stderr.on('data', data => console.error(`Daemon: ${data}`));
|
this.subprocess.stderr.on('data', data => console.error(`Daemon: ${data}`));
|
||||||
this.subprocess.on('exit', () => this.fire('exit'));
|
this.subprocess.on('exit', () => this.fire('exit'));
|
||||||
this.subprocess.on('error', error => console.error(`Daemon: ${error}`));
|
this.subprocess.on('error', error => console.error(`Daemon error: ${error}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
quit() {
|
quit() {
|
||||||
|
|
|
@ -64,8 +64,9 @@ if (isDev) {
|
||||||
}
|
}
|
||||||
|
|
||||||
app.on('ready', async () => {
|
app.on('ready', async () => {
|
||||||
const processList = await findProcess('name', 'lbrynet-daemon');
|
const processList = await findProcess('name', 'lbrynet');
|
||||||
const isDaemonRunning = processList.length > 0;
|
const isDaemonRunning = processList.length > 0;
|
||||||
|
|
||||||
if (!isDaemonRunning) {
|
if (!isDaemonRunning) {
|
||||||
daemon = new Daemon();
|
daemon = new Daemon();
|
||||||
daemon.on('exit', () => {
|
daemon.on('exit', () => {
|
||||||
|
@ -95,11 +96,16 @@ app.on('ready', async () => {
|
||||||
// HACK: patch webrequest to fix devtools incompatibility with electron 2.x.
|
// HACK: patch webrequest to fix devtools incompatibility with electron 2.x.
|
||||||
// See https://github.com/electron/electron/issues/13008#issuecomment-400261941
|
// See https://github.com/electron/electron/issues/13008#issuecomment-400261941
|
||||||
session.defaultSession.webRequest.onBeforeRequest({}, (details, callback) => {
|
session.defaultSession.webRequest.onBeforeRequest({}, (details, callback) => {
|
||||||
if (details.url.indexOf('7accc8730b0f99b5e7c0702ea89d1fa7c17bfe33') !== -1) {
|
if (details.url.indexOf('7accc8730b0f99b5e7c0702ea89d1fa7c17bfe33') !== -1) {
|
||||||
callback({redirectURL: details.url.replace('7accc8730b0f99b5e7c0702ea89d1fa7c17bfe33', '57c9d07b416b5a2ea23d28247300e4af36329bdc')});
|
callback({
|
||||||
} else {
|
redirectURL: details.url.replace(
|
||||||
callback({cancel: false});
|
'7accc8730b0f99b5e7c0702ea89d1fa7c17bfe33',
|
||||||
}
|
'57c9d07b416b5a2ea23d28247300e4af36329bdc'
|
||||||
|
),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback({ cancel: false });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doNotify } from 'lbry-redux';
|
import { doNotify } from 'lbry-redux';
|
||||||
import Address from './view';
|
import Address from './view';
|
||||||
|
|
||||||
export default connect(null, {
|
export default connect(
|
||||||
doNotify,
|
null,
|
||||||
})(Address);
|
{
|
||||||
|
doNotify,
|
||||||
|
}
|
||||||
|
)(Address);
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import CardMedia from './view';
|
import CardMedia from './view';
|
||||||
|
|
||||||
const select = state => ({});
|
export default CardMedia;
|
||||||
const perform = dispatch => ({});
|
|
||||||
|
|
||||||
export default connect(select, perform)(CardMedia);
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
makeSelectFileInfoForUri,
|
makeSelectFileInfoForUri,
|
||||||
makeSelectIsUriResolving,
|
makeSelectIsUriResolving,
|
||||||
makeSelectClaimIsMine,
|
makeSelectClaimIsMine,
|
||||||
|
makeSelectClaimIsPending,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import {
|
import {
|
||||||
|
@ -13,34 +14,22 @@ import {
|
||||||
makeSelectContentPositionForUri,
|
makeSelectContentPositionForUri,
|
||||||
} from 'redux/selectors/content';
|
} from 'redux/selectors/content';
|
||||||
import { selectShowNsfw } from 'redux/selectors/settings';
|
import { selectShowNsfw } from 'redux/selectors/settings';
|
||||||
import { selectPendingPublish } from 'redux/selectors/publish';
|
|
||||||
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
|
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
|
||||||
import { doClearContentHistoryUri } from 'redux/actions/content';
|
import { doClearContentHistoryUri } from 'redux/actions/content';
|
||||||
import FileCard from './view';
|
import FileCard from './view';
|
||||||
|
|
||||||
const select = (state, props) => {
|
const select = (state, props) => ({
|
||||||
let pendingPublish;
|
pending: makeSelectClaimIsPending(props.uri)(state),
|
||||||
if (props.checkPending) {
|
claim: makeSelectClaimForUri(props.uri)(state),
|
||||||
pendingPublish = selectPendingPublish(props.uri)(state);
|
obscureNsfw: !selectShowNsfw(state),
|
||||||
}
|
claimIsMine: makeSelectClaimIsMine(props.uri)(state),
|
||||||
|
rewardedContentClaimIds: selectRewardContentClaimIds(state, props),
|
||||||
const fileCardInfo = pendingPublish || {
|
fileInfo: makeSelectFileInfoForUri(props.uri)(state),
|
||||||
claim: makeSelectClaimForUri(props.uri)(state),
|
metadata: makeSelectMetadataForUri(props.uri)(state),
|
||||||
fileInfo: makeSelectFileInfoForUri(props.uri)(state),
|
isResolvingUri: makeSelectIsUriResolving(props.uri)(state),
|
||||||
metadata: makeSelectMetadataForUri(props.uri)(state),
|
position: makeSelectContentPositionForUri(props.uri)(state),
|
||||||
isResolvingUri: makeSelectIsUriResolving(props.uri)(state),
|
isSubscribed: makeSelectIsSubscribed(props.uri)(state),
|
||||||
};
|
});
|
||||||
|
|
||||||
return {
|
|
||||||
obscureNsfw: !selectShowNsfw(state),
|
|
||||||
claimIsMine: makeSelectClaimIsMine(props.uri)(state),
|
|
||||||
rewardedContentClaimIds: selectRewardContentClaimIds(state, props),
|
|
||||||
...fileCardInfo,
|
|
||||||
pending: !!pendingPublish,
|
|
||||||
position: makeSelectContentPositionForUri(props.uri)(state),
|
|
||||||
isSubscribed: makeSelectIsSubscribed(props.uri)(state),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
navigate: (path, params) => dispatch(doNavigate(path, params)),
|
navigate: (path, params) => dispatch(doNavigate(path, params)),
|
||||||
|
|
|
@ -10,15 +10,15 @@ type Props = {
|
||||||
sortByHeight?: boolean,
|
sortByHeight?: boolean,
|
||||||
claimsById: Array<{}>,
|
claimsById: Array<{}>,
|
||||||
fileInfos: Array<FileInfo>,
|
fileInfos: Array<FileInfo>,
|
||||||
checkPending?: boolean,
|
|
||||||
sortBy: string,
|
sortBy: string,
|
||||||
page: string,
|
page?: string,
|
||||||
setFileListSort: (string, string) => void,
|
setFileListSort: (?string, string) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileList extends React.PureComponent<Props> {
|
class FileList extends React.PureComponent<Props> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
hideFilter: false,
|
hideFilter: false,
|
||||||
|
sortBy: SORT_OPTIONS.DATE_NEW,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
|
@ -29,9 +29,12 @@ class FileList extends React.PureComponent<Props> {
|
||||||
[SORT_OPTIONS.DATE_NEW]: fileInfos =>
|
[SORT_OPTIONS.DATE_NEW]: fileInfos =>
|
||||||
this.props.sortByHeight
|
this.props.sortByHeight
|
||||||
? fileInfos.sort((fileInfo1, fileInfo2) => {
|
? fileInfos.sort((fileInfo1, fileInfo2) => {
|
||||||
if (fileInfo1.pending) {
|
if (fileInfo1.confirmations < 1) {
|
||||||
return -1;
|
return -1;
|
||||||
|
} else if (fileInfo2.confirmations < 1) {
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const height1 = this.props.claimsById[fileInfo1.claim_id]
|
const height1 = this.props.claimsById[fileInfo1.claim_id]
|
||||||
? this.props.claimsById[fileInfo1.claim_id].height
|
? this.props.claimsById[fileInfo1.claim_id].height
|
||||||
: 0;
|
: 0;
|
||||||
|
@ -124,7 +127,8 @@ class FileList extends React.PureComponent<Props> {
|
||||||
sortFunctions: {};
|
sortFunctions: {};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { fileInfos, hideFilter, checkPending, sortBy } = this.props;
|
const { fileInfos, hideFilter, sortBy } = this.props;
|
||||||
|
|
||||||
const content = [];
|
const content = [];
|
||||||
if (!fileInfos) {
|
if (!fileInfos) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -150,7 +154,7 @@ class FileList extends React.PureComponent<Props> {
|
||||||
const outpoint = `${txid}:${nout}`;
|
const outpoint = `${txid}:${nout}`;
|
||||||
|
|
||||||
// See https://github.com/lbryio/lbry-desktop/issues/1327 for discussion around using outpoint as the key
|
// See https://github.com/lbryio/lbry-desktop/issues/1327 for discussion around using outpoint as the key
|
||||||
content.push(<FileCard key={outpoint} uri={uri} checkPending={checkPending} isNew={isNew} />);
|
content.push(<FileCard key={outpoint} uri={uri} isNew={isNew} />);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -8,9 +8,4 @@ const select = (state, props) => ({
|
||||||
isSearching: selectIsSearching(state),
|
isSearching: selectIsSearching(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = () => ({});
|
export default connect(select)(FileListSearch);
|
||||||
|
|
||||||
export default connect(
|
|
||||||
select,
|
|
||||||
perform
|
|
||||||
)(FileListSearch);
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import FormFieldPrice from './view';
|
import FormFieldPrice from './view';
|
||||||
|
|
||||||
export default connect(null, null)(FormFieldPrice);
|
export default FormFieldPrice;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { selectBalance } from 'lbry-redux';
|
|
||||||
import PublishForm from './view';
|
import PublishForm from './view';
|
||||||
|
|
||||||
export default connect(null, null)(PublishForm);
|
export default PublishForm;
|
||||||
|
|
|
@ -123,7 +123,7 @@ class PublishForm extends React.PureComponent<Props> {
|
||||||
const { channel, updatePublishForm } = this.props;
|
const { channel, updatePublishForm } = this.props;
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
updatePublishForm({ nameError: undefined });
|
updatePublishForm({ name: '', nameError: __('A name is required.') });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,6 @@ class ChannelSection extends React.PureComponent<Props, State> {
|
||||||
<FormField
|
<FormField
|
||||||
key="channel"
|
key="channel"
|
||||||
type="select"
|
type="select"
|
||||||
tabIndex="1"
|
|
||||||
onChange={this.handleChannelChange}
|
onChange={this.handleChannelChange}
|
||||||
value={channel}
|
value={channel}
|
||||||
>
|
>
|
||||||
|
|
|
@ -5,18 +5,20 @@ import { FormRow } from 'component/common/form';
|
||||||
import * as statuses from 'constants/shape_shift';
|
import * as statuses from 'constants/shape_shift';
|
||||||
import Address from 'component/address';
|
import Address from 'component/address';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import type { Dispatch } from 'redux/actions/shape_shift';
|
import type { Dispatch, ThunkAction } from 'types/redux';
|
||||||
|
import type { Action } from 'redux/actions/shape_shift';
|
||||||
|
|
||||||
import ShiftMarketInfo from './market_info';
|
import ShiftMarketInfo from './market_info';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
shiftState: ?string,
|
shiftState: ?string,
|
||||||
shiftCoinType: ?string,
|
shiftCoinType: ?string,
|
||||||
shiftDepositAddress: ?string,
|
shiftDepositAddress: string,
|
||||||
shiftReturnAddress: ?string,
|
shiftReturnAddress: ?string,
|
||||||
shiftOrderId: ?string,
|
shiftOrderId: ?string,
|
||||||
originCoinDepositMax: ?number,
|
originCoinDepositMax: ?number,
|
||||||
clearShapeShift: Dispatch,
|
clearShapeShift: () => (Dispatch<Action>) => ThunkAction<Action>,
|
||||||
getActiveShift: Dispatch,
|
getActiveShift: string => (Dispatch<Action>) => ThunkAction<Action>,
|
||||||
shapeShiftRate: ?number,
|
shapeShiftRate: ?number,
|
||||||
originCoinDepositMax: ?number,
|
originCoinDepositMax: ?number,
|
||||||
originCoinDepositFee: ?number,
|
originCoinDepositFee: ?number,
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { getExampleAddress } from 'util/shape_shift';
|
import { getExampleAddress } from 'util/shape_shift';
|
||||||
import { FormField, FormRow, Submit } from 'component/common/form';
|
import { FormField, FormRow, Submit } from 'component/common/form';
|
||||||
import type { ShapeShiftFormValues, Dispatch } from 'redux/actions/shape_shift';
|
import type { ShapeShiftFormValues, Action } from 'redux/actions/shape_shift';
|
||||||
|
import type { Dispatch, ThunkAction } from 'types/redux';
|
||||||
import ShiftMarketInfo from './market_info';
|
import ShiftMarketInfo from './market_info';
|
||||||
|
|
||||||
type ShapeShiftFormErrors = {
|
type ShapeShiftFormErrors = {
|
||||||
|
@ -19,7 +20,7 @@ type Props = {
|
||||||
isSubmitting: boolean,
|
isSubmitting: boolean,
|
||||||
shiftSupportedCoins: Array<string>,
|
shiftSupportedCoins: Array<string>,
|
||||||
originCoin: string,
|
originCoin: string,
|
||||||
getCoinStats: Dispatch,
|
getCoinStats: string => (Dispatch<Action>) => ThunkAction<Action>,
|
||||||
originCoinDepositFee: number,
|
originCoinDepositFee: number,
|
||||||
originCoinDepositMin: string,
|
originCoinDepositMin: string,
|
||||||
originCoinDepositMax: number,
|
originCoinDepositMax: number,
|
||||||
|
|
|
@ -4,17 +4,23 @@ import { Formik } from 'formik';
|
||||||
import { validateShapeShiftForm } from 'util/shape_shift';
|
import { validateShapeShiftForm } from 'util/shape_shift';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import type { ShapeShiftState } from 'redux/reducers/shape_shift';
|
import type { ShapeShiftState } from 'redux/reducers/shape_shift';
|
||||||
import type { Dispatch, ShapeShiftFormValues } from 'redux/actions/shape_shift';
|
import type { ShapeShiftFormValues, Action } from 'redux/actions/shape_shift';
|
||||||
|
import type { Dispatch, ThunkAction } from 'types/redux';
|
||||||
|
import type { FormikActions } from 'types/common';
|
||||||
|
|
||||||
import ShapeShiftForm from './internal/form';
|
import ShapeShiftForm from './internal/form';
|
||||||
import ActiveShapeShift from './internal/active-shift';
|
import ActiveShapeShift from './internal/active-shift';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
shapeShift: ShapeShiftState,
|
shapeShift: ShapeShiftState,
|
||||||
getCoinStats: Dispatch,
|
getCoinStats: string => (Dispatch<Action>) => ThunkAction<Action>,
|
||||||
createShapeShift: Dispatch,
|
createShapeShift: (
|
||||||
clearShapeShift: Dispatch,
|
ShapeShiftFormValues,
|
||||||
getActiveShift: Dispatch,
|
FormikActions
|
||||||
shapeShiftInit: Dispatch,
|
) => (Dispatch<Action>) => ThunkAction<Action>,
|
||||||
|
clearShapeShift: () => (Dispatch<Action>) => ThunkAction<Action>,
|
||||||
|
getActiveShift: string => (Dispatch<Action>) => ThunkAction<Action>,
|
||||||
|
shapeShiftInit: () => (Dispatch<Action>) => ThunkAction<Action>,
|
||||||
receiveAddress: string,
|
receiveAddress: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,7 +48,6 @@ class ShapeShift extends React.PureComponent<Props> {
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
loading,
|
|
||||||
updating,
|
updating,
|
||||||
error,
|
error,
|
||||||
shiftSupportedCoins,
|
shiftSupportedCoins,
|
||||||
|
@ -104,7 +109,7 @@ class ShapeShift extends React.PureComponent<Props> {
|
||||||
getActiveShift={getActiveShift}
|
getActiveShift={getActiveShift}
|
||||||
shiftCoinType={shiftCoinType}
|
shiftCoinType={shiftCoinType}
|
||||||
shiftReturnAddress={shiftReturnAddress}
|
shiftReturnAddress={shiftReturnAddress}
|
||||||
shiftDepositAddress={shiftDepositAddress}
|
shiftDepositAddress={shiftDepositAddress || ''}
|
||||||
shiftOrderId={shiftOrderId}
|
shiftOrderId={shiftOrderId}
|
||||||
shiftState={shiftState}
|
shiftState={shiftState}
|
||||||
clearShapeShift={clearShapeShift}
|
clearShapeShift={clearShapeShift}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectThemePath } from 'redux/selectors/settings.js';
|
import { selectThemePath } from 'redux/selectors/settings';
|
||||||
import Theme from './view';
|
import Theme from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
themePath: selectThemePath(state),
|
themePath: selectThemePath(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, null)(Theme);
|
export default connect(select)(Theme);
|
||||||
|
|
|
@ -38,18 +38,12 @@ class UriIndicator extends React.PureComponent<Props> {
|
||||||
if (!claim) {
|
if (!claim) {
|
||||||
return <span className="empty">{isResolvingUri ? 'Validating...' : 'Unused'}</span>;
|
return <span className="empty">{isResolvingUri ? 'Validating...' : 'Unused'}</span>;
|
||||||
}
|
}
|
||||||
|
const { channel_name: channelName, signature_is_valid: signatureIsValid, value } = claim;
|
||||||
const {
|
|
||||||
channel_name: channelName,
|
|
||||||
has_signature: hasSignature,
|
|
||||||
signature_is_valid: signatureIsValid,
|
|
||||||
value,
|
|
||||||
} = claim;
|
|
||||||
|
|
||||||
const channelClaimId =
|
const channelClaimId =
|
||||||
value && value.publisherSignature && value.publisherSignature.certificateId;
|
value && value.publisherSignature && value.publisherSignature.certificateId;
|
||||||
|
|
||||||
if (!hasSignature || !channelName) {
|
if (!channelName) {
|
||||||
return <span className="channel-name">Anonymous</span>;
|
return <span className="channel-name">Anonymous</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,19 +12,19 @@ type Props = {
|
||||||
gettingNewAddress: boolean,
|
gettingNewAddress: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
class WalletAddress extends React.PureComponent<Props> {
|
type State = {
|
||||||
|
showQR: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
|
class WalletAddress extends React.PureComponent<Props, State> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
showQR: false,
|
showQR: false,
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
toggleQR() {
|
this.toggleQR = this.toggleQR.bind(this);
|
||||||
this.setState({
|
|
||||||
showQR: !this.state.showQR,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
|
@ -36,6 +36,14 @@ class WalletAddress extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleQR: Function;
|
||||||
|
|
||||||
|
toggleQR() {
|
||||||
|
this.setState({
|
||||||
|
showQR: !this.state.showQR,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { receiveAddress, getNewAddress, gettingNewAddress } = this.props;
|
const { receiveAddress, getNewAddress, gettingNewAddress } = this.props;
|
||||||
const { showQR } = this.state;
|
const { showQR } = this.state;
|
||||||
|
@ -62,7 +70,7 @@ class WalletAddress extends React.PureComponent<Props> {
|
||||||
<Button
|
<Button
|
||||||
button="link"
|
button="link"
|
||||||
label={showQR ? __('Hide QR code') : __('Show QR code')}
|
label={showQR ? __('Hide QR code') : __('Show QR code')}
|
||||||
onClick={this.toggleQR.bind(this)}
|
onClick={this.toggleQR}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import {
|
import {
|
||||||
doSendSupport,
|
doSendTip,
|
||||||
makeSelectTitleForUri,
|
makeSelectTitleForUri,
|
||||||
makeSelectClaimForUri,
|
makeSelectClaimForUri,
|
||||||
selectIsSendingSupport,
|
selectIsSendingSupport,
|
||||||
|
@ -16,7 +16,10 @@ const select = (state, props) => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
sendSupport: (amount, claimId, uri) => dispatch(doSendSupport(amount, claimId, uri)),
|
sendSupport: (amount, claimId, uri) => dispatch(doSendTip(amount, claimId, uri)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(WalletSendTip);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(WalletSendTip);
|
||||||
|
|
|
@ -23,12 +23,12 @@ export default function doLogWarningConsoleMessage(activeOnDev = false) {
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
"%cIf you don't understand what you are doing here, please close this window and keep your LBC credits/wallet safe.",
|
"%cIf you don't understand exactly what you are doing here, please close this window and keep your LBC credits/wallet safe.",
|
||||||
style.redText
|
style.redText
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
'%cIf you do understand exactly what you are doing, you should come work with us https://lbry.io/join-us',
|
'%cIf you do understand exactly what you are doing, joins us, earn LBC, and make LBRY better! All of LBRY is open-source and we have a sweet secret handshake. Get started at https://lbry.tech/contribute',
|
||||||
style.normalText
|
style.normalText
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,13 @@ import { connect } from 'react-redux';
|
||||||
import { doHideNotification } from 'lbry-redux';
|
import { doHideNotification } from 'lbry-redux';
|
||||||
import ModalAuthFailure from './view';
|
import ModalAuthFailure from './view';
|
||||||
|
|
||||||
const select = state => ({});
|
const select = () => ({});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
close: () => dispatch(doHideNotification()),
|
close: () => dispatch(doHideNotification()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, null)(ModalAuthFailure);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(ModalAuthFailure);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doAutoUpdateDeclined } from 'redux/actions/app';
|
import { doAutoUpdateDeclined } from 'redux/actions/app';
|
||||||
import { doHideNotification } from 'lbry-redux';
|
import { doHideNotification } from 'lbry-redux';
|
||||||
|
@ -9,4 +8,7 @@ const perform = dispatch => ({
|
||||||
declineAutoUpdate: () => dispatch(doAutoUpdateDeclined()),
|
declineAutoUpdate: () => dispatch(doAutoUpdateDeclined()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, perform)(ModalAutoUpdateConfirm);
|
export default connect(
|
||||||
|
null,
|
||||||
|
perform
|
||||||
|
)(ModalAutoUpdateConfirm);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doAutoUpdateDeclined } from 'redux/actions/app';
|
import { doAutoUpdateDeclined } from 'redux/actions/app';
|
||||||
import { doHideNotification } from 'lbry-redux';
|
import { doHideNotification } from 'lbry-redux';
|
||||||
|
@ -9,4 +8,7 @@ const perform = dispatch => ({
|
||||||
declineAutoUpdate: () => dispatch(doAutoUpdateDeclined()),
|
declineAutoUpdate: () => dispatch(doAutoUpdateDeclined()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, perform)(ModalAutoUpdateDownloaded);
|
export default connect(
|
||||||
|
null,
|
||||||
|
perform
|
||||||
|
)(ModalAutoUpdateDownloaded);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doStartUpgrade, doCancelUpgrade } from 'redux/actions/app';
|
import { doStartUpgrade, doCancelUpgrade } from 'redux/actions/app';
|
||||||
import { doHideNotification } from 'lbry-redux';
|
import { doHideNotification } from 'lbry-redux';
|
||||||
|
|
|
@ -2,10 +2,13 @@ import { connect } from 'react-redux';
|
||||||
import { doHideNotification } from 'lbry-redux';
|
import { doHideNotification } from 'lbry-redux';
|
||||||
import ModalTransactionFailed from './view';
|
import ModalTransactionFailed from './view';
|
||||||
|
|
||||||
const select = state => ({});
|
const select = () => ({});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
closeModal: () => dispatch(doHideNotification()),
|
closeModal: () => dispatch(doHideNotification()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(ModalTransactionFailed);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(ModalTransactionFailed);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectDaemonSettings } from 'redux/selectors/settings';
|
import { selectDaemonSettings } from 'redux/selectors/settings';
|
||||||
import BackupPage from './view';
|
import BackupPage from './view';
|
||||||
|
@ -7,4 +6,4 @@ const select = state => ({
|
||||||
daemonSettings: selectDaemonSettings(state),
|
daemonSettings: selectDaemonSettings(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, null)(BackupPage);
|
export default connect(select)(BackupPage);
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectPendingPublishes, selectClaimsWithPendingPublishes } from 'redux/selectors/publish';
|
import { selectPendingPublishes } from 'redux/selectors/publish';
|
||||||
import { selectIsFetchingClaimListMine, selectFileListPublishedSort } from 'lbry-redux';
|
import { selectIsFetchingClaimListMine, selectFileListPublishedSort, selectMyClaimsWithoutChannels } from 'lbry-redux';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import { doCheckPendingPublishes } from 'redux/actions/publish';
|
import { doCheckPendingPublishes } from 'redux/actions/publish';
|
||||||
import FileListPublished from './view';
|
import FileListPublished from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
claims: selectClaimsWithPendingPublishes(state),
|
claims: selectMyClaimsWithoutChannels(state),
|
||||||
fetching: selectIsFetchingClaimListMine(state),
|
fetching: selectIsFetchingClaimListMine(state),
|
||||||
pendingPublishes: selectPendingPublishes(state),
|
|
||||||
sortBy: selectFileListPublishedSort(state),
|
sortBy: selectFileListPublishedSort(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
navigate: path => dispatch(doNavigate(path)),
|
navigate: path => dispatch(doNavigate(path)),
|
||||||
checkIfPublishesConfirmed: publishes => dispatch(doCheckPendingPublishes(publishes)),
|
checkPendingPublishes: () => dispatch(doCheckPendingPublishes()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
import type { Claim } from 'types/claim';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import FileList from 'component/fileList';
|
import FileList from 'component/fileList';
|
||||||
|
@ -6,9 +7,8 @@ import Page from 'component/page';
|
||||||
import { PAGES } from 'lbry-redux';
|
import { PAGES } from 'lbry-redux';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
pendingPublishes: Array<{}>,
|
claims: Array<Claim>,
|
||||||
claims: Array<{}>,
|
checkPendingPublishes: () => void,
|
||||||
checkIfPublishesConfirmed: (Array<{}>) => void,
|
|
||||||
navigate: (string, ?{}) => void,
|
navigate: (string, ?{}) => void,
|
||||||
fetching: boolean,
|
fetching: boolean,
|
||||||
sortBy: string,
|
sortBy: string,
|
||||||
|
@ -16,10 +16,8 @@ type Props = {
|
||||||
|
|
||||||
class FileListPublished extends React.PureComponent<Props> {
|
class FileListPublished extends React.PureComponent<Props> {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { pendingPublishes, checkIfPublishesConfirmed } = this.props;
|
const { checkPendingPublishes } = this.props;
|
||||||
if (pendingPublishes.length) {
|
checkPendingPublishes();
|
||||||
checkIfPublishesConfirmed(pendingPublishes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import GetCreditsPage from './view';
|
import GetCreditsPage from './view';
|
||||||
|
|
||||||
export default connect(null, null)(GetCreditsPage);
|
export default GetCreditsPage;
|
||||||
|
|
|
@ -26,7 +26,6 @@ type VersionInfo = {
|
||||||
os_release: string,
|
os_release: string,
|
||||||
platform: string,
|
platform: string,
|
||||||
lbrynet_version: string,
|
lbrynet_version: string,
|
||||||
lbryum_version: string,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
@ -209,10 +208,6 @@ class HelpPage extends React.PureComponent<Props, State> {
|
||||||
<td>{__('Daemon (lbrynet)')}</td>
|
<td>{__('Daemon (lbrynet)')}</td>
|
||||||
<td>{ver.lbrynet_version}</td>
|
<td>{ver.lbrynet_version}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>{__('Wallet (lbryum)')}</td>
|
|
||||||
<td>{ver.lbryum_version}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>{__('Connected Email')}</td>
|
<td>{__('Connected Email')}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import SendReceivePage from './view';
|
import SendReceivePage from './view';
|
||||||
|
|
||||||
export default connect(null, null)(SendReceivePage);
|
export default SendReceivePage;
|
||||||
|
|
|
@ -3,7 +3,7 @@ import WalletSend from 'component/walletSend';
|
||||||
import WalletAddress from 'component/walletAddress';
|
import WalletAddress from 'component/walletAddress';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
|
|
||||||
const SendReceivePage = props => (
|
const SendReceivePage = () => (
|
||||||
<Page>
|
<Page>
|
||||||
<WalletSend />
|
<WalletSend />
|
||||||
<WalletAddress />
|
<WalletAddress />
|
||||||
|
|
|
@ -15,7 +15,6 @@ import {
|
||||||
} from 'redux/actions/subscriptions';
|
} from 'redux/actions/subscriptions';
|
||||||
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 { selectFileListSubscriptionSort } from 'lbry-redux';
|
|
||||||
import SubscriptionsPage from './view';
|
import SubscriptionsPage from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
@ -26,7 +25,6 @@ const select = state => ({
|
||||||
autoDownload: makeSelectClientSetting(settings.AUTO_DOWNLOAD)(state),
|
autoDownload: makeSelectClientSetting(settings.AUTO_DOWNLOAD)(state),
|
||||||
allSubscriptions: selectSubscriptionClaims(state),
|
allSubscriptions: selectSubscriptionClaims(state),
|
||||||
unreadSubscriptions: selectUnreadSubscriptions(state),
|
unreadSubscriptions: selectUnreadSubscriptions(state),
|
||||||
sortBy: selectFileListSubscriptionSort(state),
|
|
||||||
viewMode: selectViewMode(state),
|
viewMode: selectViewMode(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import FileList from 'component/fileList';
|
||||||
import HiddenNsfwClaims from 'component/hiddenNsfwClaims';
|
import HiddenNsfwClaims from 'component/hiddenNsfwClaims';
|
||||||
import { FormField } from 'component/common/form';
|
import { FormField } from 'component/common/form';
|
||||||
import FileCard from 'component/fileCard';
|
import FileCard from 'component/fileCard';
|
||||||
import { parseURI, PAGES } from 'lbry-redux';
|
import { parseURI } from 'lbry-redux';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
subscribedChannels: Array<string>, // The channels a user is subscribed to
|
subscribedChannels: Array<string>, // The channels a user is subscribed to
|
||||||
|
@ -25,7 +25,6 @@ type Props = {
|
||||||
doSetViewMode: ViewMode => void,
|
doSetViewMode: ViewMode => void,
|
||||||
doFetchMySubscriptions: () => void,
|
doFetchMySubscriptions: () => void,
|
||||||
doSetClientSetting: (string, boolean) => void,
|
doSetClientSetting: (string, boolean) => void,
|
||||||
sortBy: string,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class extends React.PureComponent<Props> {
|
export default class extends React.PureComponent<Props> {
|
||||||
|
@ -45,19 +44,13 @@ export default class extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSubscriptions() {
|
renderSubscriptions() {
|
||||||
const { viewMode, unreadSubscriptions, allSubscriptions, sortBy } = this.props;
|
const { viewMode, unreadSubscriptions, allSubscriptions } = this.props;
|
||||||
|
|
||||||
if (viewMode === VIEW_ALL) {
|
if (viewMode === VIEW_ALL) {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div className="card__title">{__('Your subscriptions')}</div>
|
<div className="card__title">{__('Your subscriptions')}</div>
|
||||||
<FileList
|
<FileList hideFilter sortByHeight fileInfos={allSubscriptions} />
|
||||||
hideFilter
|
|
||||||
sortByHeight
|
|
||||||
fileInfos={allSubscriptions}
|
|
||||||
sortBy={sortBy}
|
|
||||||
page={PAGES.SUBSCRIPTIONS}
|
|
||||||
/>
|
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import WalletPage from './view';
|
import WalletPage from './view';
|
||||||
|
|
||||||
export default connect(null, null)(WalletPage);
|
export default WalletPage;
|
||||||
|
|
|
@ -292,7 +292,7 @@ export function doFetchClaimsByChannel(uri, page, pageSize) {
|
||||||
data: { uri, page },
|
data: { uri, page },
|
||||||
});
|
});
|
||||||
|
|
||||||
Lbry.claim_list_by_channel({ uri, page: page || 1, page_size: pageSize || 48 }).then(result => {
|
Lbry.claim_list_by_channel({ uri, page: page || 1, page_size: pageSize || 20 }).then(result => {
|
||||||
const claimResult = result[uri] || {};
|
const claimResult = result[uri] || {};
|
||||||
const { claims_in_channel: claimsInChannel, returned_page: returnedPage } = claimResult;
|
const { claims_in_channel: claimsInChannel, returned_page: returnedPage } = claimResult;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
import type { Dispatch, GetState } from 'types/redux';
|
||||||
|
import type { Source, Metadata } from 'types/claim';
|
||||||
|
import type {
|
||||||
|
UpdatePublishFormData,
|
||||||
|
UpdatePublishFormAction,
|
||||||
|
PublishParams,
|
||||||
|
} from 'redux/reducers/publish';
|
||||||
import {
|
import {
|
||||||
ACTIONS,
|
ACTIONS,
|
||||||
Lbry,
|
Lbry,
|
||||||
|
@ -7,20 +14,14 @@ import {
|
||||||
selectMyChannelClaims,
|
selectMyChannelClaims,
|
||||||
THUMBNAIL_STATUSES,
|
THUMBNAIL_STATUSES,
|
||||||
batchActions,
|
batchActions,
|
||||||
|
creditsToString,
|
||||||
|
selectPendingById,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { selectPendingPublishes } from 'redux/selectors/publish';
|
|
||||||
import type {
|
|
||||||
UpdatePublishFormData,
|
|
||||||
UpdatePublishFormAction,
|
|
||||||
PublishParams,
|
|
||||||
} from 'redux/reducers/publish';
|
|
||||||
import { selectosNotificationsEnabled } from 'redux/selectors/settings';
|
import { selectosNotificationsEnabled } from 'redux/selectors/settings';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { CC_LICENSES, COPYRIGHT, OTHER } from 'constants/licenses';
|
import { CC_LICENSES, COPYRIGHT, OTHER } from 'constants/licenses';
|
||||||
import type { Dispatch, GetState } from 'types/redux';
|
|
||||||
import type { Source } from 'types/claim';
|
|
||||||
|
|
||||||
type Action = UpdatePublishFormAction | { type: ACTIONS.CLEAR_PUBLISH };
|
type Action = UpdatePublishFormAction | { type: ACTIONS.CLEAR_PUBLISH };
|
||||||
|
|
||||||
|
@ -229,7 +230,6 @@ export const doPublish = (params: PublishParams) => (
|
||||||
licenseUrl,
|
licenseUrl,
|
||||||
language,
|
language,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
fee: fee || undefined,
|
|
||||||
description: description || undefined,
|
description: description || undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -237,16 +237,23 @@ export const doPublish = (params: PublishParams) => (
|
||||||
name: ?string,
|
name: ?string,
|
||||||
channel_id: string,
|
channel_id: string,
|
||||||
bid: ?number,
|
bid: ?number,
|
||||||
metadata: ?any,
|
metadata: ?Metadata,
|
||||||
file_path?: string,
|
file_path?: string,
|
||||||
sources?: Source,
|
sources?: Source,
|
||||||
} = {
|
} = {
|
||||||
name,
|
name,
|
||||||
channel_id: channelId,
|
channel_id: channelId,
|
||||||
bid,
|
bid: creditsToString(bid),
|
||||||
metadata,
|
metadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (fee) {
|
||||||
|
metadata.fee = {
|
||||||
|
currency: fee.currency,
|
||||||
|
amount: creditsToString(fee.amount),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (filePath) {
|
if (filePath) {
|
||||||
publishPayload.file_path = filePath;
|
publishPayload.file_path = filePath;
|
||||||
} else {
|
} else {
|
||||||
|
@ -258,7 +265,6 @@ export const doPublish = (params: PublishParams) => (
|
||||||
const success = () => {
|
const success = () => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.PUBLISH_SUCCESS,
|
type: ACTIONS.PUBLISH_SUCCESS,
|
||||||
data: { pendingPublish: { ...publishPayload } },
|
|
||||||
});
|
});
|
||||||
dispatch(doNotify({ id: MODALS.PUBLISH }, { uri }));
|
dispatch(doNotify({ id: MODALS.PUBLISH }, { uri }));
|
||||||
};
|
};
|
||||||
|
@ -274,28 +280,21 @@ export const doPublish = (params: PublishParams) => (
|
||||||
// Calls claim_list_mine until any pending publishes are confirmed
|
// Calls claim_list_mine until any pending publishes are confirmed
|
||||||
export const doCheckPendingPublishes = () => (dispatch: Dispatch<Action>, getState: GetState) => {
|
export const doCheckPendingPublishes = () => (dispatch: Dispatch<Action>, getState: GetState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const pendingPublishes = selectPendingPublishes(state);
|
const pendingById = selectPendingById(state);
|
||||||
|
if (!Object.keys(pendingById)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let publishCheckInterval;
|
let publishCheckInterval;
|
||||||
|
|
||||||
const checkFileList = () => {
|
const checkFileList = () => {
|
||||||
Lbry.claim_list_mine().then(claims => {
|
Lbry.claim_list_mine().then(claims => {
|
||||||
const pendingPublishMap = {};
|
|
||||||
pendingPublishes.forEach(({ name }) => {
|
|
||||||
pendingPublishMap[name] = name;
|
|
||||||
});
|
|
||||||
|
|
||||||
const actions = [];
|
|
||||||
claims.forEach(claim => {
|
claims.forEach(claim => {
|
||||||
if (pendingPublishMap[claim.name]) {
|
// If it's confirmed, check that it wasn't pending previously
|
||||||
actions.push({
|
if (claim.confirmations > 0 && pendingById[claim.claim_id]) {
|
||||||
type: ACTIONS.REMOVE_PENDING_PUBLISH,
|
delete pendingById[claim.claim_id];
|
||||||
data: {
|
|
||||||
name: claim.name,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
delete pendingPublishMap[claim.name];
|
// If it's confirmed, check if we should notify the user
|
||||||
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://${
|
body: `${claim.value.stream.metadata.title} has been published to lbry://${
|
||||||
|
@ -314,25 +313,21 @@ export const doCheckPendingPublishes = () => (dispatch: Dispatch<Action>, getSta
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
actions.push({
|
dispatch({
|
||||||
type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED,
|
type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED,
|
||||||
data: {
|
data: {
|
||||||
claims,
|
claims,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatch(batchActions(...actions));
|
if (!Object.keys(pendingById).length) {
|
||||||
|
|
||||||
if (!Object.keys(pendingPublishMap).length) {
|
|
||||||
clearInterval(publishCheckInterval);
|
clearInterval(publishCheckInterval);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (pendingPublishes.length) {
|
checkFileList();
|
||||||
|
publishCheckInterval = setInterval(() => {
|
||||||
checkFileList();
|
checkFileList();
|
||||||
publishCheckInterval = setInterval(() => {
|
}, 30000);
|
||||||
checkFileList();
|
|
||||||
}, 30000);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -100,7 +100,7 @@ export const doFetchMySubscriptions = () => (dispatch: ReduxDispatch, getState:
|
||||||
data: subscriptions,
|
data: subscriptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
subscriptions.forEach(({ uri }) => dispatch(doFetchClaimsByChannel(uri, 1, 20)));
|
subscriptions.forEach(({ uri }) => dispatch(doFetchClaimsByChannel(uri, 1)));
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -205,7 +205,7 @@ export const doRemoveUnreadSubscription = (channelUri: string, readUri: string)
|
||||||
dispatch(doRemoveUnreadSubscriptions(channelUri, [readUri]));
|
dispatch(doRemoveUnreadSubscriptions(channelUri, [readUri]));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doCheckSubscription = (subscriptionUri: string, shouldNotify?: boolean) => async (
|
export const doCheckSubscription = (subscriptionUri: string, shouldNotify?: boolean) => (
|
||||||
dispatch: ReduxDispatch,
|
dispatch: ReduxDispatch,
|
||||||
getState: GetState
|
getState: GetState
|
||||||
) => {
|
) => {
|
||||||
|
@ -223,85 +223,86 @@ export const doCheckSubscription = (subscriptionUri: string, shouldNotify?: bool
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const claimListByChannel = await Lbry.claim_list_by_channel({ uri: subscriptionUri, page: 1 });
|
Lbry.claim_list_by_channel({ uri: subscriptionUri, page: 1 }).then(claimListByChannel => {
|
||||||
const claimResult = claimListByChannel[subscriptionUri] || {};
|
const claimResult = claimListByChannel[subscriptionUri] || {};
|
||||||
const { claims_in_channel: claimsInChannel } = claimResult;
|
const { claims_in_channel: claimsInChannel } = claimResult;
|
||||||
|
|
||||||
// may happen if subscribed to an abandoned channel or an empty channel
|
// may happen if subscribed to an abandoned channel or an empty channel
|
||||||
if (!claimsInChannel || !claimsInChannel.length) {
|
if (!claimsInChannel || !claimsInChannel.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if the latest subscription currently saved is actually the latest subscription
|
// Determine if the latest subscription currently saved is actually the latest subscription
|
||||||
const latestIndex = claimsInChannel.findIndex(
|
const latestIndex = claimsInChannel.findIndex(
|
||||||
claim => `${claim.name}#${claim.claim_id}` === savedSubscription.latest
|
claim => `${claim.name}#${claim.claim_id}` === savedSubscription.latest
|
||||||
);
|
);
|
||||||
|
|
||||||
// If latest is -1, it is a newly subscribed channel or there have been 10+ claims published since last viewed
|
// If latest is -1, it is a newly subscribed channel or there have been 10+ claims published since last viewed
|
||||||
const latestIndexToNotify = latestIndex === -1 ? 10 : latestIndex;
|
const latestIndexToNotify = latestIndex === -1 ? 10 : latestIndex;
|
||||||
|
|
||||||
// If latest is 0, nothing has changed
|
// If latest is 0, nothing has changed
|
||||||
// Do not download/notify about new content, it would download/notify 10 claims per channel
|
// Do not download/notify about new content, it would download/notify 10 claims per channel
|
||||||
if (latestIndex !== 0 && savedSubscription.latest) {
|
if (latestIndex !== 0 && savedSubscription.latest) {
|
||||||
let downloadCount = 0;
|
let downloadCount = 0;
|
||||||
|
|
||||||
const newUnread = [];
|
const newUnread = [];
|
||||||
claimsInChannel.slice(0, latestIndexToNotify).forEach(claim => {
|
claimsInChannel.slice(0, latestIndexToNotify).forEach(claim => {
|
||||||
const uri = buildURI({ contentName: claim.name, claimId: claim.claim_id }, true);
|
const uri = buildURI({ contentName: claim.name, claimId: claim.claim_id }, true);
|
||||||
const shouldDownload =
|
const shouldDownload =
|
||||||
shouldAutoDownload &&
|
shouldAutoDownload &&
|
||||||
Boolean(downloadCount < SUBSCRIPTION_DOWNLOAD_LIMIT && !claim.value.stream.metadata.fee);
|
Boolean(downloadCount < SUBSCRIPTION_DOWNLOAD_LIMIT && !claim.value.stream.metadata.fee);
|
||||||
|
|
||||||
// Add the new content to the list of "un-read" subscriptions
|
// Add the new content to the list of "un-read" subscriptions
|
||||||
if (shouldNotify) {
|
if (shouldNotify) {
|
||||||
newUnread.push(uri);
|
newUnread.push(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldDownload) {
|
if (shouldDownload) {
|
||||||
downloadCount += 1;
|
downloadCount += 1;
|
||||||
dispatch(doPurchaseUri(uri, { cost: 0 }, true));
|
dispatch(doPurchaseUri(uri, { cost: 0 }, true));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
dispatch(
|
||||||
|
doUpdateUnreadSubscriptions(
|
||||||
|
subscriptionUri,
|
||||||
|
newUnread,
|
||||||
|
downloadCount > 0 ? NOTIFICATION_TYPES.DOWNLOADING : NOTIFICATION_TYPES.NOTIFY_ONLY
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the latest piece of content for a channel
|
||||||
|
// This allows the app to know if there has been new content since it was last set
|
||||||
dispatch(
|
dispatch(
|
||||||
doUpdateUnreadSubscriptions(
|
setSubscriptionLatest(
|
||||||
subscriptionUri,
|
{
|
||||||
newUnread,
|
channelName: claimsInChannel[0].channel_name,
|
||||||
downloadCount > 0 ? NOTIFICATION_TYPES.DOWNLOADING : NOTIFICATION_TYPES.NOTIFY_ONLY
|
uri: buildURI(
|
||||||
|
{
|
||||||
|
channelName: claimsInChannel[0].channel_name,
|
||||||
|
claimId: claimsInChannel[0].claim_id,
|
||||||
|
},
|
||||||
|
false
|
||||||
|
),
|
||||||
|
},
|
||||||
|
buildURI(
|
||||||
|
{ contentName: claimsInChannel[0].name, claimId: claimsInChannel[0].claim_id },
|
||||||
|
false
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Set the latest piece of content for a channel
|
// calling FETCH_CHANNEL_CLAIMS_COMPLETED after not calling STARTED
|
||||||
// This allows the app to know if there has been new content since it was last set
|
// means it will delete a non-existant fetchingChannelClaims[uri]
|
||||||
dispatch(
|
dispatch({
|
||||||
setSubscriptionLatest(
|
type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED,
|
||||||
{
|
data: {
|
||||||
channelName: claimsInChannel[0].channel_name,
|
uri: subscriptionUri,
|
||||||
uri: buildURI(
|
claims: claimsInChannel || [],
|
||||||
{
|
page: 1,
|
||||||
channelName: claimsInChannel[0].channel_name,
|
|
||||||
claimId: claimsInChannel[0].claim_id,
|
|
||||||
},
|
|
||||||
false
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
buildURI(
|
});
|
||||||
{ contentName: claimsInChannel[0].name, claimId: claimsInChannel[0].claim_id },
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// calling FETCH_CHANNEL_CLAIMS_COMPLETED after not calling STARTED
|
|
||||||
// means it will delete a non-existant fetchingChannelClaims[uri]
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED,
|
|
||||||
data: {
|
|
||||||
uri: subscriptionUri,
|
|
||||||
claims: claimsInChannel || [],
|
|
||||||
page: 1,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ type PublishState = {
|
||||||
bidError: ?string,
|
bidError: ?string,
|
||||||
otherLicenseDescription: string,
|
otherLicenseDescription: string,
|
||||||
licenseUrl: string,
|
licenseUrl: string,
|
||||||
pendingPublishes: Array<any>,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UpdatePublishFormData = {
|
export type UpdatePublishFormData = {
|
||||||
|
@ -115,7 +114,6 @@ const defaultState: PublishState = {
|
||||||
publishing: false,
|
publishing: false,
|
||||||
publishSuccess: false,
|
publishSuccess: false,
|
||||||
publishError: undefined,
|
publishError: undefined,
|
||||||
pendingPublishes: [],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default handleActions(
|
export default handleActions(
|
||||||
|
@ -127,10 +125,9 @@ export default handleActions(
|
||||||
...data,
|
...data,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[ACTIONS.CLEAR_PUBLISH]: (state: PublishState): PublishState => {
|
[ACTIONS.CLEAR_PUBLISH]: (): PublishState => ({
|
||||||
const { pendingPublishes } = state;
|
...defaultState,
|
||||||
return { ...defaultState, pendingPublishes };
|
}),
|
||||||
},
|
|
||||||
[ACTIONS.PUBLISH_START]: (state: PublishState): PublishState => ({
|
[ACTIONS.PUBLISH_START]: (state: PublishState): PublishState => ({
|
||||||
...state,
|
...state,
|
||||||
publishing: true,
|
publishing: true,
|
||||||
|
@ -139,29 +136,11 @@ export default handleActions(
|
||||||
...state,
|
...state,
|
||||||
publishing: false,
|
publishing: false,
|
||||||
}),
|
}),
|
||||||
[ACTIONS.PUBLISH_SUCCESS]: (state: PublishState, action): PublishState => {
|
[ACTIONS.PUBLISH_SUCCESS]: (state: PublishState): PublishState => ({
|
||||||
const { pendingPublish } = action.data;
|
...state,
|
||||||
|
publishing: false,
|
||||||
const newPendingPublishes = state.pendingPublishes.slice();
|
}),
|
||||||
|
|
||||||
newPendingPublishes.push(pendingPublish);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
publishing: false,
|
|
||||||
pendingPublishes: newPendingPublishes,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
[ACTIONS.REMOVE_PENDING_PUBLISH]: (state: PublishState, action) => {
|
|
||||||
const { name } = action.data;
|
|
||||||
const pendingPublishes = state.pendingPublishes.filter(publish => publish.name !== name);
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
pendingPublishes,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
[ACTIONS.DO_PREPARE_EDIT]: (state: PublishState, action) => {
|
[ACTIONS.DO_PREPARE_EDIT]: (state: PublishState, action) => {
|
||||||
const { pendingPublishes } = state;
|
|
||||||
const { ...publishData } = action.data;
|
const { ...publishData } = action.data;
|
||||||
const { channel, name, uri } = publishData;
|
const { channel, name, uri } = publishData;
|
||||||
|
|
||||||
|
@ -175,7 +154,6 @@ export default handleActions(
|
||||||
return {
|
return {
|
||||||
...defaultState,
|
...defaultState,
|
||||||
...publishData,
|
...publishData,
|
||||||
pendingPublishes,
|
|
||||||
editingURI: uri,
|
editingURI: uri,
|
||||||
uri: shortUri,
|
uri: shortUri,
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,47 +10,11 @@ import {
|
||||||
|
|
||||||
const selectState = state => state.publish || {};
|
const selectState = state => state.publish || {};
|
||||||
|
|
||||||
export const selectPendingPublishes = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.pendingPublishes.map(pendingClaim => ({ ...pendingClaim, pending: true })) || []
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectClaimsWithPendingPublishes = createSelector(
|
|
||||||
selectMyClaimsWithoutChannels,
|
|
||||||
selectPendingPublishes,
|
|
||||||
(claims, pendingPublishes) => {
|
|
||||||
// ensure there are no duplicates, they are being checked for in a setInterval
|
|
||||||
// no need to wait for it to complete though
|
|
||||||
// loop through myclaims
|
|
||||||
// if a claim has the same name as one in pendingPublish, remove it from pending
|
|
||||||
const claimMap = {};
|
|
||||||
claims.forEach(claim => {
|
|
||||||
claimMap[claim.name] = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
const filteredPendingPublishes = pendingPublishes.filter(claim => !claimMap[claim.name]);
|
|
||||||
return [...filteredPendingPublishes, ...claims];
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectPublishFormValues = createSelector(selectState, state => {
|
export const selectPublishFormValues = createSelector(selectState, state => {
|
||||||
const { pendingPublish, ...formValues } = state;
|
const { pendingPublish, ...formValues } = state;
|
||||||
return formValues;
|
return formValues;
|
||||||
});
|
});
|
||||||
|
|
||||||
export const selectPendingPublish = uri =>
|
|
||||||
createSelector(selectPendingPublishes, pendingPublishes => {
|
|
||||||
const { claimName, contentName } = parseURI(uri);
|
|
||||||
|
|
||||||
if (!pendingPublishes.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pendingPublishes.filter(
|
|
||||||
publish => publish.name === claimName || publish.name === contentName
|
|
||||||
)[0];
|
|
||||||
});
|
|
||||||
|
|
||||||
// Is the current uri the same as the uri they clicked "edit" on
|
// Is the current uri the same as the uri they clicked "edit" on
|
||||||
export const selectIsStillEditing = createSelector(selectPublishFormValues, publishState => {
|
export const selectIsStillEditing = createSelector(selectPublishFormValues, publishState => {
|
||||||
const { editingURI, uri } = publishState;
|
const { editingURI, uri } = publishState;
|
||||||
|
|
|
@ -227,8 +227,7 @@
|
||||||
|
|
||||||
.card__subtitle {
|
.card__subtitle {
|
||||||
color: $lbry-gray-5;
|
color: $lbry-gray-5;
|
||||||
font-size: .9em;
|
font-size: 0.9em;
|
||||||
line-height: .9em;
|
|
||||||
padding-top: $spacing-vertical * 1/3;
|
padding-top: $spacing-vertical * 1/3;
|
||||||
|
|
||||||
@media (min-width: $large-breakpoint) {
|
@media (min-width: $large-breakpoint) {
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-field__error {
|
.form-field__error {
|
||||||
color: $lbry-red-5;
|
color: $lbry-red-3 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-field__help {
|
.form-field__help {
|
||||||
|
|
|
@ -115,4 +115,19 @@ html[data-theme='dark'] {
|
||||||
.item-list__item:not(:last-of-type) {
|
.item-list__item:not(:last-of-type) {
|
||||||
border-bottom: 1px solid rgba($lbry-gray-1, 0.1);
|
border-bottom: 1px solid rgba($lbry-gray-1, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-overlay,
|
||||||
|
.error-modal-overlay {
|
||||||
|
background-color: rgba($lbry-black, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
color: $lbry-gray-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
background-color: rgba($lbry-black, 0.9);
|
||||||
|
border: 1px solid rgba($lbry-gray-1, 0.1);
|
||||||
|
color: $lbry-gray-3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
export function formatCredits(amount, precision) {
|
export function formatCredits(amount, precision = 1) {
|
||||||
return amount.toFixed(precision || 1).replace(/\.?0+$/, '');
|
return parseFloat(amount)
|
||||||
|
.toFixed(precision || 1)
|
||||||
|
.replace(/\.?0+$/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatFullPrice(amount, precision = 1) {
|
export function formatFullPrice(amount, precision = 1) {
|
||||||
|
|
|
@ -13,7 +13,6 @@ const isDev = PROCESS_ARGV && PROCESS_ARGV.original &&
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// This rule is temporarily necessary until https://github.com/electron-userland/electron-webpack/issues/60 is fixed.
|
// This rule is temporarily necessary until https://github.com/electron-userland/electron-webpack/issues/60 is fixed.
|
||||||
entry: ['babel-polyfill', `${ELECTRON_RENDERER_PROCESS_ROOT}/index.js`],
|
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
|
|
14
yarn.lock
14
yarn.lock
|
@ -5663,25 +5663,25 @@ 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:
|
lbry-redux@lbryio/lbry-redux#2375860d6269d0369418879c2531b1d48c4e47f2:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/a8e81949837171e94e649fce6f7c7a8b7faadd51"
|
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/2375860d6269d0369418879c2531b1d48c4e47f2"
|
||||||
dependencies:
|
dependencies:
|
||||||
proxy-polyfill "0.1.6"
|
proxy-polyfill "0.1.6"
|
||||||
reselect "^3.0.0"
|
reselect "^3.0.0"
|
||||||
|
|
||||||
lbry-redux@lbryio/lbry-redux#03aea43da5f12bc01546a92bdf460ebd08681013:
|
lbry-redux@lbryio/lbry-redux#f193d38c61ea061679ebc7b4ca139a0e9c95ef8a:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/03aea43da5f12bc01546a92bdf460ebd08681013"
|
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/f193d38c61ea061679ebc7b4ca139a0e9c95ef8a"
|
||||||
dependencies:
|
dependencies:
|
||||||
proxy-polyfill "0.1.6"
|
proxy-polyfill "0.1.6"
|
||||||
reselect "^3.0.0"
|
reselect "^3.0.0"
|
||||||
|
|
||||||
lbryinc@lbryio/lbryinc#3f34af546ee73ff2ee7d8ad05e540b3b0aa658fb:
|
lbryinc@lbryio/lbryinc#7a458ea13ceceffa0191e73139f94e5c953f22b1:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/3f34af546ee73ff2ee7d8ad05e540b3b0aa658fb"
|
resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/7a458ea13ceceffa0191e73139f94e5c953f22b1"
|
||||||
dependencies:
|
dependencies:
|
||||||
lbry-redux lbryio/lbry-redux
|
lbry-redux lbryio/lbry-redux#2375860d6269d0369418879c2531b1d48c4e47f2
|
||||||
reselect "^3.0.0"
|
reselect "^3.0.0"
|
||||||
|
|
||||||
lcid@^1.0.0:
|
lcid@^1.0.0:
|
||||||
|
|
Loading…
Add table
Reference in a new issue