diff --git a/ui/js/component/app/index.js b/ui/js/component/app/index.js index b917c04f7..66b50bb71 100644 --- a/ui/js/component/app/index.js +++ b/ui/js/component/app/index.js @@ -6,9 +6,8 @@ import { selectActiveHistoryEntry, } from "redux/selectors/navigation"; import { selectUser } from "redux/selectors/user"; -import { doCheckUpgradeAvailable, doAlertError } from "redux/actions/app"; +import { doAlertError } from "redux/actions/app"; import { doRecordScroll } from "redux/actions/navigation"; -import { doFetchRewardedContent } from "redux/actions/content"; import App from "./view"; const select = (state, props) => ({ @@ -20,8 +19,6 @@ const select = (state, props) => ({ const perform = dispatch => ({ alertError: errorList => dispatch(doAlertError(errorList)), - checkUpgradeAvailable: () => dispatch(doCheckUpgradeAvailable()), - fetchRewardedContent: () => dispatch(doFetchRewardedContent()), recordScroll: scrollPosition => dispatch(doRecordScroll(scrollPosition)), }); diff --git a/ui/js/component/app/view.jsx b/ui/js/component/app/view.jsx index 7a54b0de0..edc9fa2dc 100644 --- a/ui/js/component/app/view.jsx +++ b/ui/js/component/app/view.jsx @@ -13,23 +13,11 @@ class App extends React.PureComponent { } componentWillMount() { - const { - alertError, - checkUpgradeAvailable, - fetchRewardedContent, - } = this.props; + const { alertError } = this.props; document.addEventListener("unhandledError", event => { alertError(event.detail); }); - - if (!this.props.upgradeSkipped) { - checkUpgradeAvailable(); - } - - fetchRewardedContent(); - - this.setTitleFromProps(this.props); } componentDidMount() { diff --git a/ui/js/component/dateTime/index.js b/ui/js/component/dateTime/index.js index 106de7126..dbef1e030 100644 --- a/ui/js/component/dateTime/index.js +++ b/ui/js/component/dateTime/index.js @@ -5,9 +5,10 @@ import { doFetchBlock } from "redux/actions/wallet"; import DateTime from "./view"; const select = (state, props) => ({ - date: !props.date && props.block - ? makeSelectBlockDate(props.block)(state) - : props.date, + date: + !props.date && props.block + ? makeSelectBlockDate(props.block)(state) + : props.date, }); const perform = dispatch => ({ diff --git a/ui/js/component/header/index.js b/ui/js/component/header/index.js index e461f4efa..4e2a2d078 100644 --- a/ui/js/component/header/index.js +++ b/ui/js/component/header/index.js @@ -12,18 +12,21 @@ import { doHistoryForward, } from "redux/actions/navigation"; import Header from "./view"; +import { selectIsUpgradeAvailable } from "../../selectors/app"; +import { doDownloadUpgrade } from "../../actions/app"; const select = state => ({ isBackDisabled: selectIsBackDisabled(state), isForwardDisabled: selectIsForwardDisabled(state), + isUpgradeAvailable: selectIsUpgradeAvailable(state), balance: formatCredits(selectBalance(state) || 0, 1), - publish: __("Publish"), }); const perform = dispatch => ({ navigate: path => dispatch(doNavigate(path)), back: () => dispatch(doHistoryBack()), forward: () => dispatch(doHistoryForward()), + downloadUpgrade: () => dispatch(doDownloadUpgrade()), }); export default connect(select, perform)(Header); diff --git a/ui/js/component/header/view.jsx b/ui/js/component/header/view.jsx index 89f6df923..7bbf9899e 100644 --- a/ui/js/component/header/view.jsx +++ b/ui/js/component/header/view.jsx @@ -9,8 +9,9 @@ export const Header = props => { forward, isBackDisabled, isForwardDisabled, + isUpgradeAvailable, navigate, - publish, + downloadUpgrade, } = props; return ( ); }; diff --git a/ui/js/component/publishForm/view.jsx b/ui/js/component/publishForm/view.jsx index fa3aacec4..75ac22d2b 100644 --- a/ui/js/component/publishForm/view.jsx +++ b/ui/js/component/publishForm/view.jsx @@ -340,9 +340,10 @@ class PublishForm extends React.PureComponent { handleFeePrefChange(feeEnabled) { this.setState({ isFee: feeEnabled, - feeAmount: this.state.feeAmount == "" - ? this._defaultPaidPrice - : this.state.feeAmount, + feeAmount: + this.state.feeAmount == "" + ? this._defaultPaidPrice + : this.state.feeAmount, }); } @@ -556,82 +557,82 @@ class PublishForm extends React.PureComponent { } /> - {!this.state.hasFile && !this.myClaimExists() - ? null - :
-
- { - this.handleMetadataChange(event); - }} - /> -
-
- { - this.handleMetadataChange(event); - }} - /> -
-
- { - this.handleDescriptionChanged(text); - }} - /> -
-
- { - this.handleMetadataChange(event); - }} - > - - - - - - - - -
-
- { - this.handleMetadataChange(event); - }} - > - {/* */} - - - -
-
} + {!this.state.hasFile && !this.myClaimExists() ? null : ( +
+
+ { + this.handleMetadataChange(event); + }} + /> +
+
+ { + this.handleMetadataChange(event); + }} + /> +
+
+ { + this.handleDescriptionChanged(text); + }} + /> +
+
+ { + this.handleMetadataChange(event); + }} + > + + + + + + + + +
+
+ { + this.handleMetadataChange(event); + }} + > + {/* */} + + + +
+
+ )}
@@ -668,13 +669,14 @@ class PublishForm extends React.PureComponent { onChange={val => this.handleFeeChange(val)} /> - {this.state.isFee && this.state.feeCurrency.toUpperCase() != "LBC" - ?
- {__( - "All content fees are charged in LBC. For non-LBC payment methods, the number of credits charged will be adjusted based on the value of LBRY credits at the time of purchase." - )} -
- : null} + {this.state.isFee && + this.state.feeCurrency.toUpperCase() != "LBC" ? ( +
+ {__( + "All content fees are charged in LBC. For non-LBC payment methods, the number of credits charged will be adjusted based on the value of LBRY credits at the time of purchase." + )} +
+ ) : null}
@@ -740,49 +742,45 @@ class PublishForm extends React.PureComponent { "Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International" )} - - + + - {this.state.licenseType == "copyright" - ? { - this.handleCopyrightNoticeChange(event); - }} - /> - : null} + {this.state.licenseType == "copyright" ? ( + { + this.handleCopyrightNoticeChange(event); + }} + /> + ) : null} - {this.state.licenseType == "other" - ? { - this.handleOtherLicenseDescriptionChange(event); - }} - /> - : null} + {this.state.licenseType == "other" ? ( + { + this.handleOtherLicenseDescriptionChange(event); + }} + /> + ) : null} - {this.state.licenseType == "other" - ? { - this.handleOtherLicenseUrlChange(event); - }} - /> - : null} + {this.state.licenseType == "other" ? ( + { + this.handleOtherLicenseUrlChange(event); + }} + /> + ) : null}
@@ -798,8 +796,7 @@ class PublishForm extends React.PureComponent {
{__( "This is the exact address where people find your content (ex. lbry://myvideo)." - )} - {" "} + )}{" "}
- {this.state.rawName - ?
- { - this.handleBidChange(event); - }} - value={this.state.bid} - placeholder={this.claim() ? this.topClaimValue() + 10 : 100} - helper={lbcInputHelp} - min="0" - /> -
- : ""} + {this.state.rawName ? ( +
+ { + this.handleBidChange(event); + }} + value={this.state.bid} + placeholder={this.claim() ? this.topClaimValue() + 10 : 100} + helper={lbcInputHelp} + min="0" + /> +
+ ) : ( + "" + )}
@@ -850,8 +851,7 @@ class PublishForm extends React.PureComponent { ref="tosAgree" label={ - {__("I agree to the")} - {" "} + {__("I agree to the")}{" "}

- {__("Your file has been published to LBRY at the address")} - {" "}{this.state.uri}! + {__("Your file has been published to LBRY at the address")}{" "} + {this.state.uri}!

{__( diff --git a/ui/js/component/uriIndicator/view.jsx b/ui/js/component/uriIndicator/view.jsx index bff2cbf97..3fa1cb41f 100644 --- a/ui/js/component/uriIndicator/view.jsx +++ b/ui/js/component/uriIndicator/view.jsx @@ -60,13 +60,17 @@ class UriIndicator extends React.PureComponent { const inner = ( - {channelName} {" "} - {!signatureIsValid - ? - : ""} + {channelName}{" "} + {!signatureIsValid ? ( + + ) : ( + "" + )} ); diff --git a/ui/js/constants/action_types.js b/ui/js/constants/action_types.js index 9a9143070..b2f88f31f 100644 --- a/ui/js/constants/action_types.js +++ b/ui/js/constants/action_types.js @@ -20,7 +20,12 @@ export const UPGRADE_DOWNLOAD_STARTED = "UPGRADE_DOWNLOAD_STARTED"; export const UPGRADE_DOWNLOAD_COMPLETED = "UPGRADE_DOWNLOAD_COMPLETED"; export const UPGRADE_DOWNLOAD_PROGRESSED = "UPGRADE_DOWNLOAD_PROGRESSED"; export const CHECK_UPGRADE_AVAILABLE = "CHECK_UPGRADE_AVAILABLE"; +export const CHECK_UPGRADE_START = "CHECK_UPGRADE_START"; +export const CHECK_UPGRADE_SUCCESS = "CHECK_UPGRADE_SUCCESS"; +export const CHECK_UPGRADE_FAIL = "CHECK_UPGRADE_FAIL"; +export const CHECK_UPGRADE_SUBSCRIBE = "CHECK_UPGRADE_SUBSCRIBE"; export const UPDATE_VERSION = "UPDATE_VERSION"; +export const UPDATE_REMOTE_VERSION = "UPDATE_REMOTE_VERSION"; export const SKIP_UPGRADE = "SKIP_UPGRADE"; export const START_UPGRADE = "START_UPGRADE"; diff --git a/ui/js/jsonrpc.js b/ui/js/jsonrpc.js index d3cebcfda..70320b0d7 100644 --- a/ui/js/jsonrpc.js +++ b/ui/js/jsonrpc.js @@ -27,7 +27,9 @@ jsonrpc.call = function( function makeRequest(url, options) { return new Promise((resolve, reject) => { - fetch(url, options).then(resolve).catch(reject); + fetch(url, options) + .then(resolve) + .catch(reject); if (timeout) { const e = new Error(__("Protocol request timed out")); diff --git a/ui/js/main.js b/ui/js/main.js index 2b55421ba..759b2a179 100644 --- a/ui/js/main.js +++ b/ui/js/main.js @@ -71,7 +71,10 @@ var init = function() { ReactDOM.render( -

+
+ + +
, canvas ); diff --git a/ui/js/modal/modalCreditIntro/view.jsx b/ui/js/modal/modalCreditIntro/view.jsx index 1b48f87b4..c7db6127a 100644 --- a/ui/js/modal/modalCreditIntro/view.jsx +++ b/ui/js/modal/modalCreditIntro/view.jsx @@ -12,37 +12,41 @@ const ModalCreditIntro = props => {

{__("Blockchain 101")}

- LBRY is controlled and powered by a blockchain asset called {" "} - .{" "} - {" "} + LBRY is controlled and powered by a blockchain asset called{" "} + + + . {" "} {__( "is used to publish content, to have a say in the network rules, and to access paid content." )}

- {currentBalance <= 0 - ?
-

- You currently have , so - the actions you can take are limited. -

-

- However, there are a variety of ways to get credits, including - more than {" "} - {totalRewardValue - ? - : {__("?? credits")}} - {" "}{" "} - {__( - " in rewards available for being a proven human during the LBRY beta." - )} -

-
- :
-

- But you probably knew this, since you've already got{" "} - . -

-
} + {currentBalance <= 0 ? ( +
+

+ You currently have , so + the actions you can take are limited. +

+

+ However, there are a variety of ways to get credits, including + more than{" "} + {totalRewardValue ? ( + + ) : ( + {__("?? credits")} + )}{" "} + {__( + " in rewards available for being a proven human during the LBRY beta." + )} +

+
+ ) : ( +
+

+ But you probably knew this, since you've already got{" "} + . +

+
+ )}
({ isPending: selectAuthenticationIsPending(state) || - selectUserIsPending(state) || - selectIdentityVerifyIsPending(state), + selectUserIsPending(state) || + selectIdentityVerifyIsPending(state), email: selectEmailToVerify(state), pathAfterAuth: selectPathAfterAuth(state), user: selectUser(state), diff --git a/ui/js/page/report.js b/ui/js/page/report.js index 321cc723e..9bb766aef 100644 --- a/ui/js/page/report.js +++ b/ui/js/page/report.js @@ -86,8 +86,7 @@ class ReportPage extends React.Component {

{__("Developer?")}

- {__("You can also")} - {" "} + {__("You can also")}{" "} dispatch(doUpdateDownloadProgress(Math.round(p * 100))), directory: dir, }; - download( - remote.getCurrentWindow(), - selectUpdateUrl(state), - options - ).then(downloadItem => { - /** + download(remote.getCurrentWindow(), selectUpdateUrl(state), options).then( + downloadItem => { + /** * TODO: get the download path directly from the download object. It should just be * downloadItem.getSavePath(), but the copy on the main process is being garbage collected * too soon. */ - dispatch({ - type: types.UPGRADE_DOWNLOAD_COMPLETED, - data: { - downloadItem, - path: path.join(dir, upgradeFilename), - }, - }); - }); + dispatch({ + type: types.UPGRADE_DOWNLOAD_COMPLETED, + data: { + downloadItem, + path: path.join(dir, upgradeFilename), + }, + }); + } + ); dispatch({ type: types.UPGRADE_DOWNLOAD_STARTED, @@ -129,15 +132,25 @@ export function doCancelUpgrade() { export function doCheckUpgradeAvailable() { return function(dispatch, getState) { const state = getState(); + dispatch({ + type: types.CHECK_UPGRADE_START, + }); - lbry.getAppVersionInfo().then(({ remoteVersion, upgradeAvailable }) => { - if (upgradeAvailable) { - dispatch({ - type: types.UPDATE_VERSION, - data: { - version: remoteVersion, - }, - }); + const success = ({ remoteVersion, upgradeAvailable }) => { + dispatch({ + type: types.CHECK_UPGRADE_SUCCESS, + data: { + upgradeAvailable, + remoteVersion, + }, + }); + + if ( + upgradeAvailable && + !selectCurrentModal(state) && + (!selectIsUpgradeSkipped(state) || + remoteVersion !== selectRemoteVersion(state)) + ) { dispatch({ type: types.OPEN_MODAL, data: { @@ -145,6 +158,30 @@ export function doCheckUpgradeAvailable() { }, }); } + }; + + const fail = () => { + dispatch({ + type: types.CHECK_UPGRADE_FAIL, + }); + }; + + lbry.getAppVersionInfo().then(success, fail); + }; +} + +/* + Initiate a timer that will check for an app upgrade every 10 minutes. + */ +export function doCheckUpgradeSubscribe() { + return function(dispatch) { + const checkUpgradeTimer = setInterval( + () => dispatch(doCheckUpgradeAvailable()), + CHECK_UPGRADE_INTERVAL + ); + dispatch({ + type: types.CHECK_UPGRADE_SUBSCRIBE, + data: { checkUpgradeTimer }, }); }; } @@ -153,9 +190,10 @@ export function doCheckDaemonVersion() { return function(dispatch, getState) { lbry.version().then(({ lbrynet_version }) => { dispatch({ - type: config.lbrynetDaemonVersion == lbrynet_version - ? types.DAEMON_VERSION_MATCH - : types.DAEMON_VERSION_MISMATCH, + type: + config.lbrynetDaemonVersion == lbrynet_version + ? types.DAEMON_VERSION_MATCH + : types.DAEMON_VERSION_MISMATCH, }); }); }; @@ -176,11 +214,18 @@ export function doAlertError(errorList) { export function doDaemonReady() { return function(dispatch, getState) { + const state = getState(); + dispatch(doAuthenticate()); dispatch({ type: types.DAEMON_READY }); dispatch(doFetchDaemonSettings()); dispatch(doBalanceSubscribe()); dispatch(doFetchFileInfosAndPublishedClaims()); + dispatch(doFetchRewardedContent()); + if (!selectIsUpgradeSkipped(state)) { + dispatch(doCheckUpgradeAvailable()); + } + dispatch(doCheckUpgradeSubscribe()); }; } diff --git a/ui/js/redux/actions/content.js b/ui/js/redux/actions/content.js index 886fb28d3..ab3b630a8 100644 --- a/ui/js/redux/actions/content.js +++ b/ui/js/redux/actions/content.js @@ -51,10 +51,10 @@ export function doResolveUris(uris) { certificate: null, }; - const { claim, certificate, claims_in_channel } = uriResolveInfo && - !uriResolveInfo.error - ? uriResolveInfo - : fallbackResolveInfo; + const { claim, certificate, claims_in_channel } = + uriResolveInfo && !uriResolveInfo.error + ? uriResolveInfo + : fallbackResolveInfo; resolveInfo[uri] = { claim, certificate, claims_in_channel }; } diff --git a/ui/js/redux/actions/cost_info.js b/ui/js/redux/actions/cost_info.js index 70a1a5a36..8420e3cd4 100644 --- a/ui/js/redux/actions/cost_info.js +++ b/ui/js/redux/actions/cost_info.js @@ -45,9 +45,10 @@ export function doFetchCostInfoForUri(uri) { }, reject); */ - const fee = claim.value && claim.value.stream && claim.value.stream.metadata - ? claim.value.stream.metadata.fee - : undefined; + const fee = + claim.value && claim.value.stream && claim.value.stream.metadata + ? claim.value.stream.metadata.fee + : undefined; if (fee === undefined) { resolve({ cost: 0, includesData: true }); diff --git a/ui/js/redux/actions/rewards.js b/ui/js/redux/actions/rewards.js index 9ebc3d715..3bdf140e8 100644 --- a/ui/js/redux/actions/rewards.js +++ b/ui/js/redux/actions/rewards.js @@ -93,12 +93,11 @@ export function doClaimEligiblePurchaseRewards() { if (rewardsByType[rewards.TYPE_FIRST_STREAM]) { dispatch(doClaimRewardType(rewards.TYPE_FIRST_STREAM)); } else { - [ - rewards.TYPE_MANY_DOWNLOADS, - rewards.TYPE_FEATURED_DOWNLOAD, - ].forEach(type => { - dispatch(doClaimRewardType(type)); - }); + [rewards.TYPE_MANY_DOWNLOADS, rewards.TYPE_FEATURED_DOWNLOAD].forEach( + type => { + dispatch(doClaimRewardType(type)); + } + ); } }; } diff --git a/ui/js/redux/reducers/app.js b/ui/js/redux/reducers/app.js index d7bc2cd6b..b44e84ccb 100644 --- a/ui/js/redux/reducers/app.js +++ b/ui/js/redux/reducers/app.js @@ -64,7 +64,7 @@ reducers[types.SKIP_UPGRADE] = function(state, action) { sessionStorage.setItem("upgradeSkipped", true); return Object.assign({}, state, { - upgradeSkipped: true, + isUpgradeSkipped: true, modal: null, }); }; @@ -75,6 +75,19 @@ reducers[types.UPDATE_VERSION] = function(state, action) { }); }; +reducers[types.CHECK_UPGRADE_SUCCESS] = function(state, action) { + return Object.assign({}, state, { + isUpgradeAvailable: action.data.upgradeAvailable, + remoteVersion: action.data.remoteVersion, + }); +}; + +reducers[types.CHECK_UPGRADE_SUBSCRIBE] = function(state, action) { + return Object.assign({}, state, { + checkUpgradeTimer: action.data.checkUpgradeTimer, + }); +}; + reducers[types.OPEN_MODAL] = function(state, action) { return Object.assign({}, state, { modal: action.data.modal, diff --git a/ui/js/redux/selectors/app.js b/ui/js/redux/selectors/app.js index c721916c0..24c2f2b95 100644 --- a/ui/js/redux/selectors/app.js +++ b/ui/js/redux/selectors/app.js @@ -20,13 +20,19 @@ export const selectUpdateUrl = createSelector(selectPlatform, platform => { } }); -export const selectVersion = createSelector(_selectState, state => { - return state.version; -}); +export const selectRemoteVersion = createSelector( + _selectState, + state => state.remoteVersion +); + +export const selectIsUpgradeAvailable = createSelector( + _selectState, + state => state.isUpgradeAvailable +); export const selectUpgradeFilename = createSelector( selectPlatform, - selectVersion, + selectRemoteVersion, (platform, version) => { switch (platform) { case "darwin": @@ -56,9 +62,9 @@ export const selectDownloadComplete = createSelector( state => state.upgradeDownloadCompleted ); -export const selectUpgradeSkipped = createSelector( +export const selectIsUpgradeSkipped = createSelector( _selectState, - state => state.upgradeSkipped + state => state.isUpgradeSkipped ); export const selectUpgradeDownloadPath = createSelector(