mirror of
https://github.com/LBRYFoundation/lbry-desktop.git
synced 2025-09-01 09:45:10 +00:00
Merge branch 'instant-purchase'
This commit is contained in:
commit
f7aec65912
7 changed files with 127 additions and 15 deletions
|
@ -8,7 +8,7 @@ Web UI version numbers should always match the corresponding version of LBRY App
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
*
|
* Add setting to automatically purchase low-cost content without a confirmation dialog
|
||||||
*
|
*
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import * as types from "constants/action_types";
|
import * as types from "constants/action_types";
|
||||||
|
import * as settings from "constants/settings";
|
||||||
import lbry from "lbry";
|
import lbry from "lbry";
|
||||||
import lbryio from "lbryio";
|
import lbryio from "lbryio";
|
||||||
import lbryuri from "lbryuri";
|
import lbryuri from "lbryuri";
|
||||||
|
@ -322,26 +323,55 @@ export function doPurchaseUri(uri) {
|
||||||
const downloadingByOutpoint = selectDownloadingByOutpoint(state);
|
const downloadingByOutpoint = selectDownloadingByOutpoint(state);
|
||||||
const alreadyDownloading =
|
const alreadyDownloading =
|
||||||
fileInfo && !!downloadingByOutpoint[fileInfo.outpoint];
|
fileInfo && !!downloadingByOutpoint[fileInfo.outpoint];
|
||||||
const costInfo = makeSelectCostInfoForUri(uri)(state);
|
|
||||||
const { cost } = costInfo;
|
|
||||||
|
|
||||||
if (
|
function attemptPlay(cost, instantPurchaseMax = null) {
|
||||||
alreadyDownloading ||
|
if (!instantPurchaseMax || cost > instantPurchaseMax) {
|
||||||
(fileInfo && fileInfo.completed && fileInfo.written_bytes > 0)
|
dispatch(doOpenModal(modals.AFFIRM_PURCHASE, { uri }));
|
||||||
) {
|
} else {
|
||||||
return;
|
dispatch(doLoadVideo(uri));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we already fully downloaded the file.
|
// we already fully downloaded the file.
|
||||||
if (
|
if (fileInfo && fileInfo.completed) {
|
||||||
cost === 0 ||
|
// If written_bytes is false that means the user has deleted/moved the
|
||||||
(fileInfo && (fileInfo.completed || fileInfo.download_directory))
|
// file manually on their file system, so we need to dispatch a
|
||||||
) {
|
// doLoadVideo action to reconstruct the file from the blobs
|
||||||
return dispatch(doLoadVideo(uri));
|
if (!fileInfo.written_bytes) dispatch(doLoadVideo(uri));
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we are already downloading the file
|
||||||
|
if (alreadyDownloading) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
const costInfo = makeSelectCostInfoForUri(uri)(state);
|
||||||
|
const { cost } = costInfo;
|
||||||
|
|
||||||
if (cost > balance) {
|
if (cost > balance) {
|
||||||
return dispatch(doOpenModal(modals.INSUFFICIENT_CREDITS));
|
dispatch(doOpenModal(modals.INSUFFICIENT_CREDITS));
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
cost == 0 ||
|
||||||
|
!lbry.getClientSetting(settings.INSTANT_PURCHASE_ENABLED)
|
||||||
|
) {
|
||||||
|
attemptPlay(cost);
|
||||||
|
} else {
|
||||||
|
const instantPurchaseMax = lbry.getClientSetting(
|
||||||
|
settings.INSTANT_PURCHASE_MAX
|
||||||
|
);
|
||||||
|
if (instantPurchaseMax.currency == "LBC") {
|
||||||
|
attemptPlay(cost, instantPurchaseMax.amount);
|
||||||
|
} else {
|
||||||
|
// Need to convert currency of instant purchase maximum before trying to play
|
||||||
|
lbryio.getExchangeRates().then(({ lbc_usd }) => {
|
||||||
|
attemptPlay(cost, instantPurchaseMax.amount / lbc_usd);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dispatch(doOpenModal(modals.AFFIRM_PURCHASE, { uri }));
|
return dispatch(doOpenModal(modals.AFFIRM_PURCHASE, { uri }));
|
||||||
|
|
|
@ -6,5 +6,7 @@ export const NEW_USER_ACKNOWLEDGED = "welcome_acknowledged";
|
||||||
export const LANGUAGE = "language";
|
export const LANGUAGE = "language";
|
||||||
export const SHOW_NSFW = "showNsfw";
|
export const SHOW_NSFW = "showNsfw";
|
||||||
export const SHOW_UNAVAILABLE = "showUnavailable";
|
export const SHOW_UNAVAILABLE = "showUnavailable";
|
||||||
|
export const INSTANT_PURCHASE_ENABLED = "instantPurchaseEnabled";
|
||||||
|
export const INSTANT_PURCHASE_MAX = "instantPurchaseMax";
|
||||||
export const THEME = "theme";
|
export const THEME = "theme";
|
||||||
export const THEMES = "themes";
|
export const THEMES = "themes";
|
||||||
|
|
|
@ -41,6 +41,9 @@ let lbry = {
|
||||||
language: "en",
|
language: "en",
|
||||||
theme: "light",
|
theme: "light",
|
||||||
themes: [],
|
themes: [],
|
||||||
|
instantPurchaseMax: null,
|
||||||
|
instantPurchaseEnabled: false,
|
||||||
|
instantPurchaseMax: { currency: "LBC", amount: 0.1 },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,13 @@ const select = state => ({
|
||||||
daemonSettings: selectDaemonSettings(state),
|
daemonSettings: selectDaemonSettings(state),
|
||||||
showNsfw: makeSelectClientSetting(settings.SHOW_NSFW)(state),
|
showNsfw: makeSelectClientSetting(settings.SHOW_NSFW)(state),
|
||||||
showUnavailable: makeSelectClientSetting(settings.SHOW_UNAVAILABLE)(state),
|
showUnavailable: makeSelectClientSetting(settings.SHOW_UNAVAILABLE)(state),
|
||||||
|
instantPurchaseEnabled: makeSelectClientSetting(
|
||||||
|
settings.INSTANT_PURCHASE_ENABLED
|
||||||
|
)(state),
|
||||||
|
instantPurchaseMax: makeSelectClientSetting(settings.INSTANT_PURCHASE_MAX)(
|
||||||
|
state
|
||||||
|
),
|
||||||
|
showUnavailable: makeSelectClientSetting(settings.SHOW_UNAVAILABLE)(state),
|
||||||
theme: makeSelectClientSetting(settings.THEME)(state),
|
theme: makeSelectClientSetting(settings.THEME)(state),
|
||||||
themes: makeSelectClientSetting(settings.THEMES)(state),
|
themes: makeSelectClientSetting(settings.THEMES)(state),
|
||||||
language: selectCurrentLanguage(state),
|
language: selectCurrentLanguage(state),
|
||||||
|
|
|
@ -13,6 +13,8 @@ class SettingsPage extends React.PureComponent {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
|
instantPurchaseEnabled: props.instantPurchaseEnabled,
|
||||||
|
instantPurchaseMax: props.instantPurchaseMax,
|
||||||
clearingCache: false,
|
clearingCache: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -59,6 +61,22 @@ class SettingsPage extends React.PureComponent {
|
||||||
this.props.setClientSetting(settings.THEME, value);
|
this.props.setClientSetting(settings.THEME, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oninstantPurchaseEnabledChange(enabled) {
|
||||||
|
this.props.setClientSetting(settings.INSTANT_PURCHASE_ENABLED, enabled);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
instantPurchaseEnabled: enabled,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onInstantPurchaseMaxChange(newValue) {
|
||||||
|
this.props.setClientSetting(settings.INSTANT_PURCHASE_MAX, newValue);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
instantPurchaseMax: newValue,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// onMaxUploadPrefChange(isLimited) {
|
// onMaxUploadPrefChange(isLimited) {
|
||||||
// if (!isLimited) {
|
// if (!isLimited) {
|
||||||
// this.setDaemonSetting("max_upload", 0.0);
|
// this.setDaemonSetting("max_upload", 0.0);
|
||||||
|
@ -113,6 +131,8 @@ class SettingsPage extends React.PureComponent {
|
||||||
language,
|
language,
|
||||||
languages,
|
languages,
|
||||||
showNsfw,
|
showNsfw,
|
||||||
|
instantPurchaseEnabled,
|
||||||
|
instantPurchaseMax,
|
||||||
showUnavailable,
|
showUnavailable,
|
||||||
theme,
|
theme,
|
||||||
themes,
|
themes,
|
||||||
|
@ -167,9 +187,14 @@ class SettingsPage extends React.PureComponent {
|
||||||
</section>
|
</section>
|
||||||
<section className="card">
|
<section className="card">
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
<h3>{__("Max Purchase Price")}</h3>
|
<h3>{__("Purchase Settings")}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
|
<div className="form-row__label-row">
|
||||||
|
<label className="form-row__label">
|
||||||
|
{__("Max Purchase Price")}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<FormRow
|
<FormRow
|
||||||
type="radio"
|
type="radio"
|
||||||
name="max_key_fee"
|
name="max_key_fee"
|
||||||
|
@ -211,6 +236,47 @@ class SettingsPage extends React.PureComponent {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="card__content">
|
||||||
|
<div className="form-row__label-row">
|
||||||
|
<label className="form-row__label">
|
||||||
|
{__("Purchase Confirmations")}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<FormRow
|
||||||
|
type="radio"
|
||||||
|
name="instant_purchase_max"
|
||||||
|
checked={!this.state.instantPurchaseEnabled}
|
||||||
|
label={__("Ask for confirmation of all purchases")}
|
||||||
|
onClick={e => {
|
||||||
|
this.oninstantPurchaseEnabledChange(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="form-row">
|
||||||
|
<FormField
|
||||||
|
type="radio"
|
||||||
|
name="instant_purchase_max"
|
||||||
|
checked={this.state.instantPurchaseEnabled}
|
||||||
|
label={
|
||||||
|
"Single-click purchasing of content less than" +
|
||||||
|
(this.state.instantPurchaseEnabled ? "" : "...")
|
||||||
|
}
|
||||||
|
onClick={e => {
|
||||||
|
this.oninstantPurchaseEnabledChange(true);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{this.state.instantPurchaseEnabled &&
|
||||||
|
<FormFieldPrice
|
||||||
|
min="0.1"
|
||||||
|
step="0.1"
|
||||||
|
onChange={val => this.onInstantPurchaseMaxChange(val)}
|
||||||
|
defaultValue={this.state.instantPurchaseMax}
|
||||||
|
/>}
|
||||||
|
</div>
|
||||||
|
<div className="form-field__helper">
|
||||||
|
When this option is chosen, LBRY won't ask you to confirm
|
||||||
|
downloads below the given price.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="card">
|
<section className="card">
|
||||||
|
|
|
@ -6,6 +6,10 @@ import lbry from "lbry";
|
||||||
const reducers = {};
|
const reducers = {};
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
clientSettings: {
|
clientSettings: {
|
||||||
|
instantPurchaseEnabled: lbry.getClientSetting(
|
||||||
|
settings.INSTANT_PURCHASE_ENABLED
|
||||||
|
),
|
||||||
|
instantPurchaseMax: lbry.getClientSetting(settings.INSTANT_PURCHASE_MAX),
|
||||||
showNsfw: lbry.getClientSetting(settings.SHOW_NSFW),
|
showNsfw: lbry.getClientSetting(settings.SHOW_NSFW),
|
||||||
showUnavailable: lbry.getClientSetting(settings.SHOW_UNAVAILABLE),
|
showUnavailable: lbry.getClientSetting(settings.SHOW_UNAVAILABLE),
|
||||||
welcome_acknowledged: lbry.getClientSetting(settings.NEW_USER_ACKNOWLEDGED),
|
welcome_acknowledged: lbry.getClientSetting(settings.NEW_USER_ACKNOWLEDGED),
|
||||||
|
|
Loading…
Add table
Reference in a new issue