Revoke claims from Txn list

This commit is contained in:
hackrush 2017-10-24 18:40:27 +05:30
parent c8cc05b685
commit 74c4e1efa3
8 changed files with 134 additions and 16 deletions

View file

@ -505,3 +505,34 @@ export function doPublish(params) {
});
};
}
export function doAbandonClaim(claimId, txid, nout) {
return function(dispatch, getState) {
const state = getState();
dispatch({
type: types.ABANDON_CLAIM_STARTED,
data: {
claimId: claimId,
txid: txid,
nout: nout,
},
});
const success = dispatch({
type: types.ABANDON_CLAIM_SUCCEEDED,
data: {
claimId: claimId,
txid: txid,
nout: nout,
},
});
lbry
.claim_abandon({
txid: txid,
nout: nout,
})
.then(success);
};
}

View file

@ -102,10 +102,15 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) {
const fileInfo = byOutpoint[outpoint];
if (fileInfo) {
txid = fileInfo.outpoint.slice(0, -2);
nout = fileInfo.outpoint.slice(-1);
dispatch({
type: types.ABANDON_CLAIM_STARTED,
data: {
claimId: fileInfo.claim_id,
txid: txid,
nout: nout,
},
});
@ -113,9 +118,16 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) {
type: types.ABANDON_CLAIM_SUCCEEDED,
data: {
claimId: fileInfo.claim_id,
txid: txid,
nout: nout,
},
});
lbry.claim_abandon({ claim_id: fileInfo.claim_id }).then(success);
lbry
.claim_abandon({
txid: txid,
nout: nout,
})
.then(success);
}
}

View file

@ -1,15 +1,23 @@
import React from "react";
import { connect } from "react-redux";
import { doNavigate } from "actions/navigation";
import { doAbandonClaim, doResolveUri } from "actions/content";
import { selectClaimedRewardsByTransactionId } from "selectors/rewards";
import { selectAllMyClaimsByTxidNout } from "selectors/claims";
import { selectResolvingUris } from "selectors/content";
import TransactionList from "./view";
const select = state => ({
rewards: selectClaimedRewardsByTransactionId(state),
myClaims: selectAllMyClaimsByTxidNout(state),
resolvingUris: selectResolvingUris(state),
});
const perform = dispatch => ({
navigate: (path, params) => dispatch(doNavigate(path, params)),
resolveUri: uri => dispatch(doResolveUri(uri)),
abandonClaim: (claimId, txid, nout) =>
dispatch(doAbandonClaim(claimId, txid, nout)),
});
export default connect(null, perform)(TransactionList);
export default connect(select, perform)(TransactionList);

View file

@ -6,8 +6,12 @@ import Link from "component/link";
import lbryuri from "lbryuri";
class TransactionListItem extends React.PureComponent {
abandonClaim(abandonData) {
this.props.revokeClaim(abandonData);
}
render() {
const { reward, transaction } = this.props;
const { reward, transaction, isRevokeable } = this.props;
const {
amount,
claim_id: claimId,
@ -16,8 +20,16 @@ class TransactionListItem extends React.PureComponent {
fee,
txid,
type,
nout,
} = transaction;
const abandonData = {
name: name,
claimId: claimId,
txid: txid,
nout: nout,
};
const dateFormat = {
month: "short",
day: "numeric",
@ -80,6 +92,12 @@ class TransactionListItem extends React.PureComponent {
<td>
<LinkTransaction id={txid} />
</td>
<td>
{isRevokeable &&
<Link onClick={() => this.abandonClaim(abandonData)}>
{__("Revoke")}
</Link>}
</td>
</tr>
);
}

View file

@ -1,6 +1,7 @@
import React from "react";
import TransactionListItem from "./internal/TransactionListItem";
import FormField from "component/formField";
import lbryuri from "lbryuri";
class TransactionList extends React.PureComponent {
constructor(props) {
@ -23,6 +24,27 @@ class TransactionList extends React.PureComponent {
return !filter || filter == transaction.type;
}
isRevokeable(txid, nout) {
// a claim/support/update is revokable if it
// is in my claim list(claim_list_mine)
return this.props.myClaims.has(`${txid}:${nout}`);
}
revokeClaim(abandonData) {
const {
name: name,
claimId: claimId,
txid: txid,
nout: nout,
} = abandonData;
const uri = lbryuri.build({ name, claimId });
this.props.resolveUri(uri);
if (!this.props.resolvingUris.includes(uri)) {
this.props.abandonClaim(claimId, txid, nout);
}
}
render() {
const { emptyMessage, rewards, transactions } = this.props;
@ -62,6 +84,7 @@ class TransactionList extends React.PureComponent {
<th>{__("Type")} </th>
<th>{__("Details")} </th>
<th>{__("Transaction")}</th>
<th>{__("Action")}</th>
</tr>
</thead>
<tbody>
@ -70,6 +93,8 @@ class TransactionList extends React.PureComponent {
key={`${t.txid}:${t.nout}`}
transaction={t}
reward={rewards && rewards[t.txid]}
isRevokeable={this.isRevokeable(t.txid, t.nout)}
revokeClaim={this.revokeClaim.bind(this)}
/>
)}
</tbody>

View file

@ -45,6 +45,9 @@ reducers[types.FETCH_CLAIM_LIST_MINE_COMPLETED] = function(state, action) {
const byId = Object.assign({}, state.byId);
const pendingById = Object.assign({}, state.pendingById);
const abandoningById = Object.assign({}, state.abandoningById);
const allMyClaimsByTxidNout = new Set(
claims.map(claim => `${claim.txid}:${claim.nout}`)
);
const myClaims = new Set(
claims
.map(claim => claim.claim_id)
@ -78,6 +81,7 @@ reducers[types.FETCH_CLAIM_LIST_MINE_COMPLETED] = function(state, action) {
return Object.assign({}, state, {
isFetchingClaimListMine: false,
myClaims: myClaims,
allMyClaimsByTxidNout: allMyClaimsByTxidNout,
byId,
pendingById,
});
@ -157,21 +161,35 @@ reducers[types.ABANDON_CLAIM_STARTED] = function(state, action) {
};
reducers[types.ABANDON_CLAIM_SUCCEEDED] = function(state, action) {
const { claimId } = action.data;
const { claimId, txid, nout } = action.data;
const myClaims = new Set(state.myClaims);
const byId = Object.assign({}, state.byId);
const claimsByUri = Object.assign({}, state.claimsByUri);
const supports = byId[claimId].supports;
const uris = [];
Object.keys(claimsByUri).forEach(uri => {
if (claimsByUri[uri] === claimId) {
delete claimsByUri[uri];
}
});
// This logic is needed when a claim has supports
// and it is the support that is being abandoned
// so we need to remove the support from the state
// but this is not working, even after calling resolve on the uri.
if (supports && supports.length > 0) {
indexToDelete = supports.findIndex(support => {
return support.txid === txid && support.nout === nout;
});
delete byId[claimId];
myClaims.delete(claimId);
supports.splice[(indexToDelete, 1)];
}
if (!supports || supports.length == 0) {
Object.keys(claimsByUri).forEach(uri => {
if (claimsByUri[uri] === claimId) {
delete claimsByUri[uri];
}
});
delete byId[claimId];
myClaims.delete(claimId);
}
return Object.assign({}, state, {
myClaims,
byId,

View file

@ -157,6 +157,11 @@ export const selectMyClaimsWithoutChannels = createSelector(
myClaims => myClaims.filter(claim => !claim.name.match(/^@/))
);
export const selectAllMyClaimsByTxidNout = createSelector(
_selectState,
state => state.allMyClaimsByTxidNout || {}
);
export const selectMyClaimsOutpoints = createSelector(
selectMyClaims,
myClaims => {

View file

@ -62,9 +62,10 @@ table.table-stretch {
}
table.table-transactions {
td:nth-of-type(1) { width: 15%; }
td:nth-of-type(2) { width: 15%; }
td:nth-of-type(3) { width: 15%; }
td:nth-of-type(4) { width: 40%; }
td:nth-of-type(5) { width: 15%; }
td:nth-of-type(1) { width: 13%; }
td:nth-of-type(2) { width: 13%; }
td:nth-of-type(3) { width: 13%; }
td:nth-of-type(4) { width: 35%; }
td:nth-of-type(5) { width: 13%; }
td:nth-of-type(6) { width: 13%; }
}