{reward &&
diff --git a/ui/js/component/transactionList/view.jsx b/ui/js/component/transactionList/view.jsx
index beb2f8514..f736320bf 100644
--- a/ui/js/component/transactionList/view.jsx
+++ b/ui/js/component/transactionList/view.jsx
@@ -1,6 +1,9 @@
import React from "react";
import TransactionListItem from "./internal/TransactionListItem";
import FormField from "component/formField";
+import Link from "component/link";
+import * as icons from "constants/icons";
+import * as modals from "constants/modal_types";
class TransactionList extends React.PureComponent {
constructor(props) {
@@ -23,6 +26,16 @@ 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(txid, nout) {
+ this.props.openModal(modals.CONFIRM_CLAIM_REVOKE, { txid, nout });
+ }
+
render() {
const { emptyMessage, rewards, transactions } = this.props;
@@ -48,6 +61,11 @@ class TransactionList extends React.PureComponent {
+ {" "}
+
}
{!transactionList.length &&
@@ -70,6 +88,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)}
/>
)}
diff --git a/ui/js/component/video/view.jsx b/ui/js/component/video/view.jsx
index 31f0d9e23..f65a63204 100644
--- a/ui/js/component/video/view.jsx
+++ b/ui/js/component/video/view.jsx
@@ -73,9 +73,7 @@ class Video extends React.PureComponent {
"It looks like you deleted or moved this file. We're rebuilding it now. It will only take a few seconds."
);
} else if (isLoading) {
- loadStatusMessage = __(
- "Requesting stream..."
- );
+ loadStatusMessage = __("Requesting stream...");
} else if (isDownloading) {
loadStatusMessage = __("Downloading stream... not long left now!");
}
diff --git a/ui/js/constants/icons.js b/ui/js/constants/icons.js
index ce2f54e22..d28d7591e 100644
--- a/ui/js/constants/icons.js
+++ b/ui/js/constants/icons.js
@@ -2,3 +2,4 @@ export const FEATURED = "rocket";
export const LOCAL = "folder";
export const FILE = "file";
export const HISTORY = "history";
+export const HELP_CIRCLE = "question-circle";
diff --git a/ui/js/constants/modal_types.js b/ui/js/constants/modal_types.js
index 9e82be50a..d68349d44 100644
--- a/ui/js/constants/modal_types.js
+++ b/ui/js/constants/modal_types.js
@@ -13,3 +13,4 @@ export const INSUFFICIENT_BALANCE = "insufficient_balance";
export const REWARD_APPROVAL_REQUIRED = "reward_approval_required";
export const AFFIRM_PURCHASE = "affirm_purchase";
export const CREDIT_INTRO = "credit_intro";
+export const CONFIRM_CLAIM_REVOKE = "confirmClaimRevoke";
diff --git a/ui/js/constants/transaction_types.js b/ui/js/constants/transaction_types.js
new file mode 100644
index 000000000..89530f9f0
--- /dev/null
+++ b/ui/js/constants/transaction_types.js
@@ -0,0 +1 @@
+export const TIP = "tip";
diff --git a/ui/js/modal/modalRevokeClaim/index.js b/ui/js/modal/modalRevokeClaim/index.js
new file mode 100644
index 000000000..766095b64
--- /dev/null
+++ b/ui/js/modal/modalRevokeClaim/index.js
@@ -0,0 +1,17 @@
+import React from "react";
+import { connect } from "react-redux";
+import { doCloseModal } from "actions/app";
+import { doAbandonClaim } from "actions/content";
+import { selectTransactionItems } from "selectors/wallet";
+import ModalRevokeClaim from "./view";
+
+const select = state => ({
+ transactionItems: selectTransactionItems(state),
+});
+
+const perform = dispatch => ({
+ closeModal: () => dispatch(doCloseModal()),
+ abandonClaim: (txid, nout) => dispatch(doAbandonClaim(txid, nout)),
+});
+
+export default connect(select, perform)(ModalRevokeClaim);
diff --git a/ui/js/modal/modalRevokeClaim/view.jsx b/ui/js/modal/modalRevokeClaim/view.jsx
new file mode 100644
index 000000000..06f1362f8
--- /dev/null
+++ b/ui/js/modal/modalRevokeClaim/view.jsx
@@ -0,0 +1,86 @@
+import React from "react";
+import { Modal } from "modal/modal";
+import * as txnTypes from "constants/transaction_types";
+
+class ModalRevokeClaim extends React.PureComponent {
+ constructor(props) {
+ super(props);
+ }
+
+ revokeClaim() {
+ const { txid, nout } = this.props;
+
+ this.props.closeModal();
+ this.props.abandonClaim(txid, nout);
+ }
+
+ getButtonLabel(type) {
+ if (type == txnTypes.TIP) {
+ return "Confirm Tip Unlock";
+ } else {
+ return "Confirm Claim Revoke";
+ }
+ }
+
+ getMsgBody(type) {
+ if (type == txnTypes.TIP) {
+ return (
+
+
{__("Confirm Tip Unlock")}
+
+ {__("Are you sure you want to unlock these credits?")}
+
+
+ {__(
+ "These credits are permanently yours and can be\
+ unlocked at any time. Unlocking them allows you to\
+ spend them, but can hurt the performance of your\
+ content in lookups and search results. It is\
+ recommended you leave tips locked until you\
+ need or want to spend them."
+ )}
+
+
+ );
+ } else {
+ return (
+
+
{__("Confirm Claim Revoke")}
+
+ {__("Are you sure want to revoke this claim?")}
+
+
+ {__(
+ "This will prevent others from resolving and\
+ accessing the content you published. It will return\
+ the LBC to your spendable balance, less a small\
+ transaction fee."
+ )}
+