Revoke claims from Txn list
This commit is contained in:
parent
c8cc05b685
commit
74c4e1efa3
8 changed files with 134 additions and 16 deletions
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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%; }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue