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];
|
const fileInfo = byOutpoint[outpoint];
|
||||||
|
|
||||||
if (fileInfo) {
|
if (fileInfo) {
|
||||||
|
txid = fileInfo.outpoint.slice(0, -2);
|
||||||
|
nout = fileInfo.outpoint.slice(-1);
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.ABANDON_CLAIM_STARTED,
|
type: types.ABANDON_CLAIM_STARTED,
|
||||||
data: {
|
data: {
|
||||||
claimId: fileInfo.claim_id,
|
claimId: fileInfo.claim_id,
|
||||||
|
txid: txid,
|
||||||
|
nout: nout,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -113,9 +118,16 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) {
|
||||||
type: types.ABANDON_CLAIM_SUCCEEDED,
|
type: types.ABANDON_CLAIM_SUCCEEDED,
|
||||||
data: {
|
data: {
|
||||||
claimId: fileInfo.claim_id,
|
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 React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doNavigate } from "actions/navigation";
|
import { doNavigate } from "actions/navigation";
|
||||||
|
import { doAbandonClaim, doResolveUri } from "actions/content";
|
||||||
import { selectClaimedRewardsByTransactionId } from "selectors/rewards";
|
import { selectClaimedRewardsByTransactionId } from "selectors/rewards";
|
||||||
|
import { selectAllMyClaimsByTxidNout } from "selectors/claims";
|
||||||
|
import { selectResolvingUris } from "selectors/content";
|
||||||
import TransactionList from "./view";
|
import TransactionList from "./view";
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
rewards: selectClaimedRewardsByTransactionId(state),
|
rewards: selectClaimedRewardsByTransactionId(state),
|
||||||
|
myClaims: selectAllMyClaimsByTxidNout(state),
|
||||||
|
resolvingUris: selectResolvingUris(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
navigate: (path, params) => dispatch(doNavigate(path, params)),
|
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";
|
import lbryuri from "lbryuri";
|
||||||
|
|
||||||
class TransactionListItem extends React.PureComponent {
|
class TransactionListItem extends React.PureComponent {
|
||||||
|
abandonClaim(abandonData) {
|
||||||
|
this.props.revokeClaim(abandonData);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { reward, transaction } = this.props;
|
const { reward, transaction, isRevokeable } = this.props;
|
||||||
const {
|
const {
|
||||||
amount,
|
amount,
|
||||||
claim_id: claimId,
|
claim_id: claimId,
|
||||||
|
@ -16,8 +20,16 @@ class TransactionListItem extends React.PureComponent {
|
||||||
fee,
|
fee,
|
||||||
txid,
|
txid,
|
||||||
type,
|
type,
|
||||||
|
nout,
|
||||||
} = transaction;
|
} = transaction;
|
||||||
|
|
||||||
|
const abandonData = {
|
||||||
|
name: name,
|
||||||
|
claimId: claimId,
|
||||||
|
txid: txid,
|
||||||
|
nout: nout,
|
||||||
|
};
|
||||||
|
|
||||||
const dateFormat = {
|
const dateFormat = {
|
||||||
month: "short",
|
month: "short",
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
|
@ -80,6 +92,12 @@ class TransactionListItem extends React.PureComponent {
|
||||||
<td>
|
<td>
|
||||||
<LinkTransaction id={txid} />
|
<LinkTransaction id={txid} />
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{isRevokeable &&
|
||||||
|
<Link onClick={() => this.abandonClaim(abandonData)}>
|
||||||
|
{__("Revoke")}
|
||||||
|
</Link>}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import TransactionListItem from "./internal/TransactionListItem";
|
import TransactionListItem from "./internal/TransactionListItem";
|
||||||
import FormField from "component/formField";
|
import FormField from "component/formField";
|
||||||
|
import lbryuri from "lbryuri";
|
||||||
|
|
||||||
class TransactionList extends React.PureComponent {
|
class TransactionList extends React.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -23,6 +24,27 @@ class TransactionList extends React.PureComponent {
|
||||||
return !filter || filter == transaction.type;
|
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() {
|
render() {
|
||||||
const { emptyMessage, rewards, transactions } = this.props;
|
const { emptyMessage, rewards, transactions } = this.props;
|
||||||
|
|
||||||
|
@ -62,6 +84,7 @@ class TransactionList extends React.PureComponent {
|
||||||
<th>{__("Type")} </th>
|
<th>{__("Type")} </th>
|
||||||
<th>{__("Details")} </th>
|
<th>{__("Details")} </th>
|
||||||
<th>{__("Transaction")}</th>
|
<th>{__("Transaction")}</th>
|
||||||
|
<th>{__("Action")}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -70,6 +93,8 @@ class TransactionList extends React.PureComponent {
|
||||||
key={`${t.txid}:${t.nout}`}
|
key={`${t.txid}:${t.nout}`}
|
||||||
transaction={t}
|
transaction={t}
|
||||||
reward={rewards && rewards[t.txid]}
|
reward={rewards && rewards[t.txid]}
|
||||||
|
isRevokeable={this.isRevokeable(t.txid, t.nout)}
|
||||||
|
revokeClaim={this.revokeClaim.bind(this)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -45,6 +45,9 @@ reducers[types.FETCH_CLAIM_LIST_MINE_COMPLETED] = function(state, action) {
|
||||||
const byId = Object.assign({}, state.byId);
|
const byId = Object.assign({}, state.byId);
|
||||||
const pendingById = Object.assign({}, state.pendingById);
|
const pendingById = Object.assign({}, state.pendingById);
|
||||||
const abandoningById = Object.assign({}, state.abandoningById);
|
const abandoningById = Object.assign({}, state.abandoningById);
|
||||||
|
const allMyClaimsByTxidNout = new Set(
|
||||||
|
claims.map(claim => `${claim.txid}:${claim.nout}`)
|
||||||
|
);
|
||||||
const myClaims = new Set(
|
const myClaims = new Set(
|
||||||
claims
|
claims
|
||||||
.map(claim => claim.claim_id)
|
.map(claim => claim.claim_id)
|
||||||
|
@ -78,6 +81,7 @@ reducers[types.FETCH_CLAIM_LIST_MINE_COMPLETED] = function(state, action) {
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
isFetchingClaimListMine: false,
|
isFetchingClaimListMine: false,
|
||||||
myClaims: myClaims,
|
myClaims: myClaims,
|
||||||
|
allMyClaimsByTxidNout: allMyClaimsByTxidNout,
|
||||||
byId,
|
byId,
|
||||||
pendingById,
|
pendingById,
|
||||||
});
|
});
|
||||||
|
@ -157,21 +161,35 @@ reducers[types.ABANDON_CLAIM_STARTED] = function(state, action) {
|
||||||
};
|
};
|
||||||
|
|
||||||
reducers[types.ABANDON_CLAIM_SUCCEEDED] = 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 myClaims = new Set(state.myClaims);
|
||||||
const byId = Object.assign({}, state.byId);
|
const byId = Object.assign({}, state.byId);
|
||||||
const claimsByUri = Object.assign({}, state.claimsByUri);
|
const claimsByUri = Object.assign({}, state.claimsByUri);
|
||||||
|
const supports = byId[claimId].supports;
|
||||||
const uris = [];
|
const uris = [];
|
||||||
|
|
||||||
Object.keys(claimsByUri).forEach(uri => {
|
// This logic is needed when a claim has supports
|
||||||
if (claimsByUri[uri] === claimId) {
|
// and it is the support that is being abandoned
|
||||||
delete claimsByUri[uri];
|
// 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];
|
supports.splice[(indexToDelete, 1)];
|
||||||
myClaims.delete(claimId);
|
}
|
||||||
|
|
||||||
|
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, {
|
return Object.assign({}, state, {
|
||||||
myClaims,
|
myClaims,
|
||||||
byId,
|
byId,
|
||||||
|
|
|
@ -157,6 +157,11 @@ export const selectMyClaimsWithoutChannels = createSelector(
|
||||||
myClaims => myClaims.filter(claim => !claim.name.match(/^@/))
|
myClaims => myClaims.filter(claim => !claim.name.match(/^@/))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const selectAllMyClaimsByTxidNout = createSelector(
|
||||||
|
_selectState,
|
||||||
|
state => state.allMyClaimsByTxidNout || {}
|
||||||
|
);
|
||||||
|
|
||||||
export const selectMyClaimsOutpoints = createSelector(
|
export const selectMyClaimsOutpoints = createSelector(
|
||||||
selectMyClaims,
|
selectMyClaims,
|
||||||
myClaims => {
|
myClaims => {
|
||||||
|
|
|
@ -62,9 +62,10 @@ table.table-stretch {
|
||||||
}
|
}
|
||||||
|
|
||||||
table.table-transactions {
|
table.table-transactions {
|
||||||
td:nth-of-type(1) { width: 15%; }
|
td:nth-of-type(1) { width: 13%; }
|
||||||
td:nth-of-type(2) { width: 15%; }
|
td:nth-of-type(2) { width: 13%; }
|
||||||
td:nth-of-type(3) { width: 15%; }
|
td:nth-of-type(3) { width: 13%; }
|
||||||
td:nth-of-type(4) { width: 40%; }
|
td:nth-of-type(4) { width: 35%; }
|
||||||
td:nth-of-type(5) { width: 15%; }
|
td:nth-of-type(5) { width: 13%; }
|
||||||
|
td:nth-of-type(6) { width: 13%; }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue