(WIP) Tip as support Functionality Only.
This commit is contained in:
parent
4d60f96b85
commit
03ee864af0
9 changed files with 179 additions and 84 deletions
76
ui/js/actions/claims.js
Normal file
76
ui/js/actions/claims.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
import lbry from "lbry";
|
||||
import { selectBalance } from "selectors/wallet";
|
||||
import {
|
||||
selectSupportTransaction,
|
||||
selectSupportTransactionAmount,
|
||||
} from "selectors/claims";
|
||||
import { doOpenModal, doShowSnackBar } from "actions/app";
|
||||
import * as types from "constants/action_types";
|
||||
import * as modals from "constants/modal_types";
|
||||
|
||||
export function doSendSupport() {
|
||||
return function(dispatch, getState) {
|
||||
const state = getState();
|
||||
const supportTx = selectSupportTransaction(state);
|
||||
const balance = selectBalance(state);
|
||||
const amount = selectSupportTransactionAmount(state);
|
||||
|
||||
if (balance - amount < 1) {
|
||||
return dispatch(doOpenModal(modals.INSUFFICIENT_BALANCE));
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: types.SUPPORT_TRANSACTION_STARTED,
|
||||
});
|
||||
|
||||
const successCallback = results => {
|
||||
if (results.txid) {
|
||||
dispatch({
|
||||
type: types.SUPPORT_TRANSACTION_COMPLETED,
|
||||
});
|
||||
dispatch(
|
||||
doShowSnackBar({
|
||||
message: __(`You sent ${amount} LBC as support, Mahalo!`),
|
||||
linkText: __("History"),
|
||||
linkTarget: __("/wallet"),
|
||||
})
|
||||
);
|
||||
} else {
|
||||
dispatch({
|
||||
type: types.SUPPORT_TRANSACTION_FAILED,
|
||||
data: { error: results },
|
||||
});
|
||||
dispatch(doOpenModal(modals.TRANSACTION_FAILED));
|
||||
}
|
||||
};
|
||||
|
||||
const errorCallback = error => {
|
||||
dispatch({
|
||||
type: types.SUPPORT_TRANSACTION_FAILED,
|
||||
data: { error: error.message },
|
||||
});
|
||||
dispatch(doOpenModal(modals.TRANSACTION_FAILED));
|
||||
};
|
||||
|
||||
lbry
|
||||
.claim_send_tip({
|
||||
claim_id: supportTx.claim_id,
|
||||
amount: supportTx.amount,
|
||||
})
|
||||
.then(successCallback, errorCallback);
|
||||
};
|
||||
}
|
||||
|
||||
export function doSetSupportAmount(amount) {
|
||||
return {
|
||||
type: types.SET_SUPPORT_AMOUNT,
|
||||
data: { amount },
|
||||
};
|
||||
}
|
||||
|
||||
export function doSetSupportClaimID(claim_id) {
|
||||
return {
|
||||
type: types.SET_SUPPORT_CLAIMID,
|
||||
data: { claim_id },
|
||||
};
|
||||
}
|
|
@ -187,7 +187,7 @@ class FileActions extends React.PureComponent {
|
|||
onTipShow={this.handleTipShow.bind(this)}
|
||||
onTipHide={this.handleTipHide.bind(this)}
|
||||
showTipBox={showTipBox}
|
||||
address={claimInfo.address}
|
||||
claim_id={claimInfo.claim_id}
|
||||
/>
|
||||
{showMenu && !showTipBox
|
||||
? <DropDownMenu>
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import PriceForm from "./view";
|
||||
|
||||
export default connect(null, null)(PriceForm);
|
|
@ -1,40 +0,0 @@
|
|||
import React from "react";
|
||||
import { FormField } from "component/form";
|
||||
|
||||
const PriceForm = props => {
|
||||
const {
|
||||
onFeeChange,
|
||||
onCurrencyChange,
|
||||
defaultFeeValue,
|
||||
defaultCurrencyValue,
|
||||
placeholder,
|
||||
min,
|
||||
step,
|
||||
isTip,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<span className={"form-field " + (isTip ? "form-field--tip " : " ")}>
|
||||
<FormField
|
||||
type="number"
|
||||
min={min}
|
||||
placeholder={placeholder || null}
|
||||
step={step}
|
||||
onChange={onFeeChange}
|
||||
defaultValue={defaultFeeValue}
|
||||
className="form-field__input--inline"
|
||||
/>
|
||||
<FormField
|
||||
type="select"
|
||||
onChange={onCurrencyChange}
|
||||
defaultValue={defaultCurrencyValue}
|
||||
className="form-field__input--inline"
|
||||
>
|
||||
<option value="LBC">{__("LBRY credits")}</option>
|
||||
<option value="USD">{__("US Dollars")}</option>
|
||||
</FormField>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default PriceForm;
|
|
@ -1,18 +1,18 @@
|
|||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import {
|
||||
doSendDraftTransaction,
|
||||
doSetDraftTransactionAmount,
|
||||
doSetDraftTransactionAddress,
|
||||
} from "actions/wallet";
|
||||
doSendSupport,
|
||||
doSetSupportAmount,
|
||||
doSetSupportClaimID,
|
||||
} from "actions/claims";
|
||||
import TipLink from "./view";
|
||||
|
||||
const select = state => ({});
|
||||
|
||||
const perform = dispatch => ({
|
||||
sendToAddress: () => dispatch(doSendDraftTransaction()),
|
||||
setAmount: amount => dispatch(doSetDraftTransactionAmount(amount)),
|
||||
setAddress: address => dispatch(doSetDraftTransactionAddress(address)),
|
||||
sendSupport: () => dispatch(doSendSupport()),
|
||||
setAmount: amount => dispatch(doSetSupportAmount(amount)),
|
||||
setClaimID: claim_id => dispatch(doSetSupportClaimID(claim_id)),
|
||||
});
|
||||
|
||||
export default connect(select, perform)(TipLink);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React from "react";
|
||||
import Link from "component/link";
|
||||
import { FormField } from "component/form";
|
||||
import PriceForm from "component/priceForm";
|
||||
import FormFieldPrice from "component/formFieldPrice";
|
||||
|
||||
class TipLink extends React.PureComponent {
|
||||
constructor(props) {
|
||||
|
@ -13,35 +12,30 @@ class TipLink extends React.PureComponent {
|
|||
};
|
||||
}
|
||||
|
||||
handleTipPublisherButtonClicked() {
|
||||
handleSupportButtonClicked() {
|
||||
this.resetDefaults();
|
||||
this.props.onTipShow();
|
||||
}
|
||||
|
||||
handleTipButtonClicked() {
|
||||
let address = this.props.address;
|
||||
handleSendButtonClicked() {
|
||||
let claim_id = this.props.claim_id;
|
||||
let amount = this.state.feeAmount;
|
||||
|
||||
this.props.setAddress(address);
|
||||
this.props.setClaimID(claim_id);
|
||||
this.props.setAmount(amount);
|
||||
this.props.sendToAddress();
|
||||
this.props.sendSupport();
|
||||
|
||||
this.props.onTipHide();
|
||||
}
|
||||
|
||||
handleTipCancelButtonClicked() {
|
||||
handleSupportCancelButtonClicked() {
|
||||
this.props.onTipHide();
|
||||
}
|
||||
|
||||
handleFeeAmountChange(event) {
|
||||
handleSupportPriceChange(newValue) {
|
||||
this.setState({
|
||||
feeAmount: event.target.value,
|
||||
});
|
||||
}
|
||||
|
||||
handleCurrencyChange(event) {
|
||||
this.setState({
|
||||
currency: event.target.value,
|
||||
feeAmount: newValue.amount,
|
||||
feeCurrency: newValue.currency,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -54,37 +48,35 @@ class TipLink extends React.PureComponent {
|
|||
|
||||
render() {
|
||||
const { showTipBox } = this.props;
|
||||
const { feeAmount, currency } = this.state;
|
||||
|
||||
let tipLink = (
|
||||
<Link
|
||||
label={__("Tip")}
|
||||
label={__("Support")}
|
||||
button="text"
|
||||
icon="icon-gift"
|
||||
onClick={this.handleTipPublisherButtonClicked.bind(this)}
|
||||
onClick={this.handleSupportButtonClicked.bind(this)}
|
||||
/>
|
||||
);
|
||||
|
||||
let tipBox = (
|
||||
<span>
|
||||
<PriceForm
|
||||
isTip={true}
|
||||
min="0.01"
|
||||
<FormFieldPrice
|
||||
min="0"
|
||||
placeholder="1.00"
|
||||
step="0.1"
|
||||
onFeeChange={event => this.handleFeeAmountChange(event)}
|
||||
defaultFeeValue={this.state.feeAmount}
|
||||
onCurrencyChange={event => this.handleCurrencyChange(event)}
|
||||
defaultCurrencyValue="LBC"
|
||||
onChange={value => this.handleSupportPriceChange(value)}
|
||||
defaultValue={{ amount: feeAmount, currency: currency }}
|
||||
/>
|
||||
<Link
|
||||
label={__("Tip")}
|
||||
label={__("Send")}
|
||||
button="primary"
|
||||
onClick={this.handleTipButtonClicked.bind(this)}
|
||||
onClick={this.handleSendButtonClicked.bind(this)}
|
||||
/>
|
||||
<Link
|
||||
label={__("Cancel")}
|
||||
button="alt"
|
||||
onClick={this.handleTipCancelButtonClicked.bind(this)}
|
||||
onClick={this.handleSupportCancelButtonClicked.bind(this)}
|
||||
/>
|
||||
<div className="form-field__helper">
|
||||
{__("This sends the entered amount of LBCs to the publisher.")}
|
||||
|
|
|
@ -112,5 +112,11 @@ export const CLAIM_REWARD_STARTED = "CLAIM_REWARD_STARTED";
|
|||
export const CLAIM_REWARD_SUCCESS = "CLAIM_REWARD_SUCCESS";
|
||||
export const CLAIM_REWARD_FAILURE = "CLAIM_REWARD_FAILURE";
|
||||
export const CLAIM_REWARD_CLEAR_ERROR = "CLAIM_REWARD_CLEAR_ERROR";
|
||||
export const FETCH_REWARD_CONTENT_COMPLETED =
|
||||
"FETCH_REWARD_CONTENT_COMPLETED";
|
||||
export const FETCH_REWARD_CONTENT_COMPLETED = "FETCH_REWARD_CONTENT_COMPLETED";
|
||||
|
||||
// Supports
|
||||
export const SET_SUPPORT_CLAIMID = "SET_SUPPORT_CLAIMID";
|
||||
export const SET_SUPPORT_AMOUNT = "SET_SUPPORT_AMOUNT";
|
||||
export const SUPPORT_TRANSACTION_STARTED = "SUPPORT_TRANSACTION_STARTED";
|
||||
export const SUPPORT_TRANSACTION_COMPLETED = "SUPPORT_TRANSACTION_COMPLETED";
|
||||
export const SUPPORT_TRANSACTION_FAILED = "SUPPORT_TRANSACTION_FAILED";
|
||||
|
|
|
@ -2,7 +2,14 @@ import * as types from "constants/action_types";
|
|||
import lbryuri from "lbryuri";
|
||||
|
||||
const reducers = {};
|
||||
const defaultState = {};
|
||||
const buildSupportTransaction = () => ({
|
||||
claim_id: undefined,
|
||||
amount: undefined,
|
||||
});
|
||||
|
||||
const defaultState = {
|
||||
supportTransaction: buildSupportTransaction(),
|
||||
};
|
||||
|
||||
reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) {
|
||||
const { uri, certificate, claim } = action.data;
|
||||
|
@ -190,6 +197,55 @@ reducers[types.CREATE_CHANNEL_COMPLETED] = function(state, action) {
|
|||
});
|
||||
};
|
||||
|
||||
reducers[types.SET_SUPPORT_AMOUNT] = function(state, action) {
|
||||
const oldDraft = state.supportTransaction;
|
||||
const newDraft = Object.assign({}, oldDraft, {
|
||||
amount: parseFloat(action.data.amount),
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
supportTransaction: newDraft,
|
||||
});
|
||||
};
|
||||
|
||||
reducers[types.SET_SUPPORT_CLAIMID] = function(state, action) {
|
||||
const oldDraft = state.supportTransaction;
|
||||
const newDraft = Object.assign({}, oldDraft, {
|
||||
claim_id: action.data.claim_id,
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
supportTransaction: newDraft,
|
||||
});
|
||||
};
|
||||
|
||||
reducers[types.SUPPORT_TRANSACTION_STARTED] = function(state, action) {
|
||||
const newSupportTransaction = Object.assign({}, state.supportTransaction, {
|
||||
sendingSupport: true,
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
supportTransaction: newSupportTransaction,
|
||||
});
|
||||
};
|
||||
|
||||
reducers[types.SUPPORT_TRANSACTION_COMPLETED] = function(state, action) {
|
||||
return Object.assign({}, state, {
|
||||
supportTransaction: buildSupportTransaction(),
|
||||
});
|
||||
};
|
||||
|
||||
reducers[types.SUPPORT_TRANSACTION_FAILED] = function(state, action) {
|
||||
const newSupportTransaction = Object.assign({}, state.supportTransaction, {
|
||||
sendingSupport: false,
|
||||
error: action.data.error,
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
supportTransaction: newSupportTransaction,
|
||||
});
|
||||
};
|
||||
|
||||
export default function reducer(state = defaultState, action) {
|
||||
const handler = reducers[action.type];
|
||||
if (handler) return handler(state, action);
|
||||
|
|
|
@ -215,3 +215,13 @@ export const selectMyChannelClaims = createSelector(
|
|||
return claims;
|
||||
}
|
||||
);
|
||||
|
||||
export const selectSupportTransaction = createSelector(
|
||||
_selectState,
|
||||
state => state.supportTransaction || {}
|
||||
);
|
||||
|
||||
export const selectSupportTransactionAmount = createSelector(
|
||||
selectSupportTransaction,
|
||||
supportTxAmount => supportTxAmount.amount
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue